從邏輯迴歸開始入門深度學習

從邏輯迴歸開始入門深度學習

本文主要來源於吳恩達《深度學習與神經網絡》。本文根據課程內容作一個串聯。html

本文內容安排以下:python

  • 符號定義
  • 邏輯迴歸LR:定義、實現、高效實現
  • 淺層神經網絡(2層):實現、優化
  • 深度神經網絡:實現、優化、應用

咱們以一個分類問題做爲研究背景。研究問題爲判斷輸入圖片是否爲貓咪的二分類。算法

符號定義

在解決問題以前,咱們先對使用的數學符號作一個定義:網絡

  • (x, y): 輸入樣本; x ∈ \(R^{n_x}\), y ∈ {0, 1}
  • {\((x^{(1)}, y^{(1)}), (x^{(2)}, y^{(2)})... (x^{(m)}, y^{(m)})\)}: 訓練數據集,包含m個訓練樣本
  • [a,b,c,.....,z].T: 向量,默認狀況下,向量指的是列向量
  • \(m = m_{train}\), \(m_{test}\)=#test examples
  • $X \in R^{n_x * m} \(: 訓練集,訓練樣本以**列的方式**進行堆疊,換言之,X矩陣的每一列是一個樣本,而不是行; X.shape = (\)n_x$, m)
  • \(Y \in R^{1*m}\): 訓練標籤,標籤以列的方式進行堆疊, \(Y.shape = (1,m)\)

邏輯迴歸

在介紹邏輯回顧處理圖片分類。咱們處理的問題是二分類,輸入一張圖片判斷圖片中是否有貓。輸入圖片格式爲RGB三色圖,像素取值爲0~255。app

img

原理介紹

邏輯迴歸用於處理二分類問題。邏輯迴歸中\(\hat{h} = P(y=1|x)\)用於計算輸入樣本爲1的機率。以單個樣本爲例,其計算公式爲函數

\[\hat{y} = sigmoid(w^Tx+b) \]

其中,\(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(z) = \frac{1}{1+e^{-z}} \]

Sigmoid

從上圖能夠看出,sigmoid取值範圍爲[0, 1],當自變量z很是小時,sigmoid趨近於0;當z很是大時,sigmoid趨近於1(實際上當z=10時,輸出值爲0.9999,很是趨近於1)。spa

Loss function

咱們如今知道了如何使用邏輯迴歸計算一個樣本爲正例的機率,那麼如何評估模型的好壞呢?這就依賴於損失函數。

給定一個樣本\((x^{(i)}, y^{(i)})\),使用邏輯迴歸計算這個樣本爲正例的機率P(y=1|x),

\[\hat{y}^{(i)} = \sigma(w^Tx^{(i)} + b), where \ \sigma(z)=\frac{1}{1+e^{-z}} \]

理想狀況下,輸出結果\(\hat y\)應該和樣本標籤y儘量相等,即\(\hat y^{(i)} \approx y^{(i)}\)

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

當y=1時,\(L(\hat y, y)=-log\hat y\);當y=0時,\(L(\hat y, y) = -log(1-\hat y)\).

在所有訓練樣本上,損失函數cost function爲

\[J(w, b) = \frac1{m}\sum_{i=1}^m L(\hat y, y) = -\frac1{m}\sum_{i=1}^m[y^{(i)}log\hat y^{(i)} + (1-y^{(i)})log(1-\hat y^{(i)})] \]

損失函數是參數w,b的函數,咱們想要經過最小化損失函數找到最佳的參數w,b,最後用於樣本的預測[經過最小化損失函數,咱們能夠保證預測結果與真實樣本標籤之間差距儘量小,進而保證預測結果的準確性]。

LR損失函數可使用最大似然估計來進行推導。

Gradient Descent

知道了模型的損失函數,接下來就是經過最小化損失函數獲得最終的參數w,b。經常使用的方法是使用梯度降低法,使用當前位置的偏導數對參數進行更新,反覆屢次後,損失函數到達最低點,此時w,b即爲最終結果。

Gradient Descent

使用梯度降低算法,w,b的更新公式以下:

