研究室のBossがサンタクロースと見分けがつかないので機械学習で自動判定させてみた
ふと寝る前に思ったことがある。
「うちの研究室のBoss(教授)サンタクロースじゃね?」
↑Boss
↑サンタクロース
いや絶対、副業でサンタクロースやってるでしょ!!
赤い服と帽子したら完全にサンタクロース
Bossが研究室に入ってきたらサンタクロースだと思ってしまい、クリスマス気分となってしますので全然研究が進まない、、、
これではダメだと思ってBossとサンタクロースを機械学習を用いて見分けることにした。
Bossの学習用のデータは研究室にたくさん写真があったのでBossの顔だけ抽出して使用
サンタクロースの学習用のデータはGoogleの画像検索から拾ってきた
Bossとサンタクロースだけでは味気ないのでカーネルさんも混ぜてあげた
Bossデータ
サンタクロースデータ
カーネルデータ
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 %
低い、、もともとのデータ数が少ないので当然といえば当然
実際の分類はこんな感じ
↑判定:Boss
↑判定:カーネル
↑判定:Boss
↑判定:カーネル
↑判定:Boss
↑判定:Boss
↑判定:Boss
ちなみにこれ↓はBossだそうです。
確かに似てる!!
Bossのデータセットが少ないので精度が低くなりました。これからは研究しながらこっそり集めたいと思います。 こんなことしてるから研究進まないんですけどね