《Neural Networks and Deep Learning》課程筆記


Lesson 1 Neural Network and Deep Learning

這篇文章其實是 Coursera 上吳恩達老師的深度學習專業課程的第一門課程的課程筆記。

參考了其他人的筆記繼續歸納的。

邏輯回歸 (Logistic Regression)

邏輯回歸的定義

神經網絡的訓練過程可以分為前向傳播(forward propagation) 反向傳播 (backward propagation) 的 過程。我們通過邏輯回歸的例子進行說明。

邏輯回歸是一個用於二分類 (binary clasification) 的算法。比如說,我們有一張圖片作為輸入,比如下圖中的貓,如果識別這張圖片為貓,則輸出標簽1作為結果;如果識別出不是貓,那么輸出標簽0作為結果。而我們把輸出結果用 \(y\) 表示就如下圖所示。

269118812ea785aee00f6ffc11b5c882

圖片在計算機中保存的話,我們需要保存三個矩陣,它們分別對應圖片中的紅、綠、藍三種顏色通道。如果圖片是 \(64\times64\) 像素的,那么這三個矩陣的大小都是 \(64\times64\)

1e664a86fa2014d5212bcb88f1c419cf

為了把這張圖片的像素值轉換為特征向量 \(x\),我們需要把三個矩陣展開為一個向量,而這個向量的總維度用 \(n_x\) 表示的話,就是 \(n_x=3\times64\times64=12,288\)

符號定義:

\(x\):表示一個 \(n_x\) 維數據,為輸入數據,維度為 \((n_x,1)\)

\(y\):表示輸出結果,取值為 \((0,1)\)

\((x^{(i)},y^{(i)})\):表示第 \(i\) 組數據,可能是訓練數據,也可能是測試數據;

\(X=[x^{(1)},x^{(2)},\dots,x^{(m)}]\):表示所有的訓練數據集的輸入值,放在一個 \(n_x\times m\) 的矩陣中,每一列為一組數據,其中 \(m\) 表示樣本數目;

\(Y=[y^{(1)},y^{(2)},\dots,y^{(m)}]\):對應表示所有訓練數據集的輸出值,維度為 \(1\times m\)

其實對於邏輯回歸來說,我們想要的輸出結果是預測,稱為 \(\hat{y}\),也就是對實際值 \(y\) 的估計。\(\hat{y}\) 表示 \(y=1\)

的一種可能性,用上面的例子來說,就是讓 \(\hat{y}\) 告訴我們這是一只貓的圖片的幾率有多大。

邏輯回歸使用的參數有兩個: \(w\) (表示特征權重,維度與特征向量相同)和 \(b\) (表示偏差)。這時我們不能使用 \(\hat{y}=w^Tx+b\) 進行預測,這實際是一個線性回歸,而我們需要讓 \(\hat{y}\) 在 0 到 1 之間來表示對結果的預測。因此,我們使用 sigmoid 函數,這個非線性函數,即 \(\hat{y}=\sigma(w^Tx+b)\)

sigmoid 函數

函數的定義為:$ f(x) = \frac{1}{1 + e^{-x}} $,其值域為 $ (0,1) $。

函數圖像如下所示

3-26

邏輯回歸的代價函數

為了訓練邏輯回歸模型的參數,我們需要一個代價函數 (cost function),有時也翻譯為成本函數。我們通過訓練代價函數來得到我們需要的參數 \(w\)\(b\)

損失函數 (loss function),又稱為誤差函數,用來衡量算法的運行情況。一般定義為:\(L(\hat{y},y)\)

通過損失函數,我們可以衡量預測輸出值和實際值有多接近。一般我們用預測值和實際值的平方差或者它們平方差的一半,但是通常在邏輯回歸中不這么做。因為學習邏輯回歸參數的時候,我們的優化目標不是凸優化,只能找到多個局部最優值,梯度下降法很可能找不到全局最優值。

所以,在邏輯回歸中使用的損失函數是

\[L(\hat{y},y)=-ylog(\hat{y})-(1-y)log(1-\hat{y}) \]

\(y=1\) 時,損失函數 \(L=-log(\hat{y})\),如果想要損失函數盡可能的小,那么 \(\hat{y}\) 就要盡可能大,因為 sigmoid 函數值域是 \((0,1)\),所以 \(\hat{y}\) 會無限接近 1。

