此專欄文章隨時更新編輯,如果你看到的文章還沒寫完,那麼多半是作者正在更新或者上一次沒有更新完,請耐心等待,正常的頻率是每天更新一篇文章。
此文章主要是吳恩達在Cursera上的系列課程“深度學習(DeepLearning)”的學習筆記,這一篇是關於第三週測試題的筆記,首發於知乎的專欄“深度學習+自然語言處理(NLP)”。
該系列文章的目的在於理清深度學習進的一些基本概念。
以下是正文:
====================================================================
先放出文章結構:
先看看我們要處理的資料
搭建神經網路模型
首先定義神經網路的結構
前向傳播
後向傳播
最佳化引數
整合模型
預測
====================================================================
1。先看看我們要處理的資料
本週作業的題目是:Planar data classification with one hidden layer,也就是用一層隱藏層的神經網路解決Planar data的分類問題。
什麼是Planar data?Planar data 來自於planar_utils這個庫,為了讀入這個資料我們需要先引用該庫:
from
planar_utils
import
load_planar_dataset
load_planar_dataset就是用來讀入資料的函式:
X, Y = load_planar_dataset()
為了更加直觀,我們畫出函式影象:
看起來像是“鮮花形狀的資料”。
這是個二分類問題,也就是說圖中有兩類資料(紅色和藍色)。
我們的目的就是如何搭建很好的模型分類該資料。
我們先嚐試用傳統的邏輯迴歸演算法解決該問題,這裡忽略過程,直接看結果如下圖:
很明顯,簡單的用一條線分類,無法解決該問題!
2。 搭建神經網路模型
先看一下我們要搭建的模型結構:
這張圖描述的是當輸入一組資料時,輸入層有兩個變數,隱藏層有4個‘神經元’,輸出層採用的是sigmoid函式,最後得到一個機率,如果該機率<0。5,我們就預測該組資料的輸出類別是0,反之是1。
為什麼輸入變數是2,因為輸入資料的特徵值有兩個:
shape_X
=
X
。
shape
(
‘The shape of X is: ’
+
str
(
shape_X
))
# The shape of X is: (2, 400)
為什麼隱藏層神經元的數量是4,因為這是我們自己設定的,簡單來說,神經元越多演算法的效能越好,直到過擬合。
2。1 首先定義神經網路的結構
如果我們用n_x, n_h, n_y分別代表輸入層、隱藏層、輸出層的大小。
顯然,根據我們第一部分講的內容,這些引數是由資料X和Y決定的。
n_x
=
X
。
shape
[
0
]
# size of input layer
n_h
=
4
n_y
=
Y
。
shape
[
0
]
# size of output layer
這裡應該定義一個函式layer_sizes(X, Y),輸出是n_x, n_h, n_y,但是為了專注於講解程式碼思路,縮短篇幅,這裡全部省略了,想看完整程式碼可以點選文章最後的連結。
2。2 初始化模型引數
模型引數也就是我們的引數W1,b1,W2,b2。
這裡涉及到的問題就是,如何確定引數的維度,這裡的技巧是,每一層的W引數的行數是下一層的維度,列數是上一層的維度。b引數的行數是下一層的維度,列數是1。
以上圖舉例說明:對於引數W1來說,上一層是輸入層,維度是2,下一層是隱藏層,維度是4,所以W1的維度是4x2,b1的維度是4x1。
給出程式碼:
W1
=
np
。
random
。
randn
(
n_h
,
n_x
)
*
0。01
b1
=
np
。
zeros
((
n_h
,
1
))
W2
=
np
。
random
。
randn
(
n_y
,
n_h
)
*
0。01
b2
=
np
。
zeros
((
n_y
,
1
))
2。2 前向傳播
前向傳播在python中的實現,就是將上一層的輸出作為本層的輸入,然後代入公式計算,得到本層的輸出,再輸如給下一層。
先給出每一層的公式:
python程式碼實現:
Z1
=
np
。
dot
(
W1
,
X
)
+
b1
A1
=
np
。
tanh
(
Z1
)
Z2
=
np
。
dot
(
W2
,
A1
)
+
b2
A2
=
sigmoid
(
Z2
)
然後,計算代價,代價函式公式如下:
python實現:
logprobs
=
np
。
multiply
(
np
。
log
(
A2
),
Y
)
+
np
。
multiply
(
np
。
log
(
1
-
A2
),
1
-
Y
)
cost
=
-
(
1
/
m
)
*
np
。
sum
(
logprobs
)
cost
=
np
。
squeeze
(
cost
)
# makes sure cost is the dimension we expect。
# E。g。, turns [[17]] into 17
2。3 後向傳播
後向傳播的目的就是為了最佳化引數。
怎麼最佳化呢?
首先,透過代價函式對引數求導得到每一個引數的梯度dW1,db1,dW2,db2
然後最佳化引數:
,這裡的
代表我們模型的引數。
先給出後向傳播的公式:
python實現:
dZ2
=
A2
-
Y
dW2
=
(
1
/
m
)
*
np
。
dot
(
dZ2
,
A1
。
T
)
db2
=
(
1
/
m
)
*
np
。
sum
(
dZ2
,
axis
=
1
,
keepdims
=
True
)
dZ1
=
np
。
dot
(
W2
。
T
,
dZ2
)
*
(
1
-
np
。
power
(
A1
,
2
))
dW1
=
(
1
/
m
)
*
np
。
dot
(
dZ1
,
X
。
T
)
db1
=
(
1
/
m
)
*
np
。
sum
(
dZ1
,
axis
=
1
,
keepdims
=
True
)
2。4 最佳化引數
最後一步,最佳化引數。
公式在2。3節已經給出:
,這裡的
代表我們模型的引數,
代表學習率,是我們自己定義的引數大小。
python實現比較簡單:
W1
=
W1
-
learning_rate
*
dW1
b1
=
b1
-
learning_rate
*
db1
W2
=
W2
-
learning_rate
*
dW2
b2
=
b2
-
learning_rate
*
db2
至此,已經完成了主要的工作,一個完整的神經網路已經搭建完成。
但是還有一個問題,迭代!
如果我們只最佳化一次引數是遠遠不夠的,我們需要進行大量的迭代,也就是不斷的完成“前向傳播->後向傳播->最佳化引數”的過程。
這就需要進行下一項工作:整合模型。
3。 整合模型
將本文第二部分的工作整合,並進行大量的迭代。
python程式碼:
for
i
in
range
(
0
,
num_iterations
):
### START CODE HERE ### (≈ 4 lines of code)
# Forward propagation。 Inputs: “X, parameters”。 Outputs: “A2, cache”。
A2
,
cache
=
forward_propagation
(
X
,
parameters
)
# Cost function。 Inputs: “A2, Y, parameters”。 Outputs: “cost”。
cost
=
compute_cost
(
A2
,
Y
,
parameters
)
# Backpropagation。 Inputs: “parameters, cache, X, Y”。 Outputs: “grads”。
grads
=
backward_propagation
(
parameters
,
cache
,
X
,
Y
)
# Gradient descent parameter update。 Inputs: “parameters, grads”。 Outputs: “parameters”。
parameters
=
update_parameters
(
parameters
,
grads
)
這裡的num_iterations,是迭代次數,可自行設定。
4。 預測
完成了模型引數的最佳化,我們就可以使用該模型進行預測了。
python實現:
A2, cache = forward_propagation(X,parameters)
#predictions = (A2>0。5)
predictions = np。where(A2 > 0。5, 1, 0)
注意,預測的時候只需要利用前向傳播就可以了,因為模型已經最佳化完成,不再需要後向傳播。
至此,一個完整的用於解決二分類問題的神經網路的python實現已經完成了。
本文的完整python程式碼可以點選以下連結檢視:
吳恩達深度學習課程week3作業程式碼