[ch04-02] 用梯度下降法解決線性迴歸問題
系列部落格,原文在筆者所維護的github上:https://aka.ms/beginnerAI,
點選star加星不要吝嗇,星越多筆者越努力。
4.2 梯度下降法
有了上一節的最小二乘法做基準,我們這次用梯度下降法求解w和b,從而可以比較二者的結果。
4.2.1 數學原理
在下面的公式中,我們規定x是樣本特徵值(單特徵),y是樣本標籤值,z是預測值,下標 \(i\) 表示其中一個樣本。
預設函式(Hypothesis Function)
為一個線性函式:
\[z_i = x_i \cdot w + b \tag{1}\]
損失函式(Loss Function)
為均方差函式:
\[loss(w,b) = \frac{1}{2} (z_i-y_i)^2 \tag{2}\]
與最小二乘法比較可以看到,梯度下降法和最小二乘法的模型及損失函式是相同的,都是一個線性模型加均方差損失函式,模型用於擬合,損失函式用於評估效果。
區別在於,最小二乘法從損失函式求導,直接求得數學解析解,而梯度下降以及後面的神經網路,都是利用導數傳遞誤差,再通過迭代方式一步一步逼近近似解。
4.2.2 梯度計算
計算z的梯度
根據公式2:
\[
{\partial loss \over \partial z_i}=z_i - y_i \tag{3}
\]
計算w的梯度
我們用loss的值作為誤差衡量標準,通過求w對它的影響,也就是loss對w的偏導數,來得到w的梯度。由於loss是通過公式2->公式1間接地聯絡到w的,所以我們使用鏈式求導法則,通過單個樣本來求導。
根據公式1和公式3:
\[ {\partial{loss} \over \partial{w}} = \frac{\partial{loss}}{\partial{z_i}}\frac{\partial{z_i}}{\partial{w}}=(z_i-y_i)x_i \tag{4} \]
計算b的梯度
\[ \frac{\partial{loss}}{\partial{b}} = \frac{\partial{loss}}{\partial{z_i}}\frac{\partial{z_i}}{\partial{b}}=z_i-y_i \tag{5} \]
4.2.3 程式碼實現
if __name__ == '__main__': reader = SimpleDataReader() reader.ReadData() X,Y = reader.GetWholeTrainSamples() eta = 0.1 w, b = 0.0, 0.0 for i in range(reader.num_train): # get x and y value for one sample xi = X[i] yi = Y[i] # 公式1 zi = xi * w + b # 公式3 dz = zi - yi # 公式4 dw = dz * xi # 公式5 db = dz # update w,b w = w - eta * dw b = b - eta * db print("w=", w) print("b=", b)
大家可以看到,在程式碼中,我們完全按照公式推導實現了程式碼,所以,大名鼎鼎的梯度下降,其實就是把推導的結果轉化為數學公式和程式碼,直接放在迭代過程裡!另外,我們並沒有直接計算損失函式值,而只是把它融入在公式推導中。
4.2.4 執行結果
w= [1.71629006]
b= [3.19684087]
讀者可能會注意到,上面的結果和最小二乘法的結果(w1=2.056827, b1=2.965434)相差比較多,這個問題我們留在本章稍後的地方解決。
程式碼位置
ch04, Level2