\(y=0\) 時,損失函數 \(L=-log(1-\hat{y})\),如果想要損失函數盡可能的小,那么 \(\hat{y}\) 就要盡可能小,因為 sigmoid 函數值域是 \((0,1)\),所以 \(\hat{y}\) 會無限接近 0。

當然,損失函數只是對於單個訓練樣本定義的,它衡量的是算法在單個訓練樣本中表現如何。為了衡量算法在全部訓練樣本上的表現如何,我們需要定義一個算法的代價函數,也就是對 \(m\) 個樣本的損失函數求均值:

\[J(w,b)=\frac{1}{m} \sum^{m}_{i=1} L(\hat{y}^{(i)},y^{(i)})=\frac{1}{m} \sum^{m}_{i=1} (-y^{(i)}\log{\hat{y}^{(i)}}-(1-y^{(i)})\log{(1-\hat{y}^{(i)})}) \]

所以在訓練邏輯回歸模型時候,我們需要找到合適的參數來讓代價函數的總代價降到最低。邏輯回歸可以看作一個非常小的神經網絡。

梯度下降法 (Gradient Descent)

梯度下降法可以在測試集上,通過最小化代價函數 \(J(w,b)\) 來訓練參數 \(w\)\(b\)

形象化地來表示梯度下降法如下圖所示。

a3c81d2c8629d674141def47dc02f312

在上圖中,橫軸表示參數 \(w\)\(b\),在實際操作中,\(w\) 可以是更高維度的。這里僅為了繪圖需要,定義 \(w\)\(b\) 為單一實數,代價函數就是圖中的曲面,因此曲面的高度就是代價函數 \(J(w,b)\) 在某一點的函數值。

236774be30d12524a2002c3c484d22d5

如上圖,代價函數是一個凸函數 (convex function)

af11ecd5d72c85f777592f8660678ce6

而上圖,就不太一樣了。它是非凸的,而且有很多個不同的局部最小值。由於邏輯回歸的代價函數的特性,我們必須定義代價函數 \(J(w,b)\) 為凸函數。初始化參數 \(w\)\(b\) 可以采用隨機初始化的方法,對於邏輯回歸幾乎所有的初始化方法都有效,因為函數是凸函數,無論在哪里初始化,應該達到同一點或大致相同的點。

比如說下圖,從最開始的小紅點開始初始化,朝最陡的下坡方向走,不斷地迭代,直到走到全局最優解或者接近全局最優解的地方。

c5eda5608fd2f4d846559ed8e89ed33c

細節化說明梯度下降法

假定代價函數 \(J(w)\) 只有一個參數 \(w\),即用一維曲線代替多維曲線。如下圖所示。

5300d40870ec58cb0b8162747b9559b9

迭代就是不斷地重復下圖的公式:

6cdef1989a113fc1caaaaf6ebaaa3549

其中,

\(:=\) 表示更新參數,

\(\alpha\) 表示學習率 (learning rate),用來控制步長 (step),即向下走一步的長度 \(\frac{dJ(w)}{dw}\) 就是函數 \(J(w)\)\(w\) 求導 (derivative),在代碼中我們會使用 \(dw\) 表示這個結果。

對於導數更加形象化的理解就是斜率 (slope),如圖該點的導數就是這個點相切於 \(J(w)\) 的小三角形的高除寬。假設我們以如圖點為初始化點,該點處的斜率的符號是正的,即 \(\frac{dJ(w)}{dw}>0\),所以接下來會向左走一步。整個梯度下降法的迭代過程就是不斷地向左走,直至逼近最小值點。

4fb3b91114ecb2cd81ec9f3662434d81

那么現在把代價函數的參數重新設定為兩個,\(w\)\(b\)。迭代的公式則為:

\[w:=w-\alpha \frac{\partial{J(w,b)}}{\partial{w}}\\ b:=b-\alpha \frac{\partial{J(w,b)}}{\partial{b}} \]

其中,\(\partial\) 表示求偏導符號,\(\frac{\partial{J(w,b)}}{\partial {w}}\) 就是函數 \(J(w,b)\)\(w\) 求偏導。

邏輯回歸中的梯度下降

假設樣本只有兩個特征 \(x_1\)\(x_2\),為了計算 \(z\),我們需要輸入參數 \(w_1\)\(w2\)\(b\),除此之外還有特征值 \(x_1\)\(x_2\)。因此 \(z\) 的計算公式為:

