吳恩達深度學習筆記(一)by LKP

神經網絡與深度學習

第一週:深度學習概論

ReLU函數(Rectified Linear Unit):

簡單神經網絡(房價預測)

複雜神經網絡(房價預測)

在圖上每一個畫的小圓圈都可以是ReLU的一部分,或者其它稍微非線性的函數。

監督學習的例子

Input(x) Output(y) Application
Home features Price Real Estate(Standard NN)
Ad, user info Click on ad?(0/1) Online Advertising(Standard NN)
Image Object(1,…,1000) Photo tagging(CNN)
Audio Text transcript Speech recognition(RNN)
English Chinese Machine translation(RNN)
Image, Radar info Position of other cars Autonomous driving(Custom/hybrid)

神經網絡的例子

結構化數據與非結構化數據

爲什麼深度學習能夠如此有效?

如今最可靠的方法來在神經網絡上獲得更好的性能,往往就是要麼訓練一個更大的神經網絡,要麼投入更多的數據。

對於Logistic迴歸中的sigmoid函數,在這個區域兩端,sigmoid函數的梯度會接近零,所以學習的速度會變得非常緩慢,因爲當實現梯度下降以及梯度接近零的時候,參數會更新的很慢,所以學習的速率也會變的很慢,而改變激活函數爲ReLU函數(修正線性單元),ReLU它的梯度對於所有輸入的負值都是零,因此梯度更加不會趨向逐漸減少到零。而這裏的梯度,這條線的斜率在這左邊是零,僅僅通過將Sigmod函數轉換成ReLU函數,便能夠使得gradient descent的算法運行的更快。

第二週:神經網絡基礎(review)

在神經網絡的計算中,通常先有一個叫做前向傳播(foward propagation)的步驟,接着有一個叫做做反向傳播(backward propagation)的步驟。

二分類(Logistic迴歸):識別貓

圖像表示(圖片大小爲64x64像素):

X=[255231255134]n=nx=64×64×3=12288XyX=\left[ \begin{array}{c} 255\\ 231\\ \vdots\\ 255\\ 134\\ \vdots\\ \end{array} \right]\text{,}n=n_x=64\times 64\times 3=12288\text{,}X\longrightarrow y

在二分類問題中,我們的目標就是求得一個分類器,它以圖片的特徵向量作爲輸入,然後預測輸出結果yy爲1還是0,也就是預測圖片中是否有貓。

一些記號:
(x,y)xRnxy{0,1}\left( x,y \right) \text{,}x\in \mathbb{R}^{n_x}\text{,}y\in \left\{ \text{0,}1 \right\}
m  training  examples{(x(1),y(1)),(x(2),y(2)),...,(x(m),y(m))}m\,\,training\,\,examples\text{:}\left\{ \left( x^{\left( 1 \right)},y^{\left( 1 \right)} \right) ,\left( x^{\left( 2 \right)},y^{\left( 2 \right)} \right) ,...,\left( x^{\left( m \right)},y^{\left( m \right)} \right) \right\}
m=MtrainMtest=#test  examplesm=M_{train}\text{,}M_{test}=\#test\,\,examples
X=[x(1)  x(2)  ...x(m)]XRnx×mX=\left[ x^{\left( 1 \right)}\,\,x^{\left( 2 \right)}\,\,... \, x^{\left( m \right)} \right] 表示所有的訓練數據集的輸入值\text{,}X\in \mathbb{R}^{n_x\times m}
Y=[y(1)  y(2)  ...y(m)]YR1×mY=\left[ y^{\left( 1 \right)}\,\,y^{\left( 2 \right)}\,\,... \, y^{\left( m \right)} \right] 表示所有訓練數據集的輸出值\text{,}Y\in \mathbb{R}^{1\times m}

X.shape   %用於顯示矩陣的規模,(n_x,m)
Y.shape   %(1,m)

Logistic迴歸
Given  xRnxwant  y=P(y=1|x)0y1Given\,\,x\in \mathbb{R}^{n_x}\text{,}want\,\,\overset{\land}{y}=P\left( y=\text{1|}x \right) \text{,}0\leqslant \overset{\land}{y}\leqslant 1
ParametersωRnxbRParameters\text{:}\omega \in \mathbb{R}^{n_x}\text{,}b\in \mathbb{R}
Outputy=σ(ωTx+b)z=ωTx+bOutput\text{:}\overset{\land}{y}=\sigma \left( \omega ^Tx+b \right) \text{,}z=\omega ^Tx+b
σ(z)=11+ez\sigma \left( z \right) =\frac{1}{1+e^{-z}} 見下圖
If z large,σ(z)11+0=1\sigma \left( z \right) \approx \frac{1}{1+0}=1
If z large negative number,σ(z)11+big  number=0\sigma \left( z \right) \approx \frac{1}{1+big\,\,number}=0

Logistic迴歸的代價函數
y(i)=σ(ωTx(i)+b)where  σ(z(i))=11+ez(i)z(i)=ωTx(i)+b\overset{\land}{y}^{\left( i \right)}=\sigma \left( \omega ^Tx^{\left( i \right)}+b \right) \text{,}where\,\,\sigma \left( z^{\left( i \right)} \right) =\frac{1}{1+e^{-z^{\left( i \right)}}}\text{,}z^{\left( i \right)}=\omega ^Tx^{\left( i \right)}+b
Given{(x(1),y(1)),(x(2),y(2)),...,(x(m),y(m))}want  y(i)=y(i)Given\,\left\{ \left( x^{\left( 1 \right)},y^{\left( 1 \right)} \right) ,\left( x^{\left( 2 \right)},y^{\left( 2 \right)} \right) ,...,\left( x^{\left( m \right)},y^{\left( m \right)} \right) \right\} \text{,}want\,\,\overset{\land}{y}^{\left( i \right)}=y^{\left( i \right)}

損失函數又叫做誤差函數,用來衡量算法的運行情況,來衡量預測輸出值和實際值有多接近。一般我們用預測值和實際值的平方差的一半,但是在邏輯迴歸中,因爲當我們在學習邏輯迴歸參數的時候,會發現我們的優化目標不是凸優化,只能找到多個局部最優值,梯度下降法很可能找不到全局最優值。log=lnlog=ln

Loss(error)  functionL(y,y)=(ylogy+(1y)log(1y))Loss\left( error \right) \,\,function\text{:}\mathscr{L}\left( \overset{\land}{y},y \right) =-\left( y\log \overset{\land}{y}+\left( 1-y \right) \log \left( 1-\overset{\land}{y} \right) \right)

對於這個邏輯迴歸損失函數,我們也想讓它儘可能地小,爲了更好地理解這個損失函數怎麼起作用,我們舉兩個例子:

If  y=1:L(y,y)=logywant  logy  largewant  y  large(1)If\,\,y=\text{1:}\mathscr{L}\left( \overset{\land}{y},y \right) =-\log \overset{\land}{y}\longleftarrow want\,\,\log \overset{\land}{y}\,\,large\text{,}want\,\,\overset{\land}{y}\,\,large\left( 1 \right)
If  y=0:L(y,y)=log(1y)want  log(1y)  largewant  y  small(0)If\,\,y=\text{0:}\mathscr{L}\left( \overset{\land}{y},y \right) =-\log \left( 1-\overset{\land}{y} \right) \longleftarrow want\,\,\log \left( 1-\overset{\land}{y} \right) \,\,large\text{,}want\,\,\overset{\land}{y}\,\,small\left( 0 \right)

在這門課中有很多的函數效果和現在這個類似,就是如果yy等於1,我們就儘可能讓y\overset{\land}{y}變大,如果yy等於0,我們就儘可能讓y\overset{\land}{y}變小。

損失函數是在單個訓練樣本中定義的,它衡量的是算法在單個訓練樣本中的表現,爲了衡量算法在全部訓練樣本上的表現,我們需要定義一個算法的代價函數:
Cost  functionJ(ω,b)=1mi=1mL(y(i),y(i))=1mi=1m(y(i)logy(i)+(1y(i))log(1y(i)))Cost\,\,function\text{:}J\left( \omega ,b \right) =\frac{1}{m}\sum_{i=1}^m{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}=-\frac{1}{m}\sum_{i=1}^m{\left( y^{\left( i \right)}\log \overset{\land}{y}^{\left( i \right)}+\left( 1-y^{\left( i \right)} \right) \log \left( 1-\overset{\land}{y}^{\left( i \right)} \right) \right)}

在訓練邏輯迴歸模型時候,我們需要找到合適的ω\omegabb,來讓代價函數 JJ降到最低。邏輯迴歸可以看做是一個非常小的神經網絡。

