kerasでCNN 自分で拾った画像でやってみる
基本はこの記事を参照して作成しました。
微妙に違うだけです。
細かい部分は自分で調べて何とかしました。
ぶっちゃけ動いたからヨシなので勉強不足です。
目的としてはとある物の写真からOKとNGを判定したいので
元となるデータとしては画像データ(640x480)を
OK・NG共に1000枚使用しています。
あくまでも初心者が辿り着いた結果をメモとして残すのが目的です。
#環境
Windows10 64bit
Anaconda navigator
Jupiter notebook
Python 3.7.7
tensorflow 2.1.0
tensorflow-gpu 2.1.0
keras 2.3.1
numpy 1.18.1
matplotlib 3.1.3
上記環境でプログラムを構築
#ライブラリ
import keras
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers.convolutional import MaxPooling2D
from keras.layers import Activation, Conv2D, Flatten, Dense,Dropout
from sklearn.model_selection import train_test_split
from keras.optimizers import SGD, Adadelta, Adagrad, Adam, Adamax, RMSprop, Nadam
from PIL import Image
import numpy as np
import glob
import matplotlib.pyplot as plt
import time
import os
from keras.optimizers import
にはAdadelta
だけでよかったですが
色々と試したくて入れてます。(結局テストせんかったけど…)
#各種設定関係
#設定
batch_size = 16
epochs = 200
#画像ディレクトリ
test_dir ="画像保存しているディレクトリを指定"
folder = os.listdir(test_dir)
#元画像640x480をresizeする際の大きさ設定
x_image_size = 200#640→200
y_image_size = 200#480→200
dense_size = len(folder)
batch_size
に関しては色々なサイトを見るに1・4・32等々設定値が転がっていたので
初めは32で回してみましたがエラーが出てなんともならなくなったので16に設定しています。
細かい部分まで調べ切れていないので正しいとは言えないと…
ただ回ったのでヨシにしています。
画像サイズを縦・横で色々と変えて試す為に分けて設定していますが
結果200まで落とさないと重すぎて動きませんでした。
なのでimage_size = 200
でも問題ありません。(後の記述は一部変更必要)
#画像読み込み
X = []
Y = []
for index, name in enumerate(folder):
dir = test_dir + name
files = glob.glob(dir + "/*.jpg")
for i, file in enumerate(files):
image = Image.open(file)
image = image.convert("RGB")
image = image.resize((x_image_size, y_image_size))
data = np.asarray(image)
X.append(data)
Y.append(index)
X = np.array(X)
Y = np.array(Y)
X = X.astype('float32')
X = X / 255.0
Y = np_utils.to_categorical(Y, dense_size)
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.15)
今回はテストを15%にした位で、参考にさせて頂いた記事とほとんど変わりません。
#CNNモデル作成
model = Sequential()
model.add(Conv2D(32, (3, 3), padding='same',input_shape=X_train.shape[1:]))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Conv2D(64, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(dense_size))
model.add(Activation('softmax'))
model.summary()
正直な所、勉強しながらなので
どこをどのように触れば変化するのか?については分かってないです。
keras公式サイト
ここを見ていますが、素人には理解できないっす…
#学習機作成
optimizers ="Adadelta"
results = {}
model.compile(loss='categorical_crossentropy', optimizer=optimizers, metrics=['accuracy'])
results[0]= model.fit(X_train, y_train, validation_split=0.2, epochs=epochs,batch_size=batch_size)
model_json_str = model.to_json()
open('model.json', 'w').write(model_json_str)
model.save('weights.h5');
正直、Qiitaがなければ辿り着く事すら出来ませんでした。
ありがとうございます。
はじめはひどいもので学習結果が横棒になるという結果でした。
その時は画像データも各50枚程度と少なく
epoch数も20程度でした。
とある方に『画像が命』と教えて頂きましたが、正にその通りの結果になったと思います。
後はこのデータを元に推論を作って、ちゃんと結果出るかがドキドキです。
#まとめ
なんだかんだでデータとしては作る事が出来ました。
『色々と試してみる』部分が圧倒的に不足している事を思い知りました。
手を動かさないと覚えない・知ろうとしない事を改めて知る事が出来ました。
40歳目前から始めると脳が拒否するので大変です。
以上です。