吳恩達《神經網路與深度學習》課程筆記(2)– 神經網路基礎之邏輯迴歸

紅色石頭發表於2018-07-29

上節課我們主要對深度學習(Deep Learning)的概念做了簡要的概述。我們先從房價預測的例子出發,建立了標準的神經網路(Neural Network)模型結構。然後從監督式學習入手,介紹了Standard NN,CNN和RNN三種不同的神經網路模型。接著介紹了兩種不同型別的資料集:Structured Data和Unstructured Data。最後,我們解釋了近些年來深度學習效能優於傳統機器學習的原因,歸結為三個因素:Data,Computation和Algorithms。本節課,我們將開始介紹神經網路的基礎:邏輯迴歸(Logistic Regression)。通過對邏輯迴歸模型結構的分析,為我們後面學習神經網路模型打下基礎。

1. Binary Classification

我們知道邏輯迴歸模型一般用來解決二分類(Binary Classification)問題。二分類就是輸出y只有{0,1}兩個離散值(也有{-1,1}的情況)。我們以一個影象識別問題為例,判斷圖片中是否有貓存在,0代表noncat,1代表cat。主要是通過這個例子簡要介紹神經網路模型中一些標準化的、有效率的處理方法和notations。

如上圖所示,這是一個典型的二分類問題。一般來說,彩色圖片包含RGB三個通道。例如該cat圖片的尺寸為(64,64,3)。在神經網路模型中,我們首先要將圖片輸入x(維度是(64,64,3))轉化為一維的特徵向量(feature vector)。方法是每個通道一行一行取,再連線起來。由於64x64x3=12288,則轉化後的輸入特徵向量維度為(12288,1)。此特徵向量x是列向量,維度一般記為n_x

如果訓練樣本共有m張圖片,那麼整個訓練樣本X組成了矩陣,維度是(n_x,m)。注意,這裡矩陣X的行n_x代表了每個樣本x^{(i)}特徵個數,列m代表了樣本個數。這裡,Andrew解釋了X的維度之所以是(n_x,m)而不是(m,n_x)的原因是為了之後矩陣運算的方便。算是Andrew給我們的一個小小的經驗吧。而所有訓練樣本的輸出Y也組成了一維的行向量,寫成矩陣的形式後,它的維度就是(1,m)。

2. Logistic Regression

接下來我們就來介紹如何使用邏輯迴歸來解決二分類問題。邏輯迴歸中,預測值\hat h=P(y=1\ |\ x)表示為1的概率,取值範圍在[0,1]之間。這是其與二分類模型不同的地方。使用線性模型,引入引數w和b。權重w的維度是(n_x,1),b是一個常數項。這樣,邏輯迴歸的線性預測輸出可以寫成:

\hat y = w^Tx+b

值得注意的是,很多其它機器學習資料中,可能把常數b當做w_0處理,並引入x_0=1。這樣從維度上來看,x和w都會增加一維。但在本課程中,為了簡化計算和便於理解,Andrew建議還是使用上式這種形式將w和b分開比較好。

上式的線性輸出區間為整個實數範圍,而邏輯迴歸要求輸出範圍在[0,1]之間,所以還需要對上式的線性函式輸出進行處理。方法是引入Sigmoid函式,讓輸出限定在[0,1]之間。這樣,邏輯迴歸的預測輸出就可以完整寫成:

\hat y = Sigmoid(w^Tx+b)=\sigma(w^Tx+b)

Sigmoid函式是一種非線性的S型函式,輸出被限定在[0,1]之間,通常被用在神經網路中當作啟用函式(Activation function)使用。Sigmoid函式的表示式和曲線如下所示:

Sigmoid(z)=\frac{1}{1+e^{-z}}

從Sigmoid函式曲線可以看出,當z值很大時,函式值趨向於1;當z值很小時,函式值趨向於0。且當z=0時,函式值為0.5。還有一點值得注意的是,Sigmoid函式的一階導數可以用其自身表示:

