はじめに
前回は、関数の勾配を求めるところまで記載したので、
今回は勾配法について記載します。
勾配とは、「関数の値を最も減らす方向」でしたが、
勾配法を使用し、関数の値を勾配の方向に一定量だけ値を減らし、
減らした場所で、また勾配を求め、一定量だけ値を減らしていき、
これを繰り返し、最小値を探していきます。
勾配法の式
勾配法は、次の式で表されます。
X1・X2と変数がある場合、
X1=X1ー[学習率]×勾配
X2=X2ー[学習率]×勾配
となります。
つまり、取得した勾配の逆方向に学習率分だけX1・X2を更新する処理となります。
ここで学習率とは、1回の学習でどれだけ更新するかの指標です。
勾配法の実装
実装は、結構簡単でした。
import numpy as np # 勾配を求める def numrerical_gradient(f, x): h = 1e-4 gradient = np.zeros_like(x) for index in range(x.size): temp_val = x[index] x[index] = temp_val + h f1 = f(x) x[index] = temp_val - h f2 = f(x) gradient[index] = (f1 - f2) / (2 * h) x[index] = temp_val return gradient #勾配法 def gradient_descent(f, init_x, learning_rate=0.01, count=100): x = init_x for i in range(count): grad = numrerical_gradient(f, x) x = x - (learning_rate * grad) print(x) return x # 関数 def function2(x) : return x[0] ** 2 + x[1] ** 2 #X1=3.0、X2=4.0、学習率0.1で、10回繰り返して、最終的な勾配を求める gd = gradient_descent(function2, init_x = np.array([3.0, 4.0]), learning_rate = 0.1, count = 10)
実行結果
[2.4 3.2] [1.92 2.56] [1.536 2.048] [1.2288 1.6384] [0.98304 1.31072] [0.786432 1.048576] [0.6291456 0.8388608] [0.50331648 0.67108864] [0.40265318 0.53687091] [0.32212255 0.42949673]
徐々に[0, 0]に近づいています。
最後に・・・
次回は、この勾配法を用いて、
ニューラルネットワークの重みパラメータを更新し、
より教師データに近づいていく、重みパラメータを得る処理を実装してみます。
お読みいただき、ありがとうございました!