国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【DL-CV】反向傳播,(隨機)梯度下降

missonce / 1351人閱讀

摘要:下面介紹梯度下降算法以并用反向傳播來求梯度梯度下降看名字就和梯度脫不了關系了。運用反向傳播,我們可以計算損失函數關于每一層權重的梯度,然后實現每一層權重的訓練。應用小批量梯度下降法的隨機梯度下降法已經成為當前深度學習的主流算法。

【DL-CV】損失函數,SVM損失與交叉熵損失<前篇---后篇>【DL-CV】激活函數及其選擇

有了損失函數L,我們能定量的評價模型的好壞。我們希望損失能最小化,或具體點,我們希望能找到使損失最小化的權重W。當然這個過程不是一步完成的,我們會使用梯度下降算法來一步步修改權重W,好讓損失逐漸逼近最小值,這是一個收斂的過程。下面介紹梯度下降算法以并用反向傳播來求梯度

梯度下降 Gradient descent

看名字就和梯度脫不了關系了。其原理很簡單,學過高數都知道,梯度是一個向量,方向指向函數增大最快的方向;那反過來梯度的負值指向函數衰減最快的方向。損失函數展開后是關于權重W的函數L(W),那其梯度負值 -?L 指向損失下降最快的方向,我們讓權重W往該方向走一小步得到新的權重Wnew(更新權重),它對應更低的損失。不停地重復計算梯度,更新權重這兩步,權重/模型就會趨于完美(所謂迭代訓練過程)

負梯度: $-?L =- {?L over ?W}$, 權重更新: $W_{nwe}={W-alpha {?L over ?W}}$,從公式中也知道梯度$?L over ?W$$是和W形狀一樣的矩陣(標量對矩陣求導的特性)。
當然這里的權重W是一個矩陣而不是一個值,會涉及矩陣乘法求梯度。

這里的α叫學習率(通常是個很小的正數),用于控制權重變化的幅度,可以理解為步長。學習率的選擇是神經網絡訓練中最重要的超參數設定之一,學習率太大,容易越過損失函數的最小值然后在最小值周圍浮動無法收斂;學習率太小,收斂速度太慢,訓練效率降低。關于學習率的設定我們延后詳細講解。

總的來說,這就是原味不加特效的梯度下降法,也就是完全跟著梯度走。隨著知識的深入,后面會介紹更高級的更新法則(不再死跟梯度),以獲得更高的性能。

反向傳播 Back propagation

原理就是高數中求復合函數偏導數/偏微分的鏈式法則,我還記得剛學的時候會畫樹狀圖,用著老師教的口訣“分叉相加,分層相乘”進行推導。不過那都是很簡單的題目了,遇上這種層數多參數多涉及矩陣的神經網絡,還是很容易犯錯的,最好還是老老實實的看下反向傳播吧。

在應用于神級網絡模型之前,我們拿個簡單的函數直觀地展示反向傳播原理。
設有函數$f(w,x)={1over 1+e^{w*x}}$,w是行向量,x是列向量。我們可以原函數的計算細分成很多小步,交給不同的子函數完成,這些子函數嵌套(復合函數)起來便能計算出原函數的值。把每個子函數看做一個節點,相連得下圖

正向傳播是計算函數值,輸出結果給下一個函數計算(從左往右)。反向傳播求全局梯度的原理就是先求局部梯度的公式,然后接受正向傳播傳來的結果帶入局部梯度公式得到局部梯度,于是每個節點都有自己的局部梯度,最后我們在反向的過程中(從右往左)運用口訣“分叉相加,分層相乘”把它們拼起來得到全局梯度了。從圖中可以看出對w的梯度大小是和w一樣的。

有人可能會一口氣算出復合函數的導數公式然后一個勁地帶w和x進去得到結果,像這樣簡單函數當然是可以的。但這樣對計算機來說運算量就加倍了:正向傳播時計算了一遍,而用你的公式代w和x又會重復正向傳播的計算。面對多層神經網絡這是超耗時的,所以正向傳播時要分層保存結果供每層局部梯度計算使用(實際上深度學習框架就是這樣干的)