\sigma'(z)=\sigma(z)(1-\sigma(z))

這樣,通過Sigmoid函式,就能夠將邏輯迴歸的輸出限定在[0,1]之間了。

3. Logistic Regression Cost Function

邏輯迴歸中,w和b都是未知引數,需要反覆訓練優化得到。因此,我們需要定義一個cost function,包含了引數w和b。通過優化cost function,當cost function取值最小時,得到對應的w和b。

提一下,對於m個訓練樣本,我們通常使用上標來表示對應的樣本。例如(x^{(i)},y^{(i)})表示第i個樣本。

如何定義所有m個樣本的cost function呢?先從單個樣本出發,我們希望該樣本的預測值\hat y與真實值越相似越好。我們把單個樣本的cost function用Loss function來表示,根據以往經驗,如果使用平方錯誤(squared error)來衡量,如下所示:

L(\hat y,y)=\frac12(\hat y-y)^2

但是,對於邏輯迴歸,我們一般不使用平方錯誤來作為Loss function。原因是這種Loss function一般是non-convex的。non-convex函式在使用梯度下降演算法時,容易得到區域性最小值(local minumum),即區域性最優化。而我們最優化的目標是計算得到全域性最優化(Global optimization)。因此,我們一般選擇的Loss function應該是convex的。

Loss function的原則和目的就是要衡量預測輸出\hat y與真實樣本輸出y的接近程度。平方錯誤其實也可以,只是它是non-convex的,不利於使用梯度下降演算法來進行全域性優化。因此,我們可以構建另外一種Loss function,且是convex的,如下所示:

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

我們來分析一下這個Loss function,它是衡量錯誤大小的,Loss function越小越好。

當y=1時,L(\hat y,y)=-log\ \hat y。如果\hat y越接近1,L(\hat y,y)\approx 0,表示預測效果越好;如果\hat y越接近0,L(\hat y,y)\approx +\infty,表示預測效果越差。這正是我們希望Loss function所實現的功能。

當y=0時,L(\hat y,y)=-log\ (1-\hat y)。如果\hat y越接近0,L(\hat y,y)\approx 0,表示預測效果越好;如果\hat y越接近1,L(\hat y,y)\approx +\infty,表示預測效果越差。這也正是我們希望Loss function所實現的功能。

因此,這個Loss function能夠很好地反映預測輸出\hat y與真實樣本輸出y的接近程度,越接近的話,其Loss function值越小。而且這個函式是convex的。上面我們只是簡要地分析為什麼要使用這個Loss function,後面的課程中,我們將詳細推導該Loss function是如何得到的。並不是憑空捏造的哦。。。

還要提一點的是,上面介紹的Loss function是針對單個樣本的。那對於m個樣本,我們定義Cost function,Cost function是m個樣本的Loss function的平均值,反映了m個樣本的預測輸出\hat y與真實樣本輸出y的平均接近程度。Cost function可表示為:

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

Cost function已經推匯出來了,Cost function是關於待求係數w和b的函式。我們的目標就是迭代計算出最佳的w和b值,最小化Cost function,讓Cost function儘可能地接近於零。

其實邏輯迴歸問題可以看成是一個簡單的神經網路,只包含一個神經元。這也是我們這裡先介紹邏輯迴歸的原因。

4. Gradient Descent

我們已經掌握了Cost function的表示式,接下來將使用梯度下降(Gradient Descent)演算法來計算出合適的w和b值,從而最小化m個訓練樣本的Cost function,即J(w,b)。

由於J(w,b)是convex function,梯度下降演算法是先隨機選擇一組引數w和b值,然後每次迭代的過程中分別沿著w和b的梯度(偏導數)的反方向前進一小步,不斷修正w和b。每次迭代更新w和b後,都能讓J(w,b)更接近全域性最小值。梯度下降的過程如下圖所示。

