詳解神經網路中反向傳播和梯度下降

語言: CN / TW / HK
摘要:反向傳播指的是計算神經網路引數梯度的方法。

本文分享自華為雲社群《反向傳播與梯度下降詳解》,作者:嵌入式視覺 。

一,前向傳播與反向傳播

1.1,神經網路訓練過程

神經網路訓練過程是:

  1. 先通過隨機引數“猜“一個結果(模型前向傳播過程),這裡稱為預測結果 a
  2. 然後計算 a 與樣本標籤值 y 的差距(即損失函式的計算過程);
  3. 隨後通過反向傳播演算法更新神經元引數,使用新的引數再試一次,這一次就不是“猜”了,而是有依據地向正確的方向靠近,畢竟引數的調整是有策略的(基於梯度下降策略)。

以上步驟如此反覆多次,一直到預測結果和真實結果之間相差無幾,亦即 ∣a−y∣→0,則訓練結束。

1.2,前向傳播

前向傳播(forward propagation 或 forward pass)指的是: 按順序(從輸入層到輸出層)計算和儲存神經網路中每層的結果。

為了更深入理解前向傳播的計算過程,我們可以根據網路結構繪製網路的前向傳播計算圖。下圖是簡單網路與對應的計算圖示例:

其中正方形表示變數,圓圈表示操作符。資料流的方向是從左到右依次計算。

1.3,反向傳播

反向傳播(backward propagation,簡稱 BP)指的是計算神經網路引數梯度的方法。其原理是基於微積分中的鏈式規則,按相反的順序從輸出層到輸入層遍歷網路,依次計算每個中間變數和引數的梯度。

梯度的自動計算(自動微分)大大簡化了深度學習演算法的實現。

注意,反向傳播演算法會重複利用前向傳播中儲存的中間值,以避免重複計算,因此,需要保留前向傳播的中間結果,這也會導致模型訓練比單純的預測需要更多的記憶體(視訊記憶體)。同時這些中間結果佔用記憶體(視訊記憶體)大小與網路層的數量和批量(batch_size)大小成正比,因此使用大 batch_size 訓練更深層次的網路更容易導致記憶體不足(out of memory)的錯誤!

1.4,總結

  • 前向傳播在神經網路定義的計算圖中按順序計算和儲存中間變數,它的順序是從輸入層到輸出層。
  • 反向傳播按相反的順序(從輸出層到輸入層)計算和儲存神經網路的中間變數和引數的梯度。
  • 在訓練神經網路時,在初始化模型引數後,我們交替使用前向傳播和反向傳播,基於反向傳播計算得到的梯度,結合隨機梯度下降優化演算法(或者 Adam 等其他優化演算法)來更新模型引數。
  • 深度學習模型訓練比預測需要更多的記憶體。

二,梯度下降

2.1,深度學習中的優化

大多數深度學習演算法都涉及某種形式的優化。優化器的目的是更新網路權重引數,使得我們平滑地到達損失面中損失值的最小點

深度學習優化存在許多挑戰。其中一些最令人煩惱的是區域性最小值、鞍點和梯度消失。

  • 區域性最小值(local minimum): 對於任何目標函式 f(x),如果在 x 處對應的 f(x)值小於在 x 附近任何其他點的 f(x)值,那麼 f(x) 可能是區域性最小值。如果 f(x) 在 x 處的值是整個域上目標函式的最小值,那麼 f(x) 是全域性最小值。
  • 鞍點(saddle point): 指函式的所有梯度都消失但既不是全域性最小值也不是區域性最小值的任何位置。
  • 梯度消失(vanishing gradient): 因為某些原因導致目標函式f 的梯度接近零(即梯度消失問題),是在引入 ReLU 啟用函式和 ResNet 之前訓練深度學習模型相當棘手的原因之一。

在深度學習中,大多數目標函式都很複雜,沒有解析解,因此,我們需使用數值優化演算法,本文中的優化演算法: SGD 和 Adam 都屬於此類別。

2.2,如何理解梯度下降法

梯度下降(gradient descent, GD)演算法是神經網路模型訓練中最為常見的優化器。儘管梯度下降(gradient descent)很少直接用於深度學習,但理解它是理解隨機梯度下降和小批量隨機梯度下降演算法的基礎。

大多數文章都是以“一個人被困在山上,需要迅速下到谷底”來舉例理解梯度下降法,但這並不完全準確。在自然界中,梯度下降的最好例子,就是泉水下山的過程:

  1. 水受重力影響,會在當前位置,沿著最陡峭的方向流動,有時會形成瀑布(梯度的反方向為函式值下降最快的方向);
  2. 水流下山的路徑不是唯一的,在同一個地點,有可能有多個位置具有同樣的陡峭程度,而造成了分流(可以得到多個解);
  3. 遇到坑窪地區,有可能形成湖泊,而終止下山過程(不能得到全域性最優解,而是區域性最優解)。

