本文主要來源於吳恩達《深度學習與神經網絡》。本文根據課程內容作一個串聯。html
本文內容安排以下:python
咱們以一個分類問題做爲研究背景。研究問題爲判斷輸入圖片是否爲貓咪的二分類。算法
在解決問題以前,咱們先對使用的數學符號作一個定義:網絡
在介紹邏輯回顧處理圖片分類。咱們處理的問題是二分類,輸入一張圖片判斷圖片中是否有貓。輸入圖片格式爲RGB三色圖,像素取值爲0~255。app
邏輯迴歸用於處理二分類問題。邏輯迴歸中\(\hat{h} = P(y=1|x)\)用於計算輸入樣本爲1的機率。以單個樣本爲例,其計算公式爲函數
其中,\(x \in R^{n_x}\), \(w \in R^{n_x}\) ,\(b \in R\)。輸出結果的取值範圍爲[0, 1]。oop
邏輯迴歸實際上是線性迴歸的進一步加工,線性迴歸計算結果的取值範圍爲\((-\infty, +\infty)\),咱們將線性迴歸的計算結果使用sigmoid將範圍壓縮到[0, 1].學習
Sigmoid是一種非線性的S型函數,取值範圍在[0, 1],這種輸出值能夠別理解爲機率表示。Sigmoid函數的計算公式和曲線以下。優化
從上圖能夠看出,sigmoid取值範圍爲[0, 1],當自變量z很是小時,sigmoid趨近於0;當z很是大時,sigmoid趨近於1(實際上當z=10時,輸出值爲0.9999,很是趨近於1)。spa
咱們如今知道了如何使用邏輯迴歸計算一個樣本爲正例的機率,那麼如何評估模型的好壞呢?這就依賴於損失函數。
給定一個樣本\((x^{(i)}, y^{(i)})\),使用邏輯迴歸計算這個樣本爲正例的機率P(y=1|x),
理想狀況下,輸出結果\(\hat y\)應該和樣本標籤y儘量相等,即\(\hat y^{(i)} \approx y^{(i)}\)
當y=1時,\(L(\hat y, y)=-log\hat y\);當y=0時,\(L(\hat y, y) = -log(1-\hat y)\).
在所有訓練樣本上,損失函數cost function爲
損失函數是參數w,b的函數,咱們想要經過最小化損失函數找到最佳的參數w,b,最後用於樣本的預測[經過最小化損失函數,咱們能夠保證預測結果與真實樣本標籤之間差距儘量小,進而保證預測結果的準確性]。
LR損失函數可使用最大似然估計來進行推導。
知道了模型的損失函數,接下來就是經過最小化損失函數獲得最終的參數w,b。經常使用的方法是使用梯度降低法,使用當前位置的偏導數對參數進行更新,反覆屢次後,損失函數到達最低點,此時w,b即爲最終結果。
使用梯度降低算法,w,b的更新公式以下:
其中,\(\alpha\)爲學習率,含義是每次參數更新的步幅;若是\(\alpha\)過大,致使參數更新幅度過大,可能會錯過模型的最優值;若是\(\alpha\)過下,致使每次更新幅度很小,模型須要更多的迭代次數才能收斂。在程序代碼中,咱們使用dw表示\(\frac{\partial J(w, b)}{\partial w}\), db表示\(\frac{\partial J(w, b)}{\partial b}\).
神經網絡的計算過程通常分爲兩個階段:前向傳播和反向傳播。使用計算圖來描述計算過程更清晰:將整個計算過程分步驟進行計算。
假設J(a, b, c) = 3(a + bc),其中a=5, b=3, c=2.這個計算過程可使用計算圖來描述,如:
設定u = bc, v = a + u, J=3v.
反向傳播過程,須要計算da, db, dc.此時,能夠經過計算圖依據鏈式法則進行計算。
在計算圖中,藍色線爲前向傳播計算過程,紅色線爲反向傳播計算過程。
經過上面的計算圖咱們知道了神經網絡的計算流程。下面咱們使用計算圖來描述單個樣本的邏輯迴歸的計算過程,而後擴展到m個樣本上;以後介紹LR的優化過程,即向量化。
單個樣本的邏輯迴歸計算公式以下:
咱們假設訓練樣本x的維度爲2(有兩個特徵x一、x2)。
描述邏輯迴歸的loss函數的計算圖將運算過程分爲3步, 分別爲計算z、\(\hat y\),以及L(a,y)。
邏輯迴歸的參數更新法則以下:
所以,接下來的計算過程主要集中在偏導數\(\frac{\partial L}{\partial w_1}\), \(\frac{\partial L}{\partial w_2}\)以及\(\frac{\partial L}{\partial b}\)的計算。
從計算圖來看:
在反向傳播過程當中根據鏈式法則,咱們能夠知道
知道了單個樣本的反向傳播過程,接下來咱們將樣本數擴展到m個,看看計算有什麼變化。
對於m個樣本,邏輯迴歸的cost function計算過程以下:
對應的偏導數爲:
\(\frac{\partial J}{\partial w_1} = \frac1{m}*\sum_{i=1}^m(a^{(i)}-y^{(i)})*x_1^{(i)}\)
\(\frac{\partial J}{\partial w_2} = \frac1{m}*\sum_{i=1}^m(a^{(i)}-y^{(i)})*x_2^{(i)}\)
\(\frac{\partial J}{\partial b} = \frac1{m}*\sum_{i=1}^m(a^{(i)}-y^{(i)})\)
其實就是將m個樣本的偏導數求和,而後取平均。
使用僞代碼描述這個過程以下:
J=0; dw1=0; dw2=0; db=0 for i = 1 to m: # 前向傳播計算損失函數 z(i) = w * x(i) + b a(i) = sigmoid(z(i)) J += -[y(i)loga(i) + (1-y(i))log(1-a(i))] # 反向傳播計算導數 dz(i) = a(i) - y(i) dw1 += dz(i)*x1(i) # x1(i):第i個樣本的第一個特徵 dw2 += dz(i)*x2(i) db += dz(1) # 遍歷完m個樣本,計算梯度均值 J /= m dw1 /= m dw2 /= m db /= m
梯度計算完成後,對參數進行一次更新:
w1 -= alpha * dw1 w2 -= alpha * dw2 b -= alpha * db
這個過程是對樣本集的一次遍歷,梯度降低算法能夠規定遍歷的次數,遍歷n次後整個梯度降低過程就完成了。
整個計算過程當中,使用的是顯示的for循環,咱們可使用矩陣運算來對整個計算過程進行優化。
Z計算: \(z = w^Tx+b\)
對於單個樣本,\(z = w^Tx + b\); 其中, \(w \in R^{n_x},x \in R^{n_x}, b \in R\)
for-loop形式
z = 0 for i in range(n_x): z += w[i]*x[i] z += b
向量形式
import numpy as np z = np.dot(w.T, x) + b
對於m個樣本,z的計算結果爲一個向量。$X \in R^{n_x * m},w \in R^{n_x} $
for-loop 方法
z = np.zeros((1, m)) for i in range(m): for j in range(n_x): z[i] += w[j]*X[j][i]
向量形式
z = np.dot(w.T, X)
使用矩陣運算後的LR計算過程以下:
# w: [n_x, 1]; x: [n_x, m], b: float Z = np.dot(w.T, X) + b # [1, m] A = sigmoid(Z) # 反向傳播計算梯度dw, db dZ = A -Y dw = 1./m * X * dZ.T db = 1./m * np.sum(dZ) # 參數更新 w -= learning_rate * dw b -= learning_rate * db
使用矩陣運算,減小了對樣本的for訓練遍歷以及對梯度計算過程當中對參數的遍歷。
Whenever possible, avoid explicit for-loops.
值得注意的是,這裏關於非參數的矩陣表示,如訓練樣本矩陣X,標籤矩陣Y都是以列的方式進行堆疊而成的。矩陣運算將for循環集中在一次計算過程當中完成。
從某種角度上說,邏輯迴歸LR也能夠看做一種神經網絡,示意圖以下。
中間的神經元完成兩種運算,分別爲z和a。
淺層神經網絡示意圖以下,其中每一個「圓圈」的運算相似於LR,區別在於第二步a的計算中使用的激活函數不一樣。LR激活函數爲sigmoid,這裏能夠爲relu、tanh、sigmoid等等。
這個神經網絡有輸入層、隱藏層和輸出層三層組成,可是通常狀況下輸入層忽略不計,因此這個神經網絡有2層組成。
咱們這裏設定\(w_i^{[l]}\)表示神經網絡第l層的第i個神經元的權重參數。對於單個樣本而言,這個淺層神經網絡的計算過程以下:
在隱藏層:
\(z_1^{[1]} = w_1^{[1]T}*x + b_1^{[1]},\ a_1^{[1]} = \sigma(z_1^{[1]});\)
\(z_2^{[1]} = w_2^{[1]T}*x + b_2^{[1]},\ a_2^{[1]} = \sigma(z_2^{[1]});\)
\(z_3^{[1]} = w_3^{[1]T}*x + b_3^{[1]},\ a_3^{[1]} = \sigma(z_3^{[1]});\)
\(z_4^{[1]} = w_4^{[1]T}*x + b_4^{[1]},\ a_4^{[1]} = \sigma(z_4^{[1]});\)
輸出結果獲得一個[4, 1]向量:[\(a_1^{[1]};a_2^{[1]};a_3^{[1]};a_4^{[1]}\)]. 咱們使用\(a^{[1]}\)表示這個結果,同時做爲輸出層的輸入繼續計算。
輸出層計算結果:
\(z_1^{[2]} = w_1^{[2]T}*a^{[1]} + b_1^{[2]}, \hat y=a^{[2]} = \sigma(z^{[2]})\)
使用矩陣表示整個計算過程以下,隱藏層的參數用\(W^{[1]}\)表示,由隱藏層各個神經元對應權重參數以行的方式堆疊而成,這裏形狀爲[4, 3] (權重參數的第一維度爲本層神經元的數目,另外一個維度爲上一層網絡的神經元數目)
單個樣本的矩陣表示計算過程以下:
\(z^{[1]} = W^{[1]}x + b^{[1]}\)
\(a^{[1]} = \sigma(z^{[1]})\)
\(z^{[2]} = W^{[2]}a^{[1]} + b^{[2]}\)
\(a^{[2]}=\sigma(z^{[2]})\)
若是將樣本數擴展到m個,使用for循環的計算過程爲:
for i = 1 to m: z[1](i) = W[1]x(i) + b[1] a[1](i) = sigma(z[1](i)) z[2](i) = W[2]a[1](i) + b[2] a[2](i) = sigma(z[2](i))
若是使用矩陣運算,咱們設定m個訓練樣本以列的方式進行堆疊,用X表示,形狀爲[3, m]。使用矩陣運算過程以下,
Z[1] = W[1]X + b[1] A[1] = sigma(Z[1]) Z[2] = W[2]A[1] + b[2] A[2] = sigma(Z[2])
示意圖以下:
反向傳播主要用於計算梯度dw1, dw2, dw3, db.爲了方便理解,咱們先用for循環進行介紹,以後再使用矩陣進行計算優化。
單個樣本
計算過程相似於邏輯迴歸的反向傳播過程。
\(dz^{[2]} = a^{[2]} - y\)
\(dW^{[2]} = dz^{[2]} * \frac{\partial dz^{[2]}}{\partial W^{[2]}} = dz^{[2]} * a^{[1]T}\)
$db^{[2]} = dz^{[2]} * \frac{\partial dz^{[2]}}{\partial b^{[2]}} = dz^{[2]} $
\(dz^{[1]} = dz^{[2]} * \frac{\partial dz^{[2]}}{\partial a^{[1]}} * \frac{\partial a^{[1]}}{\partial z^{[1]}} = W^{[2]T}*dz^{[2]} * g^{[1]^{'}}(z^{[1]})\)
\(dW^{[1]} = dz^{[1]} * \frac{\partial dz^{[1]}}{\partial W^{[1]}} = dz^{[1]} * x^T\)
\(db^{[1]} = dz^{[1]} * \frac{\partial dz^{[1]}}{\partial b^{[1]}} = dz^{[1]} * 1 = dz^{[1]}\)
對應的向量形式爲(將m個樣本堆疊在一塊兒,一同計算):
深層神經網絡是指包括多個隱藏的神經網絡模型。如
深層神經網絡計算過程相似於淺層神經網絡,分爲前向傳播計算loss,反向傳播計算梯度,而後更新權重;反覆更新直到模型收斂。
模型的前向傳播郭恆比較簡單,咱們接下來主要介紹模型的反向傳播。以神經網絡的某一層爲例:
Input: \(da^{[l]}\)
Output: \(da^{[l-1]}, dW^{[l]}, db^{[l]}\)
咱們知道前向傳播過程當中:
\(z^{[l]} = W^{[l]}*a^{[l-1]} + b^{[l]}\)
\(a^{[l]} = g(z^{[l]})\)
那麼,
\(dz^{[l]} = da^{[l]} * g^{[l]'}(z^{[l]})\)
\(da^{[l-1]} = W^{[l]T} * dz^{[l]}\)
\(dW^{[l-1]} = dz^{[l]} * a^{[l-1]}\)
\(db^{[l-1]} = dz^{[l]}\)
獲得\(da^{[l-1]}\)以後,咱們能夠繼續往前傳播。
爲了方便運算,咱們能夠在前向傳播過程當中保存計算結果\(g(z^{[l]})\)。
深度神經網絡的計算圖能夠描述以下。
神經網絡的前向傳播和反向傳播計算過程能夠總結以下:
本文自下而上的對神經網絡進行了介紹。首先,從邏輯迴歸開始介紹其計算過程、反向傳播、更新方法,在介紹過程當中先以單個樣本的計算開始,而後擴展到m個樣本,以後爲了提升計算速度,採用向量化方法進行計算;咱們瞭解了邏輯迴歸以後,介紹淺層神經網絡。淺層神經網絡是一個2層神經網絡,每層神經網絡的神經元能夠看作是一個「邏輯迴歸」計算單元,區別在於使用的激活函數不一樣。淺層神經網絡的介紹也是先從單個樣本開始,經過單個樣本明白其計算過程,而後擴展到m個樣本,最終使用向量化方式完成計算。最後,介紹深層神經網絡,深層神經網絡只是增長了隱藏層的數目,其計算過程和淺層神經網絡十分類似。
歡迎關注個人公衆號,一同窗習成長。