梯度下降演算法每次迭代更新,w和b的修正表示式為:

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

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

上式中,\alpha是學習因子(learning rate),表示梯度下降的步進長度。\alpha越大,w和b每次更新的“步伐”更大一些;\alpha越小,w和b每次更新的“步伐”更小一些。在程式程式碼中,我們通常使用dw來表示\frac{\partial J(w,b)}{\partial w},用db來表示\frac{\partial J(w,b)}{\partial b}。微積分裡,\frac{df}{dx}表示對單一變數求導數,\frac{\partial f}{\partial x}表示對多個變數中某個變數求偏導數。

梯度下降演算法能夠保證每次迭代w和b都能向著J(w,b)全域性最小化的方向進行。其數學原理主要是運用泰勒一階展開來證明的,可以參考我的另一篇部落格中的Gradient Descent有提到如何推導:臺灣大學林軒田機器學習基石課程學習筆記10 — Logistic Regression

5. Derivatives

這一部分的內容非常簡單,Andrew主要是給對微積分、求導數不太清楚的同學介紹的。梯度或者導數一定程度上可以看成是斜率。關於求導數的方法這裡就不再贅述了。

6. More Derivative Examples

Andrew給出了更加複雜的求導數的例子,略。

7. Computation graph

整個神經網路的訓練過程實際上包含了兩個過程:正向傳播(Forward Propagation)和反向傳播(Back Propagation)。正向傳播是從輸入到輸出,由神經網路計算得到預測輸出的過程;反向傳播是從輸出到輸入,對引數w和b計算梯度的過程。下面,我們用計算圖(Computation graph)的形式來理解這兩個過程。

舉個簡單的例子,假如Cost function為J(a,b,c)=3(a+bc),包含a,b,c三個變數。我們用u表示bc,v表示a+u,則J=3v。它的計算圖可以寫成如下圖所示:

令a=5,b=3,c=2,則u=bc=6,v=a+u=11,J=3v=33。計算圖中,這種從左到右,從輸入到輸出的過程就對應著神經網路或者邏輯迴歸中輸入與權重經過運算計算得到Cost function的正向過程。

8. Derivatives with a Computation Graph

上一部分介紹的是計算圖的正向傳播(Forward Propagation),下面我們來介紹其反向傳播(Back Propagation),即計算輸出對輸入的偏導數。

還是上個計算圖的例子,輸入引數有3個,分別是a,b,c。

首先計算J對引數a的偏導數。從計算圖上來看,從右到左,J是v的函式,v是a的函式。則利用求導技巧,可以得到:

\frac{\partial J}{\partial a}=\frac{\partial J}{\partial v}\cdot \frac{\partial v}{\partial a}=3\cdot 1=3

根據這種思想,然後計算J對引數b的偏導數。從計算圖上來看,從右到左,J是v的函式,v是u的函式,u是b的函式。可以推導:

\frac{\partial J}{\partial b}=\frac{\partial J}{\partial v}\cdot \frac{\partial v}{\partial u}\cdot \frac{\partial u}{\partial b}=3\cdot 1\cdot c=3\cdot 1\cdot 2=6

最後計算J對引數c的偏導數。仍從計算圖上來看,從右到左,J是v的函式,v是u的函式,u是c的函式。可以推導:

\frac{\partial J}{\partial c}=\frac{\partial J}{\partial v}\cdot \frac{\partial v}{\partial u}\cdot \frac{\partial u}{\partial c}=3\cdot 1\cdot b=3\cdot 1\cdot 3=9

為了統一格式,在程式程式碼中,我們使用da,db,dc來表示J對引數a,b,c的偏導數。

9. Logistic Regression Gradient Descent

現在,我們將對邏輯迴歸進行梯度計算。對單個樣本而言,邏輯迴歸Loss function表示式如下:

z=w^Tx+b

\hat y=a=\sigma(z)

