NLP

学習したことを記録しています

研究室のBossがサンタクロースと見分けがつかないので機械学習で自動判定させてみた

ふと寝る前に思ったことがある。

「うちの研究室のBoss(教授)サンタクロースじゃね?」

f:id:hayan10:20170829191815p:plain

↑Boss

   f:id:hayan10:20170829192953j:plain    f:id:hayan10:20170829193810j:plain

       ↑サンタクロース

いや絶対、副業でサンタクロースやってるでしょ!!

赤い服と帽子したら完全にサンタクロース

Bossが研究室に入ってきたらサンタクロースだと思ってしまい、クリスマス気分となってしますので全然研究が進まない、、、

これではダメだと思ってBossとサンタクロースを機械学習を用いて見分けることにした。

Bossの学習用のデータは研究室にたくさん写真があったのでBossの顔だけ抽出して使用

サンタクロースの学習用のデータはGoogleの画像検索から拾ってきた

Bossとサンタクロースだけでは味気ないのでカーネルさんも混ぜてあげた

f:id:hayan10:20170829195824j:plain

Bossデータ

f:id:hayan10:20170829215633p:plain

サンタクロースデータ

f:id:hayan10:20170829215635p:plain

カーネルデータ

f:id:hayan10:20170829215637p:plain

train用がそれぞれ25枚づつでtest用が8枚用意しました。

Bossの写真があんまりなくて学習が不安…

コードはこんな感じ こちらを参考にさせていただきました

http://qiita.com/hiroeorz@github/items/2fbb3b8d12b0e20f0384#_reference-99be2aef3ed42fdd155a

from keras.models import Sequential
from keras.layers import Activation, Dense, Dropout, Convolution2D, Flatten, MaxPooling2D
from keras.utils.np_utils import to_categorical
from keras.optimizers import Adagrad
from keras.optimizers import Adam
import numpy as np
from PIL import Image
import os

image_list = []
label_list = []

for dir in os.listdir("data/train"):
    if dir == ".DS_Store":
        continue

    dir1 = "data/train/" + dir 
    label = 0

    if dir == "boss":    
        label = 0
    elif dir == "santa":
        label = 1
    elif dir == "colonel":
        label = 2

    for file in os.listdir(dir1):
        if file != ".DS_Store":
            label_list.append(label)
            filepath = dir1 + "/" + file
            image = np.array(Image.open(filepath).resize((100, 100)))
            print(filepath)
            image = image.transpose(2, 0, 1)
            print(image.shape)
            image_list.append(image / 255.)

image_list = np.array(image_list)

Y = to_categorical(label_list)

model = Sequential()
model.add(Convolution2D(32, 3, 3, border_mode='same', input_shape=(3, 100, 100)))
model.add(Activation("relu"))
model.add(Convolution2D(32, 3, 3))
model.add(Activation("relu"))
model.add(Convolution2D(32, 3, 3))
model.add(Activation("relu"))
model.add(MaxPooling2D(pool_size=(2, 2), border_mode=("same")))
model.add(Dropout(0.25))

model.add(Flatten())

model.add(Dense(200))
model.add(Activation("relu"))
model.add(Dropout(0.2))

model.add(Dense(200))
model.add(Activation("relu"))
model.add(Dropout(0.2))

model.add(Dense(3))
model.add(Activation("softmax"))

opt = Adam(lr=0.0001)

model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"])
model.fit(image_list, Y, nb_epoch=1000, batch_size=25, validation_split=0.1)

total = 0.
ok_count = 0.

for dir in os.listdir("data/test"):
    if dir == ".DS_Store":
        continue

    dir1 = "data/test/" + dir 
    label = 0

    if dir == "boss":
        label = 0
    elif dir == "santa":
        label = 1
    elif dir == "colonel":
        label = 2

    for file in os.listdir(dir1):
        if file != ".DS_Store":
            label_list.append(label)
            filepath = dir1 + "/" + file
            image = np.array(Image.open(filepath).resize((100, 100)))
            print(filepath)
            image = image.transpose(2, 0, 1)
            result = model.predict_classes(np.array([image / 255.]))
            print("label:", label, "result:", result[0])

            total += 1.

            if label == result[0]:
                ok_count += 1.

print("accuracy: ", ok_count / total * 100, "%")

実際に実行すると・・

Epoch 1000/1000
25/67 [==========>...................] - ETA: 0s - loss: 9.7016e-05 - acc: 1.00067/67 [==============================] - 0s - loss: 1.8117e-04 - acc: 1.0000 - val_loss: 0.8950 - val_acc: 0.8750
data/test/colonel/index7.jpeg
1/1 [==============================] - 0s
label: 2 result: 2
data/test/colonel/index3.jpeg
1/1 [==============================] - 0s
label: 2 result: 0
data/test/colonel/index4.jpeg
1/1 [==============================] - 0s
label: 2 result: 2
data/test/colonel/index6.jpeg
1/1 [==============================] - 0s

   (省略)

label: 1 result: 1
data/test/santa/index1.jpeg
1/1 [==============================] - 0s
label: 1 result: 1
data/test/santa/index5.jpeg
1/1 [==============================] - 0s
label: 1 result: 1
data/test/santa/index0.jpeg
1/1 [==============================] - 0s
label: 1 result: 1
accuracy:  79.16666666666666 %
79.16666666666666 %

低い、、もともとのデータ数が少ないので当然といえば当然

実際の分類はこんな感じ

f:id:hayan10:20170829203427p:plain

↑判定:Boss

f:id:hayan10:20170829203713p:plain

↑判定:カーネル

f:id:hayan10:20170829210413p:plain

↑判定:Boss

f:id:hayan10:20170829210505p:plain

↑判定:カーネル

f:id:hayan10:20170829210326p:plain

↑判定:Boss

f:id:hayan10:20170829210705p:plain

↑判定:Boss

f:id:hayan10:20170829210242p:plain

↑判定:Boss

ちなみにこれ↓はBossだそうです。

f:id:hayan10:20170829211435j:plain

確かに似てる!!

Bossのデータセットが少ないので精度が低くなりました。これからは研究しながらこっそり集めたいと思います。 こんなことしてるから研究進まないんですけどね

最後に

Bossはサンタクロースよりもカーネル似でした
これらの結果から言えることは
面接官がBossならカーネルさんと思え、以上
Bossに怒られそうで怖い。。