\[z=w_1x_1+w_2x_2+b \]

回想一下邏輯回歸的公式:

\[\hat{y}=a=\sigma(z) \]

其中 \(z=w^Tx+b\), \(\sigma(z)=\frac{1}{1+e^{-z}}\)

損失函數:

\[L(\hat{y}^{(i)},y^{(i)})=-y^{(i)}\log{\hat{y}^{(i)}-(1-y^{(i)})\log{(1-\hat{y}^{(i)})}} \]

代價函數:

\[J(w,b)=\frac{1}{m} \sum^m_i{L(\hat{y}^{(i)},y^{(i)})} \]

現在先只考慮單個樣本的情況,單個樣本的代價函數(也就是損失函數)為:

\[L(a,y)=-(y\log{a}+(1-y)\log{(1-a)} \]

其中,\(a\) 是邏輯回歸的輸出,\(y\) 是樣本的標簽值。

前面我們已經說了如何在單個訓練樣本上計算代價函數的前向步驟,現在我們來通過反向計算出導數。

\[da=\frac{dL(a,y)}{da}=-\frac{y}{a}+\frac{1-y}{1-a}\\ dz=\frac{dL(a,y)}{dz}=\frac{dL}{dz}=(\frac{dL}{da})\cdot(\frac{da}{dz})=(-\frac{y}{a}+\frac{1-y}{1-a})\cdot(a\cdot(1-a))=a-y \]

而對於參數 \(w\)\(b\) 來說:

\[dw_1=\frac{1}{m}\sum^m_i{x_1^{(i)}(a^{(i)}-y^{(i)})}\\ dw_2=\frac{1}{m}\sum^m_i{x_2^{(i)}(a^{(i)}-y^{(i)})}\\ db=\frac{1}{m}\sum^m_i{(a^{(i)}-y^{(i)})} \]

而對於我們剛剛說的單樣本情況:

\[dw_1=x_1 \cdot dz\\ d2_2=x_2 \cdot dz\\ db=dz \]

所以,總得來說,單樣本的梯度下降算法更新一次步驟如下:

  • 計算 \(dz\)
  • 計算 \(dw_1,dw_2,db\)
  • 更新 \(w_1,w_2,b\)

擴展到 m 個樣本的梯度下降是類似的。給相應的值,添加上標 \(^{(i)}\) 就行了。

偽代碼如下圖所示。

8b725e51dcffc53a5def49438b70d925

向量化 (Vectorization)

向量化是非常基礎的去除代碼中 for 循環的藝術。for 循環非常沒有效率而且也沒美觀。

向量化后的公式如下:

前向傳播

\[Z = w^{T}X + b = np.dot( w.T,X)+b\\ A = \sigma( Z )\\ \]

后向傳播

\[dZ = A - Y\\ {{dw} = \frac{1}{m}*X*dz^{T}\ }\\ db= \frac{1}{m}*np.sum( dZ) \\ w: = w - \alpha*dw\\ b:=b-\alpha*db \]

當然,我們希望多次迭代進行梯度下降,仍然還會需要使用到 for 循環。

淺層神經網絡 (Shallow Neural Network)

神經網絡看起來是下圖這個樣子。我們可以把許多個 sigmoid 單元堆疊起來形成一個神經網絡。

L1_week3_2

在這個神經網絡對應的 3 個節點,首先計算第一層網絡中的各個節點相關的數 \(z^{[1]}\),接着計算 \(a^{[1]}\)。同理再計算下一層的網絡。注意這里,我們使用了上標 \(^{[m]}\) 表示第 m 層網絡中節點相關的數,這些節點的集合被稱為第 m 層網絡。

整個計算過程,公式如下:

\[\left. \begin{array}{r} {x }\\ {W^{[1]}}\\ {b^{[1]}} \end{array} \right\} \implies{z^{[1]}=W^{[1]}x+b^{[1]}} \implies{a^{[1]} = \sigma(z^{[1]})}\\ \left. \begin{array}{r} \text{$a^{[1]} = \sigma(z^{[1]})$}\\ \text{$W^{[2]}$}\\ \text{$b^{[2]}$}\\ \end{array} \right\} \implies{z^{[2]}=W^{[2]}a^{[1]}+b^{[2]}} \implies{a^{[2]} = \sigma(z^{[2]})}\\ \implies{{L}\left(a^{[2]},y \right)} \]

