konchangakita

KPSを一番楽しんでいたブログ 会社の看板を背負いません 転載はご自由にどうぞ

【DeepLearning特訓】MLPの基礎 学習アルゴリズム

E資格向けの自習アウトプット
自分用メモ

学習アルゴリズムとして、確率的勾配降下法はよく利用される方法ですが、勾配を求めてパラメータを更新する方向は分かれど、どれくらい更新すればよいかが明確に示されるわけではないので、学習が遅くなる場合がある。そこで過去の勾配情報を利用したりしながらパラメータ更新する工夫を行う
きっとモーメンタムとか今はほとんど使われていないのだろうけど、試験にでそうなので丸暗記

モメンタム

運動量の考え方を追加、速度 v、減速率 momentum を追加
速度 v は初期値は「0」で、アップデートされ減速していく

f:id:konchangakita:20210107233116p:plain

# モーメンタム
# w:重み、dw:重みの勾配
lr = 0.01   # 学習率
v = 0       # 初期値は0で更新されていく
momentum = 0.9     # モーメンタム

def momentum(w, lr, v, momentum):
    v = momentum * v - lr * dw
    w += v
    return w, v


ネステロフのモーメンタム

モーメントに直前の速度を加味する
f:id:konchangakita:20210108000229p:plain

書いてみたもののよくわからぬ

# ネステロフのモーメンタム
# w:重み、dw:重みの勾配
lr = 0.01   # 学習率
v = 0       # 初期値は0で更新されていく
momentum = 0.9     # モーメンタム

def momentum(dw, lr, v, momentum):
    old_v = v
    v = momentum * v - lr * dw
    w += -momentum * old_v + (1+momentum) * v
    return w, v


AdaGrad

モーメンタムアルゴリズムでは運動量が追加されていたが、AdaGradでは過去の勾配を蓄積させていく(どんどん小さくなる)
f:id:konchangakita:20210108005327p:plain:w400

# AdaGrad
delta = 1e-7    # 0で割ると困るから
lr = 0.01       # 学習率
h = 0           # 初期値は0で更新されていく

def adagrad(dw, lr, h):
    h += dw * dw
    w -= lr * dw / (np.sqrt(h) + delta)
    return w, h


RMSProp

AdaGrad の修正版
AdaGrad の弱点は、学習に十分時間がたつと勾配がどんどん小さくなり最適解の前に学習が止まってしまう
減衰率をもちいて、過去の勾配の影響を小さくする
累積二乗和ではなく、移動平均

# RMSProp
delta = 1e-7    # 0で割ると困るから
lr = 0.01       # 学習率
h = 0           # 初期値は0で更新されていく
decay_late = 0.9    # 減衰率

def rmsprop(dw, lr, h, decay_rate):
    h = h * decay_rate + (1 - decay_rate) * dw * dw # 減衰率を加味
    w -= lr * dw / (np.sqrt(h) + delta)
    return w, h


Adam

モーメンタム + AdaGrad/RMSProp の組み合わせ
運動量と移動平均を両方組み合わせ
よく利用されている、とりあえずこれにしておけば間違いない(?)

f:id:konchangakita:20210108111519p:plain
beta の部分をなんて呼ぶのかは知らない

# Adam
delta = 1e-7        # 0で割ると困るから
lr = 0.01           # 学習率
first_m, second_m = 0, 0    # 初期値は0で更新されていく
beta1, beta2 = 0.9, 0.99    # 減衰率?
t = 1   # 更新回数ごとの増やす(補正の影響を小さくしていく)

def adam(dw, lr, first_m, second_m, beta1, beta2):
    first_m = beta1 * first_m + (1 - beta1) * dx
    second_m = beta2 * second_m + (1 -beta2) * dx * dx
    first_unbias = first_m / (1 - beta1**t)
    second_unbias = second_m / (1 - beta2**t)
    w -= lr * first_unbias / (np.sqrt(second_unbias) + delta)
    t += 1
    return w, first_unbias, second_unbias

まとめ

パラメータ更新方法の考え方がいくつか出てきました。ムズイ
結局どれがよいのか?は扱う問題によって変わってきます
(きっとAdamが汎用性あるのだろうけども)
Python 実装してみてそれぞれの学習する過程を確認してみたいと