我們的多層神經網絡的模型就相當于一個巨大的函數,它由多個線性分類器$f(x,W,b) = {W*x+b}$,激活函數,最后加個損失函數(這些函數都是連續可微的)復合而成。運用反向傳播,我們可以計算損失函數關于每一層權重的梯度,然后實現每一層權重的訓練。

關于矩陣乘法的梯度

上面反向傳播的例子是對權重某個具體值進行求導的,實際使用上我們是對整個權重這個矩陣進行求導的,但概念是通用的,建議初學時寫出一個很小很明確的向量化例子,在紙上演算梯度,然后對其一般化,得到一個高效的向量化操作形式。
但更多時候我們會用一個小技巧,這個技巧的關鍵是分析維度,我們可以通過維度的拼湊使得拼出來的${?L over ?W}與{W}形狀相同$,總有一個方式是能夠讓維度之間能夠對的上的

# 前向傳播
W = np.random.randn(5, 10) # 假設W是 5x10 矩陣
X = np.random.randn(10, 3) # x是 10x3 矩陣
D = W.dot(X) # D=W*x 是 5x3 矩陣


# 假設我們得到了D的梯度?L/?D
dD = np.random.randn(*D.shape) # 和D一樣的尺寸 5x3

#X.T指X的轉置
dW = dD.dot(X.T) #?L/?W應該是 5x10 矩陣,由 dD*X.T拼出([5x3]*[3x10]=[5x10])
dX = W.T.dot(dD) #?L/?X應該是 10x3 矩陣,由 W.T*dD拼出([10x5]*[5x3]=[10x3])
隨機梯度下降 Stochastisc Gradient Descent

有隨機當然就有不隨機,這種不隨機的算法叫批量學習(batch learning)算法,為了引入主角“隨機”我們先來聊聊其它。批量學習算法在進行迭代訓練(計算損失,計算梯度,權重更新三循環)的時候要遍歷全部訓練樣本,也因此,這種算法能夠有效地抑制訓練集內帶噪聲的樣本所導致的劇烈變動,并且獲得全局最優解;但同時也難免顧此失彼,由于每次更新權重所有樣本都要參與訓練,訓練集一大起來非常耗時。


為了彌補面對大量數據時用時上的缺陷,就有了隨機梯度下降法,這里介紹其中一種叫小批量梯度下降(mini-batch gradient descent)的算法:
每次迭代訓練時從訓練集中隨機部分樣本(也就是batch size,數量通常為2n,常用32,64,128,256,根據情況定)進行迭代更新權重。由于每次迭代只使用部分樣本,所以和批量學習相比,能減少單次訓練時間。它保持收斂性的同時還能減少了迭代結果陷入局部最優解的情況。應用小批量梯度下降法的隨機梯度下降法已經成為當前深度學習的主流算法

# 大概思路
while True:
    data_batch = sample_training_data(data, 256) # 從訓練集中隨機取256個樣本用于訓練
    weights_grad = evaluate_gradient(loss_fun, data_batch, weights) #獲取梯度
    weights += - step_size * weights_grad # 更新權重
雙層網絡&softmax損失函數反向傳播

下面我們通過一個小網絡例子并運用求導技巧來展示神經網絡反向傳播的實現。現在我們有一個使用softmax損失的雙層網絡,我們的目標是求$partial Loverpartial W_1$,$partial Loverpartial W_2$,$partial Loverpartial b_1$,$partial Loverpartial b_2$

輸入(X)→→線性分類器+relu激活函數(h1 =max(0,X*W1 + b1) )→→線性分類器(h2 = h1*W2 + b2)→→輸出(S=h2)→→softmax損失函數并使用L2正則化

X是(N*D)的矩陣,包含N個樣本數據,每行Xi是第i個樣本的數據

