MomentumとAdaGrad
MomentumとAdaGrad
前回まではパラメータの更新に確率的勾配降下法(SGD)を使いました。精度は30%ぐらいだったので、今回はMomentumとAdaGradを使ってどの位変わるか試してみます。
SGD
定義
コード
SGDクラスを作成する。
class SGD: def __init__(self, lr=0.5): self.lr = lr def update(self, paramas, grads): for key in params.keys(): params[key] -= self.lr * grads[key]
Momentum
定義
コード
Momentumクラスを作成する。
class Momentum: def __init__(self, lr=0.01, momentum=0.9): self.lr = lr self.momentum = momentum self.v = None def update(self, params, grads): if self.v is None: self.v ={} for key, val in params.items(): self.v[key] = np.zeros_like(val) for key in params.keys(): self.v[key] = self.momentum*self.v[key] - self.lr*grads[key] params[key] += self.v[key]
AdaGrad
定義
[tex: {h←h+\frac{∂L}{∂W}\frac{∂L}{∂W}}]
[tex: {W←W-η\frac{1}{\sqrt{h}}\frac{∂L}{∂W}}]
学習回数が増えるにしたがい、パラメータ更新が小さくなる。
コード
AdaGradクラスを作成する。
class AdaGrad: def __init__(self, lr=0.01): self.lr = lr self.h = None def update(self, params, grads): if self.h is None: self.h = {} for key, val in pramas.items(): self.h[key] = np.zeros_like(val) for key in params.keys(): self.h[key] += grads[key] * grads[key] params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]+1e-7))
mainプログラム
最適化手法を選べるようにプログラムを修正する。
ans_label = np.argmax(t_train, axis=1) ans = 0 for i in range(100): network = LayerNet(2, 2, 2) optimizer = Momentum() #最適化手法を選択 for step in range(1001): batch_mask = np.random.choice([0,1,2,3], 1) x_batch = x_train[batch_mask] t_batch = t_train[batch_mask] grads = network.training(x_batch, t_batch) params = network.params optimizer.update(params, grads) if step == 1000: y = np.argmax(network.predict(x_train), axis=1) print("y:", y) a = (y == ans_label) if a.all(): ans += 1 print("ans:", ans, "/ 100")
出力
Momentum
学習率0.01 運動量0.9
('ans:', 52, '/ 100') ('ans:', 53, '/ 100') ('ans:', 51, '/ 100')
学習率0.5 運動量0.9
('ans:', 0, '/ 100') ('ans:', 0, '/ 100')
学習率0.05 運動量0.9
('ans:', 18, '/ 100')
学習率0.01 運動量0.5
('ans:', 39, '/ 100')
AdaGrad
学習率0.01
('ans:', 0, '/ 100') ('ans:', 0, '/ 100')
学習率0.5
('ans:', 7, '/ 100') ('ans:', 6, '/ 100')
結論
学習率と運動量をうまく設定すれば、Momentumを使用することで精度があがる。 AdaGradはXOR回路ではうまくいかない。 ハイパーパラメータ(学習率,運動量など)はランダムに選んで、良い結果を導けるプログラムに修正すると尚よい。