The more batch size, the better.
batch size | time | train mean loss | SSE | score |
64 | 10855.791047 | 0.302706 | 130.547356431 | 0 |
128 | 10692.346976 | 0.355007 | 126.1506579977 | 0 |
256 | 11432.415434 | 0.719253 | 125.145132211 | 3878.5556403073 |
512 | 11727.674402 | 0.901692 | 122.4872463326 | 25034.6092029519 |
1024 | 9788.413161 | 1.126872 | 120.8812013435 | 37818.2934424894 |
#coding: utf-8 import numpy as np import sys import chainer from chainer import cuda import chainer.functions as F from chainer import optimizers import time import cPickle #epoch: 20, time: 10692.346976, train mean loss: 0.355007 #SSE = 126.15065799772859 #SSE Base = 125.63240448203754 #SSE on [angry] = 10.759377271761652 #SSE on [anxious] = 9.174422347429728 #SSE on [confident] = 13.666987468290872 #SSE on [happy] = 49.13119229673229 #SSE on [neutral] = 31.023431109263406 #SSE on [sad] = 6.87797579854229 #SSE on [surprised] = 5.517271705708345 #Score = 0.0 class FacialEmotions: def __init__(self): self.startTime = time.clock(); # self.useMax = True self.useMax = False # self.useModel = True self.useModel = False # self.train_size10 = True self.train_size10 = False self.train = [] self.train_result = [] self.train_index = 0 self.test = [] self.test_index = 0 self.batchsize = 128 self.useSmallImage = True # self.useSmallImage = False self.size = 64 self.model = chainer.FunctionSet(conv1=F.Convolution2D(3, 32, 3, pad=1), # l1=F.Linear(32*(self.size/2)*(self.size/2), 256), conv2=F.Convolution2D(32, 64, 3, pad=1), l1=F.Linear(64*(self.size/4)*(self.size/4), 256), # conv3=F.Convolution2D(64, 128, 3, pad=1), # l1=F.Linear(128*(self.size/8)*(self.size/8), 256), # conv4=F.Convolution2D(128, 256, 3, pad=1), # l1=F.Linear(256*(self.size/16)*(self.size/16), 256), # conv5=F.Convolution2D(256, 512, 3, pad=1), # l1=F.Linear(512*(self.size/32)*(self.size/32), 256), l2=F.Linear(256, 7)) self.folder = "./python/layer2/mini-batch" + str(self.batchsize) + "/" def newImage(self, img): size = self.size original = np.zeros((3,250,250)) for r in range(250): for c in range(250): value = img[r * 250 + c] red = (value >> 16) & 255 green = (value >> 8) & 255 blue = (value >> 0) & 255 original[0][r][c] = red original[1][r][c] = green original[2][r][c] = blue if self.useSmallImage == True: small = np.zeros((3,125,125)) for color in range(3): for r in range(125): for c in range(125): value = original[color][2*r][2*c] value += original[color][2*r][2*c+1] value += original[color][2*r+1][2*c] value += original[color][2*r+1][2*c+1] small[color][r][c] = value/4.0 res = np.zeros((3,size,size)) for color in range(3): for r in range(size): for c in range(size): res[color][r][c] = small[color][(125/2) - (size/2) + r][(125/2) - (size/2) + c] else: res = np.zeros((3,size,size)) for color in range(3): for r in range(size): for c in range(size): res[color][r][c] = original[color][(250/2) - (size/2) + r][(250/2) - (size/2) + c] return res def newImage0(self, img): size = 250 newImg = np.zeros((3,size,size)) for r in range(size): for c in range(size): value = img[r*250+c] red = (value >> 16) & 255 green = (value >> 8) & 255 blue = (value >> 0) & 255 newImg[0][r][c] = red newImg[1][r][c] = green newImg[2][r][c] = blue return newImg def training(self, img,emot,*args): if self.train_index % 100 == 0: print >> sys.stderr, self.train_index if self.useModel == True: return 1 self.train.append(self.newImage(img)) emotion = 0 for i in range(7): emotion += (i+0) * emot[i] self.train_result.append(emotion) self.train_index+=1 if self.train_size10 == True and self.train_index == 10: return 1 return 0 def testing(self, img,*args): if self.useModel == True and self.test_index == 0: pkl_file = open(self.folder + "FacialEmotions.pkl", "rb") self.model = cPickle.load(pkl_file) elif self.test_index == 0: self.train = np.array(self.train, dtype=np.float32) self.train_result = np.array(self.train_result, dtype=np.int32) self.test = np.array(self.test, dtype=np.float32) self.train /= 255.0 self.test /= 255.0 def forward(x_data, y_data, train=True): x, t = chainer.Variable(x_data), chainer.Variable(y_data) h = F.max_pooling_2d(F.relu(self.model.conv1(x)), 2) h = F.max_pooling_2d(F.relu(self.model.conv2(h)), 2) h = F.dropout(F.relu(self.model.l1(h)), train=train) y = self.model.l2(h) if train: return F.softmax_cross_entropy(y, t) else: return F.accuracy(y, t) optimizer = optimizers.Adam() optimizer.setup(self.model) batchsize = self.batchsize n_epoch = 20 xp = np X_train = self.train y_train = self.train_result N = len(y_train) print >> sys.stderr, "start epoch, time: %f" % (time.clock() - self.startTime) for epoch in range(1, n_epoch + 1): perm = np.random.permutation(N) sum_loss = 0 for i in range(0, N, batchsize): x_batch = xp.asarray(X_train[perm[i:i + batchsize]]) y_batch = xp.asarray(y_train[perm[i:i + batchsize]]) optimizer.zero_grads() loss = forward(x_batch, y_batch) loss.backward() optimizer.update() sum_loss += float(loss.data) * len(y_batch) print >> sys.stderr, "epoch: %d, time: %f, train mean loss: %f" % (epoch,time.clock() - self.startTime, sum_loss / N) if self.useModel == False: self.model.to_cpu() cPickle.dump(self.model, open(self.folder + "FacialEmotions.pkl", "wb"), -1) def forward_predict(x_data, train=True): x = chainer.Variable(x_data) h = F.max_pooling_2d(F.relu(self.model.conv1(x)), 2) h = F.max_pooling_2d(F.relu(self.model.conv2(h)), 2) h = F.dropout(F.relu(self.model.l1(h)), train=train) y = self.model.l2(h) return y self.test_index+=1 newImg = self.newImage(img) test = [] test.append(newImg) test = np.array(test, dtype=np.float32) test /= 255.0 predict = forward_predict(test) if self.useMax == True: res = [] max_value = max(predict.data[0]) for value in predict.data[0]: if value == max_value: res.append(1) else: res.append(0) return res else: min_value = min(predict.data[0]) res0 = [] for value in predict.data[0]: res0.append(value-min_value) sum = 0 for value in res0: sum += value res = [] for value in res0: res.append(value/sum) return res if __name__ == "__main__": fe = FacialEmotions() N = int(raw_input()) for i in range(N): S = int(raw_input()) imageData = [] emotions = [] for j in range(S): imageData.append(int(raw_input())) for j in range(7): emotions.append(float(raw_input())) ret = fe.training(imageData, emotions) print ret sys.stdout.flush() if ret == 1: break M = int(raw_input()) for i in range(M): S = int(raw_input()) imageData = [] for j in range(S): imageData.append(int(raw_input())) ret = fe.testing(imageData) for j in ret: print j sys.stdout.flush()
コメント