來源| OSCHINA 社區(qū)
摘要:反向傳播指的是計(jì)算神經(jīng)網(wǎng)絡(luò)參數(shù)梯度的方法。
本文分享自華為云社區(qū)《反向傳播與梯度下降詳解》,作者:嵌入式視覺 。
一,前向傳播與反向傳播
1.1,神經(jīng)網(wǎng)絡(luò)訓(xùn)練過程
神經(jīng)網(wǎng)絡(luò)訓(xùn)練過程是:
先通過隨機(jī)參數(shù) “猜 “一個結(jié)果(模型前向傳播過程),這里稱為預(yù)測結(jié)果a;
然后計(jì)算a與樣本標(biāo)簽值 y 的差距(即損失函數(shù)的計(jì)算過程);
隨后通過反向傳播算法更新神經(jīng)元參數(shù),使用新的參數(shù)再試一次,這一次就不是 “猜” 了,而是有依據(jù)地向正確的方向靠近,畢竟參數(shù)的調(diào)整是有策略的(基于梯度下降策略)。
以上步驟如此反復(fù)多次,一直到預(yù)測結(jié)果和真實(shí)結(jié)果之間相差無幾,亦即 ∣a?y∣→0,則訓(xùn)練結(jié)束。
1.2,前向傳播
前向傳播 (forward propagation 或 forward pass) 指的是:按順序 (從輸入層到輸出層) 計(jì)算和存儲神經(jīng)網(wǎng)絡(luò)中每層的結(jié)果。
為了更深入理解前向傳播的計(jì)算過程,我們可以根據(jù)網(wǎng)絡(luò)結(jié)構(gòu)繪制網(wǎng)絡(luò)的前向傳播計(jì)算圖。下圖是簡單網(wǎng)絡(luò)與對應(yīng)的計(jì)算圖示例:
其中正方形表示變量,圓圈表示操作符。數(shù)據(jù)流的方向是從左到右依次計(jì)算。
1.3,反向傳播
反向傳播 (backward propagation,簡稱 BP) 指的是計(jì)算神經(jīng)網(wǎng)絡(luò)參數(shù)梯度的方法。其原理是基于微積分中的鏈?zhǔn)揭?guī)則,按相反的順序從輸出層到輸入層遍歷網(wǎng)絡(luò),依次計(jì)算每個中間變量和參數(shù)的梯度。
梯度的自動計(jì)算 (自動微分) 大大簡化了深度學(xué)習(xí)算法的實(shí)現(xiàn)。
注意,反向傳播算法會重復(fù)利用前向傳播中存儲的中間值,以避免重復(fù)計(jì)算,因此,需要保留前向傳播的中間結(jié)果,這也會導(dǎo)致模型訓(xùn)練比單純的預(yù)測需要更多的內(nèi)存(顯存)。同時這些中間結(jié)果占用內(nèi)存(顯存)大小與網(wǎng)絡(luò)層的數(shù)量和批量(batch_size)大小成正比,因此使用大 batch_size 訓(xùn)練更深層次的網(wǎng)絡(luò)更容易導(dǎo)致內(nèi)存不足(out of memory)的錯誤!
1.4,總結(jié)
前向傳播在神經(jīng)網(wǎng)絡(luò)定義的計(jì)算圖中按順序計(jì)算和存儲中間變量,它的順序是從輸入層到輸出層。
反向傳播按相反的順序 (從輸出層到輸入層) 計(jì)算和存儲神經(jīng)網(wǎng)絡(luò)的中間變量和參數(shù)的梯度。
在訓(xùn)練神經(jīng)網(wǎng)絡(luò)時,在初始化模型參數(shù)后,我們交替使用前向傳播和反向傳播,基于反向傳播計(jì)算得到的梯度,結(jié)合隨機(jī)梯度下降優(yōu)化算法(或者 Adam 等其他優(yōu)化算法)來更新模型參數(shù)。
深度學(xué)習(xí)模型訓(xùn)練比預(yù)測需要更多的內(nèi)存。
二,梯度下降
2.1,深度學(xué)習(xí)中的優(yōu)化
大多數(shù)深度學(xué)習(xí)算法都涉及某種形式的優(yōu)化。優(yōu)化器的目的是更新網(wǎng)絡(luò)權(quán)重參數(shù),使得我們平滑地到達(dá)損失面中損失值的最小點(diǎn)。
深度學(xué)習(xí)優(yōu)化存在許多挑戰(zhàn)。其中一些最令人煩惱的是局部最小值、鞍點(diǎn)和梯度消失。
局部最小值(local minimum): 對于任何目標(biāo)函數(shù) f (x),如果在 x 處對應(yīng)的 f (x) 值小于在x附近任何其他點(diǎn)的 f (x) 值,那么 f (x) 可能是局部最小值。如果 f (x) 在x處的值是整個域上目標(biāo)函數(shù)的最小值,那么f(x) 是全局最小值。
鞍點(diǎn)(saddle point): 指函數(shù)的所有梯度都消失但既不是全局最小值也不是局部最小值的任何位置。
梯度消失(vanishing gradient): 因?yàn)槟承┰驅(qū)е履繕?biāo)函數(shù)f的梯度接近零(即梯度消失問題),是在引入 ReLU 激活函數(shù)和 ResNet 之前訓(xùn)練深度學(xué)習(xí)模型相當(dāng)棘手的原因之一。
在深度學(xué)習(xí)中,大多數(shù)目標(biāo)函數(shù)都很復(fù)雜,沒有解析解,因此,我們需使用數(shù)值優(yōu)化算法,本文中的優(yōu)化算法: SGD 和 Adam 都屬于此類別。
2.2,如何理解梯度下降法
梯度下降(gradient descent, GD)算法是神經(jīng)網(wǎng)絡(luò)模型訓(xùn)練中最為常見的優(yōu)化器。盡管梯度下降 (gradient descent) 很少直接用于深度學(xué)習(xí),但理解它是理解隨機(jī)梯度下降和小批量隨機(jī)梯度下降算法的基礎(chǔ)。
大多數(shù)文章都是以 “一個人被困在山上,需要迅速下到谷底” 來舉例理解梯度下降法,但這并不完全準(zhǔn)確。在自然界中,梯度下降的最好例子,就是泉水下山的過程:
水受重力影響,會在當(dāng)前位置,沿著最陡峭的方向流動,有時會形成瀑布(梯度的反方向?yàn)楹瘮?shù)值下降最快的方向);
水流下山的路徑不是唯一的,在同一個地點(diǎn),有可能有多個位置具有同樣的陡峭程度,而造成了分流(可以得到多個解);
遇到坑洼地區(qū),有可能形成湖泊,而終止下山過程(不能得到全局最優(yōu)解,而是局部最優(yōu)解)。
示例參考 AI-EDU: 梯度下降。
2.3,梯度下降原理
梯度下降的數(shù)學(xué)公式:
其中:
θn+1:下一個值(神經(jīng)網(wǎng)絡(luò)中參數(shù)更新后的值);
θn:當(dāng)前值(當(dāng)前參數(shù)值);
?:減號,梯度的反向(梯度的反方向?yàn)楹瘮?shù)值下降最快的方向);
η:學(xué)習(xí)率或步長,控制每一步走的距離,不要太快以免錯過了最佳景點(diǎn),不要太慢以免時間太長(需要手動調(diào)整的超參數(shù));
?:梯度,函數(shù)當(dāng)前位置的最快上升點(diǎn)(梯度向量指向上坡,負(fù)梯度向量指向下坡);
J (θ):函數(shù)(等待優(yōu)化的目標(biāo)函數(shù))。
下圖展示了梯度下降法的步驟。梯度下降的目的就是使得x值向極值點(diǎn)逼近。
由于是雙變量,所以梯度下降的迭代過程需要用三維圖來解釋。表 2 可視化了三維空間內(nèi)的梯度下降過程。
圖中間那條隱隱的黑色線,表示梯度下降的過程,從紅色的高地一直沿著坡度向下走,直到藍(lán)色的洼地。
雙變量凸函數(shù) J (x,y)=x2+2y2 的梯度下降優(yōu)化過程以及可視化代碼如下所示:
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 # 學(xué)習(xí)率 error = 5e-3 # 迭代終止條件,目標(biāo)函數(shù)值 < 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)注意!總結(jié)下,不同的步長 η ,隨著迭代次數(shù)的增加,會導(dǎo)致被優(yōu)化函數(shù) J 的值有不同的變化:
圖片來源如何理解梯度下降法?。
三,隨機(jī)梯度下降與小批量隨機(jī)梯度下降
3.1,隨機(jī)梯度下降
在深度學(xué)習(xí)中,目標(biāo)函數(shù)通常是訓(xùn)練數(shù)據(jù)集中每個樣本的損失函數(shù)的平均值。如果使用梯度下降法,則每個自變量迭代的計(jì)算代價為 O (n),它隨 n(樣本數(shù)目)線性增?。因此,當(dāng)訓(xùn)練數(shù)據(jù)集較大時,每次迭代的梯度下降計(jì)算代價將較高。 隨機(jī)梯度下降 (SGD) 可降低每次迭代時的計(jì)算代價。在隨機(jī)梯度下降的每次迭代中,我們對數(shù)據(jù)樣本隨機(jī)均勻采樣一個索引 i,其中 i∈1,...,n,并計(jì)算梯度 ?J (θ) 以更新權(quán)重參數(shù) θ:
每次迭代的計(jì)算代價從梯度下降的 O (n) 降至常數(shù) O (1)。另外,值得強(qiáng)調(diào)的是,隨機(jī)梯度 ?Ji (θ) 是對完整梯度 ?J (θ) 的無偏估計(jì)。 無偏估計(jì)是用樣本統(tǒng)計(jì)量來估計(jì)總體參數(shù)時的一種無偏推斷。 在實(shí)際應(yīng)用中,隨機(jī)梯度下降 SGD 法必須和動態(tài)學(xué)習(xí)率方法結(jié)合起來使用,否則使用固定學(xué)習(xí)率 + SGD 的組合會使得模型收斂過程變得更復(fù)雜。
3.2,小批量隨機(jī)梯度下降
前面講的梯度下降(GD)和隨機(jī)梯度下降(SGD)方法都過于極端,要么使用完整數(shù)據(jù)集來計(jì)算梯度并更新參數(shù),要么一次只處理一個訓(xùn)練樣本來更新參數(shù)。在實(shí)際項(xiàng)目中,會對兩者取折中,即小批量隨機(jī)梯度下降 (minibatch gradient descent),使用小批量隨機(jī)梯度下降還可以提高計(jì)算效率。 小批量的所有樣本數(shù)據(jù)元素都是從訓(xùn)練集中隨機(jī)抽出的,樣本數(shù)目個數(shù)為 batch_size(縮寫 bs)
另外,一般項(xiàng)目中使用 SGD 優(yōu)化算法都默認(rèn)會使用小批量隨機(jī)梯度下降,即 batch_size > 1,除非顯卡顯存不夠了,才會設(shè)置 batch_size = 1。
審核編輯:湯梓紅
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4733瀏覽量
100420 -
參數(shù)
+關(guān)注
關(guān)注
11文章
1754瀏覽量
32044 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4277瀏覽量
62323 -
模型
+關(guān)注
關(guān)注
1文章
3112瀏覽量
48660 -
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5463瀏覽量
120890
原文標(biāo)題:詳解神經(jīng)網(wǎng)絡(luò)中反向傳播和梯度下降
文章出處:【微信號:OSC開源社區(qū),微信公眾號:OSC開源社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論