此時 \(a^{[2]}\) 就是整個神經網絡最終的輸出,用 \(\hat{y}\) 表示網絡的輸出。

與邏輯回歸類似,神經網絡我們也需要反向計算。

\[\left. \begin{array}{r} {da^{[1]} = {d}\sigma(z^{[1]})}\\ {dW^{[2]}}\\ {db^{[2]}}\\ \end{array} \right\} \impliedby{{dz}^{[2]}={d}(W^{[2]}\alpha^{[1]}+b^{[2]}}) \impliedby{{{da}^{[2]}} = {d}\sigma(z^{[2]})}\\ \impliedby{{dL}\left(a^{[2]},y \right)} \]

神經網絡的表示

以下圖的神經網絡例子來說明一下。

L1_week3_3

其中輸入特征 \(x_1,x_2,x_3\),被稱為神經網絡的輸入層 (input layer);接着第二層的四個節點,我們稱之為隱藏層 (hide layer);最后只有一個結點構成的層被稱為輸出層 (output layer),它負責產生預測值。在論文里,也有人把這個神經網絡稱為一個兩層的神經網絡,因為輸入層不算作一個標准的層。

引入符號標記

在這里,我們用符號 \(a^{[0]}\) 表示輸入特征,從而替代了向量 \(x\)\(a\) 表示激活的意思,它以為着網絡中不同層的值會傳遞到它們后面的層中,輸入層將 \(x\) 傳遞給隱藏層,所以我們將輸入層的激活值稱為 \(a^{[0]}\)。同理,下一層即隱藏層也會產生激活值,我們記為 \(a^{[1]}\)。它們是向量,具體地說,隱藏層的第一個單元我們將表示為 \(a^{[1]}_1\),以此類推。

\[a^{[1]} = \left[ \begin{array}{ccc} a^{[1]}_{1}\\ a^{[1]}_{2}\\ a^{[1]}_{3}\\ a^{[1]}_{4} \end{array} \right] \]

隱藏層以及最后的輸出層是帶有參數的,這里的隱藏層將有兩個參數 \(W\)\(b\)。因為隱藏層算第一層,所以我們給它們加上上標 \(^{[1]}\),即 \((W^{[1]},b^{[1]})\)。在這個例子里,參數 \(W\) 是一個 \(4\times3\) 的矩陣,而參數 \(b\) 是一個 \(4\times1\) 的向量。其中,4 源自於隱藏層有 4 個節點(隱藏層單元),3 源自於輸入層有 3 個輸入特征。相似地,輸出層也有參數 \(W^{[2]}\)\(b^{[2]}\),它們的維數分別是 \(1\times4\)\(1\times1\)

神經網絡的計算

依舊以上面的兩層的神經網絡為例。我們從隱藏層的第一個神經元開始計算,與邏輯回歸相似,這個神經元的計算同樣也分為兩步:

第一步,計算 \(z_1^{[1]}\)\(z_1^{[1]}=w_1^{[1]T}x+b_1^{[1]}\)

第二步,通過激活函數計算 \(a_1^{[1]}\)\(a_1^{[1]}=\sigma(z_1^{[1]})\)

隱藏層的余下幾個神經元的計算過程一樣,只是符號表示不同,最終分別可以得到 \(a_2^{[1]},a_3^{[1]},a_4^{[1]}\)

向量化計算

轉換成向量化之后,公式如下

\[z^{[n]} = w^{[n]}x + b^{[n]}\\ a^{[n]}=\sigma(z^{[n]}) \]

具體到第一層隱藏層的計算則如下

\[\left[ \begin{array}{c} z^{[1]}_{1}\\ z^{[1]}_{2}\\ z^{[1]}_{3}\\ z^{[1]}_{4}\\ \end{array} \right] = \overbrace{ \left[ \begin{array}{c} ...W^{[1]T}_{1}...\\ ...W^{[1]T}_{2}...\\ ...W^{[1]T}_{3}...\\ ...W^{[1]T}_{4}... \end{array} \right] }^{W^{[1]}} * \overbrace{ \left[ \begin{array}{c} x_1\\ x_2\\ x_3\\ \end{array} \right] }^{input} + \overbrace{ \left[ \begin{array}{c} b^{[1]}_1\\ b^{[1]}_2\\ b^{[1]}_3\\ b^{[1]}_4\\ \end{array} \right] }^{b^{[1]}} \]

