EvbCFfp1XB

problem and my answer.

January 2016


It looks random.



epoch SSE
10 125.4981752754
20 128.3121159201
30 133.8689272647
40 133.617967041
50 132.1159835049
60 128.3779561962
70 129.4106086883
80 131.6864443667
90 130.1017239823
100 128.3965430144
110 131.0931574591
120 133.0148986858
130 132.0645031124
140 129.987868105
150 130.3467179628
160 126.5596166926
170 129.5290312334
180 128.700665234
190 128.1035207545
200 130.3923627785



#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




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 = 256
        self.useSmallImage = True
#        self.useSmallImage = Fal/se
        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) + "/epoch/"
 
        
    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 + "FacialEmotions200.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 = 200
            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 and epoch%10 == 0:
                    self.model.to_cpu()
                    cPickle.dump(self.model, open(self.folder + "FacialEmotions"+ str(epoch) +".pkl", "wb"), -1)







        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()



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()





mean(random 4000seeds) solution
0.9880 submission3 (BeamWidth250)
0.9889 submission3 with BeamWidth300
0.9898 submission3 with BeamWidth350
0.9903 submission3 with BeamWidth400

mean(random 4000seeds) solution
0.9880 submission3 (1to10)
0.9890 submission3 with 1to12
0.9895(3994.7502/4037) submission3 with 1to14
0.9895(3994.4547/4037) submission3 with 1to16

mean(random 4000seeds) solution
0.9884 fhlasek
0.9880 submission3 (1to10 MaxDepth20 BeamWidth250)
0.9913 submission3 with 1to12 MaxDepth25 BeamWidth300

mean(random 5000seeds) solution
0.9863 submission3 with MaxDepth15
0.9889 submission3 (MaxDepth20)
0.9894 submission3 with MaxDepth25
0.9891 submission3 with MaxDepth30

mean(random 7000seeds) solution
0.9906 submission3 with BeamWidth400
0.9909 submission3 with BeamWidth450
0.9905 submission3 with BeamWidth500
0.9904 submission3 with BeamWidth550
0.9898 submission3 with BeamWidth600

このページのトップヘ