はじめに
どうも、趣味で機械学習を勉強している者です。
今回は、Tensorflowのチュートリアルにある画像分類にて、モデルの学習を実行したらエラーを起こしたので、解決方法と教訓を紹介します。
(結論を言ってしまえば、しょうもないミスでした...)
エラー内容
チュートリアルにはお手本になるコードと説明文が載っています。
説明文を読みながらコードを写経していたはずなのにエラーが発生!
発生したエラーがこちら
WARNING:tensorflow:Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least
steps_per_epoch * epochs
batches (in this case, 30000 batches). You may need to use the repeat() function when building your dataset.
どうやらinputしているジェネレータのバッチ数がダメだよと言われているもよう。
しかもご丁寧に「今回の場合は、30000バッチ数」だよとの記載。
しかし自分は、お手本に沿ってジェネレータを作成し、モデルを構築。
もちろんパラメータに使っている変数も間違っていない。
それなのに何故...
エラー原因と解決方法
では実際にどんなコードでエラーを起こしたのか、自分が書いたコード(全ての元凶)がこちらです。
history = model.fit_generator(
train_data_gen,
steps_per_epoch=total_train,
epochs=epochs,
validation_data=val_data_gen,
validation_steps=total_val
)
そして、チュートリアルに記載しているお手本となるコードがこちら。
もうお気づきでしょう。
冒頭でコードを写経したと言っておきながら、できてなかったのですね。
そう、
// batch_size
が抜けてますね...
コードのパラメータの詳細は以下になります。
パラメータ | 説明 |
---|---|
train_data_gen | 学習データのジェネレータ(学習データ) |
steps_per_epoch | 学習データに対して、1つのエポックを宣言し、次のエポックを開始するまでの合計ステップ数 |
total_train | 学習データの合計数(ここでは2000) |
epochs | 学習データ全体を学習するまでの反復数(ここでは15を指定) |
validation_data | 検証用データ |
val_data_gen | 検証データのジェネレータ |
validation_steps | 検証データに対して、1つのエポックを宣言し、次のエポックを開始するまでの合計ステップ数 |
total_val | 検証データの合計数(ここでは1000) |
batch_size | 重み更新ごとのサンプル数 |
つまりエラーを起こしたコードでは、15のエポックで学習データ全体を学習すると指定しておきながら、1つのエポックのステップ数を学習データ全体としているためにエラーが発生していたのです。
だからエラーの内容で30000といわれていたのですね。
steps_per_epoch がtotal_train (2000)の場合、epochsが15なので学習データは2000×15=30000必要になるってことだったんですね。
なので、原因は // batch_size
を書き忘れていたことであり、解決方法は // batch_size
を追加するということでした。
本当にしょうもないミスでしたね...
エラーを起こした原因
エラーの原因は分かりました。
では、そもそもなぜこんなミス(コードの写経漏れ)を起こしてしまったのか。
お手本のコードを見てください。
// batch_size
はご丁寧に赤文字で記載されていますね。
そうです!赤文字で記載されているからこそ、私は写経漏れを起こしたのです!
ずばり、 // batch_size
をコメントと勘違いしたんです!
(えぇ...なんとも恥ずかしい...)
pythonで //
といえば切り捨て除算の演算子だということをすっかり忘れていたんですね。
(ちなみに、//
でコメントアウトできるのはjavascriptです)
今回の教訓
自分は今何の言語を使っているのか、それをしっかり頭に入れながらコードを書いていくことが重要だなと再認識させられたエラーでした。