梯度下降
Repeat{
     ω:=ωαJ(ω,b)ω\omega :=\omega -\alpha \frac{\partial J\left( \omega ,b \right)}{\partial \omega}

     b:=bαJ(ω,b)bb:=b-\alpha \frac{\partial J\left( \omega ,b \right)}{\partial b}
}
在代碼中使用dωd\omegadbdb表示J(ω,b)ω\frac{\partial J\left( \omega ,b \right)}{\partial \omega}J(ω,b)ω\frac{\partial J\left( \omega ,b \right)}{\partial \omega}.

僅有一個參數:

兩個參數:對於邏輯迴歸幾乎所有的初始化方法都有效,因爲函數J(ω,b)J\left( \omega ,b \right)是凸函數,無論在哪裏初始化,應該達到同一點或大致相同的點。朝最陡的下坡方向走一步,不斷地迭代,直到走到全局最優解或者接近全局最優解的地方。

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

從這個小例子中我們可以看出,通過一個從左向右的過程,你可以計算出JJ的值。爲了計算導數,從右到左(紅色箭頭,和藍色箭頭的過程相反)的過程是用於計算導數最自然的方式。

使用計算圖求導數(實質:鏈式法則)
dvdv是Python代碼裏的變量名,其真正的定義是dJdv\frac{dJ}{dv}。當計算所有這些導數時,最有效率的辦法是從右到左計算,跟着這個紅色箭頭走。

用到的公式:

Logistic迴歸的梯度下降法

da=dL(a,y)da=ya+1y1a“da”=\frac{d\mathscr{L}\left( a,y \right)}{da}=-\frac{y}{a}+\frac{1-y}{1-a}

dz=dL(a,y)dz=dLdadadz=(ya+1y1a)a(1a)=ay“dz”=\frac{d\mathscr{L}\left( a,y \right)}{dz}=\frac{d\mathscr{L}}{da}\frac{da}{dz}=\left( -\frac{y}{a}+\frac{1-y}{1-a} \right) \cdot a\left( 1-a \right) =a-y

dω1=Lω1=x1dzd\omega _1=\frac{\partial \mathscr{L}}{\partial \omega _1}=x_1dz

dω2=Lω2=x2dzd\omega _2=\frac{\partial \mathscr{L}}{\partial \omega _2}=x_2dz

dω1=Lb=dzd\omega _1=\frac{\partial \mathscr{L}}{\partial b}=dz

關於單個樣本的梯度下降算法,需要做如下的事情:
        使用公式dz=aydz=a-y計算dzdz, 使用dω1=x1dzd\omega_1=x_1dz計算dω1d\omega_1dω2=x2dzd\omega_2=x_2dz計算dω2d\omega_2db=dzdb=dz來計算dbdb, 然後:更新ω1=ω1αdω1\omega_1=\omega_1-\alpha d\omega_1, 更新ω2=ω2αdω2\omega_2=\omega_2-\alpha d\omega_2, 更新b=bαdbb=b-\alpha db。這就是關於單個樣本實例的梯度下降算法中參數更新一次的步驟。

m 個樣本的梯度下降
回顧公式:J(ω,b)=1mi=1mL(a(i),y(i))J\left( \omega ,b \right) =\frac{1}{m}\sum_{i=1}^m{\mathscr{L}\left( a^{\left( i \right)},y^{\left( i \right)} \right)}
a(i)=y(i)=σ(z(i))=σ(ωTx(i)+b)a^{\left( i \right)}=\overset{\land}{y}^{\left( i \right)}=\sigma \left( z^{\left( i \right)} \right) =\sigma \left( \omega ^Tx^{\left( i \right)}+b \right)
J(ω,b)ω1=1mi=1mL(a(i),y(i))ω1=1mi=1mdω1(i)\frac{\partial J\left( \omega ,b \right)}{\partial \omega _1}=\frac{1}{m}\sum_{i=1}^m{\frac{\partial \mathscr{L}\left( a^{\left( i \right)},y^{\left( i \right)} \right)}{\partial \omega _1}}=\frac{1}{m}\sum_{i=1}^m{d\omega _{1}^{\left( i \right)}}

代碼流程:(好好理解)

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);      #2個特徵,n=2
    dw2 += x2(i)dz(i);
    db += dz(i);
J /= m;
dw1 /= m;
dw2 /= m;
db /= m;
w=w-alpha*dw
b=b-alpha*db

應用此方法在邏輯迴歸上你需要編寫兩個for循環。第一個for循環是一個小循環遍歷mm個訓練樣本,第二個for循環是一個遍歷所有特徵的for循環。

向量化
向量化是非常基礎的去除代碼中for循環的藝術。在logistic迴歸中需要計算z=wTx+bz=w^Tx+bw,xRnxw,x\in\mathbb{R}^{n_x},非向量化方法計算wTxw^Tx

z=0
for i in range(n_x)
    z+=w[i]*x[i]
z+=b

向量化方法計算wTxw^Tx

z=np.dot(w,x)+b

Jupyter notebook的一個例子

import numpy as np #導入numpy庫
a = np.array([1,2,3,4]) #創建一個數據a
print(a)
# [1 2 3 4]
import time #導入時間庫
a = np.random.rand(1000000)
b = np.random.rand(1000000) #通過random隨機得到兩個一百萬維度的數組
tic = time.time() #現在測量一下當前時間
#向量化的版本
c = np.dot(a,b)
toc = time.time()
print(c)
print(“Vectorized version:+ str(1000*(toc-tic)) +”ms”) #打印一下向量化的版本的時間
#繼續增加非向量化的版本
c = 0
tic = time.time()
for i in range(1000000):
    c += a[i]*b[i]
toc = time.time()
print(c)
print(“For loop:+ str(1000*(toc-tic)) + “ms”)#打印for循環的版本的時間

運行結果:

你可能聽過很多類似如下的話,“大規模的深度學習使用了GPU或者圖像處理單元實現”,但是我做的所有的案例都是在jupyter notebook上面實現,這裏只有CPU,CPU和GPU都有並行化的指令,他們有時候會叫做SIMD指令,這個代表了一個單獨指令多維數據,這個的基礎意義是,如果你使用了built-in函數,像np.function或者並不要求你實現循環的函數,它可以讓python的充分利用並行化計算,在GPU和CPU計算中,GPU更加擅長SIMD計算,但是CPU事實上也不是太差,可能沒有GPU那麼擅長。

更多例子:
(1)計算向量u=Avu=Av,矩陣乘法定義爲:ui=j(Aijvi)u_i=\sum_j(A_{ij}v_i),非向量化方法:

u = np.zeros((n,1))
for i=...
	for j=...
		u[i] += A[i][j]*v[j]

向量化方法:u = np.dot(A,v)
(2)對向量元素進行運算v=[v1vn]u=[ev1evn]v=\left[ \begin{array}{c} v_1\\ \vdots\\ v_n\\ \end{array} \right] \rightarrow u=\left[ \begin{array}{c} e^{v_1}\\ \vdots\\ e^{v_n}\\ \end{array} \right]
非向量化方法:

u = np.zeros((n,1))
for i in range(n):
	u[i]=math.exp(v[i])

向量化方法:

import numpy as np
u = np.exp(v)

(3)u=np.log(v)計算對數函數,np.abs(v)計算數據的絕對值,np.maximum(v,0)求出向量vv中所有元素和00之間相比的最大值,v2v**2計算向量vv每個元素的平方。

(4)邏輯迴歸(未完善)

J=0;dw=np.zeros((n_x,1));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);
    dw += x(i)dz(i);
    db += dz(i);
J /= m;
dw /= m;
db /= m;
w=w-alpha*dw;
b=b-alpha*db;

向量化logistic迴歸
X=[x(1)  x(2)  ....x(m)]Rnx×mX=\left[ x^{\left( 1 \right)}\,\,x^{\left( 2 \right)}\,\,.... \,x^{\left( m \right)} \right] \in \mathbb{R}^{n_x\times m}

Z=[z(1)  z(2)  ....z(m)]=wTX+[b  b  ...b]=[wTx(1)+b   wTx(2)+b  ...wTx(m)+b]Z=\left[ z^{\left( 1 \right)}\,\,z^{\left( 2 \right)}\,\,.... \,z^{\left( m \right)} \right] =w^TX+\left[ b\,\,b\,\,... \,b \right] =\left[ w^Tx^{\left( 1 \right)}+b\, \,\,w^Tx^{\left( 2 \right)}+b\,\,... \,w^Tx^{\left( m \right)}+b \right],其中wTw^T爲行向量。

A=[a(1)  a(2)  ....a(m)]=σ(Z)A=\left[ a^{\left( 1 \right)}\,\,a^{\left( 2 \right)}\,\,.... \,a^{\left( m \right)} \right]=\sigma \left( Z \right)

