Fine-Tuningの学習データはどこまで減らせるのか？

転移学習やFine-Tuningでは、比較的少ないデータ数でもカテゴライズできるという神話がある。
しかし、どの程度のデータ数ならある程度信頼できる識別器ができるのかというのは、なかなか記載がない。

前回の記事
「AKB２０１７総選挙ランキング上位者のFine-Tuning その２～顔抽出と少数データ」
https://qiita.com/MuAuan/items/4ab6c3d9c5ad6f5c98cc
で見たように、一応識別器はできるが、それはどこまでのデータに適用可能なのかは、正直よくわからない。
##実験的な試行検証
ということで、ここでは以下のような実験的な試行を実施して、検証したいと思う。

①前回は全体データ数を減少させていったが、今回は同数データに対して、TrainデータとTestデータの割合を変更して、一致率の変化を見る
②Trainデータはどこまで減らせるのかをみるため、元データ数を可能な限り小さくして学習の収束性を見る
※ただし、Trainデータ５個以下のデータは、Augmentationして８倍に増やした

##結果
###①TrainデータとTestデータの比率を変える
結果は、立ち上がりはTrainデータの割合が減少すると徐々に遅くなるのは、前回と同じだが、test_accはかなり良い結果が得られ、【Train５０％、Test５０％】でも７０％程度の精度が得られた。そして、【Train１０％、Test９０％】でさえ４０％弱の精度が得られている。これは、ばらつきはあるが、Trainデータがそれぞれ１０個程度あれば、４０％程度の識別器ができることになる。
【注意】データは、前回の記事と異なり（本来同じデータでやりたいが、残念）、クレンジングされたカテゴリ毎に１００個位から１２０個位までばらつきがあるデータを利用
【Train９０％、Test１０％】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/0fbc0596-8d47-c8c0-5f72-b5dfa06e06ef.png)
【Train８０％、Test２０％】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/aa1369d5-1e5c-c2e7-c1b3-105a221d9449.png)
【Train５０％、Test５０％】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/e120e54c-fe1c-e842-8ace-19aef440bd6e.png)
【Train２０％、Test８０％】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/e4882482-3c5e-14bf-456c-e8d33dbba338.png)
【Train１０％、Test９０％】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/c8827c60-5168-ebd4-48c7-00db5c64628b.png)

| 　　 条件　       |    val_acc      |    立ち上がり/epoch |
|:-----------------|------------------:|:------------------:|
| 90%, 10%         |       85%         |         20         |
| 80%, 20%         |       82%         |         20         |
| 50%, 50%         |       73%         |         35         |
| 20%, 80%         |       55%         |         85         |
| 10%, 90%         |       37%         |        220         |
###②Trainデータはどこまで減らせるのか？
上記で見れば、普通の精度のいい識別器は少なくともTrainデータ割合７０％程度でフィッティングすればいい気がするが、実際５０％のデータでも７０％の精度が出ており、かなり汎用性は高いと評価できる。
そして、１０％の結果は、識別器が学習するという意味では、１０個程度のデータがあれば、ある意味ちゃんとした識別器が作成できるということである。
さらに、Trainデータを削減しても収束するのか？
１０％というのは１０個程度ということを示すので、以下半分の５個、４個、３個、２個、そして元データ１個で識別器が収束するのか？そして、それでどこまで識別できるのかを見てみた。
【Train５個、Test残り】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/40e088a9-2690-a159-8bba-74f111ed271f.png)
【Train４個、Test残り】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/890cf84a-7582-34c2-f9a8-bea3c0b59f60.png)
【Train３個、Test残り】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/cb69077a-4935-a52b-5340-795b3d3829f8.png)
【Train２個、Test残り】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/54f75dc2-66cc-bc71-63f5-8e208ca7fa6c.png)
【Train１個、Test残り】ResNet50【９０層固定】
![val_acc&train_acc.png](https://qiita-image-store.s3.amazonaws.com/0/233744/d1d6053e-ad53-344d-babc-fbf17264c0f0.png)

| 　　 条件　       |    val_acc      |    立ち上がり/epoch |
|:-----------------|------------------:|:------------------:|
| 5, res.          |       37%         |         30         |
| 4, res.          |       34%         |         52         |
| 3, res.          |       32%         |         60         |
| 2, res.          |       23%         |         95         |
| 1, res.          |       22%         |        150         |

上記の結果は、ある意味驚きである。特に１個のデータは立ち上がりこそずいぶん遅いし、だらだらであるが、train_acc２０％程度つまり、各カテゴリ２０個程度は識別できている。また、５個程度のTrainデータは３５％程度の識別率でこれでも分野によっては、或いは当初データクレンジングするには有用な識別器になると思う。
もちろん少数データでの学習には過学習という問題は当然あるのだが、その影響を考慮すれば上記結果は予想以上の識別率だといえる。

上記の結果をグラフにすると以下のようになった。
５個以下のデータ数が小さいところではAugmentationを実施しており、ちょっと誤差もありそうだが、全体としてはほぼ一様な変化をしていると言える。
![FR vs. Data.png](https://qiita-image-store.s3.amazonaws.com/0/233744/4e214c1e-12a1-36fc-3c4b-2a23fa76f728.png)

あまりにもきれいな直線に乗ったので、近似曲線
y = 21.324ln(x) - 10.761   , x>10
R² = 0.9963
y;Fitting_Ratio x;Fraction of Training data


##まとめ
①データ割合が１０－９０％の範囲で、比較的簡単な関係があり、フィッティング率はデータ割合の対数に対してリニアな関係がある。
②データ割合を変更して、フィッティング率をみると、Trainデータ７０％以上だと８０％以上の十分な精度がえられた。
③Trainデータ５０％でも７０％程度の精度が得られ、十分なTestデータで検証されているので、ある意味汎用性のある識別器を作成できている。
④Trainデータは、１個でも８倍のAugmentationにより、それなりの識別器を作成できた。
【Augmentation】
画像の８倍水増しは以下のサイトより
「機械学習で乃木坂46を顏分類してみた」
http://blog.aidemy.net/entry/2017/12/17/214715
##課題
過学習を考えたとき、Trainデータ１個でも、適切なAugmentationを実施すれば、さらに識別率を上げることができそうである。例えば最近のstarGANを利用すれば、笑顔や怒った顔、変顔など出力でき、かなり確実な精度向上を期待できそうである。
そもそも、データにいろいろな外部要因を付加して、バリエーションを持たせる技術というのを確立することは、今後のDeepLearningの発展が大量データ分析に依存している現状を打破する可能性があると考えられる。
【参考】
「Official PyTorch Implementation of StarGAN」 
https://github.com/yunjey/StarGAN
「StarGANで顔イラストの表情変換」
https://qiita.com/mattya/items/e71ea1d203b110013753

以下は、ちょっと系統違うけど、少ないデータで識別器作っています。
「細胞種を機械学習で判別する！」
https://lp-tech.net/articles/e0mRJ