エポックとバッチ
1エポック = 全データを 1 回学習すること。
教師データのセット単位を 1 バッチ。
1 エポック = 複数バッチ
バッチ学習
バッチサイズ = エポックサイズ の学習のこと。
学習が安定してて高速ではあるが、局所解にハマりやすい。
オンライン学習
バッチサイズが 1 となる。
個々のデータに振り回されるので、バーストには弱いが、局所解にとらわれにくい。
ミニバッチ学習
訓練データを複数のバッチに分割して、バッチ単位で重みとバイアスの学習を行う。
局所解に囚われにくいし、個々のデータで振れ幅もさほどではない。
1000 の教師データがあるとき、
- バッチ学習「1000で1回重みとバイアス計算を行う」
- オンライン学習「1エポック当たり 1000 回学習するよ」
- ミニバッチ学習「1バッチ 50で設定したら、20 回学習するよ」
行列での演算
バッチサイズを 8 入力数(入力層のニューロン数) 3 とすると、入力を表す行列サイズは 8x3。
バッチサイズが 1 の時、1x3 になるので、ベクトルの様な形状になる。
試しに 4x3 (バッチサイズ 2)の思考実験をすると
import numpy as np X = np.array([ [1, 2, 3, 4], [4, 5, 6, 7] ]) W = np.array([ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]) X.dot(W)
array([[ 70, 80, 90], [136, 158, 180]])
もう少し汎用的に考えると バッチサイズ 、入力層
、ニューロン数
の行列はこんな感じか
うげ…でも数式書いてみると理解できる。
この時、座標 1,1
の結果は
となるので、同様に考えて
で、バイアスはニューロン毎に定義されるので数は ニューロン数と同数の
ここに活性関数 を適用すると結果 Y は
コード的に関係性を書くと
## 値は適当だけど、実装的にはこな感じ X = np.array([ [1, 2, 3, 4], [4, 5, 6, 7] ]) W = np.array([ [1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12] ]) B = np.array([ 1, 2, 3 ]) U = X.dot(W) + B print(U) def sigmoid(u): return 1 / (1 + np.exp(-u)) sigmoid(U)
さて、ネタは揃った、いや、揃っちゃった(汗
後はこの値に最終層(恒等関数 or ソフトマックス関数)+誤差関数 を含んだ状態で微分して、勾配降下法で W, B の値を更新すればニューラルネットワークの学習ができるはず。
次回は微分地獄かー(汗