Pythonで勾配降下法

機械学習




Pythonで勾配降下法

勾配降下法の更新

$$
\omega _ { i } = \omega _ { i } – \alpha \frac { \partial E } { \partial \omega _ { i } }
$$

数値微分

ここでは、すごく簡単な中央差分を用いて数値微分します。
$$
\lim _ { h \rightarrow 0 } \frac { f ( x + h ) – f ( x – h ) } { 2 h }
$$

h=1e-4などで、簡単な近似させます。

回帰直線を勾配法でパラメータ推定する

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
np.random.seed(1)

#学習率
alpha = 1e-3

#数値微分のh
h = 1e-3

x = np.arange(10).reshape(-1, 1)
seg = np.ones(10).reshape(-1,1)
y = 5*seg + 3*x

print("モデルのパラメータ:b={}, a={}".format(5, 3))
#パラメータの初期値
a = np.random.normal(0.0, 1.0, size=None)
b = np.random.normal(0.0, 1.0, size=None)
print("パラメータの初期値:b={}, a={}".format(b,a))

#評価関数(二乗和誤差)
def E(x, y, a, b):
    return 0.5 * (((a*x + b) - y)**2).sum()

#学習
for i in range(10000):
    #数値微分
    deda = (E(x, y, a+h, b) - E(x, y, a-h, b)) / (2*h)
    dedb = (E(x, y, a, b+h) - E(x, y, a, b-h)) / (2*h)
    
    #パラメータ更新
    a = a - alpha*deda
    b = b - alpha*dedb

print("勾配法のパラメータ推定:b={:.2f}, a={:.2f}".format(b,a))
'''
出力
'''
モデルのパラメータ:b=5, a=3
パラメータの初期値:b=-0.6117564136500754, a=1.6243453636632417
勾配法のパラメータ推定:b=5.00, a=3.00

学習part2

上のプログラムでは、学習回数を10000として、学習させた。

下のプログラムは、勾配が0.01以下になるまで、学習させるようになっている。

#学習
ds = 100
while abs(ds) > 0.01:
    #数値微分
    deda = (E(x, y, a+h, b) - E(x, y, a-h, b)) / (2*h)
    dedb = (E(x, y, a, b+h) - E(x, y, a, b-h)) / (2*h)
    
    #パラメータ更新
    a = a - alpha*deda
    b = b - alpha*dedb

    ds = deda + dedb
タイトルとURLをコピーしました