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

こんにちはリヒトです。[こちら](http://qiita.com/LichtLabo/items/c987cd93928ab70f46e1)に続いてDeepLearningチュートリアル4章
データ拡大による認識精度の改善について話します。

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

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

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

##データ拡大
データ拡大の種類について
###1. 回転, 移動, 拡大・縮小, 2値化
<img width="420" alt="rotation.png" src="https://qiita-image-store.s3.amazonaws.com/0/110732/8a3ccdf9-06dd-4ae0-59b8-22aec49f2ee0.png">

<img width="420" alt="transition.png" src="https://qiita-image-store.s3.amazonaws.com/0/110732/ee4202fe-312c-fce6-75cd-ef5ce67b99ea.png">

###2. Elastic Distortion
人工的な歪みを与える事によるデータ拡大。

<img width="333" alt="distortion.png" src="https://qiita-image-store.s3.amazonaws.com/0/110732/d92029de-0fc3-87f7-3488-a47c1d2a3397.png">
###3. ノイズ
インプルスノイズ・ガウシアンノイズなど
![impulse.png](https://qiita-image-store.s3.amazonaws.com/0/110732/fd8ea417-d928-ea39-253d-2ff42af9e3a1.png)

###4. 細線化
文字の太さとの認識の依存を解消するための細線化
![thinning.png](https://qiita-image-store.s3.amazonaws.com/0/110732/1dd6351b-1ad6-c701-20bd-5e7ff1bca30a.png)

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

<img width="100" alt="flip.png" src="https://qiita-image-store.s3.amazonaws.com/0/110732/f70219a1-0d05-ea1f-deeb-e22bcea7fb74.png">

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

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

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

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

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

```
('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まで下がっています。
３章にあった通りloss0.237のモデルで何となく手書きひらがなが認識出来たので今回は期待出来そうです。
そこで手元で適当にひらがなを50枚書いて精度をテスト。
<img width="325" alt="tegaki_aiueo.png" src="https://qiita-image-store.s3.amazonaws.com/0/110732/50e67c2b-10f2-d2b3-1e35-a1eb7fdc2b8a.png">

今回はテスト時に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枚だけ。
<img width="380" alt="missed.png" src="https://qiita-image-store.s3.amazonaws.com/0/110732/365deab5-14f8-ebc4-149d-3861cb4059bd.png">
「あ」の方は大分字が汚いですね（汗；

上手くいったものの一部
<img width="462" alt="good.png" src="https://qiita-image-store.s3.amazonaws.com/0/110732/a63277e1-0968-0c33-4d56-8ead728c5edb.png">


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

|章|タイトル|
|:----|:--------------------------------------------------------|
|1章  |[chainerをベースにしたDeepLearning環境の構築](http://qiita.com/LichtLabo/items/94063ee9d66263d1911a)|
|2章  |[機械学習によるDeepLearning予測モデルの作成](http://qiita.com/LichtLabo/items/d78b50bbf0826b8f599a)|
|3章  |[モデルを利用した文字認識](http://qiita.com/LichtLabo/items/c987cd93928ab70f46e1)|
|4章  |[データ拡大による認識精度の改善](http://qiita.com/LichtLabo/items/c4b33432a46cb7dd6b7d)|
|5章|ニューラルネット入門とソースコードの解説|
|6章|Optimizerの選択による学習効率の改善|
|7章|TTA, BatchNormalizationによる学習効率の改善|