以上的h1,h2/s,都是矩陣,每行是第i個樣本的層激活值

以下的 j 代表類別的數字,假如這個網絡輸出的是10個類別的分數,則j=0,1,2,...9

從右至左,首先來推導softmax損失函數的梯度。我們有損失公式:
$$L = { frac{1}{N} sum_i^N L_i }+ { lambda R(W) }$$
共有N個樣本,其中第i個樣本帶來的損失是:
$$L_i=log (sum_je^{s_{ij}})-s_{{iy_i}}$$
當 j!=yi 時:
$${partial L_iover partial s_{ij}}={e^{s_{ij}}over sum_je^{s_{ij}}}$$
當 j==yi 時:
$${partial L_iover partial s_{ij}}={e^{s_{ij}}over sum_je^{s_{ij}}}-1$$

據此容易求得${partial L_iover partial s_{i}}$,使用維度技巧開始拼湊,${partial L_iover partial W_2}(20*10)應該由{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)$$

繼續往上走會遇到ReLU激活函數逐元素運行max(0,x),輸入小于等于0,回傳梯度為0;輸入大于0,原封不動回傳梯度。我們有$h^1_i =max(0,X_i*W_1+b_1),另設f_i=X_i*W_1+b_1$,運用維度技巧,${partial L_iover partial h_i}(1*20)應該由{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)$$

繼續使用技巧,剩下的${partial L_iover partial W_1}(3072*20)$ 應該有由${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)$$

至于偏轉值b的梯度就好求多了,由于在公式中局部梯度為1,直接接受傳來的梯度即可
$${partial L_ioverpartial b_2}={partial L_ioverpartial s_i}$$
$${partial L_ioverpartial b_1}={partial L_ioverpartial f_i}$$
以上的推導的都是${L_i}$對誰誰的梯度,那么${L}$對誰誰的梯度怎么求?難道求N次梯度求和取平均嗎?——不用,矩陣的運算給了我們很好的性質,把上面提到的${X_i}$,${h^1_i}$,${f_i}$,${s_i}$這些向量全換成完整的矩陣${X}$,${h^1}$,${f}$,${s}$進行運算即可,矩陣乘法會執行求和操作,你只需最后求平均即可加上正則化損失的梯度即可。${L}$對$b$的梯度些許不同,需要對傳來的梯度在列上求和取平均
$${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}$對$b$的梯度些許不同,需要對傳來的梯度在列上求和取平均。

numpy代碼實現
import numpy as np
def loss_and_grads(X, y, reg):
    N, D = X.shape  #記錄X尺寸,N個樣本
    # 正向傳播
    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)  # 預處理防溢出
    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 時要減一
    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  # 布爾標記使激活值非正數的梯度為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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19781.html

相關文章

  • DL-CV反向傳播,(隨機梯度下降

    摘要:下面介紹梯度下降算法以并用反向傳播來求梯度梯度下降看名字就和梯度脫不了關系了。運用反向傳播,我們可以計算損失函數關于每一層權重的梯度,然后實現每一層權重的訓練。應用小批量梯度下降法的隨機梯度下降法已經成為當前深度學習的主流算法。 【DL-CV】損失函數,SVM損失與交叉熵損失【DL-CV】激活函數及其選擇 有了損失函數L,我們能定量的評價模型的好壞。我們希望損失能最小化,或具體點,我們...

    dadong 評論0 收藏0
  • DL-CV】激活函數及其選擇

    摘要:為什么呢本文將對這一問題進行解疑并介紹多種多種激活函數。激活函數就是用來引入這個非線性因素的,下面介紹幾種常見的激活函數及其優缺點正負號表示。如果想了解更多可上網搜激活函數選擇在同一個模型中,激活函數不會混搭使用,選定一個就用一個。 【DL-CV】反向傳播,(隨機)梯度下降【DL-CV】神經網絡的補充 在介紹線性分類器的時候,提到了激活函數,還提到線性分類器的輸出要經過激活函數才能作為...

    jokester 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<