自前で用意した花画像を使ってKerasでCNN~学習編~[Keras][CNN][深層学習][Python]
昨今様々な深層学習ライブラリが台頭してきたことにより,最新のソースコードも様々なライブラリを用いて書かれることが大きなって来た.
この為,いつも使っているpytorch以外のライブラリも触れるようにしておかなければならないと感じるようになった.
そこで本記事では,tensorflowをバックエンドとし,コードが書きやすいことで有名なkerasで簡単なCNNを,自前画像で動かしてみることにした.
自前画像の用意
今回は,kaggleから花の画像をダウンロードしてきてから学習を行う.
以下花の画像のリンク
https://www.kaggle.com/alxmamaev/flowers-recognition
花の画像は,6種類・合計4,242枚の画像で構成されており,ファイルサイズも224MBと軽い為,新しいライブラリや実験用のプログラムの検証用として使いやすいデータセットだ.
画像のサイズはバラバラだが,後にkerasのflow_from_directory関数を使用し,整形化するので問題無い.
flowers-recognition.zipをダウンロード後,以下のようにtrainとtestに画像を手動で分けて配置した.割合は8:2
flower├─test│ ├─daisy 153 files│ ├─dandelion 211 files│ ├─rose 156 files│ ├─sunflowers 146 files│ └─tulips 196 files└─train├─daisy 616 files├─dandelion 844 files├─rose 628 files├─sunflower 588 files└─tulip 788 files学習
上の方のコードを一部修正し,使わせて頂く.
import numpy as npfrom keras.preprocessing.image import load_img, img_to_arrayfrom keras.applications.vgg16 import VGG16from keras.models import Sequential, Modelfrom keras.layers import Input, Dense, Dropout, Activation, Flattenfrom keras.optimizers import SGDfrom keras.utils import np_utilsfrom keras.preprocessing.image import ImageDataGenerator# 分類クラスclasses = ['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']nb_classes = len(classes)batch_size = 32nb_epoch = 1# 画像のサイズimg_rows, img_cols = 224, 224# モデルの構築def build_model() :# 画像の読み込み.今回はカラー画像の為,shapeの3番目の引数が3(ch)input_tensor = Input(shape=(img_rows, img_cols, 3))# VGG16はモデルの名前.引数weightsでpre-trainingしているvgg16 = VGG16(include_top=False, weights='imagenet', input_tensor=input_tensor)# Sequentialは単純に,前の層の全ノードから矢印を引っ張ってくるモデルを意味している# 矢印のつなぎ方を複雑にするには,Functional APIを使う# https://qiita.com/Ishotihadus/items/e28dd461a8ba27a2676e_model = Sequential()_model.add(Flatten(input_shape=vgg16.output_shape[1:]))_model.add(Dense(256, activation='relu'))_model.add(Dropout(0.5))_model.add(Dense(nb_classes, activation='softmax'))model = Model(inputs=vgg16.input, outputs=_model(vgg16.output))# modelの14層目までのモデル重みfor layer in model.layers[:15]:layer.trainable = False# 損失関数と評価関数を指定# 評価関数に関して: https://keras.io/ja/metrics/#_3model.compile(loss='categorical_crossentropy',optimizer=SGD(lr=1e-4, momentum=0.9), metrics=['accuracy'])return modelif __name__ == "__main__":# ImageDataGeneratorはリアルタイムにデータ拡張しながら,テンソル画像データのバッチを生成する# 要はデータの水増し(Data Augumentation)に関するオプションを指定している# https://keras.io/ja/preprocessing/image/#imagedatagenerator_1train_datagen = ImageDataGenerator(rescale=1.0 / 255, # 画素値のスケーリングshear_range=0.2, # 斜め方向(pi/x)に画像を引っ張るzoom_range=0.2, # ランダムにズームhorizontal_flip=True) # 水平方向にランダムに回転# train_generator: 指定したディレクトリから画像を読み込むときに使用する関数train_generator = train_datagen.flow_from_directory(directory= 'path/to/train',target_size=(img_rows, img_cols),color_mode='rgb',classes=classes,class_mode='categorical',batch_size=batch_size,shuffle=True)# 評価用画像の用意test_datagen = ImageDataGenerator(rescale=1.0 / 255)test_generator = test_datagen.flow_from_directory(directory= '/path/to/test',target_size=(img_rows, img_cols),color_mode='rgb',classes=classes,class_mode='categorical',batch_size=batch_size,shuffle=True)# インスタンスの呼び出しmodel = build_model()# model.fit() でモデルを学習model.fit_generator(train_generator, # 訓練データの配列steps_per_epoch=3000, # 終了した1エポックを宣言して次のエポックを始めるまでのステップ数の合計epochs=nb_epoch, # エポック(学習の繰り返し回数を指定)validation_data=test_generator, # 評価用データの指定validation_steps=600 # 停止する前にバリデーションするステップの総数)# 学習後のモデルを書き出しhdf5_file = "flower-model.hdf5"model.save_weights(hdf5_file)上のコードを実行すると学習が開始する.
学習中はlossとaccuが徐々に更新されていく様子が観察できる.
結果
Found 1457 images belonging to 5 classes.Found 706 images belonging to 5 classes.Epoch 1/13000/3000 [==============================] - 1012s 337ms/step - loss: 0.1224 - acc: 0.9486 - val_loss: 6.0376 - val_acc: 0.4703Accuracyが0.94.良い結果だ. 評価用のデータセットでのスコア(val_accu)は0.47…
次は,今回学習したモデルを使ってGoogle画像検索でダウンロードした花の画像の識別をさせてみる.