一行代碼:Z = np.dot(w.T,X) + b

Python自動把這個實數bb擴展成一個1×m1\times m的行向量。所以這種情況下的操作似乎有點不可思議,它在Python中被稱作廣播(brosdcasting)。這就是在同一時間內你如何完成一個所有mm個訓練樣本的前向傳播向量化計算。

向量化logistic迴歸的梯度輸出
dZ=[dz(1)  dz(2)  ....dz(m)]dZ=\left[ dz^{\left( 1 \right)}\,\,dz^{\left( 2 \right)}\,\,.... \,dz^{\left( m \right)} \right]A=[a(1)  a(2)  ....a(m)]=σ(Z)A=\left[ a^{\left( 1 \right)}\,\,a^{\left( 2 \right)}\,\,.... \,a^{\left( m \right)} \right]=\sigma \left( Z \right)Y=[y(1)  y(2)  ....y(m)]Y=\left[ y^{\left( 1 \right)}\,\,y^{\left( 2 \right)}\,\,.... \,y^{\left( m \right)} \right]
dZ=AY=[a(1)y(1)  a(2)y(2)  ....a(m)y(m)]dZ=A-Y=\left[ a^{\left( 1 \right)}-y^{\left( 1 \right)}\,\,a^{\left( 2 \right)}-y^{\left( 2 \right)}\,\,.... \,a^{\left( m \right)}-y^{\left( m \right)} \right]

邏輯迴歸(強化版):

dw=np.zeros((n_x,1));
Z = np.dot(w.T,X)+b;
A = sigmoid(Z);
J = -np.sum(Y*np.log(A)+(1-Y)*np.log(1-A));  #自己寫的
dZ = A-Y;
dw = 1/m*X*dZ.T;
db = 1/m*np.sum(dZ);
w = w-alpha*dw;
b = b-alpha*db;

如果你希望多次迭代進行梯度下降,那麼仍然需要for循環,放在最外層。

Python中的廣播
例子:計算不同食物中不同營養成分中的卡路里百分比。

代碼如下:

import numpy as np
A = np.array([[56.0,0.0,4.4,68.0],
            [1.2,104.0,52.0,8.0],
            [1.8,135.0,99.0,0.9]])
print(A)
cal = A.sum(axis=0) #計算每列的和,axis=1計算每行的和
print(cal)
percentage = 100*A/cal.reshape(1,4) #調用了numpy的廣播機制,reshape對矩陣維度進行重塑
print(percentage) #3×4的矩陣A除以1×4的矩陣cal,自動將cal矩陣轉化爲3×4

運行結果:

更多例子:
[1234]+100=[101102103104]\left[ \begin{array}{c} 1\\ 2\\ 3\\ 4\\ \end{array} \right] +100=\left[ \begin{array}{c} 101\\ 102\\ 103\\ 104\\ \end{array} \right]

[123456]+[100200300]=[101202303104205306]\left[ \begin{array}{c} \begin{matrix} 1& 2& 3\\ \end{matrix}\\ \begin{matrix} 4& 5& 6\\ \end{matrix}\\ \end{array} \right] +\left[ \begin{matrix} 100& 200& 300\\ \end{matrix} \right] =\left[ \begin{array}{c} \begin{matrix} 101& 202& 303\\ \end{matrix}\\ \begin{matrix} 104& 205& 306\\ \end{matrix}\\ \end{array} \right]

[123456]+[100200]=[101102103204205206]\left[ \begin{array}{c} \begin{matrix} 1& 2& 3\\ \end{matrix}\\ \begin{matrix} 4& 5& 6\\ \end{matrix}\\ \end{array} \right] +\left[ \begin{array}{c} 100\\ 200\\ \end{array} \right] =\left[ \begin{array}{c} \begin{matrix} 101& 102& 103\\ \end{matrix}\\ \begin{matrix} 204& 205& 206\\ \end{matrix}\\ \end{array} \right]

廣播機制的一般原則如下:
(m,n)+/(1,n)(m,n)(m,n) +-*/ (1,n)\rightsquigarrow (m,n)
(m,n)+/(m,1)(m,n)(m,n) +-*/ (m,1)\rightsquigarrow (m,n)
(m,1)+/R(m,1)(m,1) +-*/ \mathbb{R}\rightsquigarrow (m,1)

numpy和Jupyter Notebook註記
例子代碼:

a = np.random.randn(5) #生成存儲在數組a中的5個高斯隨機數變量
print(a)               #編程練習或者在執行邏輯迴歸和神經網絡時,不需要使用這些一維數組
print(a.shape)         #a的shape(形狀)是一個(5,)的結構,是一個一維數組
print(a.T)             #轉置結果和a一樣
print(np.dot(a,a.T))   #a和a的轉置陣的內積輸出是一個數,而不是一個矩陣

a = np.random.randn(5,1) #將a置於5行1列向量中
print(a)                 #不要使用一維數組
print(a.shape)           #a的shape(形狀)是一個(5,1)的結構
print(a.T)               #轉置結果爲行向量
print(np.dot(a,a.T))     #a和a的轉置陣的外積輸出是一個矩陣

結果:

如果正在運行超負荷的進程,或者電腦運行了很長一段時間,或者在運行中出了錯,又或者網絡連接失敗,這裏依然有機會讓Kernel重新工作。只要點擊Kernel,選擇Restart,它會重新運行Kernel使程序繼續工作。

logistic損失函數的解釋
y=σ(wTx+b)where  σ(z)=11+ez\overset{\land}{y}=\sigma \left( w^Tx+b \right) \text{,}where\,\,\sigma \left( z \right) =\frac{1}{1+e^{-z}}
y=p(y=1|x)\overset{\land}{y}=p\left( y=\text{1|}x \right)   p\,\,p表示概率
我們討論的是二分類問題的損失函數,因此,yy的取值只能是0或者1
If  y=1:p(yx)=yIf  y=0:p(yx)=1y}p(yx)=yy(1y)(1y)\left. \begin{array}{r} If\,\,y=\text{1:}p\left( y|x \right) =\overset{\land}{y}\\ If\,\,y=\text{0:}p\left( y|x \right) =1-\overset{\land}{y}\\ \end{array} \right\} p\left( y|x \right) =\overset{\land}{y}^y\left( 1-\overset{\land}{y} \right) ^{\left( 1-y \right)}(分類討論即得)

logp(yx)=logyy(1y)(1y)=ylogy+(1y)log(1y)=L(y,y)\log p\left( y|x \right) =\log \overset{\land}{y}^y\left( 1-\overset{\land}{y} \right) ^{\left( 1-y \right)}=y\log \overset{\land}{y}+\left( 1-y \right) \log \left( 1-\overset{\land}{y} \right) =-\mathscr{L}\left( \overset{\land}{y},y \right)
最小化損失函數就是最大化logp(yx)\log p\left( y|x \right),前面有一個負號的原因是當你訓練學習算法時,需要算法輸出值的概率是最大的(以最大的概率預測這個值),然而在邏輯迴歸中我們需要最小化損失函數,因此最小化損失函數與最大化條件概率的對數logp(yx)\log p\left( y|x \right)關聯起來了,因此這就是單個訓練樣本的損失函數表達式。

考慮整個訓練集中標籤的概率,假設所有的訓練樣本獨立同分布,所有這些樣本的聯合概率就是每個樣本概率的乘積:
P(labels  in  training  set)=i=1mp(y(i)x(i))  (聯合概率)P\left( labels\,\,in\,\,training\,\,set \right) =\prod_{i=1}^m{p\left( y^{\left( i \right)}|x^{\left( i \right)} \right)}\,\, \left( \text{聯合概率} \right)
因爲所有的訓練樣本獨立同分布,做最大似然估計,需要尋找一組參數使得給定樣本的觀測值概率最大,但令這個概率最大化等價於令其對數最大化,在等式兩邊取對數:
logP(labels  in  training  set)=i=1mlogp(y(i)x(i))=i=1m[L(y(i),y(i))]=i=1mL(y(i),y(i))\log P\left( labels\,\,in\,\,training\,\,set \right) =\sum_{i=1}^m{\log p\left( y^{\left( i \right)}|x^{\left( i \right)} \right) }\\=\sum_{i=1}^m{\left[ -\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right) \right]}=-\sum_{i=1}^m{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}

也就是說使得這個式子i=1mL(y(i),y(i))-\sum_{i=1}^m{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}取最大值,由於訓練模型時,目標是讓成本函數最小化,所以我們不是直接用最大似然概率,要去掉這裏的負號,這樣我們就推導出了前面給出的logistic迴歸的成本函數:
CostminimizeJ(w,b)=1mi=1mL(y(i),y(i))\mathop{Cost}_{minimize}\text{:}J\left( w,b \right) =\frac{1}{m}\sum_{i=1}^m{\mathscr{L}\left( \overset{\land}{y}^{\left( i \right)},y^{\left( i \right)} \right)}