也就是對於我們簡單的兩層神經網絡來說,只需要四個公式就能計算完

\[z^{[1]}=W^{[1]}a^{[0]}+b^{[1]}\\ a^{[1]}=\sigma(z^{[1]})\\ z^{[2]}=W^{[2]}a^{[1]}+b^{[2]}\\ a^{[2]}=\sigma(z^{[2]}) \]

而對於 m 個樣本來說,只需要對每個樣本計算這個四個公式就行了,使用 for 循環就能實現。當然,可以向量化的話,我們還是要使用向量化。

按列把變量都拼成矩陣,類似如下

\[x = \left[ \begin{array}{c} \vdots & \vdots & \vdots & \vdots\\ x^{(1)} & x^{(2)} & \cdots & x^{(m)}\\ \vdots & \vdots & \vdots & \vdots\\ \end{array} \right]\\ Z^{[1]} = \left[ \begin{array}{c} \vdots & \vdots & \vdots & \vdots\\ z^{[1](1)} & z^{[1](2)} & \cdots & z^{[1](m)}\\ \vdots & \vdots & \vdots & \vdots\\ \end{array} \right]\\ A^{[1]} = \left[ \begin{array}{c} \vdots & \vdots & \vdots & \vdots\\ \alpha^{[1](1)} & \alpha^{[1](2)} & \cdots & \alpha^{[1](m)}\\ \vdots & \vdots & \vdots & \vdots\\ \end{array} \right] \]

那么計算就可以變形為如下所示

\[\left. \begin{array}{r} \text{$z^{[1](i)} = W^{[1](i)}x^{(i)} + b^{[1]}$}\\ \text{$\alpha^{[1](i)} = \sigma(z^{[1](i)})$}\\ \text{$z^{[2](i)} = W^{[2](i)}\alpha^{[1](i)} + b^{[2]}$}\\ \text{$\alpha^{[2](i)} = \sigma(z^{[2](i)})$}\\ \end{array} \right\} \implies \begin{cases} \text{$Z^{[1]} = W^{[1]}X+b^{[1]}$}\\ \text{$A^{[1]} = \sigma(z^{[1]})$}\\ \text{$Z^{[2]} = W^{[2]}A^{[1]} + b^{[2]}$}\\ \text{$A^{[2]} = \sigma(Z^{[2]})$}\\ \end{cases} \]

其中上標 \(^{(i)}\) 代表的是第 i 個樣本。

激活函數 (Activation functions)

使用一個神經網絡時,需要決定使用哪種激活函數用在隱藏層上,哪種用在輸出節點上。之前,我們都一直在用 sigmoid 函數,但是,有時其他的激活函數效果會更好。

常用的激活函數

(1)sigmoid 激活函數

函數的定義為:$ f(x) = \frac{1}{1 + e^{-x}} $,其值域為 $ (0,1) $。

函數圖像如下:

3-26

(2)tanh 激活函數

函數的定義為:$ f(x) = tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} $,值域為 $ (-1,1) $。

函數圖像如下:

3-27

(3)Relu 激活函數

函數的定義為:$ f(x) = max(0, x) $ ,值域為 $ [0,+∞) $;

函數圖像如下:

3-28

(4)Leak Relu 激活函數

函數定義為:

