はじめてのDeepLearning入門(Chainer) 日本語文字認識 4章 [データ拡大による認識精度の改善]


こんにちはリヒトです。こちらに続いてDeepLearningチュートリアル4章
データ拡大による認識精度の改善について話します。

認識精度の改善

前回(3章)ではepoch16でのloss0.526がベストスコアでした。ただこれだと活字でも稀に誤認識するなどイマイチです。

しかしこのままこれ以上学習してもtrainのlossだけが下がりtestのlossは上がり続ける「過学習」が起こり認識精度は向上しません。過学習を防いで精度を上げるためにはズバリ学習データを増やしましょう。

オリジナルの学習データを増やす事が理想的ですが、学習データの収集には時間もお金もかかるのでデータ拡大をします。

データ拡大

データ拡大の種類について

1. 回転, 移動, 拡大・縮小, 2値化

2. Elastic Distortion

人工的な歪みを与える事によるデータ拡大。

3. ノイズ

インプルスノイズ・ガウシアンノイズなど

4. 細線化

文字の太さとの認識の依存を解消するための細線化

5. 反転

通常は反転した画像が入力される事はないので、一見悪影響なデータ拡大と思いますが、TTA(テスト時にもデータ拡大をする)の観点から考えて有効です。

実践結果

回転は回転角度と回転軸(3次元的)、移動は移動ピクセル数など乱数を使う事でデータ拡大の組み合わせは無限にあるという事で上の手法を組み合わせて1枚の画像からムゲンの画像を作っていきます。
拡大枚数と結果が以下。

拡大枚数 testのlossベストスコア
10 枚 0.526
100枚 0.277
300枚 0.260
500枚 0.237

何かあっさりしてますがいい感じです。500枚にも拡大するとデータが重複しないかな?と思いますが結果的にはOK。

ちなみにElastic distortionは見た目が理想的なデータ拡大に見えますが処理に時間がかかったり、過学習の原因になったりするなど実は扱いが難しいです(あくまで経験談)

ひたすら拡大してテスト

500枚でも順調に精度が上がってる(ロスが下がっている)ので、次は3500枚に拡大してみました。(ただしメモリ的な意味でも処理時間的な意味でも(私のPC的に)限界があるので、「あ」「い」「う」「え」「お」の5枚だけに限定。)

('epoch', 1)
train mean loss=0.167535232874, accuracy=0.937596153205
test mean loss=0.23016545952, accuracy=0.914285708447
('epoch', 2)
train mean loss=0.0582337708299, accuracy=0.979920332723
test mean loss=0.132406316127, accuracy=0.955102039843
('epoch', 3)
train mean loss=0.042050985039, accuracy=0.985620883214
test mean loss=0.0967423064653, accuracy=0.959183678335
('epoch', 4)
train mean loss=0.0344518882785, accuracy=0.98846154267
test mean loss=0.0579228501539, accuracy=0.983673472794

結果はこんな感じ。
epoch4でlossが0.057まで下がっています。
3章にあった通りloss0.237のモデルで何となく手書きひらがなが認識出来たので今回は期待出来そうです。
そこで手元で適当にひらがなを50枚書いて精度をテスト。

今回はテスト時に30枚にデータ拡大してから認識結果を評価しています。
(この"30枚"には特に理由がある訳ではありません)

$ python AIUEONN_predictor.py --model loss0057model --img ../testAIUEO/o0.png 
init done 
候補 ニューロン番号:4, Unicode:304a, ひらがな:お
.
.(中略)
.
候補 ニューロン番号:4, Unicode:304a, ひらがな:お
候補 ニューロン番号:4, Unicode:304a, ひらがな:お
候補 ニューロン番号:3, Unicode:3048, ひらがな:え
候補 ニューロン番号:4, Unicode:304a, ひらがな:お
**最終判断 ニューロン番号:4, Unicode:304a, ひらがな:お**

OKです。

結果

50枚中46枚正答。4枚ミスで精度92%となりました!
ちなみにミスしたものはこちらの4枚だけ。

「あ」の方は大分字が汚いですね(汗;

上手くいったものの一部

手前味噌のテストデータセットなので表現が難しいですが、まぁまぁ良い精度が出ています。
活字中心の学習データで手書き文字にも応用性があるという事でDeepLearningの可能性を感じます。
4章はここで終了です。次5章ではHi-Kingさんのブログも参考にニューラルネットの基本から学んで行きたいと思います。

タイトル
1章 chainerをベースにしたDeepLearning環境の構築
2章 機械学習によるDeepLearning予測モデルの作成
3章 モデルを利用した文字認識
4章 データ拡大による認識精度の改善
5章 ニューラルネット入門とソースコードの解説
6章 Optimizerの選択による学習効率の改善
7章 TTA, BatchNormalizationによる学習効率の改善