3) 学習部分の実装
cat_dog_dnn_keras.pyに戻って、学習部分を実装していきます。
学習用画像ファイルを読み込む
一般的に機械学習では、学習のために学習データと検証データの2つのデータセットを用意します。
学習データはそのままDNNに学習させるデータで、用意したデータの大部分をこちらに使用します。
検証データはDNNに学習はさせず、鍛えたDNNが実戦でどれだけの精度を発揮するかを検証するために使われます。
今回は、データが以下のようなディレクトリ構造で準備されていることを想定します:
./
cat_dog_dnn_keras.py
mydnn_keras.py
data/
train/ →学習データを格納
cat/ →学習データのうち猫の画像を格納
dog/ →学習データのうち犬の画像を格納
valid/ →検証データを格納
cat/ →検証データのうち猫の画像を格納
dog/ →検証データのうち犬の画像を格納
さて実装部分ですが、ここでもKerasの機能が活躍します。
from keras.preprocessing.image import ImageDataGenerator input_size_x = 224 input_size_y = 224 batch_size = 20 keras_idg = ImageDataGenerator(rescale=1.0 / 255) train_generator = keras_idg.flow_from_directory('data/train', target_size=(input_size_x, input_size_y), batch_size=batch_size, class_mode='categorical') valid_generator = keras_idg.flow_from_directory('data/valid', target_size=(input_size_x, input_size_y), batch_size=batch_size, class_mode='categorical')
DNNに画像データを学習させるにあたっては下記のような操作が必要なのですが、ImageDataGenerator
を使用すると上記のように書くだけでそれが実現可能です。
- 指定ディレクトリ以下の画像を読み込んでDNNの入力に相応しい形式に変換
- 画像サイズを一定に調整
-
入力画像のクラス(ここでは犬か猫かという情報)を画像データに添える
- サブディレクトリの構造から判断
- 画像の量が膨大だと一度に処理できないので、小分け(
batch_size
個ずつ)にしてDNNに与える - 入力画像が一巡したら先頭に戻って無限にデータを与え続ける
また上記では使用していませんが、画像の色補正や拡大縮小によって学習データ件数を増幅するなど、他にも豊富な機能を備えています。
DNNを学習
つづいて、学習させる部分を書いていきます。
from mydnn_keras import MyDNN import os input_size_c = 3 output_size = 2 epochs = 10 num_data_train_dog = len(os.listdir('data/train/dog')) num_data_train_cat = len(os.listdir('data/train/cat')) num_data_train = num_data_train_dog + num_data_train_cat num_data_valid_dog = len(os.listdir('data/valid/dog')) num_data_valid_cat = len(os.listdir('data/valid/cat')) num_data_valid = num_data_valid_dog + num_data_valid_cat model = MyDNN(input_shape=(input_size_x, input_size_y, input_size_c), output_size=output_size) model.fit_generator(train_generator, validation_data=valid_generator, epochs=epochs, steps_per_epoch=num_data_train/batch_size, validation_steps= num_data_valid/batch_size)
Sequentialモデルにはfit
とfit_generator
という2つの学習用メソッドがあります。
fit
はあらかじめ読み込んだデータ全体を受け取って一度に処理するメソッドです。
それに対しfit_generator
は、データのジェネレータを受け取り、使用する分のみを都度読み込むように動くメソッドです。
今回のように膨大な量の画像を相手にする場合に、fit_generator
を使うことでメモリの消費量を抑制することができます。
fit_generatorメソッドの引数について
epochs
引数は、学習データ全体を何巡ぶん学習するかを示します。
steps_per_epoch
引数は、DNNの計算を何回行うと学習データを一巡したことになるかを指定します。
上述の通りDNNには学習データをbatch_size
個ずつ小分けにして与えますので、学習データ全体の数をbatch_size
で割った値を指定します。
validation_steps
引数は、DNNの計算を何回行うと検証データを一巡したことになるかを指定します。検証データ全体の数をbatch_size
で割った値を指定します。
学習したDNNを保存
学習処理が終了した時点では結果はメモリ上にあるのみですので、それを後から利用できるようファイルに書き出す必要があります。
以下のように記述すると、ckpt/mydnn_weights.hdf5
に学習結果が保存されます。
checkpoint_dir = 'ckpt' os.makedirs(checkpoint_dir, exist_ok=True) model.save_weights(os.path.join(checkpoint_dir, 'mydnn_weights.hdf5'))
学習部分完成
ここまでをcat_dog_dnn_keras.pyに適用すると、以下のようになります:
import argparse from keras.preprocessing.image import ImageDataGenerator import os from mydnn_keras import MyDNN input_size_x = 224 input_size_y = 224 batch_size = 20 input_size_c = 3 output_size = 2 epochs = 10 checkpoint_dir = 'ckpt' parser = argparse.ArgumentParser() parser.add_argument("--infer", action="store", nargs="?", type=str, help="学習は行わず、このオプションで指定した画像ファイルの判定処理を行う") args = parser.parse_args() model = MyDNN(input_shape=(input_size_x, input_size_y, input_size_c), output_size=output_size) if not args.infer: print("学習モード") # 学習データの読み込み keras_idg = ImageDataGenerator(rescale=1.0 / 255) train_generator = keras_idg.flow_from_directory('data/train', target_size=(input_size_x, input_size_y), batch_size=batch_size, class_mode='categorical') valid_generator = keras_idg.flow_from_directory('data/valid', target_size=(input_size_x, input_size_y), batch_size=batch_size, class_mode='categorical') # 学習の実行 num_data_train_dog = len(os.listdir('data/train/dog')) num_data_train_cat = len(os.listdir('data/train/cat')) num_data_train = num_data_train_dog + num_data_train_cat num_data_valid_dog = len(os.listdir('data/valid/dog')) num_data_valid_cat = len(os.listdir('data/valid/cat')) num_data_valid = num_data_valid_dog + num_data_valid_cat model.fit_generator(train_generator, validation_data=valid_generator, epochs=epochs, steps_per_epoch=num_data_train/batch_size, validation_steps= num_data_valid/batch_size) # 学習済みモデルの保存 os.makedirs(checkpoint_dir, exist_ok=True) model.save_weights(os.path.join(checkpoint_dir, 'mydnn_weights.hdf5')) else: print("判定モード") # 判定する画像の読み込み # 判定処理の実行 # 判定結果の出力
これで学習モード側の実装は終わりです!
※TensorFlow, the TensorFlow logo and any related marks are trademarks of Google Inc.
その他、本コンテンツ内で利用させて頂いた各プロダクト名やサービス名などは、各社もしくは各団体の商標または登録商標です。