はじめに
kaggle の digit-recognizer の学習時に, ImageDataGenerator を使っている. これは, 学習時にデータ拡張することで, 学習する画像の範囲を広げたり, その結果として過学習を防ぐことができる. 主なパラメータは, 下記の通りである. その結果, どのように変形されるかは, 画像から感じてほしい.
ratation_range
width_shift_range
height_shift_range
shear_range
zoom_range
大きく変形させると, 過学習は防げるが, 学習そのものの精度も悪くなる可能性がある. 一方で変形が少ないと, データ拡張の効果が薄れる. そこで最適なパラメータを探索する必要が出てくる.
ここでは ベイズ推定 による最適化を試みる. 結論を先に言うと, うまくいかなかった. この後のブログでランダムサーチなどの別のやり方を試みる予定である.
スクリプト
Parameters optimization of ImageDataGenerator usi…
ベイズ推定は GPyOpt を使った. GPyOpt は kaggle のノートブックに入ってないので, 8 行目で pip
でインストールしている.
50 行目の関数 image_data_generator_opt_f()
が, GPyOpt で最小化する関数である. 122 行目の return を見れば分かるが, 学習の全 epoch の val_loss
の最小値を返すようにしており, val_loss
を最小にするパラメータを求めるようにしている.
125 行目で各パラメータの探索範囲を設定している. 注意してほしいのは, shear_range
のパラメータで, このとき私は勘違いをしていて 0.1 から 0.4 という 小さい範囲 を設定している. 本来であれば, rotation_range
と同じようにもっと大きな範囲を指定すべきである.
132 行目が GPyOpt の初期化 (7 回計算する), 134 行目で最適化計算 (13 回) をしている.
結果
rotation_range | width_shift_range | hight_shift_range | shear_range | zoom_range | val_loss | |
---|---|---|---|---|---|---|
1 | 19.19686431951373 | 0.20901088144099314 | 0.38405454186111176 | 0.23996402282257057 | 0.10206638888533845 | 0.022220429033041 |
2 | 28.816929542901924 | 0.39100920908804004 | 0.2770841119453179 | 0.34061018253006625 | 0.11146590049130006 | 0.023088127374649048 |
3 | 43.43410413174117 | 0.2834173438742231 | 0.27375949896818885 | 0.15555809611038365 | 0.3424101150282481 | 0.029848376289010048 |
4 | 17.01003601991092 | 0.38785226660815364 | 0.30289497170727797 | 0.2637924404969271 | 0.1803972318546122 | 0.02294338308274746 |
5 | 10.755445837282691 | 0.39576001559070983 | 0.39205077518912257 | 0.38281055792921836 | 0.396320750705659 | 0.028119152411818504 |
6 | 33.27088427662058 | 0.3605383199770277 | 0.13505776272360873 | 0.13831266468917783 | 0.17340673816256794 | 0.025382887572050095 |
7 | 49.3506844198074 | 0.2978424133940589 | 0.2990829261451698 | 0.14435462701646262 | 0.1211438599851377 | 0.032194338738918304 |
8 | 23.09093999418877 | 0.4 | 0.1 | 0.1 | 0.4 | 0.0249733105301857 |
9 | 18.550498114931145 | 0.1 | 0.1 | 0.4 | 0.4 | 0.02369987592101097 |
10 | 18.63230824366345 | 0.4 | 0.4 | 0.1 | 0.1 | 0.023234009742736816 |
11 | 18.1519017887764 | 0.1 | 0.4 | 0.1 | 0.1 | 0.020590541884303093 |
12 | 18.10422186453 | 0.1 | 0.4 | 0.1 | 0.1 | 0.021966272965073586 |
13 | 17.718261335584014 | 0.1 | 0.4 | 0.1 | 0.1 | 0.023602882400155067 |
14 | 18.759275901922862 | 0.1 | 0.4 | 0.1 | 0.1 | 0.02378304861485958 |
15 | 18.276551985644694 | 0.1 | 0.4 | 0.1 | 0.1 | 0.023956721648573875 |
16 | 18.742473332615006 | 0.1 | 0.4 | 0.4 | 0.1 | 0.022985640913248062 |
17 | 18.388879177471168 | 0.1 | 0.4 | 0.4 | 0.1 | 0.0249274130910635 |
18 | 19.806055360855435 | 0.1 | 0.4 | 0.1 | 0.1 | 0.02428913302719593 |
19 | 27.73900197039526 | 0.1 | 0.4 | 0.1 | 0.1 | 0.02649843692779541 |
20 | 18.01584412083525 | 0.4 | 0.1 | 0.1 | 0.1 | 0.021857010200619698 |
11 行目の val_loss
が最小値になっており, そのときのパラメータは次のとおりである.
rotation_range
; 18.15width_shift_range
; 0.1height_shift_range
; 0.4shear_range
; 0.1zoom_range
; 0.1
width_shift_range
, shear_range
, zoom_range
の 3 つのパラメータは, 振った範囲で最小の値となっており, データ拡張しないほうが学習結果が良い という, 当たり前な結果になってしまった. GPyOpt はきちんと仕事をしていると思うが, 結果としてはイマイチなパラメータが出てきた.
まとめ
ImageDataGenerator のパラメータの最適化をベイズ推定 (GPyOpt) で行ったところ, データ拡張の効果を小さくするほうが良いという, 当たり前な結果になってしまった. val_loss
は小さくなっているかもしれないが, 過学習の懸念がある.