\[w = w - \alpha \frac{\partial J(w, b)}{\partial w} \\b = b - \alpha \frac{\partial J(w, b)}{\partial 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.此時,能夠經過計算圖依據鏈式法則進行計算。

\[\frac{\partial J}{\partial a} = \frac{\partial J}{\partial v} * \frac{\partial v}{\partial a} = 3 * 1 = 3 \]

\[\frac{\partial J}{\partial b} = \frac{\partial J}{\partial v} * \frac{\partial v}{\partial u} * \frac{\partial u}{\partial b}= 3 * 1 * c= 6 \]

\[\frac{\partial J}{\partial c} = \frac{\partial J}{\partial v} * \frac{\partial v}{\partial u} * \frac{\partial u}{\partial c}= 3 * 1 * b= 9 \]

在計算圖中,藍色線爲前向傳播計算過程,紅色線爲反向傳播計算過程。

LR的優化計算

經過上面的計算圖咱們知道了神經網絡的計算流程。下面咱們使用計算圖來描述單個樣本的邏輯迴歸的計算過程,而後擴展到m個樣本上;以後介紹LR的優化過程,即向量化。

單個樣本的計算

單個樣本的邏輯迴歸計算公式以下:

\[\hat y = \sigma(w^Tx+b), where \ \sigma(z)=\frac1{1+e^{-z}} \\L(\hat y, y) = -[ylog\hat y + (1-y)log(1-\hat y)] \]

咱們假設訓練樣本x的維度爲2(有兩個特徵x一、x2)。

描述邏輯迴歸的loss函數的計算圖將運算過程分爲3步, 分別爲計算z、\(\hat y\),以及L(a,y)。

邏輯迴歸的參數更新法則以下:

\[w_1 = w_1 - \alpha * \frac{\partial L}{\partial w_1} \\w_2 = w_2 - \alpha * \frac{\partial L}{\partial w_2}\\b = b - \alpha * \frac{\partial L}{\partial b} \]

所以,接下來的計算過程主要集中在偏導數\(\frac{\partial L}{\partial w_1}\), \(\frac{\partial L}{\partial w_2}\)以及\(\frac{\partial L}{\partial b}\)的計算。

從計算圖來看:

\[\frac{\partial J}{\partial a} = \frac{\partial -[yloga + (1-y)log(1-a)]}{\partial a} = -[\frac{y}{a} - \frac{1-y}{1-a}] \]

\[\frac{\partial a}{\partial z} = \frac{\partial \frac{1}{1+e^{-z}}}{\partial z} = \frac{1}{1+e^{-z}} * \frac{e^{-z}}{1+e^{-z}} = a * (1 - a) \\\frac{\partial z}{\partial w_1} = \frac{\partial (w_1x_1+w_2x_2+b)}{\partial w_1} = x_1 \\\frac{\partial z}{\partial w_2} = \frac{\partial (w_1x_1+w_2x_2+b)}{\partial w_2} = x_2 \\\frac{\partial z}{\partial b} = \frac{\partial (w_1x_1+w_2x_2+b)}{\partial b} = 1 \]

在反向傳播過程當中根據鏈式法則,咱們能夠知道

\[\frac{\partial J}{\partial w_1} = \frac{\partial J}{\partial a} * \frac{\partial a}{\partial z} * \frac{\partial z}{\partial w_1} = -[\frac{y}{a} - \frac{1-y}{1-a}] * a * (1 - a) * x_1 \\= (a-y)*x_1 \]

\[\frac{\partial J}{\partial w_2} = \frac{\partial J}{\partial a} * \frac{\partial a}{\partial z} * \frac{\partial z}{\partial w_2} = -[\frac{y}{a} - \frac{1-y}{1-a}] * a * (1 - a) * x_2 \\= (a-y)*x_2 \]

\[\frac{\partial J}{\partial b} = \frac{\partial J}{\partial a} * \frac{\partial a}{\partial z} * \frac{\partial z}{\partial b} = -[\frac{y}{a} - \frac{1-y}{1-a}] * a * (1 - a) * 1 \\= a-y \]

知道了單個樣本的反向傳播過程,接下來咱們將樣本數擴展到m個,看看計算有什麼變化。

m個樣本的計算

對於m個樣本,邏輯迴歸的cost function計算過程以下:

\[z^{(i)} = w^Tx^{(i)} + b \]

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

\[J(w, b) = \frac1{m}\sum_{i=1}^m L(\hat y, y) = -\frac1{m}\sum_{i=1}^m[y^{(i)}log\hat y^{(i)} + (1-y^{(i)})log(1-\hat y^{(i)})] \]

對應的偏導數爲:

\(\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循環集中在一次計算過程當中完成。

淺層神經網絡(2層)

從某種角度上說,邏輯迴歸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個樣本,最終使用向量化方式完成計算。最後,介紹深層神經網絡,深層神經網絡只是增長了隱藏層的數目,其計算過程和淺層神經網絡十分類似。


歡迎關注個人公衆號,一同窗習成長。
公衆號

相關文章
相關標籤/搜索