空飛ぶロボットのつくりかた

ロボットをつくるために必要な技術をまとめます。ロボットの未来についても考えたりします。

機械学習のお勉強(オプティマイザーと学習率とエポック、イテレーション)

オプティマイザー

勾配

勾配(微分に負をかけたもの)が示す方向は関数の値を減らす方向になる。

↓数値微分。シンプルだが計算に時間がかかる。

def numerical_gradient(f,x):
    h = 1e-4 # 0.0001
    grad = np.zeros_like(x)

    for idx in range(x.size):
        tmp_val = x[idx]
        x[idx] = tmp_val + h
        fxh1 = f(x)

        x[idx] = tmp_val - h
        fxh2 = f(x)

        grad[idx] = (fxh1 - fxh2)/(2*h)
        x[idx] = tmp_val

    return grad

この勾配の計算を高速に求める手法として、誤差逆伝播法が存在する。

勾配降下法

勾配方向に一定距離だけ進み、そこで勾配を求め再度進む。これの繰り返しによって関数の値を減らす。

以下の式のlrは学習率(learning rate)はあらかじめ人が決める(試行錯誤的に決める)必要があり、ハイパーパラメータと呼ばれる。

このパラメータはバイアスや重みと異なり自動で決めることはできない、かつ、正しく学習するうえで重要。

def gradient_descent(f, init_x, lr = 0.01, step_num = 100):
    x = init_x
    
    for i in range(step_num):
        grad = numerical_gradient(f, x)
        x -= lr * grad
        
    return x

確率的勾配降下法

上記のxをランダムに選んだサンプル一つだけで計算したもの

ミニバッチ確率勾配降下法

上記の1つのサンプルだけではなく、k個のサンプルを1回の更新に利用

モーメンタムSGD

def gradient_descent(f, init_x, lr = 0.01, step_num = 100):
    x = init_x
    
    for i in range(step_num):
        grad = numerical_gradient(f, x)
        v = gamma * pre_v + (1 - gammma) * grad
        x -= lr * v
        pre_v = v
    return x
v = gamma * pre_v + (1 - gamma) * grad

とする、gamma=0.9などにすることが多い。

また、v[t] = (1 - gamma) * sum(gamma**k * grad[t-k] for k in range(t))

と過去の勾配の和として書くことができる。

学習率

上記の

x -= lr * grad

のlrにあたるもの。

学習の速さや最終的なロス値にトレードオフがあるため適切な学習率の設定が必要

AdaGrad

学習率を勾配が大きい時は小さく、小さい時は大きくする方法

eps = 1e-4 # 0.0001
G_2 = pre_G**2 + grad**2
x -= lr / sqrt(G_2 + eps) * grad
pre_G = G_2

G_2 は増加し続けるため、学習が進まなくなることがある

Adam

Momentum SGDの重み付き平均 と AdaGradの重み付き分散を踏まえ、

上記の問題を解決した手法

eps = 1e-4 # 0.0001
bias = sum(gamma**k * grad[t-k] for k in range(t))  # 重み付き平均
var = (bata * pre_var**2 + (1- beta) * grad**2) / (1 -beta) 
x -= lr * bias / sqrt(var + eps)
pre_var = var

参考:

Optimizer : 深層学習における勾配法について - Qiita

エポックとイテレーション

エポック

すべての学習サンプルを学習するのに要した機関

イテレーション

重みを1回更新すること

まとめ

学習率を表す際、イテレーションはバッチサイズに依存してしまうため不適切。

エポックの場合、勾配降下法なのかミニバッチ確率的勾配降下法なのかでかわらない、つまりバッチサイズに依存しない。