-
梯度
簡單來說,例如有
像這樣的全部由變量的偏導數組成的向量稱爲梯度(gradient)。
實際上,梯度會指向各點處的函數值降低的方向。更嚴格的講,梯度指示的方向是各點處的函數值減少最多的方向。
爲什麼這麼說,因爲方向導數=cos()×梯度,而是方向導數的方向和梯度方向的夾角。所以,所有的下降方向中,梯度方向下降的最多。
-
梯度法
神經網絡的主要任務是在學習時找到最優的參數(權重和偏置),這個最優參數也就是損失函數最小時的參數。但是,一般情況下,損失函數比較複雜,參數也很多,無法確定在哪裏取得最小值。所以通過梯度來尋找最小值(或者儘可能小的值)的方法就是梯度法。
需要注意的是,梯度表示的是各點處的函數值減少最多的方向,所以梯度的方向並不一定指向最小值。但是沿着它的方向能夠最大限度地減少函數的值。因此,在尋找函數的最小值(或者儘可能小的值)的位置的時候,要以梯度的信息爲線索,決定前進的方向。
此時梯度法就派上用場了。在梯度法中,函數的取值從當前位置沿着梯度方向前進一定距離,然後在新的方向重新求梯度,再沿着新梯度方向前進,如此反覆。
像這樣,通過不斷地沿梯度方向前進,逐漸減小函數值的過程就是梯度法(gradient mothod)。一般來說,神經網絡(深度學習)中,梯度法主要是指梯度下降法(gradient descent mothod)。
現在,我們試着用數學公式表達梯度下降(兩個變量情況下):
,
其中,表示更新量,在神經網絡的學習中,稱爲學習率 (learning rate)。學習率決定在一次學習中,應該學習多少,以及在多大程度上更新參數。
學習率需要事先設定爲某個值,比如0.01或0.001。一般而言,這個值過大或過小,都無法抵達一個“好的位置”。在神經網絡的學習中,一般會一邊改變學習率的值,一邊確認學習是否正確進行。
下面,我們用Python來實現梯度下降法。
def gradient_descent(f, init_x, lr=0.01, epoch=100):
x = init_x
for i in range(epoch):
grad = numerical_gradient(f, x) # 求導函數
x -= lr * grad
return x
其中,f是要求的函數,init_x是初始值,lr是learning rate,epoch是梯度法的重複次數,也就是計算多少次。
其中numerical_gradient(f, x)爲,代碼如下:
# 用定義法求導數
def numerical_gradient(f, x):
h = 1e-4
grad = np.zeros_like(x)
for idx in range(x.size):
temp = x[idx]
# 計算f(x+h)
x[idx] = temp + h
fxh1 = f(x)
# 計算f(x-h)
x[idx] = temp - h
fxh2 = f(x)
grad[idx] = (fxh1 - fxh2)/(2 * h)
x[idx] = temp
return grad
例:用梯度法求 的最小值.
def function(x):
return x[0]**2 + x[1]**2
inin_x = np.array([-3.0, 4.0])
print(gradient_descent(function, inin_x, lr=0.1, epoch=100))
初始值爲(-3,4)可以看出結果很接近(0,0)。實際的最小值點(0,0),所以可以說基本得到了正確的結果。