其中1m\frac{1}{m}是對成本函數進行適當縮放。

第三週:淺層神經網絡

神經網絡概覽
首先你需要輸入特徵xx,參數wwbb,通過這些可以計算出zz,接下來使用zz計算出aa最後可計算出loss  function  L(a,y)loss\,\,function\,\,\mathscr{L}(a,y).

xwb}z=wTx+by=a=σ(z)L(a,y)\left. \begin{array}{c} \begin{array}{r} x\\ w\\ b\\ \end{array}\\ \end{array} \right\} \Rightarrow z=w^Tx+b\Rightarrow \overset{\land}{y}=a=\sigma \left( z \right) \Rightarrow \mathscr{L}\left( a,y \right)

在這個神經網絡對應的3個節點,首先計算第一層網絡中的各個節點相關的數z[1]z^{\left[ 1 \right]},接着計算a[1]a^{\left[ 1 \right]},在計算下一層網絡同理。

使用符號[m]\,^{\left[ m \right]}表示第mm層網絡中節點相關的數,這些節點的集合被稱爲第m層網絡。

xW[1]b[1]}z[1]=W[1]x+b[1]a[1]=σ(z[1])\left. \begin{array}{c} \begin{array}{r} x\\ W^{\left[ 1 \right]}\\ b^{\left[ 1 \right]}\\ \end{array}\\ \end{array} \right\} \Rightarrow z^{\left[ 1 \right]}=W^{\left[ 1 \right]}x+b^{\left[ 1 \right]}\Rightarrow a^{\left[ 1 \right]}=\sigma \left( z^{\left[ 1 \right]} \right)

接下來需要使用另外一個線性方程對應的參數計算z[2]z^{\left[ 2 \right]},計算a[2]a^{\left[ 2 \right]},此時a[2]a^{\left[ 2 \right]}就是整個神經網絡最終的輸出,用y\overset{\land}{y}表示網絡的輸出。

a[1]=σ(z[1])W[2]b[2]}z[2]=W[2]a[1]+b[2]a[2]=σ(z[2])L(a[2],y)\left. \begin{array}{c} \begin{array}{r} a^{\left[ 1 \right]}=\sigma \left( z^{\left[ 1 \right]} \right)\\ W^{\left[ 2 \right]}\\ b^{\left[ 2 \right]}\\ \end{array}\\ \end{array} \right\} \Rightarrow z^{\left[ 2 \right]}=W^{\left[ 2 \right]}a^{\left[ 1 \right]}+b^{\left[ 2 \right]}\Rightarrow a^{\left[ 2 \right]}=\sigma \left( z^{\left[ 2 \right]} \right) \Rightarrow \mathscr{L}\left( a^{\left[ 2 \right]},y \right)

這個神經網絡中,我們反覆的計算zzaa,計算aazz,最後得到了最終的輸出loss  functionloss\,\,function. 基於邏輯迴歸重複使用了兩次該模型得到上述例子的神經網絡。

在神經網絡中我們也有從後向前的計算,最後會計算da[2]da^{\left[ 2 \right]}dz[2]dz^{\left[ 2 \right]},計算出來之後,然後計算dW[2]dW^{\left[ 2 \right]}db[2]db^{\left[ 2 \right]}等,按下面公式箭頭表示的那樣,從右到左反向計算。

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

神經網絡表示

  • 輸入層:包含了神經網絡的輸入;
  • 隱藏層:在訓練集中,這些中間結點的準確值我們是不知道到的,也就是說你看不見它們在訓練集中應具有的值;
  • 輸出層:負責產生預測值。

a[0]a^{\left[ 0 \right]}表示輸入特徵,aa表示激活的意思,它意味着網絡中不同層的值會傳遞到它們後面的層中,輸入層xx將傳遞給隱藏層,所以將輸入層的激活值稱爲a[0]a^{\left[ 0 \right]};下一層即隱藏層也會產生一些激活值,將其記作a[1]a^{\left[ 1 \right]}.

當我們計算網絡的層數時,輸入層是不算入總層數內,所以隱藏層是第一層,輸出層是第二層。

隱藏層有兩個相關的參數W[1]W^{\left[ 1 \right]}b[1]b^{\left[ 1 \right]},輸出層也有兩個相關的參數W[2]W^{\left[ 2 \right]}b[2]b^{\left[ 2 \right]}.

W[1]W^{\left[ 1 \right]}4×34\times 3,4表示4個節點,3表示3個特徵輸入,b[1]b^{\left[ 1 \right]}4×14\times1W[2]W^{\left[ 2 \right]}1×41\times4,1表示輸出層只有一個單元,4表示4個隱藏單元,b[2]b^{\left[ 2 \right]}1×11\times 1.

計算神經網絡的輸出
xx表示輸入特徵,aa表示每個神經元的輸出,WW表示特徵的權重,上標表示神經網絡的層數(隱藏層爲1),下標表示該層的第幾個神經元。這是神經網絡的符號慣例。

用圓圈表示神經網絡的計算單元,邏輯迴歸的計算有兩個步驟,首先按步驟計算出zz,然後在第二步中以sigmoidsigmoid函數爲激活函數計算zz(得出aa),一個神經網絡只是這樣子做了好多次重複計算。

[z1[1]z2[1]z3[1]z4[1]]=[w1[1]Tw2[1]Tw3[1]Tw4[1]T][x1x2x3]+[b1[1]b2[1]b3[1]b4[1]]\left[ \begin{array}{c} z_{1}^{\left[ 1 \right]}\\ z_{2}^{\left[ 1 \right]}\\ z_{3}^{\left[ 1 \right]}\\ z_{4}^{\left[ 1 \right]}\\ \end{array} \right] =\left[ \begin{array}{c} w_{1}^{\left[ 1 \right] T}\\ w_{2}^{\left[ 1 \right] T}\\ w_{3}^{\left[ 1 \right] T}\\ w_{4}^{\left[ 1 \right] T}\\ \end{array} \right] \left[ \begin{array}{c} x_1\\ x_2\\ x_3\\ \end{array} \right] +\left[ \begin{array}{c} b_{1}^{\left[ 1 \right]}\\ b_{2}^{\left[ 1 \right]}\\ b_{3}^{\left[ 1 \right]}\\ b_{4}^{\left[ 1 \right]}\\ \end{array} \right]

Z[1]=W[1](4,3)x+b[1](4,1)(m,n)Z^{\left[ 1 \right]}=W^{\left[ 1 \right]}\left( \text{4,}3 \right) x+b^{\left[ 1 \right]}\left( \text{4,}1 \right) \text{,}\left( m,n \right)表示維度。

對於W[1]W^{\left[ 1 \right]}\text{,}我們有四個邏輯迴歸單元,且每一個邏輯迴歸單元都有相對應的參數向量ww,把這四個向量堆積在一起,得出4×34\times 3的矩陣。

a[1]=[a1[1]a2[1]a3[1]a4[1]]=σ(z[1])a^{\left[ 1 \right]}=\left[ \begin{array}{c} a_{1}^{\left[ 1 \right]}\\ a_{2}^{\left[ 1 \right]}\\ a_{3}^{\left[ 1 \right]}\\ a_{4}^{\left[ 1 \right]}\\ \end{array} \right] =\sigma \left( z^{\left[ 1 \right]} \right)

把網絡左邊部分蓋住先忽略,那麼最後的輸出單元就相當於一個邏輯迴歸的計算單元。

Given input xx
z[1]=W[1]x+b[1](4,1)=(4,3)(3,1)+(4,1)z^{\left[ 1 \right]}=W^{\left[ 1 \right]}x+b^{\left[ 1 \right]}\text{,}\left( \text{4,}1 \right) =\left( \text{4,}3 \right) \left( \text{3,}1 \right) +\left( \text{4,}1 \right)

a[1]=σ(z[1])(4,1)=(4,1)a^{\left[ 1 \right]}=\sigma \left( z^{\left[ 1 \right]} \right) \text{,}\left( \text{4,}1 \right) =\left( \text{4,}1 \right)

z[2]=W[2]a[1]+b[2](1,1)=(1,4)(4,1)+(1,1)z^{\left[ 2 \right]}=W^{\left[ 2 \right]}a^{\left[ 1 \right]}+b^{\left[ 2 \right]}\text{,}\left( \text{1,}1 \right) =\left( \text{1,}4 \right) \left( \text{4,}1 \right) +\left( \text{1,}1 \right)

