Help us understand the problem. What is going on with this article?

TensorFlowで嵐の顔を判別

More than 1 year has passed since last update.

はじめに

今回 TensorFlow を初めて使いました。TensorFlow で画像認識をやりたいのですが、公式のサンプルはあまりピンと来ず、よさそうな記事を見つけたので参考にしました。

参考にした記事
keras(tensorflow)で花の画像から名前を特定 - Qiita

過去のiPhoneを使った機械学習の投稿
iPhoneで顔認識 - Qiita
機械学習でストリートファイター - Qiita
iPhoneと機械学習でフライドチキンの部位を分類する - Qiita

Tensorflowの準備

TensorFlowって何
(ウィキペディアより)
TensorFlow(テンソルフロー)とは、Googleが開発しオープンソースで公開している、機械学習に用いるためのソフトウェアライブラリである。

具体的には、Python環境で下記を実行するとインストールできます。
pip install tensorflow

画像判別に必要なもの
1. 訓練画像を集めます。
2. 訓練画像から学習モデルを作ります。
3. 入力画像を学習モデルに与えると判別されます。

訓練画像の準備

2019-0330-01.png

imagesフォルダ以下に画像を集めます。フォルダー名がカテゴリー名(分類名)となります。150枚以上が望ましいのですが、私は50枚程で心が折れました。
今回は、相葉、松本、二宮、大野、櫻井の5人です。入力画像から「強いて言えば誰か」を判別します。

使い方

  1. images フォルダ内に学習モデル用の訓練画像を用意します。
  2. inputs フォルダ内に予測したい入力画像を用意します。
  3. python model.py → mymodel.hdf5 が作成されます。
  4. python main.py → print で結果が出力されます。

ソースコード

以下を実行します。足りないものは pip install 行ってください。

model.py
# -*- coding: utf-8 -*-
import sys
import os
import gc
import glob
import numpy as np
import pandas as pd
import random, math
import traceback
from PIL import Image
from keras.models import Sequential
from keras.layers import Convolution2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.utils import np_utils

class MyModel:
    def __init__(self):
        self.images_dir = './images'
        self.hdf5_file = './mymodel.hdf5'
        self.sub_dir = [name for name in os.listdir(self.images_dir) if name != ".DS_Store"]

    #------------------------------------
    # 学習モデルの作成と保存
    #------------------------------------
    def save_model(self):
        try:
            # 画像読み込み
            train_data = [] 
            for i, sdir in enumerate(self.sub_dir): 
                print("->", sdir)
                files = [name for name in os.listdir(self.images_dir + "/" + sdir) if name != ".DS_Store"]
                for f in files:
                    data = self.create_data_from_image(self.images_dir + '/' + sdir + '/' + f)
                    train_data.append([data,i])

            # シャッフル
            random.shuffle(train_data)
            X, Y = [],[]
            for data in train_data: 
                X.append(data[0])
                Y.append(data[1])

            test_idx = math.floor(len(X) * 0.8)
            xy = (np.array(X[0:test_idx]), np.array(X[test_idx:]), 
                np.array(Y[0:test_idx]), np.array(Y[test_idx:]))
            x_train, x_test, y_train, y_test = xy

            # 正規化
            self.x_train = x_train.astype("float") / 256
            self.x_test = x_test.astype("float") / 256
            self.y_train = np_utils.to_categorical(y_train, len(self.sub_dir))
            self.y_test = np_utils.to_categorical(y_test, len(self.sub_dir))

            # 学習モデルの保存
            model = self.create_model_from_shape(self.x_train.shape[1:])
            model.fit(self.x_train, self.y_train, batch_size=32, nb_epoch=10)
            model.save_weights(self.hdf5_file)

            # テスト
            score = model.evaluate(self.x_test, self.y_test)
            print('loss=', score[0])
            print('accuracy=', score[1])

        except Exception as e:
            print('Exception:', traceback.format_exc(), e.args)

    #------------------------------------
    # 入力画像の予測
    #------------------------------------
    def predict_from_dir(self, dir):
        X = []
        files = [name for name in os.listdir(dir) if name != ".DS_Store"]
        for f in files: 
            data = self.create_data_from_image(os.path.join(dir,f))
            X.append(data)
        X = np.array(X)
        model = self.create_model_from_shape(X.shape[1:])
        model.load_weights(self.hdf5_file)
        predictions = model.predict(X)
        return predictions

    # 画像ファイルからデータを作成
    def create_data_from_image(self, file):
        img = Image.open(file)
        img = img.convert("RGB")
        img = img.resize((50,50))
        data = np.asarray(img)
        return data

    # Shape から Model の作成
    def create_model_from_shape(self, shape):
        # K=32, M=3, H=3
        model = Sequential()
        model.add(Convolution2D(32, 3, 3, border_mode='same', input_shape=shape))

        # K=64, M=3, H=3 調整
        model.add(Activation('relu'))
        model.add(MaxPooling2D(pool_size=(2, 2)))
        model.add(Dropout(0.25))
        model.add(Convolution2D(64, 3, 3, border_mode='same'))
        model.add(Activation('relu'))
        # K=64, M=3, H=3 調整
        model.add(Convolution2D(64, 3, 3))
        model.add(MaxPooling2D(pool_size=(2, 2)))
        model.add(Dropout(0.25))
        model.add(Flatten()) 
        model.add(Dense(512))
        # biases
        model.add(Activation('relu'))
        model.add(Dropout(0.5))
        model.add(Dense(len(self.sub_dir)))
        model.add(Activation('softmax'))

        model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
        return model

if __name__ == "__main__":
    m = MyModel()
    m.save_model()
    gc.collect()
main.py
# -*- coding: utf-8 -*-
import sys, os
import numpy as np
import pandas as pd
from PIL import Image
from model import MyModel

images_dir = './images'
inputs_dir = './inputs'
categories = [name for name in os.listdir(images_dir) if name != ".DS_Store"]
inputs = [name for name in os.listdir(inputs_dir) if name != ".DS_Store"]

# 入力画像の予測値
predictions = MyModel().predict_from_dir(inputs_dir)

# 結果出力
strcat = ''
for cat in categories:
    strcat += cat.ljust(10,' ')
print("             ", strcat)

for i,input in enumerate(inputs):    
    strpre = input.ljust(14, ' ')
    for pre in predictions[i]:
        strpre += str(round(pre,3)).ljust(10,' ')
    print(strpre)

結果

              Aiba      Matsumoto Ninomiya  Ohno      Sakurai
aiba.png      1.0       0.0       0.0       0.0       0.0
ninomiya.png  0.0       0.0       1.0       0.0       0.0
sakurai.png   0.0       0.0       0.0       0.0       1.0
koji1.png     0.0       0.0       0.0       1.0       0.0
koji2.png     0.0       0.0       0.0       1.0       0.0
koji3.png     0.0       0.0       0.0       1.0       0.0
入力画像 予測結果
Aiba
Ninomiya
Sakurai
koji1.png
koji2.png
koji3.png
Ohno

う~ん、0と1しか出ないのですね。要勉強です。

まとめ

私(Koji4104)は大野くんに似ているという結果が出ました。私も違う景色を見てみたいです。

koji4104
Windowsに未来はあるのか
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした