摘要:下面介紹梯度下降算法以并用反向傳播來(lái)求梯度梯度下降看名字就和梯度脫不了關(guān)系了。運(yùn)用反向傳播,我們可以計(jì)算損失函數(shù)關(guān)于每一層權(quán)重的梯度,然后實(shí)現(xiàn)每一層權(quán)重的訓(xùn)練。應(yīng)用小批量梯度下降法的隨機(jī)梯度下降法已經(jīng)成為當(dāng)前深度學(xué)習(xí)的主流算法。
【DL-CV】損失函數(shù),SVM損失與交叉熵?fù)p失<前篇---后篇>【DL-CV】激活函數(shù)及其選擇
有了損失函數(shù)L,我們能定量的評(píng)價(jià)模型的好壞。我們希望損失能最小化,或具體點(diǎn),我們希望能找到使損失最小化的權(quán)重W。當(dāng)然這個(gè)過(guò)程不是一步完成的,我們會(huì)使用梯度下降算法來(lái)一步步修改權(quán)重W,好讓損失逐漸逼近最小值,這是一個(gè)收斂的過(guò)程。下面介紹梯度下降算法以并用反向傳播來(lái)求梯度
梯度下降 Gradient descent看名字就和梯度脫不了關(guān)系了。其原理很簡(jiǎn)單,學(xué)過(guò)高數(shù)都知道,梯度是一個(gè)向量,方向指向函數(shù)增大最快的方向;那反過(guò)來(lái)梯度的負(fù)值指向函數(shù)衰減最快的方向。損失函數(shù)展開(kāi)后是關(guān)于權(quán)重W的函數(shù)L(W),那其梯度負(fù)值 -?L 指向損失下降最快的方向,我們讓權(quán)重W往該方向走一小步得到新的權(quán)重Wnew(更新權(quán)重),它對(duì)應(yīng)更低的損失。不停地重復(fù)計(jì)算梯度,更新權(quán)重這兩步,權(quán)重/模型就會(huì)趨于完美(所謂迭代訓(xùn)練過(guò)程)
負(fù)梯度: $-?L =- {?L over ?W}$, 權(quán)重更新: $W_{nwe}={W-alpha {?L over ?W}}$,從公式中也知道梯度$?L over ?W$$是和W形狀一樣的矩陣(標(biāo)量對(duì)矩陣求導(dǎo)的特性)。
當(dāng)然這里的權(quán)重W是一個(gè)矩陣而不是一個(gè)值,會(huì)涉及矩陣乘法求梯度。
這里的α叫學(xué)習(xí)率(通常是個(gè)很小的正數(shù)),用于控制權(quán)重變化的幅度,可以理解為步長(zhǎng)。學(xué)習(xí)率的選擇是神經(jīng)網(wǎng)絡(luò)訓(xùn)練中最重要的超參數(shù)設(shè)定之一,學(xué)習(xí)率太大,容易越過(guò)損失函數(shù)的最小值然后在最小值周?chē)?dòng)無(wú)法收斂;學(xué)習(xí)率太小,收斂速度太慢,訓(xùn)練效率降低。關(guān)于學(xué)習(xí)率的設(shè)定我們延后詳細(xì)講解。
總的來(lái)說(shuō),這就是原味不加特效的梯度下降法,也就是完全跟著梯度走。隨著知識(shí)的深入,后面會(huì)介紹更高級(jí)的更新法則(不再死跟梯度),以獲得更高的性能。
反向傳播 Back propagation原理就是高數(shù)中求復(fù)合函數(shù)偏導(dǎo)數(shù)/偏微分的鏈?zhǔn)椒▌t,我還記得剛學(xué)的時(shí)候會(huì)畫(huà)樹(shù)狀圖,用著老師教的口訣“分叉相加,分層相乘”進(jìn)行推導(dǎo)。不過(guò)那都是很簡(jiǎn)單的題目了,遇上這種層數(shù)多參數(shù)多涉及矩陣的神經(jīng)網(wǎng)絡(luò),還是很容易犯錯(cuò)的,最好還是老老實(shí)實(shí)的看下反向傳播吧。
在應(yīng)用于神級(jí)網(wǎng)絡(luò)模型之前,我們拿個(gè)簡(jiǎn)單的函數(shù)直觀地展示反向傳播原理。
設(shè)有函數(shù)$f(w,x)={1over 1+e^{w*x}}$,w是行向量,x是列向量。我們可以原函數(shù)的計(jì)算細(xì)分成很多小步,交給不同的子函數(shù)完成,這些子函數(shù)嵌套(復(fù)合函數(shù))起來(lái)便能計(jì)算出原函數(shù)的值。把每個(gè)子函數(shù)看做一個(gè)節(jié)點(diǎn),相連得下圖
正向傳播是計(jì)算函數(shù)值,輸出結(jié)果給下一個(gè)函數(shù)計(jì)算(從左往右)。反向傳播求全局梯度的原理就是先求局部梯度的公式,然后接受正向傳播傳來(lái)的結(jié)果帶入局部梯度公式得到局部梯度,于是每個(gè)節(jié)點(diǎn)都有自己的局部梯度,最后我們?cè)诜聪虻倪^(guò)程中(從右往左)運(yùn)用口訣“分叉相加,分層相乘”把它們拼起來(lái)得到全局梯度了。從圖中可以看出對(duì)w的梯度大小是和w一樣的。
有人可能會(huì)一口氣算出復(fù)合函數(shù)的導(dǎo)數(shù)公式然后一個(gè)勁地帶w和x進(jìn)去得到結(jié)果,像這樣簡(jiǎn)單函數(shù)當(dāng)然是可以的。但這樣對(duì)計(jì)算機(jī)來(lái)說(shuō)運(yùn)算量就加倍了:正向傳播時(shí)計(jì)算了一遍,而用你的公式代w和x又會(huì)重復(fù)正向傳播的計(jì)算。面對(duì)多層神經(jīng)網(wǎng)絡(luò)這是超耗時(shí)的,所以正向傳播時(shí)要分層保存結(jié)果供每層局部梯度計(jì)算使用(實(shí)際上深度學(xué)習(xí)框架就是這樣干的)
我們的多層神經(jīng)網(wǎng)絡(luò)的模型就相當(dāng)于一個(gè)巨大的函數(shù),它由多個(gè)線性分類(lèi)器$f(x,W,b) = {W*x+b}$,激活函數(shù),最后加個(gè)損失函數(shù)(這些函數(shù)都是連續(xù)可微的)復(fù)合而成。運(yùn)用反向傳播,我們可以計(jì)算損失函數(shù)關(guān)于每一層權(quán)重的梯度,然后實(shí)現(xiàn)每一層權(quán)重的訓(xùn)練。
關(guān)于矩陣乘法的梯度上面反向傳播的例子是對(duì)權(quán)重某個(gè)具體值進(jìn)行求導(dǎo)的,實(shí)際使用上我們是對(duì)整個(gè)權(quán)重這個(gè)矩陣進(jìn)行求導(dǎo)的,但概念是通用的,建議初學(xué)時(shí)寫(xiě)出一個(gè)很小很明確的向量化例子,在紙上演算梯度,然后對(duì)其一般化,得到一個(gè)高效的向量化操作形式。
但更多時(shí)候我們會(huì)用一個(gè)小技巧,這個(gè)技巧的關(guān)鍵是分析維度,我們可以通過(guò)維度的拼湊使得拼出來(lái)的${?L over ?W}與{W}形狀相同$,總有一個(gè)方式是能夠讓維度之間能夠?qū)Φ纳系?/p>
# 前向傳播 W = np.random.randn(5, 10) # 假設(shè)W是 5x10 矩陣 X = np.random.randn(10, 3) # x是 10x3 矩陣 D = W.dot(X) # D=W*x 是 5x3 矩陣 # 假設(shè)我們得到了D的梯度?L/?D dD = np.random.randn(*D.shape) # 和D一樣的尺寸 5x3 #X.T指X的轉(zhuǎn)置 dW = dD.dot(X.T) #?L/?W應(yīng)該是 5x10 矩陣,由 dD*X.T拼出([5x3]*[3x10]=[5x10]) dX = W.T.dot(dD) #?L/?X應(yīng)該是 10x3 矩陣,由 W.T*dD拼出([10x5]*[5x3]=[10x3])隨機(jī)梯度下降 Stochastisc Gradient Descent
有隨機(jī)當(dāng)然就有不隨機(jī),這種不隨機(jī)的算法叫批量學(xué)習(xí)(batch learning)算法,為了引入主角“隨機(jī)”我們先來(lái)聊聊其它。批量學(xué)習(xí)算法在進(jìn)行迭代訓(xùn)練(計(jì)算損失,計(jì)算梯度,權(quán)重更新三循環(huán))的時(shí)候要遍歷全部訓(xùn)練樣本,也因此,這種算法能夠有效地抑制訓(xùn)練集內(nèi)帶噪聲的樣本所導(dǎo)致的劇烈變動(dòng),并且獲得全局最優(yōu)解;但同時(shí)也難免顧此失彼,由于每次更新權(quán)重所有樣本都要參與訓(xùn)練,訓(xùn)練集一大起來(lái)非常耗時(shí)。
為了彌補(bǔ)面對(duì)大量數(shù)據(jù)時(shí)用時(shí)上的缺陷,就有了隨機(jī)梯度下降法,這里介紹其中一種叫小批量梯度下降(mini-batch gradient descent)的算法:
每次迭代訓(xùn)練時(shí)從訓(xùn)練集中隨機(jī)部分樣本(也就是batch size,數(shù)量通常為2n,常用32,64,128,256,根據(jù)情況定)進(jìn)行迭代更新權(quán)重。由于每次迭代只使用部分樣本,所以和批量學(xué)習(xí)相比,能減少單次訓(xùn)練時(shí)間。它保持收斂性的同時(shí)還能減少了迭代結(jié)果陷入局部最優(yōu)解的情況。應(yīng)用小批量梯度下降法的隨機(jī)梯度下降法已經(jīng)成為當(dāng)前深度學(xué)習(xí)的主流算法。
# 大概思路 while True: data_batch = sample_training_data(data, 256) # 從訓(xùn)練集中隨機(jī)取256個(gè)樣本用于訓(xùn)練 weights_grad = evaluate_gradient(loss_fun, data_batch, weights) #獲取梯度 weights += - step_size * weights_grad # 更新權(quán)重雙層網(wǎng)絡(luò)&softmax損失函數(shù)反向傳播
下面我們通過(guò)一個(gè)小網(wǎng)絡(luò)例子并運(yùn)用求導(dǎo)技巧來(lái)展示神經(jīng)網(wǎng)絡(luò)反向傳播的實(shí)現(xiàn)?,F(xiàn)在我們有一個(gè)使用softmax損失的雙層網(wǎng)絡(luò),我們的目標(biāo)是求$partial Loverpartial W_1$,$partial Loverpartial W_2$,$partial Loverpartial b_1$,$partial Loverpartial b_2$
輸入(X)→→線性分類(lèi)器+relu激活函數(shù)(h1 =max(0,X*W1 + b1) )→→線性分類(lèi)器(h2 = h1*W2 + b2)→→輸出(S=h2)→→softmax損失函數(shù)并使用L2正則化
X是(N*D)的矩陣,包含N個(gè)樣本數(shù)據(jù),每行Xi是第i個(gè)樣本的數(shù)據(jù)以上的h1,h2/s,都是矩陣,每行是第i個(gè)樣本的層激活值
以下的 j 代表類(lèi)別的數(shù)字,假如這個(gè)網(wǎng)絡(luò)輸出的是10個(gè)類(lèi)別的分?jǐn)?shù),則j=0,1,2,...9
從右至左,首先來(lái)推導(dǎo)softmax損失函數(shù)的梯度。我們有損失公式:
$$L = { frac{1}{N} sum_i^N L_i }+ { lambda R(W) }$$
共有N個(gè)樣本,其中第i個(gè)樣本帶來(lái)的損失是:
$$L_i=log (sum_je^{s_{ij}})-s_{{iy_i}}$$
當(dāng) j!=yi 時(shí):
$${partial L_iover partial s_{ij}}={e^{s_{ij}}over sum_je^{s_{ij}}}$$
當(dāng) j==yi 時(shí):
$${partial L_iover partial s_{ij}}={e^{s_{ij}}over sum_je^{s_{ij}}}-1$$
據(jù)此容易求得${partial L_iover partial s_{i}}$,使用維度技巧開(kāi)始拼湊,${partial L_iover partial W_2}(20*10)應(yīng)該由{partial L_iover partial s_i}(1*10)和h^1_i.T(20*1)組合而成$,于是:
$${partial L_iover partial W_2}=h^1_i.T*{partial L_iover partial s_i}quad→(20*10)=(20*1)(1*10)$$
繼續(xù)往上走會(huì)遇到ReLU激活函數(shù)逐元素運(yùn)行max(0,x),輸入小于等于0,回傳梯度為0;輸入大于0,原封不動(dòng)回傳梯度。我們有$h^1_i =max(0,X_i*W_1+b_1),另設(shè)f_i=X_i*W_1+b_1$,運(yùn)用維度技巧,${partial L_iover partial h_i}(1*20)應(yīng)該由{partial L_iover partial s_i}(1*10)和W_2.T(10*20)組合而成$,于是:
$${partial L_iover partial h^1_i}={partial L_iover partial s_i}*W_2.Tquad→(1*20)=(1*10)(10*20)$$
$${partial L_iover partial f_{ik}}={partial L_iover partial h^1_{ik}}quad (h^1_{ik}>0)$$
$${partial L_iover partial f_{ik}}=0quad (h^1_{ik}<=0)$$
繼續(xù)使用技巧,剩下的${partial L_iover partial W_1}(3072*20)$ 應(yīng)該有由${partial L_iover partial f_{i}}(1*20)$和$X_i.T(3072*1)$組合而成,于是:
$${partial L_iover partial W_1}=X_i.T*{partial L_iover partial f_{i}}quad→(3072*20)=(3072*1)(1*20)$$
至于偏轉(zhuǎn)值b的梯度就好求多了,由于在公式中局部梯度為1,直接接受傳來(lái)的梯度即可
$${partial L_ioverpartial b_2}={partial L_ioverpartial s_i}$$
$${partial L_ioverpartial b_1}={partial L_ioverpartial f_i}$$
以上的推導(dǎo)的都是${L_i}$對(duì)誰(shuí)誰(shuí)的梯度,那么${L}$對(duì)誰(shuí)誰(shuí)的梯度怎么求?難道求N次梯度求和取平均嗎?——不用,矩陣的運(yùn)算給了我們很好的性質(zhì),把上面提到的${X_i}$,${h^1_i}$,${f_i}$,${s_i}$這些向量全換成完整的矩陣${X}$,${h^1}$,${f}$,${s}$進(jìn)行運(yùn)算即可,矩陣乘法會(huì)執(zhí)行求和操作,你只需最后求平均即可加上正則化損失的梯度即可。${L}$對(duì)$b$的梯度些許不同,需要對(duì)傳來(lái)的梯度在列上求和取平均
$${partial Lover partial W_2}={1over N}h^1.T*{partial Lover partial s}+2lambda W_2quad→(20*10)=(20*N)(N*10)$$
$${partial Lover partial h^1}={partial Lover partial s}*W_2.Tquad→(N*20)=(N*10)(10*20)$$
$${partial Lover partial f_{ik}}={partial Lover partial h^1_{ik}}quad (h^1_{ik}>0)$$
$${partial Lover partial f_{ik}}=0quad (h^1_{ik}<=0)$$
$${partial Lover partial W_1}={1over N}X.T*{partial Lover partial f_{i}}+2lambda W_1quad→(3072*20)=(3072*N)(N*20)$$
${L}$對(duì)$b$的梯度些許不同,需要對(duì)傳來(lái)的梯度在列上求和取平均。
import numpy as np def loss_and_grads(X, y, reg): N, D = X.shape #記錄X尺寸,N個(gè)樣本 # 正向傳播 h1 = np.maximum(0, np.dot(X, W1) + b1) # h2 = np.dot(h1, W2) + b2 scores = h2 scores -= np.repeat(np.max(scores, axis=1), self.num_classes).reshape(scores.shape) # 預(yù)處理防溢出 exp_class_scores = np.exp(scores) exp_corrext_class_scores = exp_class_scores[np.arange(N), y] loss = np.log(np.sum(exp_class_scores, axis=1)) - exp_corrext_class_scores loss = np.sum(loss)/N loss += reg*(np.sum(W2**2)+np.sum(W1**2)) grads = {} # layer2 dh2 = exp_class_scores / np.sum(exp_class_scores, axis=1, keepdims=True) # 按行求和保持二維特性以廣播 dh2[np.arange(N), y] -= 1 #j==y_i 時(shí)要減一 dh2 /= N dW2 = np.dot(h1.T, dh2) dW2 += 2*reg*W2 # 加上正則化損失的梯度 db2 = np.sum(dh2, axis=0) / N # layer1 dh1 = np.dot(dh2, W2.T) df = dh1 df[h1 <= 0] = 0 # 布爾標(biāo)記使激活值非正數(shù)的梯度為0 dW1 = np.dot(X.T, df) dW1 += 2*reg*W1 db1 = np.sum(df, axis=0) / N grads["W2"] = dW2 grads["b2"] = db2 grads["W1"] = dW1 grads["b1"] = db1 return loss, grads
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42236.html
摘要:下面介紹梯度下降算法以并用反向傳播來(lái)求梯度梯度下降看名字就和梯度脫不了關(guān)系了。運(yùn)用反向傳播,我們可以計(jì)算損失函數(shù)關(guān)于每一層權(quán)重的梯度,然后實(shí)現(xiàn)每一層權(quán)重的訓(xùn)練。應(yīng)用小批量梯度下降法的隨機(jī)梯度下降法已經(jīng)成為當(dāng)前深度學(xué)習(xí)的主流算法。 【DL-CV】損失函數(shù),SVM損失與交叉熵?fù)p失【DL-CV】激活函數(shù)及其選擇 有了損失函數(shù)L,我們能定量的評(píng)價(jià)模型的好壞。我們希望損失能最小化,或具體點(diǎn),我們...
摘要:為什么呢本文將對(duì)這一問(wèn)題進(jìn)行解疑并介紹多種多種激活函數(shù)。激活函數(shù)就是用來(lái)引入這個(gè)非線性因素的,下面介紹幾種常見(jiàn)的激活函數(shù)及其優(yōu)缺點(diǎn)正負(fù)號(hào)表示。如果想了解更多可上網(wǎng)搜激活函數(shù)選擇在同一個(gè)模型中,激活函數(shù)不會(huì)混搭使用,選定一個(gè)就用一個(gè)。 【DL-CV】反向傳播,(隨機(jī))梯度下降【DL-CV】神經(jīng)網(wǎng)絡(luò)的補(bǔ)充 在介紹線性分類(lèi)器的時(shí)候,提到了激活函數(shù),還提到線性分類(lèi)器的輸出要經(jīng)過(guò)激活函數(shù)才能作為...
閱讀 1669·2021-09-26 09:55
閱讀 5299·2021-09-22 15:40
閱讀 2030·2019-08-30 15:53
閱讀 1511·2019-08-30 11:15
閱讀 1728·2019-08-29 15:41
閱讀 1881·2019-08-28 18:13
閱讀 3162·2019-08-26 12:00
閱讀 1682·2019-08-26 10:30