a[2]=σ(z[2])(1,1)=(1,1)a^{\left[ 2 \right]}=\sigma \left( z^{\left[ 2 \right]} \right) \text{,}\left( \text{1,}1 \right) =\left( \text{1,}1 \right)

多個例子的向量化
邏輯迴歸是將各個訓練樣本組合成矩陣,對矩陣的各列進行計算。神經網絡是通過對邏輯迴歸中的等式簡單的變形,讓神經網絡計算出輸出值。這種計算是所有的訓練樣本同時進行的。

m個訓練樣本
x(1)a[2](1)=y(1)x^{\left( 1 \right)}\rightarrow a^{\left[ 2 \right] \left( 1 \right)}=\overset{\land}{y}^{\left( 1 \right)}
x(2)a[2](2)=y(2)x^{\left( 2 \right)}\rightarrow a^{\left[ 2 \right] \left( 2 \right)}=\overset{\land}{y}^{\left( 2 \right)}
\cdots \cdots
x(m)a[2](m)=y(m)x^{\left( m \right)}\rightarrow a^{\left[ 2 \right] \left( m \right)}=\overset{\land}{y}^{\left( m \right)}

向量化多個訓練樣本
X=[x(1)  x(2)  ...x(m)]nx×mX=\left[ x^{\left( 1 \right)}\,\,x^{\left( 2 \right)}\,\,... x^{\left( m \right)} \right] _{n_x\times m}(縱向:對應不同的輸入特徵(輸入層的不同節點))

Z[1]=[z[1](1)  z[1](2)  ...z[1](m)]Z^{\left[ 1 \right]}=\left[ z^{\left[ 1 \right] \left( 1 \right)}\,\,z^{\left[ 1 \right] \left( 2 \right)}\,\,... z^{\left[ 1 \right] \left( m \right)} \right]

A[1]=[a[1](1)  a[1](2)  ...a[1](m)]  A^{\left[ 1 \right]}=\left[ a^{\left[ 1 \right] \left( 1 \right)}\,\,a^{\left[ 1 \right] \left( 2 \right)}\,\,... a^{\left[ 1 \right] \left( m \right)} \right] \,\,(橫向:對所有訓練樣本用指標排序。縱向:對應了神經網絡裏的不同節點隱藏單元的指標)。
同理Z[2]A[2]Z^{\left[ 2 \right]}\text{,}A^{\left[ 2 \right]}