\[f(x) = \left\{ \begin{aligned} ax, \quad x<0 \\ x, \quad x>0 \end{aligned} \right. \]

,值域為 $ (-∞,+∞) $。

圖像如下($ a = 0.5 $):

3-29

選擇激活函數的經驗法則

如果輸出是 0、1 值(二分類問題),則輸出層選擇 sigmoid 函數,然后其它的所有單元都選擇 Relu 函數。

這是很多激活函數的默認選擇,如果在隱藏層上不確定使用哪個激活函數,那么通常會使用 Relu 函數。

有時,也會使用 tanh 函數,但 Relu 的一個優點是:當 \(z\) 值為負時,導數等於 0。在 \(z\) 的區間變動很大的情況下,激活函數的導數或者激活函數的斜率都會遠大於 0,在實踐中,使用 Relu 激活函數神經網絡通常會比使用 sigmoid 或者 tanh 激活函數學習的更快。而且,sigmoid 和 tanh 函數的導數在正負飽和區的梯度都會接近於0,這會造成梯度彌散,Relu 和 Leaky Relu 函數大於 0 部分都為常數,不會產生梯度彌散現象(但是,Relu 進入負半區的時候,梯度為 0,神經元此時不會訓練,產生所謂的稀疏性,而 Leaky Relu 不會有這問題)。

所以,總得來說:

sigmoid 函數:除了輸出層是一個二分類問題,基本不會用它;

tanh 函數:幾乎適合所有場合;

Relu 函數:最常用的默認函數,如果不確定用哪個激活函數,就使用 Relu 或者 Leaky Relu。其中,Leaky Relu 的參數 \(a\) 一般設為 0.01。

激活函數的導數

對常見激活函數,導數計算如下:

原函數 函數表達式 導數 備注
Sigmoid 激活函數 \(f(x)=\frac{1}{1+e^{-x}}\) \(f^{'}(x)=\frac{1}{1+e^{-x}}\left( 1- \frac{1}{1+e^{-x}} \right)=f(x)(1-f(x))\) \(x=10\),或 \(x=-10\)\(f^{'}(x) \approx0\),當 \(x=0\)\(f^{'}(x) =0.25\)
Tanh 激活函數 \(f(x)=tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}}\) \(f^{'}(x)=-(tanh(x))^2\) \(x=10\),或 \(x=-10\)\(f^{'}(x) \approx0\),當 \(x=0\)\(f^{`}(x) =1\)
Relu 激活函數 \(f(x)=max(0,x)\) \(f^{'}(x)=\begin{cases} 0,x<0 \\ 1,x>0 \\ undefined,x=0\end{cases}\) 通常 \(x=0\) 時,給定其導數為 1 和 0
Leaky Relu 激活函數 \(f(x)=max(0.01x,x)\) \(f^{'}(x)=\begin{cases} 0.01,x<0 \\ 1,x>0 \\ undefined,x=0\end{cases}\) 通常 \(x=0\) 時,給定其導數為 1 和 0.01

隨機初始化 (Random Initialization)

訓練神經網絡時,權重隨機初始化是很重要的。對於邏輯回歸,把權重初始化為 0 當然也是可以的,但是對於一個神經網絡,如果把權重或者參數都初始化為 0,那么梯度下降將不會起作用。也就是說,我們把權重都初始化為 0,由於所有的隱含單元都是對稱的,都會開始計算同一個函數,所以無論運行梯度下降多久,他們都一直計算同樣的函數。

所以,我們需要進行隨機初始化參數。具體做法為,把 \(W^{[1]}\) 設為 np.random.randn(4,4),這樣生成了一個高斯分布的隨機數矩陣,通常再乘上一個小的數,比如 0.01,這樣把它初始化為很小的隨機數。然后 \(b\) 沒有這個對稱的問題 (symmetry breaking problem),所以可以把 \(b\) 初始化為 0。類似地,\(W^{[2]}\)\(b^{[2]}\) 也進行這樣的初始化。

對於為什么要將參數初始化為比較小的隨機數,原因是,如果我們使用 tanh 或者 sigmoid 激活函數,如果數值波動太大,\(z\) 就會很大或者很小,這種時候就很可能停在 tanh 或者 sigmoid 函數的平坦的地方,這些地方梯度很小,也就意味着梯度下降會很慢,學習也就很慢。

其實有時有比 0.01 更好的常數,當我們訓練一個只有一層隱藏層的網絡時,設為 0.01 可能可以。但是當訓練一個非常非常深的神經網絡,可能就需要試試 0.01 以外的常數了。

深層神經網絡 (Deep Neural Networks)

神經網絡的層數是這么定義的:從左到右,由 0 開始定義。如下圖所示。

有一個隱藏層的神經網絡,就是一個兩層神經網絡。當我們算神經網絡的層數時,我們不算輸入層,我們只算隱藏層和輸出層。

前向傳播和反向傳播 (Forward and Backward Propagation)

前向傳播

輸入 \(a^{[l-1]}\),輸出是 \(a^{[l]}\),緩存為 \(z^{[l]}\);從實踐中來看,我們還可以緩存下 \(w^{[l]}\)\(b^{[l]}\),這樣更容易在不同的環節中調用函數。

那么,前向傳播的步驟為

\[z^{[l]}=W^{[l]}\cdot a^{[l-1]}+b^{[l]}\\ a^{[l]}=g^{[l]}(z^{[l]}) \]

向量化的版本為

\[Z^{[l]}=W^{[l]}\cdot A^{[l-1]}+b^{[l]}\\ A^{[l]}=g^{[l]}(Z^{[l]}) \]

前向傳播需要喂入 \({A}^{[0]}\) 也就是 \(X\),來初始化;初始化的是第一層的輸入值。\({a}^{[0]}\) 對應於一個訓練樣本的輸入特征,而 \({{A}^{[0]}}\) 對應於一整個訓練樣本的輸入特征,所以這就是這條鏈的第一個前向函數的輸入,重復這個步驟就可以從左到右計算前向傳播。

反向傳播

輸入為 \({{da}^{[l]}}\),輸出為 \({{da}^{[l-1]}},{{dw}^{[l]}}, {{db}^{[l]}}\)

所以反向傳播的步驟可以寫成

\[d{{z}^{[l]}}=d{{a}^{[l]}}*{{g}^{[l]}}'( {{z}^{[l]}})\\ d{{w}^{[l]}}=d{{z}^{[l]}}\cdot{{a}^{[l-1]}}\\ d{{b}^{[l]}}=d{{z}^{[l]}}\\ d{{a}^{[l-1]}}={{w}^{\left[ l \right]T}}\cdot {{dz}^{[l]}}\\ d{{z}^{[l]}}={{w}^{[l+1]T}}d{{z}^{[l+1]}}\cdot \text{ }{{g}^{[l]}}'( {{z}^{[l]}}) \]

向量化的版本為

\[d{{Z}^{[l]}}=d{{A}^{[l]}}*{{g}^{\left[ l \right]}}'\left({{Z}^{[l]}} \right)\\ d{{W}^{[l]}}=\frac{1}{m}\text{}d{{Z}^{[l]}}\cdot {{A}^{\left[ l-1 \right]T}}\\ d{{b}^{[l]}}=\frac{1}{m}\text{ }np.sum(d{{z}^{[l]}},axis=1,keepdims=True)\\ d{{A}^{[l-1]}}={{W}^{\left[ l \right]T}}.d{{Z}^{[l]}} \]

核對矩陣的維數

當實現深度神經網絡的時候,可以拿一張紙過一遍算法中矩陣的維數。

\(w\) 的維度是 (下一層的維數,前一層的維數),即 \(w^{[l]}:(n^{[l]},n^{[l-1]})\)

\(b\) 的維度是 (下一層的維數,1),即 \(b^{[l]}:(n^{[l]},1)\)

類似地,\(z^{[l]},a^{[l]}:(n^{[l]},1)\)

\({{dw}^{[l]}}\)\({{w}^{[l]}}\) 維度相同,\({{db}^{[l]}}\)\({{b}^{[l]}}\) 維度相同,且 \(w\)\(b\) 向量化維度不變,但 \(z\), \(a\) 以及 \(x\) 的維度會向量化后發生變化。

向量化后:

\({Z}^{[l]}\) 可以看成由每一個單獨的 \({z}^{[l]}\) 疊加而得到,\({Z}^{[l]}=({{z}^{[l][1]}},{{z}^{[l][2]}},{{z}^{[l][3]}},…,{{z}^{[l][m]}})\)

\(m\) 為訓練集大小,所以 \({Z}^{[l]}\) 的維度不再是 \(({{n}^{[l]}},1)\),而是 \(({{n}^{[l]}},m)\)

\({A}^{[l]}\)\(({n}^{[l]},m)\)\({A}^{[0]} = X =({n}^{[l]},m)\)

參數與超參數 (Parameters vs Hyperparameters)

什么是超參數?

比如算法中的learning rate \(\alpha\)(學習率)、iterations(梯度下降法循環的數量)、\(L\)(隱藏層數目)、\({{n}^{[l]}}\)(隱藏層單元數目)、choice of activation function(激活函數的選擇)都需要你來設置,這些數字實際上控制了最后的參數 \(W\)\(b\) 的值,所以它們被稱作超參數。

如何尋找超參數的最優值?

Idea—Code—Experiment—Idea 這個循環,嘗試各種不同的參數,實現模型並觀察是否成功,然后再迭代。

References

[1] Coursera深度學習教程中文筆記

[2] 深度學習 500 問


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM