2020-4-30 吳恩達-NN&DL-w2 NN基礎(2.7 計算圖,2.8 計算圖的導數計算,2.9 邏輯迴歸中的梯度下降法,2.10 m 個樣本的梯度下降)

1.視頻網站:mooc慕課https://mooc.study.163.com/university/deeplearning_ai#/c
2.詳細筆記網站(中文):http://www.ai-start.com/dl2017/
3.github課件+作業+答案:https://github.com/stormstone/deeplearning.ai

2.7 計算圖 Computation Graph-前向傳播

一個神經網絡的計算,都是按照前向或反向傳播過程組織的。
首先我們計算出一個新的網絡的輸出(前向過程),緊接着進行一個反向傳輸操作。後者我們用來計算出對應的梯度或導數。

計算圖解釋了爲什麼我們用這種方式組織這些計算過程。

在這裏插入圖片描述

觀察上圖。
這裏說明了計算成本函數 J(a,b,c)=3(a+bc) 的過程。計算這個函數實際上有三個不同的步驟

  • step1: u=bc
  • step2: v=a+u
  • step3: J=3v

我們可以把這三步畫成計算圖,如上圖的右下部分。
當有不同的或者一些特殊的輸出變量時,例如本例中J的和邏輯迴歸中你想優化的代價函數J,計算圖用來處理這些計算會很方便。

爲了計算導數,從右到左(紅色箭頭,和藍色箭頭的過程相反)的過程是用於計算導數最自然的方式。

概括一下:計算圖組織計算的形式是用藍色箭頭從左到右的計算。

2.8 計算圖的導數計算 Derivatives with a Computation Graph-反向傳播

觀察下圖,這是上一節介紹過的計算圖,我們來看看你如何利用它計算出函數的導數。
在這裏插入圖片描述

先看最右邊,由於J=3v,所以導數ddvJ(v)=ddv3v=3\frac{d}{dv}J(v)=\frac{d}{dv}3v=3

我們在反向傳播術語中看到,如果你想使用你最關心的變量v計算最後輸出變量J的導數,那我們就完成了一步反向傳播,在這個流程圖中是一個反向步驟(圖中從右向左紅色箭頭過程)。

我們來看另一個例子,ddaJ(a)\frac{d}{da}J(a)是多少呢?換句話說,如果我們提高a的數值,對J的數值有什麼影響?

假設a=5,我們讓它增加到5.001,那麼對v的影響就是a+u,所以v從11變爲11.001,而J從33變爲33.003。可以發現,a增加0.001,J增加了0.003。所以J的增量是3乘以a的增量,意味着這個導數ddaJ(a)=3\frac{d}{da}J(a)=3

我們來解釋這個計算過程。
其中一種方式是:如果你改變了a,那麼也會改變v,通過改變v,也會改變J。當你提升a這個值0.001,J的變化量就是0.003。
在這裏插入圖片描述

a增加了,v也會增加,v增加多少呢?
這取決於dvda\frac{dv}{da},然後v的變化導致J也在增加(dJda=dJdvdvda\frac{dJ}{da}=\frac{dJ}{dv}\frac{dv}{da}),所以這在微積分裏實際上叫鏈式法則

如果a影響到v,v影響到J,那麼當你讓a變大時,J的變化量就是當你改變a時,v的變化量 乘以改變v時的 J變化量,這就是微積分裏的鏈式法則。

在這裏插入圖片描述

上圖表示瞭如何計算dJda\frac{dJ}{da}
dJdv\frac{dJ}{dv}就是J對變量v的導數(第一步反向傳播),它可以幫助你計算dJda\frac{dJ}{da},所以這是另一步反向傳播計算。求導過程就是反向傳播過程。

符號約定
在python中,我們約定用變量名dvar來表示導數。
例如:dJda\frac{dJ}{da},用da表示;dJdv\frac{dJ}{dv},用dv表示。

到目前爲止,我們通過這個流程圖完成部分的後向傳播算法。
在這裏插入圖片描述

如上圖,類似da,我們還有一個反向傳播過程,可以計算出du=3。這裏的du就是 dJdu\frac{dJ}{du}

最後我們要得到dJdb\frac{dJ}{db}。根據鏈式法則dJdb=dJdududb\frac{dJ}{db}=\frac{dJ}{du}\frac{du}{db}。那麼dudb\frac{du}{db}是多少呢?
b=3,u=6;如果b=3.001,那麼u=6.002。所以dudb=2\frac{du}{db}=2,即u的變化量是b的變化量的2倍。
所以,dJdb=32=6\frac{dJ}{db}=3*2=6

簡單觀察一下就可以發現,如果b=3.001,那麼u=6.002,v變成了11.002,J變成了33.006。這也再次證明了dJdb=6\frac{dJ}{db}=6

在這裏插入圖片描述

最後計算J對c的導數,dc(python)=dJdc=dJdududc=33=9dc(python)=\frac{dJ}{dc}=\frac{dJ}{du}\frac{du}{dc}=3*3=9

結論:在本例中,當計算所有這些導數時,最有效率的辦法是從右到左計算,跟着這個紅色箭頭走。

總結

  • 在計算流程圖中,正向或者說從左到右的計算來計算成本函數J。
  • 優化成本函數J,就是反向從右到左計算導數。

2.9 logistic 迴歸中的梯度下降法 Logistic Regression Gradient descent - 反向傳播

本節中將使用計算圖對梯度下降算法進行計算。

通過計算偏導數來實現邏輯迴歸的梯度下降算法的關鍵點是幾個重要公式。

在這裏插入圖片描述
邏輯迴歸和損失函數的公式如上圖。
假設單個樣本有兩個特徵x1和x2,爲了計算z,我們需要輸入參數w1、w2 和b。
z=w1x1+w2x2+bz=w_1*x_1+w_2*x_2+b
然後到下一步公式
y^=a=σ(z)\hat y=a=\sigma(z)
最後一步損失函數公式
L(a,y)...L(a,y)...省略
其中a是邏輯迴歸的輸出,y是樣本的標籤值。這裏的步驟就是在單個訓練樣本上計算代價函數的前向步驟。

上面的邏輯迴歸公式可以發現,僅僅變化w和b參數就可以最小化損失函數J。現在讓我們來討論通過反向計算出導數。
在這裏插入圖片描述
因爲我們想要計算出的代價函數L(a,y)的導數,首先我們需要反向計算出代價函數L(a,y)關於a的導數,在編寫python代碼時,你只需要用"da"來表示 dL(a,y)da\frac{dL(a,y)}{da}。而這個導數計算結果是
"da"=dL(a,y)da=ya+1y1a"da"=\frac{dL(a,y)}{da}=-\frac ya+\frac{1-y}{1-a}
計算出"da",關於變量a的導數後,現在可以再反向一步計算"dz"。
"dz"=dLdz=dLdadadz=(ya+1y1a)a(1a)=ay"dz"=\frac{dL}{dz}=\frac{dL}{da}\frac{da}{dz}=(-\frac ya+\frac{1-y}{1-a})*a(1-a)=a-y
以上的推導過程就是前面介紹過的鏈式法則。

現在進行最後一步反向推導,也就是計算w和b變化對代價函數L的影響。
"dw1"=dLdw1=x1dz"dw_1"=\frac{dL}{dw_1}=x_1“dz”
"dw2"=dLdw2=x2dz"dw_2"=\frac{dL}{dw_2}=x_2“dz”
"db"=dLdb=dz"db"=\frac{dL}{db}=“dz”
因此,關於單個樣本的梯度下降算法,你所需要做的就是如下的事情,先求曲線L的偏導數:

  • 使用公式"dz"=ay"dz"=a-y計算"dz“
  • 使用"dw1"=dLdw1=x1dz"dw_1"=\frac{dL}{dw_1}=x_1“dz”計算"dw1"
  • 使用"dw2"=dLdw2=x2dz"dw_2"=\frac{dL}{dw_2}=x_2“dz”計算"dw2"
  • 使用"db"=dLdb=dz"db"=\frac{dL}{db}=“dz“計算”db“

然後更新參數,實現梯度下降

  • w1:=w1α"dw1"w_1:=w_1-\alpha "dw_1"
  • w2:=w2α"dw2"w_2:=w_2-\alpha "dw_2"
  • b:=bα"db"b:=b-\alpha "db"

以上就是關於單個樣本實例的梯度下降算法中參數更新一次的步驟。

現在你已經知道了怎樣計算導數,並且實現針對單個訓練樣本的邏輯迴歸的梯度下降算法。

2.10 m 個樣本的梯度下降 Gradient descent on m examples

本節我們要應用梯度下降在邏輯迴歸的m個訓練樣本上。
在這裏插入圖片描述
m個樣本上成本函數定義複習如下
J(w,b)=1mi=1mL(a(i),y(i))J(w,b)= \frac1m\sum_{i=1}^m L(a^{(i)},y^{(i)})
a(i)a^{(i)}是訓練樣本y的預測值,前文中是用y^\hat y表示。
a(i)=y^(i)=σ(z(i))=σ(wTx(i)+b)a^{(i)}=\hat y^{(i)}=\sigma (z^{(i)})=\sigma(w^Tx^{(i)}+b)
上一節中,我們已經知道單個樣本的梯度下降第一步是獲得"dw1",“dw2"和"db”。我們在"dw1","dw2"和"db"添上上標i表示你求得的相應的值,適用於單個樣本(x(i),y(i)) 。

我們已經知道帶有求和的全局損失(代價)函數J(w,b),實際上是1到m項各個損失 L(a(i),y(i))的平均。 所以它表明全局損失(代價)函數對w1的導數(微分)也同樣是各項損失對w1導數(微分)的平均。
w1J(w,b)=1mi=1mw1L(a(i),y(i))=1mi=1m("dw1(i)")\frac∂{∂w_1}J(w,b)= \frac1m\sum_{i=1}^m \frac∂{∂w_1}L(a^{(i)},y^{(i)})= \frac1m\sum_{i=1}^m("dw_1^{(i)}")

之前我們已經演示瞭如何計算這項"dw_1",即上一節中演示的如何對單個訓練樣本進行計算。所以你現在真正需要做的是計算這些微分"dw1(i)","dw2(i)“和"db(i)”,如我們在之前的訓練樣本上做的,並且求平均,這會給你全局梯度值,你能夠把它直接應用到梯度下降算法中。

邏輯迴歸和梯度下降算法實現

初始化J=0,dw1=0,dw2=0,db=0。
我們要做的就是用一個for循環遍歷計算每個訓練樣本的導數,然後把它們加起來。

for i = 1 to m

    z(i) = wx(i)+b;

    a(i) = sigmoid(z(i)); #預測值

    J += -[y(i)log(a(i))+(1-y(i)log(1-a(i)); #損失函數

    dz(i) = a(i)-y(i);#導數,z變化對J的影響。注意:這裏有上標i,是單個樣本,即第i個樣本的計算。

    dw1 += x1(i)dz(i);#導數,參數w1變化對J的影響。注意:這裏沒有上標i,是累加整個訓練集合上的和。

    dw2 += x2(i)dz(i);#導數,參數w2變化對J的影響。注意:這裏沒有上標i,是累加整個訓練集合上的和。

    db += dz(i);#導數,參數b變化對J的影響。注意:這裏沒有上標i,是累加整個訓練集合上的和。

J/= m;#m個樣本平均

dw1/= m;#m個樣本平均

dw2/= m;#m個樣本平均

db/= m;#m個樣本平均

w=w-alpha*dw #應用梯度單步下降

b=b-alpha*db #應用梯度單步下降

上面的代碼只應用了一步梯度下降。因此你需要重複以上內容很多次,以應用多次梯度下降。

這種計算中有兩個缺點,因爲此方法在邏輯迴歸上你需要編寫兩個for循環。

  • 第一個for循環是一個小循環遍歷個訓練樣本
  • 第二個for循環是一個遍歷所有特徵的for循環。上面例子中我們只有2個特徵,如果你有更多特徵,你開始計算你的dw1,dw2,dw3等等,這就需要一個for循環遍歷所有的特徵。

在代碼中顯式地使用for循環會使你的算法很低效。在深度學習領域會有越來越大的數據集,能夠應用你的算法且沒有顯式的for循環會是重要的,並且會幫助你適用於更大的數據集。

向量化技術可以允許你的代碼擺脫這些顯式的for循環。

在深度學習時代利用向量化技術,擺脫for循環已經變得相當重要。因爲我們越來越多地訓練非常大的數據集,因此你真的需要你的代碼變得非常高效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章