6『乱数による初期パラメータ設定とバッチサイズ』
1)モデルの重みとバイアスの初期値はランダムに決められます。これはtorch.nnという機能を用いると裏で処理されてコード上に現れることがありません。手書きのコードでモデルの重みとバイアスを明示的に定義することもできます。(model.fc1.weight = nn.Parameter(fc1w_tc))
2)初期値のランダム性により学習結果は毎回完全に一致するわけではない。しかしランダム性を同じにすることもできて、random_seedを固定すると利用されるランダム値が固定され、出力が同一となります。
random.seed(0) numpy.random.seed(0) torch.manual_seed(0)
これでepoch1のLOSSは、何回初期化しなおしても1.7363と同じ値になります。すなわち学習結果は数学的に一致します。しかし、seed固定して数学的に厳密に一致させる必要はないので、私はseed固定はしないで開発しています。
3)何層にするか、バッチサイズをどれくらいにするか
今回は、5➡10➡10➡4➡1の入力1層、中間3層、出力1層、総数5層のネットワークです。「層を多くするほどいいように思いますが」と言われることがありますが、例えば、過学習といって入力データだけに特化した(例えば特定の範囲だけで正しく値を出力する)モデルを作ってしまったりします。また誤差を逆伝播させて勾配を決めてパラメータを修正していくのですが、層が多いと逆伝播が何回もでてきます。さかのぼる層が増えると微分値が積になっていき、きわめてゼロに近い値になってしまいます。勾配消失という問題で、パラメータの値が更新されずにうんともすんとも言わずにエポックのみがむなしく進んでいくことがあります。したがって、計算過程がそれなりに複雑だとか、データ数が十分にあるとか、の場合に層が多いネットワークの本領が発揮されるのでしょう。
バッチサイズ(BS)は、例えばデータがある値を中心に分散が少ないような場合はBSが大きくとも小さくとも同じような勾配が得られるでしょう。もしデータの分散が大きくてすごい大きな勾配や小さな勾配が混在するような場合はBS=10位でもその都度勾配は上へ下へと急変化を繰り返すでしょう。ちまたでは、2の乗数、4, 8, 16, 32, 64, 128が計算がうまくいくといわれたりしますが、あまり実感しませんし、なぜそうなのかの理論も良くわかりません。BS=32でもBS=30でも勾配の平均とるのだからどっちでもよいのではと思ったりします。