python初心者が作る、犬猫認識AI

Yutaka_kun
LSC PSD
Published in
6 min readOct 18, 2019

[python] [jupyter notebook] [dog_vs_cat] [CNN]

python素人です。kerasとCNN(畳み込みニューラルネットワーク)を用いて犬猫を認識させてみました。超細かい説明はできませんが、初心者が読み進めていってコードを書き移せば犬猫を認識するAIができている、、、はずです。

データセットの準備

kaggleから犬猫のデータセットをダウンロードしてください。

検証用: 500枚 (犬) 500枚(猫) 合計1000枚
訓練用:2000枚(犬) 2000枚(猫) 合計4000枚

にそれぞれデータを分け、

となるようにフォルダに画像を振り分けます。

データの前処理

ImageDataGeneratorflow_from_directoryを使って画像に前処理をします。

train_data_dir、test_data_dirそれぞれに犬猫のデータが保存されているパスを認識させます。
rescale = 1.0/255で画像のpixel値を正規化しています。
target_sizeに任意のサイズを入力します。
batch_sizeでモデルにデータを渡すときのバッチサイズを決定します。
今回犬猫の二値分類なので、class_mode”binary”を入力します。

上記のように表示されれば、前処理成功。

print(train_generator.class_indices)

で犬と猫どちらを0 1で予測してるかがわかります

{'cats': 0, 'dogs': 1}

モデル作成

CNNモデルを作成します。

.

入力は150×150の3チンネルなのでinput_shape は(150,150,3)にします

Sequential()以下からFlatten()までならんでいるConv2DMaxPooling2Dのレイヤーは自分の好きなように並べ替えて大丈夫です。今回は合わせて6層並べていますが、倍の12層にしても問題ありません。ただ、あまり層を深くすると勾配が消失して学習ができなくなってしまいます。また画像を畳み込みすぎて画像がなくなってしまわないように注意してください。

lr(学習率)は任意の数字で大丈夫ですが、小さい値にしてください
lossoptimizerはkerasのサイトから選んで、自分の好きなものを試してみてください。今回は二乗和誤差法と確率的勾配降下法を使用します。

epochsは合計4000枚のデータを何周学習させるかという意味です。
steps_per_epochはtrainデータの枚数/バッチサイズです。
validation_stepsはtestデータの枚数/バッチサイズです。

学習結果を図にしてみる

以上のようにコードを書き、lossとaccuracyのグラフを抽出します。

過学習しているので、、、

過学習の解決方法は主に3つ

1⃣データ数を増やす(複製する)
2⃣ドロップアウトを使用する
3⃣パラメーターを調整する

今回は1⃣2⃣を使用してみる。

データの複製

先ほど使用したImageDataGeneratorに複製機能が備わっているので、それを使用します。

rotation_range = 90と付け加えると、90度回転した画像を複製してくれます。角度は―90°~90°の間で自由に設定できます。ほかにも色々な複製方法があるのでkerasサイトのImageDataGeneratorクラスをチェックしてください。

ドロップアウト

層の中のノードのいくつかを無効にして、ネットワークの自由度を強制的に小さくし汎化性能を上げることで過学習を防ぐことができます。

レイヤーの間にmodel.add(Dropout(0.5))を挿入します。()内の数字は無効にしたいレイヤーの割合です。 一般的に50%程度を無効すると良いと言われています。当初Dropoutは全結合のみに適用されていましたが、畳み込み層等に適用しても同様に性能を向上させることが確かめられています。

再び学習させてみる

精度がよくなったのが、確認できます。

モデルの保存、ロード

model.save('dog_cat.h5')

でdog_cat.h5というファイルが出来上がります。

from keras.models import load_model
new_model = load_model('dog_cat.h5')

でモデルのロードができます。

予測

import numpy as np
from keras.preprocessing import image
#予測したい画像のパス
TESTPATH = "test_image.jpg"
#予測モデルに入力できるように画像を配列に落とし込む
img = image.load_img(TESTPATH, target_size=(150, 150))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = x / 255.0  #←この正規化を忘れがち
#予測
result_predict = model.predict(x)
print(result_predict)

{‘cats’: 0, ‘dogs’: 1}ということなので、、、
0.5を境に0に近づけば近づくほど”猫”と予測していますし、1に近ければ近いほど”犬”と予測しています。

予測したい画像が複数ある場合も、配列をまとめて入力してあげれば画像の枚数分だけ予測をはきだしてくれます。

モデルの保存と読み込み予測はkerasのサイトを見たほうがわかりやすいと思います。

--

--

Yutaka_kun
LSC PSD
Editor for

Microbiology technician,Machine learning engineer(beginner)