機械学習

【TensorFlow2入門】ディープラーニングで仮面ライダー俳優を見分けるAIを作る(精度up)

【TensorFlow2入門】ディープラーニング(CNN)で仮面ライダー俳優を見分けるAIを作る(後編)では精度のことはあまり気にしませんでした。

今回はドロップアウトや画像の水増しを行い、認識精度の向上をさせてみたいと思います。

以下のつの手法を試して、精度がどうなるか確認していきます。

  1. 単純にエポック数を上げてみる
  2. 画像の水増しをしてみる
  3. ドロップアウトを追加してみる
  4. 層を増やしてみる

前回までのまとめ

データ数

  • 訓練データ:352
  • テストデータ:89

上記のデータを用いて、ライダー俳優の顔識別AIを作成しました。

val_loss: 0.3212 - val_accuracy: 0.8539 という結果(過学習)になりました。

それでは、順番に試していきます!

エポック数を上げる

100エポックでやってみました。明らかな過学習ですね。

画像の水増しをする

過学習は一般に、学習サンプルが少ない場合に発生します。

ImageDataGenerator を使用して、画像の水増しを行ってみます。

ImageDataGeneratorクラスを使えば、様々な変換を画像に加えることができます。

今回は以下の変換を用います。

  • horizontal_flip: 水平反転の適用
  • rotation_range:画像のランダムな回転
  • zoom_range: ランダムズームによるデータ拡張の適用(指定した範囲内でランダムにズーム)
  • rescale: リスケール
  • width_shift_rangeheight_shift_range:幅シフト、高さシフト
  • vertical_flip: 真理値.垂直方向に入力をランダムに反転します.

他にもあるので、詳しく知りたい方はこちらを参照してください!

ソースコードの一部

変更した点のソースコードです。画像を水増しするのは訓練画像のみです。

実際に適用してみるとこんな感じになります。

少し気味が悪いですね(笑)

これがジェネレータではこのような処理が無限に行われます。そのため、同じ画像で学習する回数が減るということですね。詳しくは後程解説します。

以下、50エポックの結果です!最後になぜか急激に上がりました。

val_loss: 0.6532 - val_accuracy: 0.8125

100エポックの結果です。着実に学習している感はありますね。

val_loss: 0.7269 - val_accuracy: 0.7344

ImageDataGeneratorの画像水増しについて

訓練画像水増し→画像が増えると思っていましたが、ジェネレーターを使用する場合は少し違うみたいです。

ジェネレータはバッチごとにリアルタイム処理をするため、元々の訓練画像が増えるわけではありません。下の図がわかりやすいです。

steps_per_epochをn倍する、もしくはエポックするを増やすことで水増しした場合と同等の効果を得られるそうです。

流れとしては

  1. バッチ分のデータをとる
  2. 水増し処理 
  3. 加工された画像で学習

というイメージでよいと思います。結果的に同じ画像で学習をする回数が減るということですね!

エポック数などの理解があいまいな方は機械学習/ディープラーニングにおけるバッチサイズ、イテレーション数、エポック数の決め方でとても分かりやすく解説してくれていますので、参考にしてください。

ドロップアウトを追加する

次に、ドロップアウトという手法を試してみます。

ドロップアウトとは一言でいえばディープラーニングの「過学習」を防ぐ技術です。

Journal of Machine Learning Research 15 (2014) 1929-1958「Dropout: A Simple Way to Prevent Neural Networks from
Overfitting」

ドロップアウトでは、学習過程で上図のようにネットワークの一部のニューロンを学習途中でランダムな確率でなかったこと(0)にします。

TensorFlowでは簡単に実装できます。マーカーを引いてあるところがドロップアウトの処理です。

当初Dropoutは全結合のみに適用されていましたが、ある論文によれば畳み込み層等に適用しても同様に性能を向上させることが確かめられています。

エポック数50 確かに過学習を起こす気配はまるでないですね!  ですが、正確性はかなり落ちてますね…

val_loss: 0.7869 - val_accuracy: 0.7031

エポック数100です

val_loss: 0.8030 - val_accuracy: 0.6875 

なかなかよくなりません。もっと増やしてみます

エポック数200やってみました。少しだけ上がりましたね。

val_loss: 0.6584 - val_accuracy: 0.7656

もう少し増やしたら伸びるのでしょうか...いったん別の手法を試してみます。

層を深くしてみる

層を一つ深くしました

200エポックでやってみます。80%が限界みたいです。

こうなればやけくそ。1000エポックでやってみると

val_loss: 0.3056 - val_accuracy: 0.9062

accuracyが90%まで行きました!でも過学習ですね…

おわりに

当初、予定していた精度を上げる目的は達成できませんでした。

そもそも、初期データの量が全く足りないことが一番の原因ではないかなと思います。

他の方々のサイトを見てみても、十分な量のデータがあっての結果のような気がするので、今後やるときは元データを集めることをしっかり行いたいと思います。

色々試してみて、訓練データの質と、繰り返しの訓練が重要ということがわかりました。

ディープラーニング、難しいです…

参考サイト

機械学習/ディープラーニングにおけるバッチサイズ、イテレーション数、エポック数の決め方

【Keras】水増しとデータ拡張【犬猫判別2】

-機械学習

© 2020 まきろぐ Powered by AFFINGER5