{Z[1]=W[1]X+b[1]  (X=A[0],x=a[0],x(i)=a[0](i))A[1]=σ(Z[1])Z[2]=W[2]A[1]+b[2]A[2]=σ(Z[2])\begin{cases} Z^{\left[ 1 \right]}=W^{\left[ 1 \right]}X+b^{\left[ 1 \right]}\,\,\left( X=A^{\left[ 0 \right]}, x=a^{\left[ 0 \right]}, x^{\left( i \right)}=a^{\left[ 0 \right] \left( i \right)} \right)\\ A^{\left[ 1 \right]}=\sigma \left( Z^{\left[ 1 \right]} \right)\\ Z^{\left[ 2 \right]}=W^{\left[ 2 \right]}A^{\left[ 1 \right]}+b^{\left[ 2 \right]}\\ A^{\left[ 2 \right]}=\sigma \left( Z^{\left[ 2 \right]} \right)\\ \end{cases}

激活函數

(1)a=g(z)=tanh(z)=ezezez+eztanh\left( 1 \right) a=g\left( z \right) =\tanh \left( z \right) =\frac{e^z-e^{-z}}{e^z+e^{-z}}\text{,}tanh函數是sigmoidsigmoid的向下平移和伸縮後的結果。對它進行了變形後,穿過了點(0,0)\left( \text{0,}0 \right),並且值域介於+1和-1之間。在訓練一個算法模型時,如果使用tanhtanh函數代替sigmoidsigmoid函數中心化數據,使得數據的平均值更接近0而不是0.5.

對隱藏層使用g[1](z[1])=tanh(z[1])g^{\left[ 1 \right]}\left( z^{\left[ 1 \right]} \right) =tanh\left( z^{\left[ 1 \right]} \right)激活函數,輸出層(二分類)使用g[2](z[2])=σ(z[2])g^{\left[ 2 \right]}\left( z^{\left[ 2 \right]} \right) =\sigma \left( z^{\left[ 2 \right]} \right)函數。sigmoidsigmoid函數和tanhtanh函數兩者共同的缺點是,在z特別大或者特別小的情況下,導數的梯度或者函數的斜率會變得特別小,最後就會接近於0,這樣會拖慢梯度下降算法。

(2)ReLU\left( 2 \right) ReLU函數:a=max(0,z)a=\max \left( \text{0,}z \right)ReLUReLU沒有這種函數斜率接近0時減慢學習速度的效應,如果是二分類問題,則輸出層選擇sigmoidsigmoid函數,然後其它的所有單元都選擇ReLUReLU函數(快)。但ReLUReLU的一個缺點是:當是zz是負值的時候,導數等於0.

(3)Leaky  ReLU\left( 3 \right) Leaky\,\,ReLU函數:a=max(0.01z,z)a=\max \left( 0.01z,z \right),這個函數通常比ReLUReLU激活函數效果要好,儘管在實際中Leaky  ReLULeaky\,\,ReLU使用的並不多。

zzReLUReLU的梯度一半都是0,但是,有足夠的隱藏層使得zz值大於0,所以對大多數的訓練數據來說學習過程仍然可以很快。

  • sigmoidsigmoid激活函數:除了輸出層是一個二分類問題基本不會用它。
  • tanhtanh激活函數:tanhtanh是非常優秀的,幾乎適合所有場合。
  • ReLUReLU激活函數:最常用的默認函數,如果不確定用哪個激活函數,就使用ReLUReLU或者Leaky  ReLULeaky\,\,ReLU.

爲什麼需要非線性激活函數?
如果去掉激活函數(或用線性/恆等激活函數g(z)=zg\left( z \right) =z):

a[1]=z[1]=W[1]x+b[1]a^{\left[ 1 \right]}=z^{\left[ 1 \right]}=W^{\left[ 1 \right]}x+b^{\left[ 1 \right]}

a[2]=z[2]=W[2]a[1]+b[2]=W[2](W[1]x+b[1])+b[2]a^{\left[ 2 \right]}=z^{\left[ 2 \right]}=W^{\left[ 2 \right]}a^{\left[ 1 \right]}+b^{\left[ 2 \right]}=W^{\left[ 2 \right]}\left( W^{\left[ 1 \right]}x+b^{\left[ 1 \right]} \right) +b^{\left[ 2 \right]}
          =(W[2]W[1])x+(W[2]b[1]+b[2])=Wx+b\,\,\,\,\,\,\,\,\,\,=\left( W^{\left[ 2 \right]}W^{\left[ 1 \right]} \right) x+\left( W^{\left[ 2 \right]}b^{\left[ 1 \right]}+b^{\left[ 2 \right]} \right) =W'x+b'

神經網絡只是把輸入線性組合再輸出,如果你使用線性激活函數或者沒有使用一個激活函數,那麼無論你的神經網絡有多少層一直在做的只是計算線性函數,所以不如直接去掉全部隱藏層。

迴歸問題(如預測房價)可在輸出層使用線性激活函數,但隱藏單元不能使用線性激活函數,可以用tanh\tanhReLUReLULeaky  ReLULeaky\,\,ReLU等等。

激活函數的導數
(1)a=g(z)=11+ezg(z)=11+ez(111+ez)=a(1a)\left( 1 \right) a=g\left( z \right) =\frac{1}{1+e^{-z}}\text{,}g'\left( z \right) =\frac{1}{1+e^{-z}}\left( 1-\frac{1}{1+e^{-z}} \right) =a\left( 1-a \right)

(2)a=g(z)=tanh(z)=ezezez+ezg(z)=1a2\left( 2 \right) a=g\left( z \right) =\tanh \left( z \right) =\frac{e^z-e^{-z}}{e^z+e^{-z}}\text{,}g'\left( z \right) =1-a^2

(3)g(z)=max(0,z)g(z)={   ifz<0   ifz0(在0處設導數爲1)\left( 3 \right) g\left( z \right) =\max \left( \text{0,}z \right) \text{,}g'\left( z \right) =\begin{cases} \text{0 }\,\,\,if\,z<0\\ \text{1 }\,\,\,if\,z\geqslant 0\left( \text{在0處設導數爲}1 \right)\\ \end{cases}

(4)g(z)=max(0.01z,z)g(z)={0.01    if  z<0          if  z0\left( 4 \right) g\left( z \right) =\max \left( 0.01z,z \right) \text{,}g'\left( z \right) =\begin{cases} \text{0.01 }\,\,\,if\,\,z<0\\ \text{1 }\,\,\,\,\,\,\,\,\,\,if\,\,z\geqslant 0\\ \end{cases}

神經網絡的梯度下降法
單隱層神經網絡的參數:W[1](n[1],n[0]),b[1](n[1],1),W[2](n[2],n[1]),b[2](n[2],1)W^{\left[ 1 \right]}\left( n^{\left[ 1 \right]},n^{\left[ 0 \right]} \right) , b^{\left[ 1 \right]}\left( n^{\left[ 1 \right]},1 \right) , W^{\left[ 2 \right]}\left( n^{\left[ 2 \right]},n^{\left[ 1 \right]} \right) , b^{\left[ 2 \right]}\left( n^{\left[ 2 \right]},1 \right)

其中特徵nx=n[0]n_x=n^{\left[ 0 \right]},隱藏單元n[1]n^{\left[ 1 \right]},輸出單元n[2]=1n^{\left[ 2 \right]}=1

二分類問題的Cost function:J(W[1],b[1],W[2],b[2])=1mi=1mL(y,y)J\left( W^{\left[ 1 \right]},b^{\left[ 1 \right]},W^{\left[ 2 \right]},b^{\left[ 2 \right]} \right) =\frac{1}{m}\sum_{i=1}^m{\mathscr{L}\left( \overset{\land}{y},y \right)},其中 a[2]=ya^{\left[ 2 \right]}=\overset{\land}{y}.

Gradient descent:
Repeat{
                 \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,Compute predictions(y(i),i=1,...,m)\left( \overset{\land}{y}^{\left( i \right)}, i=\text{1,...,}m \right)
                 \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,dW[1]=JW[1]db[1]=Jb[1]dW[2]=JW[2]db[2]=Jb[2]dW^{\left[ 1 \right]}=\frac{\partial J}{\partial W^{\left[ 1 \right]}}\text{,}db^{\left[ 1 \right]}=\frac{\partial J}{\partial b^{\left[ 1 \right]}}\text{,}dW^{\left[ 2 \right]}=\frac{\partial J}{\partial W^{\left[ 2 \right]}}\text{,}db^{\left[ 2 \right]}=\frac{\partial J}{\partial b^{\left[ 2 \right]}}
                 \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,W[1]:=W[1]αdW[1]W^{\left[ 1 \right]}:=W^{\left[ 1 \right]}-\alpha dW^{\left[ 1 \right]}
                 \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,b[1]:=b[1]αdb[1]b^{\left[ 1 \right]}:=b^{\left[ 1 \right]}-\alpha db^{\left[ 1 \right]}
                 \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,W[2]:=W[2]αdW[2]W^{\left[ 2 \right]}:=W^{\left[ 2 \right]}-\alpha dW^{\left[ 2 \right]}
                 \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,b[2]:=b[2]αdb[2]b^{\left[ 2 \right]}:=b^{\left[ 2 \right]}-\alpha db^{\left[ 2 \right]}
                 \,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,}重複這些步驟很多次,直到參數看起來收斂。

Forward propagation:4個方程
{Z[1]=W[1]X+b[1]  A[1]=σ(Z[1])Z[2]=W[2]A[1]+b[2]A[2]=σ(Z[2])\begin{cases} Z^{\left[ 1 \right]}=W^{\left[ 1 \right]}X+b^{\left[ 1 \right]}\,\,\\ A^{\left[ 1 \right]}=\sigma \left( Z^{\left[ 1 \right]} \right)\\ Z^{\left[ 2 \right]}=W^{\left[ 2 \right]}A^{\left[ 1 \right]}+b^{\left[ 2 \right]}\\ A^{\left[ 2 \right]}=\sigma \left( Z^{\left[ 2 \right]} \right)\\ \end{cases}

Back propagation:6個方程
{dZ[2]=A[2]YdW[2]=1mdZ[2]A[1]Tdb[2]=1mnp.sum(dZ[2],axis=1, keepdims=True)dZ[1]=W[2]TdZ[2]g[1](z[1])dW[1]=1mdZ[1]XTdb[2]=1mnp.sum(dZ[1],axis=1, keepdims=True)\begin{cases} dZ^{\left[ 2 \right]}=A^{\left[ 2 \right]}-Y\\ dW^{\left[ 2 \right]}=\frac{1}{m}dZ^{\left[ 2 \right]}A^{\left[ 1 \right] T}\\ db^{\left[ 2 \right]}=\frac{1}{m}np.sum\left( dZ^{\left[ 2 \right]}, axis=\text{1, }keepdims=True \right)\\ dZ^{\left[ 1 \right]}=W^{\left[ 2 \right] T}dZ^{\left[ 2 \right]}\ast g^{\left[ 1 \right] }{'}\left( z^{\left[ 1 \right]} \right)\\ dW^{\left[ 1 \right]}=\frac{1}{m}dZ^{\left[ 1 \right]}X^T\\ db^{\left[ 2 \right]}=\frac{1}{m}np.sum\left( dZ^{\left[ 1 \right]}, axis=\text{1, }keepdims=True \right)\\ \end{cases}

註記:Y=[y(1)  y(2)  ...y(m)]Y=\left[ y^{\left( 1 \right)}\,\,y^{\left( 2 \right)}\,\,... y^{\left( m \right)} \right],axis=1表示水平相加求和,keepdims=True防止python直接輸出秩爲1的數組,確保輸出的是矩陣,db[2]db^{\left[ 2 \right]}維度爲n[2]×1n^{\left[ 2 \right]}\times 1\ast表示逐個元素乘積,W[2]TdZ[2]W^{\left[ 2 \right] T}dZ^{\left[ 2 \right]}g[1](z[1])g^{\left[ 1 \right]}{'}(z^{\left[ 1 \right]})的維度均爲n[1]×mn^{\left[ 1 \right]}\times mdb[1]db^{\left[ 1 \right]}維度爲n[1]×1n^{\left[ 1 \right]}\times 1.

直觀理解反向傳播
邏輯迴歸的推導
xwb}z=wTx+ba=g(z)=σ(z)L(a,y)\left. \begin{array}{r} x\\ w\\ b\\ \end{array} \right\} \Rightarrow z=w^Tx+b\Rightarrow a=g\left( z \right) =\sigma \left( z \right) \Rightarrow \mathscr{L}\left( a,y \right)

xwb}dw=dzx,db=dzz=wTx+bdz=Lz=Ladadz=dag(z)=aya=g(z)=σ(z)L(a,y)da=dLda=ya+1y1a\underset{dw=dz\cdot x,db=dz}{\underbrace{\left. \begin{array}{r} x\\ w\\ b\\ \end{array} \right\} }}\Leftarrow \underset{dz=\frac{\partial \mathscr{L}}{\partial z}=\frac{\partial \mathscr{L}}{\partial a}\cdot \frac{da}{dz}=da\cdot g'\left( z \right) =a-y}{\underbrace{z=w^Tx+b}}\Leftarrow \underset{da=\frac{d\mathscr{L}}{da}=-\frac{y}{a}+\frac{1-y}{1-a}}{\underbrace{a=g\left( z \right) =\sigma \left( z \right) \Leftarrow \mathscr{L}\left( a,y \right) }}

這裏的ww爲列向量。

單個訓練樣本推導過程如下:

多個訓練樣本向量化推導過程如下:

\\

隨機初始化
當你訓練神經網絡時,權重隨機初始化是很重要的。對於邏輯迴歸,把權重初始化爲0當然也是可以的。但是對於一個神經網絡,如果你把權重或者參數都初始化爲0,那麼梯度下降將不會起作用。

假設初始化:W[1]=[0000]W^{\left[ 1 \right]}=\left[ \begin{matrix} 0& 0\\ 0& 0\\ \end{matrix} \right]b[1]=[00]b^{\left[ 1 \right]}=\left[ \begin{array}{c} 0\\ 0\\ \end{array} \right],根據z=Wx+bz=Wx+b可知

a1[1]=a2[1]a_{1}^{\left[ 1 \right]}=a_{2}^{\left[ 1 \right]},因爲這兩個隱藏單元都在做完全一樣的計算,且dz1[1]=dz2[1]dz_{1}^{\left[ 1 \right]}=dz_{2}^{\left[ 1 \right]}.

假設W[2]=[00]W^{\left[ 2 \right]}=\left[ \begin{matrix} 0& 0\\ \end{matrix} \right],則兩個隱藏單元完全一樣,稱爲完全對稱,節點計算完全一樣的函數

由歸納法可知,每次訓練迭代後,2個隱藏單元仍在計算完全相同的函數,因爲很大一部分網絡記憶dW=[uvuv]dW=\left[ \begin{matrix} u& v\\ u& v\\ \end{matrix} \right],則W[1]=W[1]αW^{\left[ 1 \right]}=W^{\left[ 1 \right]}-\alpha dWW[1]=[]dW\text{,}W^{\left[ 1 \right]}=\left[ \begin{array}{c} \cdots\\ \cdots\\ \end{array} \right]第一行和第二行完全一樣,所以在這種情況下,多個隱藏單元沒有意義。

  • W[1]=np.random.randn((2,2))0.01W^{\left[ 1 \right]}=np.random.randn\left( \left( \text{2,}2 \right)\right) \ast 0.01
  • b[1]=np.zeros((2,1))b^{\left[ 1 \right]}=np.zeros\left( \left( \text{2,}1 \right) \right)
  • W[2]=np.random.randn((1,2))0.01W^{\left[ 2 \right]}=np.random.randn\left( \left( \text{1,}2 \right)\right) \ast 0.01
  • b[2]=0b^{\left[ 2 \right]}=0

其中0.01解釋:若W[1]W^{\left[ 1 \right]}很大則z[1]z^{\left[ 1 \right]}很大或很小,導致tanh\tanhsigmoidsigmoid接近飽和,從而減慢學習速度。

當訓練一個非常非常深的神經網絡,可能要試試0.01以外的常數。

第四周:深層神經網絡

深層神經網絡

儘管對於任何給定的問題很難去提前預測到底需要多深的神經網絡,所以先去嘗試邏輯迴歸,嘗試一層然後兩層隱含層,然後把隱含層的數量看做是另一個可以自由選擇大小的超參數,然後再保留交叉驗證數據上評估,或者用開發集來評估。

layer  NN\text{4 }layer\,\,NN 符號說明:
L=4(#layers)n[l]=#units  in  layer  lL=4\left( \#layers \right) \text{,}n^{\left[ l \right]}=\#units\,\,in\,\,layer\,\,l

n[0]=nx=3,n[1]=5=n[2]n[3]=3,n[4]=1n^{\left[ 0 \right]}=n_x=\text{3,}n^{\left[ 1 \right]}=5=n^{\left[ 2 \right]}\text{,}n^{\left[ 3 \right]}=\text{3,}n^{\left[ 4 \right]}=1

a[l]=activations  in  layer  l.a[l]=g[l](z[l])a^{\left[ l \right]}=activations\,\,in\,\,layer\,\,l. a^{\left[ l \right]}=g^{\left[ l \right]}\left( z^{\left[ l \right]} \right)

W[l]=weights  for  computing  z[l]  in  the  a[l]W^{\left[ l \right]}=weights\,\,for\,\,computing\,\,z^{\left[ l \right]}\,\,in\,\,the\,\,a^{\left[ l \right]}

b[l]  is  used  to  compute  z[l]b^{\left[ l \right]}\,\,is\,\,used\,\,to\,\,compute\,\,z^{\left[ l \right]}

x=a[0]y=a[l]x=a^{\left[ 0 \right]}\text{,}\overset{\land}{y}=a^{\left[ l \right]}

前向和反向傳播
Forward  propagation  for  layer  lForward\,\,propagation\,\,for\,\,layer\,\,l
Input  a[l1]Input\,\,a^{\left[ l-1 \right]}
Output  a[l]cache(z[l])W[l],b[l]Output\,\,a^{\left[ l \right]}\text{,}cache\left( z^{\left[ l \right]} \right) \gets W^{\left[ l \right]},b^{\left[ l \right]}
從實現的角度來說我們可以緩存下W[l]W^{\left[ l \right]}b[l]b^{\left[ l \right]},這樣更容易在不同的環節中調用函數。
{z[l]=W[l]a[l1]+b[l]a[l]=g[l](z[l])\begin{cases} z^{\left[ l \right]}=W^{\left[ l \right]}\cdot a^{\left[ l-1 \right]}+b^{\left[ l \right]}\\ a^{\left[ l \right]}=g^{\left[ l \right]}\left( z^{\left[ l \right]} \right)\\ \end{cases}

向量化
{Z[l]=W[l]A[l1]+b[l]A[l]=g[l](Z[l])\begin{cases} Z^{\left[ l \right]}=W^{\left[ l \right]}A^{\left[ l-1 \right]}+b^{\left[ l \right]}\\ A^{\left[ l \right]}=g^{\left[ l \right]}\left( Z^{\left[ l \right]} \right)\\ \end{cases}

Backward  propagation  for  layer  lBackward\,\,propagation\,\,for\,\,layer\,\,l
Input  da[l]Input\,\,da^{\left[ l \right]}
Output  da[l1]dW[l]db[l]Output\,\,da^{\left[ l-1 \right]}\text{,}dW^{\left[ l \right]}\text{,}db^{\left[ l \right]}

{dz[l]=da[l]g[l](z[l])dW[l]=dz[l]a[l1]Tdb[l]=dz[l]da[l1]=W[l]Tdz[l]\begin{cases} dz^{\left[ l \right]}=da^{\left[ l \right]}\ast g^{\left[ l \right]}{'}\left( z^{\left[ l \right]} \right)\\ dW^{\left[ l \right]}=dz^{\left[ l \right]}\cdot a^{\left[ l-1 \right] T}\\ db^{\left[ l \right]}=dz^{\left[ l \right]}\\ da^{\left[ l-1 \right]}=W^{\left[ l \right] T}\cdot dz^{\left[ l \right]}\\ \end{cases}

dz[l]=W[l+1]Tdz[l+1]g[l](z[l])\therefore dz^{\left[ l \right]}=W^{\left[ l+1 \right] T}dz^{\left[ l+1 \right]}\ast g^{\left[ l \right]}{'}\left( z^{\left[ l \right]} \right)

向量化
{dZ[l]=dA[l]g[l](Z[l])dW[l]=1mdZ[l]A[l1]Tdb[l]=1mnp.sum(dZ[l],axis=1, keepdims=True)dA[l1]=W[l]TdZ[l]\begin{cases} dZ^{\left[ l \right]}=dA^{\left[ l \right]}\ast g^{\left[ l \right]}{'}\left( Z^{\left[ l \right]} \right)\\ dW^{\left[ l \right]}=\frac{1}{m}dZ^{\left[ l \right]}\cdot A^{\left[ l-1 \right] T}\\ db^{\left[ l \right]}=\frac{1}{m}np.sum\left( dZ^{\left[ l \right]}, axis=\text{1, }keepdims=True \right)\\ dA^{\left[ l-1 \right]}=W^{\left[ l \right] T}\cdot dZ^{\left[ l \right]}\\ \end{cases}

編程實現更好理解公式!

深層網絡中的前向傳播

z[1]=W[1]a[0]+b[1]a[1]=g[1](z[1])\begin{array}{l} z^{\left[ 1 \right]}=W^{\left[ 1 \right]}\cdot a^{\left[ 0 \right]}+b^{\left[ 1 \right]}\\ a^{\left[ 1 \right]}=g^{\left[ 1 \right]}\left( z^{\left[ 1 \right]} \right)\\ \end{array}
z[2]=W[2]a[1]+b[2]a[2]=g[2](z[2])\begin{array}{l} z^{\left[ 2 \right]}=W^{\left[ 2 \right]}\cdot a^{\left[ 1 \right]}+b^{\left[ 2 \right]}\\ a^{\left[ 2 \right]}=g^{\left[ 2 \right]}\left( z^{\left[ 2 \right]} \right)\\ \end{array}
\cdots \cdots
z[4]=W[4]a[3]+b[4]a[4]=g[4](z[4])\begin{array}{l} z^{\left[ 4 \right]}=W^{\left[ 4 \right]}\cdot a^{\left[ 3 \right]}+b^{\left[ 4 \right]}\\ a^{\left[ 4 \right]}=g^{\left[ 4 \right]}\left( z^{\left[ 4 \right]} \right)\\ \end{array}

向量化
Z[1]=W[1]A[0]+b[1]A[1]=g[1](Z[1])\begin{array}{l} Z^{\left[ 1 \right]}=W^{\left[ 1 \right]}\cdot A^{\left[ 0 \right]}+b^{\left[ 1 \right]}\\ A^{\left[ 1 \right]}=g^{\left[ 1 \right]}\left( Z^{\left[ 1 \right]} \right)\\ \end{array}
Z[2]=W[2]A[1]+b[2]A[2]=g[2](Z[2])\begin{array}{l} Z^{\left[ 2 \right]}=W^{\left[ 2 \right]}\cdot A^{\left[ 1 \right]}+b^{\left[ 2 \right]}\\ A^{\left[ 2 \right]}=g^{\left[ 2 \right]}\left( Z^{\left[ 2 \right]} \right)\\ \end{array}
\cdots \cdots
Y=A[4]=g[4](Z[4])\overset{\land}{Y}=A^{\left[ 4 \right]}=g^{\left[ 4 \right]}\left( Z^{\left[ 4 \right]} \right)

這裏只能用一個顯式for循環,ll從1到LL,然後一層接着一層去計算

覈對矩陣的維數
當實現深度神經網絡的時候,其中一個我常用的檢查代碼是否有錯的方法就是拿出一張紙過一遍算法中矩陣的維數。

L=5L=5
n[0]=nx=2,n[1]=3,n[2]=5,n[3]=4,n[4]=2,n[5]=1n^{\left[ 0 \right]}=n_x=\text{2,}n^{\left[ 1 \right]}=\text{3,}n^{\left[ 2 \right]}=\text{5,}n^{\left[ 3 \right]}=\text{4,}n^{\left[ 4 \right]}=\text{2,}n^{\left[ 5 \right]}=1

z[1]=W[1]a[0]+b[1](n[1]=3,1)=(n[1]=3,n[0]=2)(n[0]=2,1)+(n[1]=3,1)z^{\left[ 1 \right]}=W^{\left[ 1 \right]}\cdot a^{\left[ 0 \right]}+b^{\left[ 1 \right]}\text{,}\left( n^{\left[ 1 \right]}=\text{3,}1 \right) =\left( n^{\left[ 1 \right]}=\text{3,}n^{\left[ 0 \right]}=2 \right) \left( n^{\left[ 0 \right]}=\text{2,}1 \right) +\left( n^{\left[ 1 \right]}=\text{3,}1 \right)

z[2]=W[2]a[1]+b[2](5,1)=(5,3)(3,1)+(n[2]=5,1)z^{\left[ 2 \right]}=W^{\left[ 2 \right]}\cdot a^{\left[ 1 \right]}+b^{\left[ 2 \right]}\text{,}\left( \text{5,}1 \right) =\left( \text{5,}3 \right) \left( \text{3,}1 \right) +\left( n^{\left[ 2 \right]}=\text{5,}1 \right)

{W[l],dW[l](n[l],n[l1])z[l],a[l],b[l],db[l](n[l],1)\begin{cases} W^{\left[ l \right]}, dW^{\left[ l \right]}\text{:}\left( n^{\left[ l \right]},n^{\left[ l-1 \right]} \right)\\ z^{\left[ l \right]}, a^{\left[ l \right]}, b^{\left[ l \right]}, db^{\left[ l \right]}\text{:}\left( n^{\left[ l \right]},1 \right)\\ \end{cases}

向量化
Z[1]=W[1]A[0]+b[1](n[1],m)=(n[1],n[0])(n[0],m)+(n[1],1)(n[1],m)Z^{\left[ 1 \right]}=W^{\left[ 1 \right]}\cdot A^{\left[ 0 \right]}+b^{\left[ 1 \right]}\text{,}\left( n^{\left[ 1 \right]},m \right) =\left( n^{\left[ 1 \right]},n^{\left[ 0 \right]} \right) \left( n^{\left[ 0 \right]},m \right) +\left( n^{\left[ 1 \right]},1 \right) \rightsquigarrow \left( n^{\left[ 1 \right]},m \right)

Z[l],dZ[l],A[l],dA[l](n[l],m)Z^{\left[ l \right]}, dZ^{\left[ l \right]}, A^{\left[ l \right]}, dA^{\left[ l \right]}\text{:}\left( n^{\left[ l \right]},m \right)

爲什麼使用深層表示?

例1 人臉識別或是人臉檢測系統
第一層:特徵探測器或邊緣探測器,看圖,然後去找這張照片的各個邊緣。

建一個大概有20個隱藏單元的深度神經網絡,隱藏單元就是這些圖裏這些小方塊。

比如,這個小方塊(第一行第一列)就是一個隱藏單元,它會去找這張照片裏“|”邊緣的方向。隱藏單元(第4行第5列),可能是在找“—”水平向的邊緣在哪裏。

第二層:把照片裏組成邊緣的像素們放在一起看,然後它可以把被探測到的邊緣組合成面部的不同部分。

比如說,可能有一個神經元會去找眼睛的部分,另外還有別的在找鼻子的部分,然後把這許多的邊緣結合在一起,就可以開始檢測人臉的不同部分。

第三層:最後再把這些部分放在一起,比如鼻子眼睛下巴,就可以識別或是探測不同的人臉。

邊緣探測器針對照片中非常小塊的面積;面部探測器就會針對於大一些的區域

這種從簡單到複雜的金字塔狀表示方法或者組成方法,也可以應用在圖像或者人臉識別以外的其他數據上。

例2 語音識別系統
輸入一個音頻片段\rightarrow探測比較低層次的音頻波形的一些特徵\rightarrow探測聲音的基本單元(音位)\rightarrow識別音頻當中的單詞\rightarrow詞組/句子。

深層的網絡隱藏單元數量相對較少,隱藏層數目較多,如果淺層的網絡想要達到同樣的計算結果則需要指數級增長的隱藏單元數量才能達到。

假設想要對輸入特徵計算異或或是奇偶性,可以算x1XORx2XORx3XORxnx_1XORx_2XORx_3\cdots XORx_n,設有nn或者nxn_x個特徵,如果畫一個異或的樹圖,先要計算x1,x2x_1,x_2的異或,然後是x3x_3x4x_4. 技術上來說如果只用或門,還有非門的話,可能會需要幾層才能計算異或函數,但是用相對小的電路,應該就可以計算異或了。然後可以繼續建這樣的一個異或樹圖(上圖左),那麼最後會得到這樣的電路來輸出結果y,也就是輸入特徵的異或,或是奇偶性,要計算異或關係。這種樹圖對應網絡的深度應該是O(logn)O\left( \log n \right),那麼節點的數量和電路部件,或是門的數量並不會很大,也不需要太多門去計算異或。

但是如果只能用單隱藏層來計算的話,這裏全部都指向從這些隱藏單元到後面這裏,再輸出yy,那麼要計算奇偶性,或者異或關係函數就需要這一隱層(上圖右方框部分)的單元數呈指數增長才行,因爲本質上來說需要列舉耗盡2n2^n種可能的配置,或是2n2^n種輸入比特的配置。異或運算的最終結果是1或0,那麼最終就會需要一個隱藏層,其中單元數目隨輸入比特指數上升。精確的說應該是2n12^{n-1}個隱藏單元數,也就是O(2n)O\left( 2^n \right).

這個結果人們還是經常提到的,用來解釋爲什麼需要更深層的網絡。

搭建深層神經網絡塊
基本上是前面講過的內容

Forward  and  backward  functionsForward\,\,and\,\,backward\,\,functions

WW會在每一層被更新爲W=WαdWW=W-\alpha dWbb也一樣,b=bαdbb=b-\alpha db.

參數VS超參數
Hyperparameters:
learning  rate  α,#iterations,#hidden  layers  L,#hidden  units  n[1],n[2],choice  of  activation  functionlearning\,\,rate\,\,\alpha \text{,\#}iterations\text{,\#}hidden\,\,layers\,\,L\text{,\#}hidden\,\,units\,\,n^{\left[ 1 \right]},n^{\left[ 2 \right]},\cdots \text{,}choice\,\,of\,\,activation\,\,function
都控制了最後的參數W和b的值。

如何尋找超參數的最優值?走Idea—Code—Experiment—Idea這個循環,嘗試各種不同的參數,實現模型並觀察是否成功,然後再迭代。

在下個課程我們會用系統性的方法去嘗試各種超參數的取值。有一條經驗規律:經常試試不同的超參數,勤於檢查結果,看看有沒有更好的超參數取值,你將會得到設定超參數的直覺。

這和大腦有什麼關係?
一個神經網絡的邏輯單元可以看成是對一個生物神經元的過度簡化,但迄今爲止連神經科學家都很難解釋究竟一個神經元能做什麼,它可能是極其複雜的;它的一些功能可能真的類似logistic迴歸的運算,但單個神經元到底在做什麼目前還沒有人能夠真正可以解釋。

但這個類比還是很粗略的,這是一個logistic迴歸單元的sigmoid激活函數,這裏是一個大腦中的神經元,圖中這個生物神經元,也是你大腦中的一個細胞,它能接受來自其他神經元的電信號,比如x1,x2,x3x_1,x_2,x_3,或可能來自於其他神經元a1,a2,a3a_1,a_2,a_3. 其中有一個簡單的臨界計算值,如果這個神經元突然激發了,它會讓電脈衝沿着這條長長的軸突,或者說一條導線傳到另一個神經元。

神經網絡和深度學習編程作業

  • 具有神經網絡思維的Logistic迴歸
  • 帶有一個隱藏層的平面數據分類
  • 一步步搭建多層神經網絡以及應用(1 & 2)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章