前回”バッチサイズの影響が非常に大きそうだ”ということが分かったので、いったん整理して確認してみることにしました。
確認内容
他条件は同一にして、バッチサイズのみ変更して、その影響を確認する。
バッチサイズは、1、4、16、64、256、1024、4096とする。
最適化方式はSGDとする。
パターン1:バッチサイズ=4,096
学習率が1.0と大きいケースから収束を始めており、学習率が0.05以下の小さいケースでは収束が始まっていない。
パターン2:バッチサイズ=1,024
同じエポック数であるが、より多くのケースが収束に向かいつつある
損失関数=101辺りに最初の踊り場があることが推測できる。
パターン3:バッチサイズ=256
傾向はパターン2と同じで、すべてのケースが収束しつつある。
パターン4:バッチサイズ=64
各ケース毎に収束する速度が上がっている
パターン3まで綺麗に収束していた学習率1.0(大きい)の収束が怪しくなってきている
パターン5:バッチサイズ=16
学習率の大きい2ケースが計算不能になっている
損失関数の値自体が少し小さくなっている
パターン6:バッチサイズ=4
さらに計3ケースで計算不能になっている
上下の振れ幅が大きく見えるのはlogスケールが小さくなったせい(と思われる)
パターン7:バッチサイズ=1
傾向はパターン6と同じで、さらに計算不能ケースが増えている
パターン8:(おまけ)バッチサイズ=4096、エポック数=10,000
パターン1の条件でエポック数を10,000まで増やしてみたが、学習率下位2つは収束する気配を見せていない
以上のことから導かれる仮説は
- 学習率が大きい方が収束が早くなる
- バッチサイズが小さい方が収束が早くなる(エポック数比)
- バッチサイズが小さいほど、計算回数が増えるため1エポックの計算時間が長くなる
- バッチサイズが小さい場合、学習率も小さくした方がよい
- ある時点で収束しなくても、エポック数を増やせば必ず収束する。とは限らない
- 従って”学習率は小さい方が良い”とは必ずしも言えない
最適化の方法(SGD:確率的勾配降下法)を考えると、1、2、3、5、6は当然な気もしますが、4の理由が見当つきません。
バッチサイズが小さい→1データの影響が大きくなる→学習率が大きいと振り切れやすくなる
等でしょうか?
Dive Into Deep Learningのサンプルでもバッチサイズに合わせて学習率をしれっと変えていましたが、理由までは書いてありませんでした。
今回裏付けが取れたので”そういうものだ”と思うことにしましょう。
計算所要時間について(あくまで参考程度ですが)まとめてみました。
バッチサイズ | 有効ケース数 | 総時間(s) | 時間/ケース |
4,096 | 8 | 454 | 56 sec |
1,024 | 8 | 388 | 48 sec |
256 | 8 | 613 | 76 sec |
64 | 8 | 1,667 | 208 sec |
16 | 6 | 4,547 | 757 sec |
4 | 5 | 14,548 | 2,909 sec |
1 | 4 | 41,037 | 10,259 sec |
単純にバッチサイズ比ではありませんが、この計算時間の増加は無視できないオーダーだと思われます。
最大の目的は
・損失関数の出力を早く収束させること
なので、基本的な考え方としては、
・中間程度の学習率、バッチサイズから状況に合わせて数値を変化させていく
感じでしょうか。
全く面白くない結論ですねw
しかし、収束しないときには、学習率だけではなくバッチサイズの変更も効果があることがわかったのは収穫です。
もちろん、許容時間内であればそれ以上数値をいじる必要はありません。
が、投資で実運用していく場合には、学習時間は極力短い方がよいはずです。
大バッチサイズ+大エポック数 vs 小バッチサイズ+小エポック数
で収束するまでの時間効率的にどうなるのかは、すごく興味がありますw