KerasによるCNNでアニメ画像の認識Part2
KerasによるCNNで画像の認識-ジャンヌ3姉妹-の続きで、ネットワークの改善をしました。
まだ、改善するところはたくさんありますが、今回の実験では、正答率が60%まで上がりました。
モデルの保存と読み込み
Kerasでは、保存するとき、hdf5ファイルもしくはh5ファイルを使用する。
jsonなどのファイル形式も使用できる。
今回は、hdf5ファイルを使用する。
モデルを保存
#modelの保存 model.save('ファイル名.hdf5')
重みを保存
#modelの保存の重みを保存 model.save_weights('ファイル名.hdf5')
モデルの読み込み
- 再構築可能なモデルの構造
- モデルの重み
- 学習時の設定 (loss,optimizer)
- optimizerの状態.これにより,学習を終えた時点から正確に学習を再開できます
モデルを保存すると、以上の4つのデータが保存されています。
#モデルを読み込む #保存したファイル.hdf5を選択 model = load_model('ファイル名.hdf5')
重みの読み込み
重みの保存は、重みしか保存されません。
重み保存した時の、ネットワークを用意する必要があります。
重み保存した時のネットワークと、読み込み時のネットワークが異なる場合は、エラーになるので気をつけなければなりません。
同じモデルを用意しなければならないことに注意です。
#重みを読み込む #保存したファイル.hdf5を選択 #model.load_weights('ファイル名.hdf5')
結果
今回は、エポックを10にしているため過学習は起こしていないと思われます。
本来、ドロップアウトは、過学習の対策で用いられるので、エポック数を増やして実験をしたいです。
学習精度
精度は、60%まで上昇しました。
前回は、30%だったので、かなり精度は上昇しました。
精度の推移
テストする(予測の実行)
画像のパスを入力すると、どのジャンヌか識別します。
成功例を紹介します。
結果
ソースコード
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
from keras.models import load_model
#ラベルを作る
LABELS = ["Jeanne", "JeanneAlt", "JeanneAltLi"]
#保存したモデル
model = load_model('jeanne_model.hdf5')
def check_jeanne(url):
# 対象画像のインポート&
img = Image.open(url)
img = img.convert("RGB")
img = img.resize((256, 256))
plt.imshow(img)
plt.show()
x = np.asarray(img)
x = x.reshape(-1, 256, 256, 3)
x = x / 255
# 予測
pre = model.predict(x)
#確率の一番高いインデックス番号を取得
idx = np.argmax(pre, axis=1)[0]
#一番高い確率をパーセンテージで取得
per = int(pre[0][idx] * 100)
return (idx, per, img)
def check_jeanne_result(url):
idx, per, img = check_jeanne(url)
#答えを表示
print("この写真は、", LABELS[idx])
print(per, "%の可能性で合っているだろう")
check_jeanne_result('train/Jeanne/IMG_0409.JPG')
まとめ
前回の実験KerasによるCNNで画像の認識-ジャンヌ3姉妹-では、ネットワークが単純であったので十分な予測精度が出ませんでしたが、今回は少し複雑にしたこともあり、精度が60%まで上昇することができました。
今後は、エポック数を増やしていく予定です。
参考書
ネットワークの構造
畳み込み層:4層
ニューラルネット:3層
ドロップアウト:0.5
今回は、ドロップアウトを実装します。
''' CNNの構築 ''' model = Sequential() #畳み込み層 model.add(Conv2D(32, (3, 3), input_shape = (256, 256, 3), activation='relu')) model.add(Conv2D(32, (3, 3), activation = 'relu')) model.add(MaxPooling2D(pool_size = (2, 2))) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(Conv2D(64, (3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2,2))) #平滑化 model.add(Flatten()) #全結合層 model.add(Dense(128, activation = 'relu')) model.add(Dense(64, activation = 'relu')) model.add(Dropout(0.5)) model.add(Dense(3, activation = 'softmax'))