導(dǎo)言
動(dòng)機(jī):為了高效的設(shè)計(jì)和調(diào)試神經(jīng)網(wǎng)絡(luò)于置,理解反向傳播的機(jī)理是很重要的髓削。
問題描述:有了函數(shù)f(x)我們對(duì)于計(jì)算f在x點(diǎn)的梯度很感興趣豆村。
在神經(jīng)網(wǎng)絡(luò)中剖踊,f相應(yīng)于損失函數(shù)和輸入x將組成訓(xùn)練集和神經(jīng)網(wǎng)絡(luò)權(quán)重驼鞭,比如損失將是SVM損失函數(shù)而輸入既是訓(xùn)練數(shù)據(jù)也是權(quán)重秦驯,既是我們可以很快的使用后向傳播計(jì)算出梯度,實(shí)際上我們通常也僅僅計(jì)算每一個(gè)參數(shù)的梯度挣棕,所以我們可以使用它來實(shí)現(xiàn)一個(gè)參數(shù)的更新译隘,然而正如我們?cè)谡n程中后面會(huì)看到的x仍然是有用的亲桥,比如為了可視化神經(jīng)網(wǎng)絡(luò)在做什么。
計(jì)算
首先看最簡(jiǎn)單的例子:
反向傳播是一個(gè)精美的本地進(jìn)程固耘。電路圖中的每個(gè)門都會(huì)獲得一些輸入题篷,可以立即計(jì)算兩件事情:1.其輸出值和2.其輸入的本地梯度相對(duì)于其輸出值。注意厅目,門可以完全獨(dú)立完成番枚,而不知道它們嵌入的全電路的任何細(xì)節(jié)。但是损敷,一旦正向通過結(jié)束葫笼,在反向傳播期間,門將最終了解其輸出值的梯度在整個(gè)電路的最終輸出拗馒。連鎖規(guī)則說路星,門應(yīng)該采用該梯度,并將其乘以其通常為其所有輸入計(jì)算的每個(gè)梯度诱桂。
所以洋丐,后向傳播其實(shí)是門之間的互相交流,通過梯度信號(hào)來交流挥等,是增加還是減少友绝,增加減少多大程度,來是的最后的輸出結(jié)果更高肝劲。
模塊度
上面介紹的門是相對(duì)來說任意的九榔,任何可微的函數(shù)都可以作為一個(gè)門,并且可以把多個(gè)門集合到一個(gè)里面或者分解一個(gè)函數(shù)到多個(gè)門中涡相。
可以用下圖來表示:
分階段反向傳播哲泊。如上面的代碼所示,在實(shí)踐中催蝗,將前進(jìn)路徑分解為容易反向推進(jìn)的階段總是有幫助的切威。例如,我們創(chuàng)建了一個(gè)中間變量點(diǎn)丙号,它保存了w和x之間的點(diǎn)積的輸出先朦。在反向通過期間,我們?nèi)缓笠来斡?jì)算(反向順序)保存這些變量的梯度的相應(yīng)變量(例如犬缨,ddot喳魏,最后dw,dx)怀薛。
本節(jié)的要點(diǎn)是刺彩,反向傳播如何執(zhí)行的細(xì)節(jié)以及我們認(rèn)為是門的前向功能的哪些部分是方便的問題。它有助于了解表達(dá)式的哪些部分具有容易的本地漸變,使得它們可以用最少的代碼和努力鏈接在一起创倔。
案例 分階段計(jì)算
下面看以下的案例:
x = 3 # example values
y = -4
# forward pass
sigy = 1.0 / (1 + math.exp(-y)) # sigmoid in numerator #(1)
num = x + sigy # numerator #(2)
sigx = 1.0 / (1 + math.exp(-x)) # sigmoid in denominator #(3)
xpy = x + y #(4)
xpysqr = xpy**2 #(5)
den = sigx + xpysqr # denominator #(6)
invden = 1.0 / den #(7)
f = num * invden # done! #(8)
有幾點(diǎn)需要注意:首先應(yīng)該將計(jì)算過的變量放入緩存瘦陈,為了后巷傳遞變量應(yīng)該把一些變量存儲(chǔ)辆飘,在實(shí)際中你想要結(jié)構(gòu)化這些變量,所以他們?cè)诤笙騻鞑ブ心軌蚩捎盟姨!A硗饽琳酰跋虻谋磉_(dá)式中用到x和y多次赛糟,所以當(dāng)我們使用后向傳播的時(shí)候應(yīng)該慎重使用+=而不是=疚沐,以在這些變量上積累梯度魄宏,而不是直接替換掉,這個(gè)符合多變量鏈?zhǔn)揭?guī)則台盯。
后向傳播流的模式
在這幅圖中首妖,add gate 會(huì)將梯度平等的傳遞給輸入節(jié)點(diǎn),無論前向的節(jié)點(diǎn)傳遞了什么值爷恳。
而max gate 規(guī)定了梯度傳遞的路線,他只會(huì)傳遞給特定的一個(gè)路線象踊。
multiply gate 會(huì)交換傳入的梯度温亲。
向量梯度
當(dāng)兩個(gè)向量相乘的時(shí)候,如何找到梯度是比較難的杯矩。
# forward pass
W = np.random.randn(5, 10)
X = np.random.randn(10, 3)
D = W.dot(X)
# now suppose we had the gradient on D from above in the circuit
dD = np.random.randn(*D.shape) # same shape as D
dW = dD.dot(X.T) #.T gives the transpose of the matrix
dX = W.T.dot(dD)
使用維度分析栈虚!請(qǐng)注意,您不需要記住dW和dX的表達(dá)式史隆,因?yàn)樗鼈內(nèi)菀赘鶕?jù)維度重新導(dǎo)出魂务。例如,我們知道權(quán)重dW上的梯度在計(jì)算之后必須與W的大小相同泌射,并且必須依賴于X和dD的矩陣乘法(如同時(shí)X粘姜,W都是單個(gè)數(shù)字的情況)而不是矩陣)∪劭幔總是有一種實(shí)現(xiàn)這一點(diǎn)的方法孤紧,以便維度得到解決。例如拒秘,X大小為[10×3]号显,dD大小為[5×3],所以如果我們想要dW和W具有[5×10]的形狀躺酒,那么實(shí)現(xiàn)這一點(diǎn)的唯一方法是使用dD.dot XT)押蚤,如上所示。
使用小的羹应,明確的例子揽碘。有些人可能會(huì)發(fā)現(xiàn)很難得出一些向量化表達(dá)式的漸變更新。我們的建議是明確地寫出一個(gè)最小的矢量化示例,導(dǎo)出紙上的漸變钾菊,然后將模式推廣到其有效的向量化形式帅矗。