TensorFlowのTutorialを改造して画像識別
- 2017.02.05
- TensorFlow
以前少しだけTensorFlowの記事を書きましたが、
久しぶりにTensorFlowを触ってみたので、成果物のご紹介。
やりたいこと
アイドルマスターシンデレラガールズのキャラクターを識別する。
やったこと
- フリーソフトを使って画像を自動収集。
- ここのプログラムの応用で、顔画像を切り出して、手動でタグ付け。(ファイル名を”タグ,(連番).jpg”に)
- チュートリアルのプログラムを元に、学習プログラムを作成して、顔画像を学習。
- 学習したパラーメタを使って検証。
学習プログラム
学習した顔画像は、64*64のリサイズにして保存しています。
また、ファイル名のカンマ以前の数字がキャラクターを識別するタグとなります。
今回は2500枚程度用意しました。
顔画像の例↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
import cv2 import sys import os.path import glob import numpy as np import tensorflow as tf image_w=64 image_h=64 dim_in=image_w*image_h dim_out=18 limit=3000 batch_size=100 paths=glob.glob("images/*") image_num=len(paths) train_x=np.zeros((image_num,dim_in)) train_y=np.zeros((image_num,dim_out)) #loading images cnt=0 for path in paths: image = cv2.imread(path,0)/255.0 tag=int(os.path.basename(path).split(",")[0]) train_x[cnt,:]=[flatten for inner in image for flatten in inner] #flatten matrix train_y[cnt,tag]=1 print (tag) cnt+=1 #neural network x = tf.placeholder(tf.float32, [None, dim_in]) #place holder W = tf.Variable(tf.zeros([dim_in, dim_out])) #weight b = tf.Variable(tf.zeros([dim_out])) #bias y = tf.nn.softmax(tf.matmul(x, W) + b) #normalize y_ = tf.placeholder(tf.float32, [None, dim_out]) #placeholder #cross entropy cross_entropy = -tf.reduce_sum(y_ * tf.log(y)) #minimize cross_entropy using the gradient descent algorithm train_step = tf.train.GradientDescentOptimizer(0.0005).minimize(cross_entropy) #initialize all variables init = tf.initialize_all_variables() #correct boolean list correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) #cast to float point numbers accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) saver=tf.train.Saver() sess = tf.Session() sess.run(init) #training step train_count=0 for i in range(limit): rnd=np.random.randint(image_num-batch_size) sess.run(train_step,feed_dict={x:train_x[rnd:rnd+batch_size,:],y_:train_y[rnd:rnd+batch_size,:]}) train_count+=1 print train_count,sess.run(accuracy,feed_dict={x:train_x[rnd:rnd+batch_size,:],y_:train_y[rnd:rnd+batch_size,:]}) print sess.run(accuracy,feed_dict={x:train_x,y_:train_y}) #save saver.save(sess,"model.ckpt") |
概要説明:
“images”フォルダに保存された顔画像を読み込み、画素情報を一次元化し、入力用テンソルに保存。
ウェイトやバイアス、損失関数や正答率用の関数を定義。
バッチサイズ分のデータを切り出して、学習。それを規定ステップ分繰り返し。
最後にモデルを保存。
評価用プログラム
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
import cv2 import os.path import glob import numpy as np import tensorflow as tf image_w=64 image_h=64 dim_in=image_w*image_h dim_out=18 paths=glob.glob("images/*") image_num=len(paths) train_x=np.zeros((image_num,dim_in)) train_y=np.zeros((image_num,dim_out)) #loading images cnt=0 for path in paths: image = cv2.imread(path,0)/255.0 tag=int(os.path.basename(path).split(",")[0]) train_x[cnt,:]=[flatten for inner in image for flatten in inner] #flatten matrix train_y[cnt,tag]=1 print (tag) cnt+=1 #neural network x = tf.placeholder(tf.float32, [None, dim_in]) #place holder W = tf.Variable(tf.zeros([dim_in, dim_out])) #weight b = tf.Variable(tf.zeros([dim_out])) #bias y = tf.nn.softmax(tf.matmul(x, W) + b) #normalize y_ = tf.placeholder(tf.float32, [None, dim_out]) #placeholder #correct boolean list correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) #cast to float point numbers accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) saver=tf.train.Saver() sess=tf.Session() saver.restore(sess,"model.ckpt") print sess.run(accuracy,feed_dict={x:train_x,y_:train_y}) |
概要説明:
画像の読み込みや変数、関数の定義は同じ。
モデルを読み込み、これを使って識別した時の正答率を表示。
所感
今回は画像があまり集められなかったことと、振り分けが面倒だったことが理由で、
画像の量が少ないですが、学習用データに対する正答率は94%程度でした。
上記のプログラムはディープラーニングではなく、非常に単純なニューラルネットワークなので、
気が向いたらディープラーニング化してみたいと思います。
-
前の記事
Unityの起動失敗と対策 2016.12.05
-
次の記事
WindowsにTensorFlowをインストール 2017.02.09