示例參考 AI-EDU: 梯度下降。

2.3,梯度下降原理

梯度下降的數學公式:

其中:

  • θn+1​:下一個值(神經網路中引數更新後的值);
  • θn​:當前值(當前引數值);
  • −:減號,梯度的反向(梯度的反方向為函式值下降最快的方向);
  • η:學習率或步長,控制每一步走的距離,不要太快以免錯過了最佳景點,不要太慢以免時間太長(需要手動調整的超引數);
  • ∇:梯度,函式當前位置的最快上升點(梯度向量指向上坡,負梯度向量指向下坡);
  • J(θ):函式(等待優化的目標函式)。

下圖展示了梯度下降法的步驟。梯度下降的目的就是使得 x 值向極值點逼近。

由於是雙變數,所以梯度下降的迭代過程需要用三維圖來解釋。表2可視化了三維空間內的梯度下降過程。

圖中間那條隱隱的黑色線,表示梯度下降的過程,從紅色的高地一直沿著坡度向下走,直到藍色的窪地。

雙變數凸函式 J(x,y)=x2+2y2的梯度下降優化過程以及視覺化程式碼如下所示:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
def target_function(x,y):
    J = pow(x, 2) + 2*pow(y, 2)
 return J
def derivative_function(theta):
    x = theta[0]
    y = theta[1]
 return np.array([2*x, 4*y])
def show_3d_surface(x, y, z):
    fig = plt.figure()
    ax = Axes3D(fig)
    u = np.linspace(-3, 3, 100)
    v = np.linspace(-3, 3, 100)
    X, Y = np.meshgrid(u, v)
    R = np.zeros((len(u), len(v)))
 for i in range(len(u)):
 for j in range(len(v)):
 R[i, j] = pow(X[i, j], 2)+ 4*pow(Y[i, j], 2)
 ax.plot_surface(X, Y, R, cmap='rainbow')
 plt.plot(x, y, z, c='black', linewidth=1.5,  marker='o', linestyle='solid')
 plt.show()
if __name__ == '__main__':
    theta = np.array([-3, -3]) # 輸入為雙變數
    eta = 0.1 # 學習率
    error = 5e-3 # 迭代終止條件,目標函式值 < error
    X = []
    Y = []
    Z = []
 for i in range(50):
 print(theta)
        x = theta[0]
        y = theta[1]
        z = target_function(x,y)
 X.append(x)
 Y.append(y)
 Z.append(z)
 print("%d: x=%f, y=%f, z=%f" % (i,x,y,z))
 d_theta = derivative_function(theta)
 print("    ", d_theta)
        theta = theta - eta * d_theta
 if z < error:
 break
    show_3d_surface(X,Y,Z)

注意!總結下,不同的步長 η ,隨著迭代次數的增加,會導致被優化函式 J 的值有不同的變化:

圖片來源如何理解梯度下降法?

三,隨機梯度下降與小批量隨機梯度下降

3.1,隨機梯度下降

在深度學習中,目標函式通常是訓練資料集中每個樣本的損失函式的平均值。如果使用梯度下降法,則每個自變數迭代的計算代價為 O(n),它隨 n(樣本數目)線性增⻓。因此,當訓練資料集較大時,每次迭代的梯度下降計算代價將較高。

隨機梯度下降(SGD)可降低每次迭代時的計算代價。在隨機梯度下降的每次迭代中,我們對資料樣本隨機均勻取樣一個索引 i,其中 i∈1,...,n,並計算梯度 ∇J(θ)以更新權重引數 θ:

每次迭代的計算代價從梯度下降的 O(n) 降至常數 O(1)。另外,值得強調的是,隨機梯度 ∇Ji(θ) 是對完整梯度 ∇J(θ) 的無偏估計。

無偏估計是用樣本統計量來估計總體引數時的一種無偏推斷。

在實際應用中,隨機梯度下降 SGD 法必須和動態學習率方法結合起來使用,否則使用固定學習率 + SGD的組合會使得模型收斂過程變得更復雜。

3.2,小批量隨機梯度下降

前面講的梯度下降(GD)和隨機梯度下降(SGD)方法都過於極端,要麼使用完整資料集來計算梯度並更新引數,要麼一次只處理一個訓練樣本來更新引數。在實際專案中,會對兩者取折中,即小批量隨機梯度下降(minibatch gradient descent),使用小批量隨機梯度下降還可以提高計算效率。

小批量的所有樣本資料元素都是從訓練集中隨機抽出的,樣本數目個數為 batch_size(縮寫 bs)

另外,一般專案中使用 SGD 優化演算法都預設會使用小批量隨機梯度下降,即 batch_size > 1,除非顯示卡視訊記憶體不夠了,才會設定 batch_size = 1。

參考資料

  1. 如何理解梯度下降法?
  2. AI-EDU: 梯度下降
  3. 《動手學習深度學習11章-優化演算法》

 

點選關注,第一時間瞭解華為雲新鮮技術~