Kerasで転移学習をする際にはpreprocess_input()を呼ぼう

画像に関するタスクを扱っている際に、事前学習済みの重みを利用した転移学習を行うことは良い精度を出すことが多く広く使われています。Kearsには学習済みのいくつかのモデルが用意されており簡単に転移学習を行うことが出来ます。

(https://www.kaggle.com/amadeus1996/fruits-360-transfer-learning-using-keras)

公式のサンプルなどを見れば問題無いのですが、この事前学習済みのモデルを使う際にはpreprocess_input()という関数を呼び出して画像に対して前処理を行うことが想定されています。しかしながら、いくつかのブログ記事などを見たところpreprocess_input()を呼ばずに、転移学習を行っている記事があったため今回この記事を書きました。厄介なことに、preprocess_input()を呼ばなくても、VGGやResNetなどの高容量なモデルは前処理分の処理を学習するようで割と良い精度を出します。本質的には前処理しないことで、無駄な訓練が行われていることになるので、忘れずにpreprocess_input()を呼ぶべきでしょう。

ちなみにpreprocess_input()の中では、モデルによって画像の正規化、ImageNetデータセットのRGB各チャンネルごとの平均値を引く、などの処理が行われているようです。

Batch Normalization と Dropout は併用しない方が良いという話

Deep Learningのモデルを訓練していたところ、思うようにvalidation lossが下がらないことがあった。色々と調べた結果、Batch NormalizationとDropoutを併用していたのが原因であったので、誰かの為に書いておく。

この論文その解説にある通り、Batch NormalizationとDropoutを併用するとパフォーマンスが悪化することがある。原因は、「Dropoutを行うことで学習時と評価時で分散が変わってしまう一方、Batch Normalizationは学習で得られた分散を評価時もキープしてしまうため齟齬が生じることが原因」とあり、言われてみればなるほどという感じである。

結論としては、DropoutかBatch Normalizationのどちらか一方だけで試してみてvalidation lossを下げようとするのが良さそう。Deep Learningを使えばすべて解決するわけではなく、パラメータチューニングやモデル構造のチューニングが良いパフォーマンスを出すためには必要だと分かる事例の一つ。