L(a,y)=-(ylog(a)+(1-y)log(1-a))

首先,該邏輯迴歸的正向傳播過程非常簡單。根據上述公式,例如輸入樣本x有兩個特徵(x_1,x_2),相應的權重w維度也是2,即(w_1,w_2)。則z=w_1x_1+w_2x_2+b,最後的Loss function如下所示:

然後,計算該邏輯迴歸的反向傳播過程,即由Loss function計算引數w和b的偏導數。推導過程如下:

da=\frac{\partial L}{\partial a}=-\frac ya+\frac{1-y}{1-a}

dz=\frac{\partial L}{\partial z}=\frac{\partial L}{\partial a}\cdot \frac{\partial a}{\partial z}=(-\frac ya+\frac{1-y}{1-a})\cdot a(1-a)=a-y

知道了dz之後,就可以直接對w_1w_2和b進行求導了。

dw_1=\frac{\partial L}{\partial w_1}=\frac{\partial L}{\partial z}\cdot \frac{\partial z}{\partial w_1}=x_1\cdot dz=x_1(a-y)

dw_2=\frac{\partial L}{\partial w_2}=\frac{\partial L}{\partial z}\cdot \frac{\partial z}{\partial w_2}=x_2\cdot dz=x_2(a-y)

db=\frac{\partial L}{\partial b}=\frac{\partial L}{\partial z}\cdot \frac{\partial z}{\partial b}=1\cdot dz=a-y

則梯度下降演算法可表示為:

w_1:=w_1-\alpha\ dw_1

w_2:=w_2-\alpha\ dw_2

b:=b-\alpha\ db

10. Gradient descent on m examples

上一部分講的是對單個樣本求偏導和梯度下降。如果有m個樣本,其Cost function表示式如下:

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

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

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

Cost function關於w和b的偏導數可以寫成和平均的形式:

dw_1=\frac1m\sum_{i=1}^mx_1^{(i)}(a^{(i)}-y^{(i)})

dw_2=\frac1m\sum_{i=1}^mx_2^{(i)}(a^{(i)}-y^{(i)})

db=\frac1m\sum_{i=1}^m(a^{(i)}-y^{(i)})

這樣,每次迭代中w和b的梯度有m個訓練樣本計算平均值得到。其演算法流程圖如下所示:

J=0; dw1=0; dw2=0; db=0;
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);
    dw1 += x1(i)dz(i);
    dw2 += x2(i)dz(i);
    db += dz(i);
J /= m;
dw1 /= m;
dw2 /= m;
db /= m;

經過每次迭代後,根據梯度下降演算法,w和b都進行更新:

w_1:=w_1-\alpha\ dw_1

w_2:=w_2-\alpha\ dw_2

b:=b-\alpha\ db

這樣經過n次迭代後,整個梯度下降演算法就完成了。

值得一提的是,在上述的梯度下降演算法中,我們是利用for迴圈對每個樣本進行dw1,dw2和db的累加計算最後再求平均數的。在深度學習中,樣本數量m通常很大,使用for迴圈會讓神經網路程式執行得很慢。所以,我們應該儘量避免使用for迴圈操作,而使用矩陣運算,能夠大大提高程式執行速度。關於vectorization的內容我們放在下次筆記中再說。

11. Summary

本節課的內容比較簡單,主要介紹了神經網路的基礎——邏輯迴歸。首先,我們介紹了二分類問題,以圖片為例,將多維輸入x轉化為feature vector,輸出y只有{0,1}兩個離散值。接著,我們介紹了邏輯迴歸及其對應的Cost function形式。然後,我們介紹了梯度下降演算法,並使用計算圖的方式來講述神經網路的正向傳播和反向傳播兩個過程。最後,我們在邏輯迴歸中使用梯度下降演算法,總結出最優化引數w和b的演算法流程。

更多AI資源請關注公眾號:AI有道(ID:redstonewill)

相關文章