0. 前言
人工神經(jīng)網(wǎng)絡(luò) (Artificial Neural Network
, ANN
) 是一種監(jiān)督學(xué)習(xí)算法,其靈感來(lái)自人類大腦的運(yùn)作方式。類似于人腦中神經(jīng)元連接和激活的方式,神經(jīng)網(wǎng)絡(luò)接受輸入,通過(guò)某些函數(shù)在網(wǎng)絡(luò)中進(jìn)行傳遞,導(dǎo)致某些后續(xù)神經(jīng)元被激活,從而產(chǎn)生輸出。函數(shù)越復(fù)雜,網(wǎng)絡(luò)對(duì)于輸入的數(shù)據(jù)擬合能力就越大,因此預(yù)測(cè)的準(zhǔn)確性就越高。
有多種不同的 ANN
架構(gòu),根據(jù)通用逼近定理,我們總能找到一個(gè)足夠大的包含正確權(quán)重集的神經(jīng)網(wǎng)絡(luò)架構(gòu),可以準(zhǔn)確地預(yù)測(cè)任何給定輸入的輸出結(jié)果。這意味著,對(duì)于給定的數(shù)據(jù)集/任務(wù),我們可以創(chuàng)建一個(gè)架構(gòu)并不斷調(diào)整其權(quán)重,直到 ANN
預(yù)測(cè)出正確結(jié)果,調(diào)整網(wǎng)絡(luò)權(quán)重的過(guò)程稱為訓(xùn)練神經(jīng)網(wǎng)絡(luò)。
計(jì)算機(jī)視覺(jué)中的一項(xiàng)重要任務(wù)是識(shí)別圖像中的對(duì)象類別,即圖像分類,ImageNet
是圖像分類領(lǐng)域的一項(xiàng)權(quán)威競(jìng)賽,歷年分類準(zhǔn)確率情況如下:
從上圖可以看出,通過(guò)利用神經(jīng)網(wǎng)絡(luò),模型錯(cuò)誤率顯著減少,隨著時(shí)間的推移,神經(jīng)網(wǎng)絡(luò)逐漸變得更深、更復(fù)雜,分類錯(cuò)誤率不斷減少,并表現(xiàn)出超越人類的水平。
在本節(jié)中,我們將使用一個(gè)簡(jiǎn)單的數(shù)據(jù)集創(chuàng)建一個(gè)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)架構(gòu),以了解 ANN
的各個(gè)組成部分(前向傳播、反向傳播、學(xué)習(xí)率等)對(duì)于模型權(quán)重調(diào)整的作用,以掌握神經(jīng)網(wǎng)絡(luò)如何根據(jù)給定輸入學(xué)習(xí)預(yù)測(cè)輸出。我們將首先介紹神經(jīng)網(wǎng)絡(luò)背后的數(shù)學(xué)原理,然后從零開(kāi)始構(gòu)建一個(gè)神經(jīng)網(wǎng)絡(luò),并介紹用于訓(xùn)練神經(jīng)網(wǎng)絡(luò)的每個(gè)組成部分。
1. 傳統(tǒng)機(jī)器學(xué)習(xí)與人工智能
傳統(tǒng)應(yīng)用程序中,系統(tǒng)是通過(guò)使用程序員編寫(xiě)的復(fù)雜算法來(lái)實(shí)現(xiàn)智能化的。例如,假設(shè)我們希望識(shí)別照片中是否包含狗。在傳統(tǒng)的機(jī)器學(xué)習(xí) (Machine Learning
, ML
) 中,需要機(jī)器學(xué)習(xí)研究人員首先確定需要從圖像中提取的特征,然后提取這些特征并將它們作為輸入傳遞給復(fù)雜算法,算法解析給定特征以判斷圖像中是否包含狗:
然而,如果要為多種類別圖像分類手動(dòng)提取特征,其數(shù)量可能是指數(shù)級(jí)的,因此,傳統(tǒng)方法在受限環(huán)境中效果很好(例如,識(shí)別證件照片),而在不受限制的環(huán)境中效果不佳,因?yàn)槊繌垐D像之間都有較大差異。
我們可以將相同的思想擴(kuò)展到其他領(lǐng)域,例如文本或結(jié)構(gòu)化數(shù)據(jù)。過(guò)去,如果希望通過(guò)編程來(lái)解決現(xiàn)實(shí)世界的任務(wù),就必須了解有關(guān)輸入數(shù)據(jù)的所有內(nèi)容并編寫(xiě)盡可能多的規(guī)則來(lái)涵蓋所有場(chǎng)景,并且不能保證所有新場(chǎng)景都會(huì)遵循已有規(guī)則。
而神經(jīng)網(wǎng)絡(luò)內(nèi)含了特征提取的過(guò)程,并將這些特征用于分類/回歸,幾乎不需要手動(dòng)特征工程,只需要標(biāo)記數(shù)據(jù)(例如,哪些圖片是狗,哪些圖片不是狗)和神經(jīng)網(wǎng)絡(luò)架構(gòu),不需要手動(dòng)提出規(guī)則來(lái)對(duì)圖像進(jìn)行分類,這減輕了傳統(tǒng)機(jī)器學(xué)習(xí)技術(shù)強(qiáng)加給程序員的大部分負(fù)擔(dān)。
訓(xùn)練神經(jīng)網(wǎng)絡(luò)需要提供大量樣本數(shù)據(jù)。例如,在前面的例子中,我們需要為模型提供大量的狗和非狗圖片,以便它學(xué)習(xí)特征。神經(jīng)網(wǎng)絡(luò)用于分類任務(wù)的流程如下,其訓(xùn)練與測(cè)試是端到端 (end-to-end
) 的:
2. 人工神經(jīng)網(wǎng)絡(luò)基礎(chǔ)
2.1 人工神經(jīng)網(wǎng)絡(luò)組成
ANN
是張量(權(quán)重, weights
)和數(shù)學(xué)運(yùn)算的集合,其排列方式近似于松散的人腦神經(jīng)元排列??梢詫⑵湟暈橐环N數(shù)學(xué)函數(shù),它將一個(gè)或多個(gè)張量作為輸入并預(yù)測(cè)相應(yīng)輸出(一個(gè)或多個(gè)張量)。將輸入連接到輸出的操作方式稱為神經(jīng)網(wǎng)絡(luò)的架構(gòu),我們可以根據(jù)不同的任務(wù)構(gòu)建不同架構(gòu),即基于問(wèn)題是包含結(jié)構(gòu)化數(shù)據(jù)還是非結(jié)構(gòu)化(圖像,文本,語(yǔ)音)數(shù)據(jù),這些數(shù)據(jù)就是輸入和輸出張量的列表。ANN
由以下部分組成:
- 輸入層:將自變量作為輸入
- 隱藏(中間)層:連接輸入和輸出層,在輸入數(shù)據(jù)之上執(zhí)行轉(zhuǎn)換;此外,隱藏層利用節(jié)點(diǎn)單元(下圖中的圓圈)將其輸入值修改為更高/更低維的值;通過(guò)修改中間節(jié)點(diǎn)的激活函數(shù)可以實(shí)現(xiàn)復(fù)雜表示函數(shù)
- 輸出層:輸入變量產(chǎn)生的值
綜上,神經(jīng)網(wǎng)絡(luò)的典型結(jié)構(gòu)如下:
輸出層中節(jié)點(diǎn)的數(shù)量(上圖中的圓圈)取決于實(shí)際任務(wù)以及我們是在嘗試預(yù)測(cè)連續(xù)變量還是分類變量。如果輸出是連續(xù)變量,則輸出有一個(gè)節(jié)點(diǎn)。如果輸出是具有 m
個(gè)可能類別的分類,則輸出層中將有 m
個(gè)節(jié)點(diǎn)。接下來(lái),我們深入介紹節(jié)點(diǎn)/神經(jīng)元的工作原理,神經(jīng)元按如下方式轉(zhuǎn)換其輸入:
其中, x 1 x_1 x1?, x 2 x_2 x2?,…, x n x_n xn? 是輸入變量, w 0 w_0 w0? 是偏置項(xiàng)(類似于線性/邏輯回歸中的偏差); w 1 w_1 w1?, w 2 w_2 w2?,…, w n w_n wn? 是賦予每個(gè)輸入變量的權(quán)重,輸出值 a a a 計(jì)算如下:
a = f ( w 0 + ∑ w i N w i x i ) a=f(w_0+\sum _{w_i} ^N w_ix_i) a=f(w0?+wi?∑N?wi?xi?)
可以看到,
a
a
a 是權(quán)重和輸入對(duì)的乘積之和,之后使用一個(gè)附加函數(shù)
f
(
w
0
+
∑
w
i
N
w
i
x
i
)
f(w_0+\sum _{w_i} ^N w_ix_i)
f(w0?+∑wi?N?wi?xi?),函數(shù)
f
f
f 是在乘積之和之上應(yīng)用的非線性激活函數(shù),用于在輸入和它們相應(yīng)的權(quán)重值的總和上引入非線性,可以通過(guò)使用多個(gè)隱藏層實(shí)現(xiàn)更強(qiáng)的非線性能力。
整體而言,神經(jīng)網(wǎng)絡(luò)是節(jié)點(diǎn)的集合,其中每個(gè)節(jié)點(diǎn)都有一個(gè)可調(diào)整的浮點(diǎn)值(權(quán)重),并且節(jié)點(diǎn)間相互連接,返回由網(wǎng)絡(luò)架構(gòu)決定的輸出。網(wǎng)絡(luò)由三個(gè)主要部分組成:輸入層、隱藏層和輸出層。我們可以使用多層 (n
) 隱藏層,深度學(xué)習(xí)通常表示具有多個(gè)隱藏層的神經(jīng)網(wǎng)絡(luò)。通常,當(dāng)神經(jīng)網(wǎng)絡(luò)需要學(xué)習(xí)具有復(fù)雜上下文或上下文不明顯的任務(wù)(例如圖像識(shí)別)時(shí),就必須具有更多隱藏層。
2.2 神經(jīng)網(wǎng)絡(luò)的訓(xùn)練
訓(xùn)練神經(jīng)網(wǎng)絡(luò)實(shí)際上就是通過(guò)重復(fù)兩個(gè)關(guān)鍵步驟來(lái)調(diào)整神經(jīng)網(wǎng)絡(luò)中的權(quán)重:前向傳播和反向傳播。
- 在前向傳播 (
feedforward propagation
) 中,我們將一組權(quán)重應(yīng)用于輸入數(shù)據(jù),將其傳遞給隱藏層,對(duì)隱藏層計(jì)算后的輸出使用非線性激活,通過(guò)若干個(gè)隱藏層后,將最后一個(gè)隱藏層的輸出與另一組權(quán)重相乘,就可以得到輸出層的結(jié)果。對(duì)于第一次正向傳播,權(quán)重的值將隨機(jī)初始化 - 在反向傳播 (
backpropagation
) 中,嘗試通過(guò)測(cè)量輸出的誤差,然后相應(yīng)地調(diào)整權(quán)重以降低誤差。神經(jīng)網(wǎng)絡(luò)重復(fù)正向傳播和反向傳播以預(yù)測(cè)輸出,直到獲得令誤差較小的權(quán)重為止
3. 前向傳播
為了進(jìn)一步了解前向傳播的工作方式,我們將通過(guò)一個(gè)簡(jiǎn)單的示例來(lái)構(gòu)建神經(jīng)網(wǎng)絡(luò),其中神經(jīng)網(wǎng)絡(luò)的輸入為 (1,1)
,相應(yīng)(預(yù)期)的輸出為 0
,我們根據(jù)這一輸入輸出對(duì)找到神經(jīng)網(wǎng)絡(luò)的最佳權(quán)重。在實(shí)際的神經(jīng)網(wǎng)絡(luò)中,會(huì)有數(shù)以萬(wàn)計(jì)的數(shù)據(jù)樣本點(diǎn)用于訓(xùn)練。
我們采用的策略如下:神經(jīng)網(wǎng)絡(luò)具有一個(gè)隱藏層,一個(gè)輸入層和一個(gè)輸出層,其中隱藏層包含三個(gè)節(jié)點(diǎn),如下所示:
在上圖中,每個(gè)箭頭都包含一個(gè)可調(diào)整的浮點(diǎn)值(權(quán)重)。我們需要找到 9
個(gè)浮點(diǎn)數(shù),當(dāng)輸入為 (1,1)
時(shí),令輸出盡可能接近 0
,這就是我們訓(xùn)練神經(jīng)網(wǎng)絡(luò)的目的(令輸出盡可能接近目標(biāo)值)。為簡(jiǎn)單起見(jiàn),我們并未在隱藏層單元中添引入偏置項(xiàng)。接下來(lái),我們將針對(duì)以上網(wǎng)絡(luò)介紹以下內(nèi)容:
- 計(jì)算隱藏層值
- 執(zhí)行非線性激活
- 計(jì)算輸出層值
- 計(jì)算損失值
3.1 計(jì)算隱藏層值
首先,為所有連接分配隨機(jī)權(quán)重;通常,神經(jīng)網(wǎng)絡(luò)在訓(xùn)練開(kāi)始之前使用隨機(jī)權(quán)重進(jìn)行初始化。為了簡(jiǎn)單起見(jiàn),在本節(jié)中,前向傳播和反向傳播時(shí)不包括偏執(zhí)值。
初始權(quán)重可以隨機(jī)初始化至 0-1
之間,但神經(jīng)網(wǎng)絡(luò)訓(xùn)練過(guò)程后的最終權(quán)重不需要在特定的區(qū)間內(nèi)。下圖左側(cè)給出了網(wǎng)絡(luò)中權(quán)重和值的可視化表示,右側(cè)給出了網(wǎng)絡(luò)中隨機(jī)初始化的權(quán)重:
接下來(lái),將輸入與權(quán)重相乘,計(jì)算隱藏層中的值。應(yīng)用激活函數(shù)前,隱藏層的單元值如下:
h
11
=
x
1
?
w
11
+
x
2
?
w
21
=
1
?
0.8
+
1
?
0.2
=
1
h
12
=
x
1
?
w
12
+
x
2
?
w
22
=
1
?
0.4
+
1
?
0.9
=
1.3
h
13
=
x
1
?
w
13
+
x
2
?
w
23
=
1
?
0.3
+
1
?
0.5
=
0.8
h_{11}=x_1*w_{11}+x_2*w_{21}=1*0.8+1*0.2=1 \\ h_{12}=x_1*w_{12}+x_2*w_{22}=1*0.4+1*0.9=1.3 \\ h_{13}=x_1*w_{13}+x_2*w_{23}=1*0.3+1*0.5=0.8
h11?=x1??w11?+x2??w21?=1?0.8+1?0.2=1h12?=x1??w12?+x2??w22?=1?0.4+1?0.9=1.3h13?=x1??w13?+x2??w23?=1?0.3+1?0.5=0.8
計(jì)算的應(yīng)用激活前隱藏層的單元值可視化如下圖所示:
接下來(lái),我們通過(guò)非線性激活傳遞隱藏層值。需要注意的是,如果我們不在隱藏層中應(yīng)用非線性激活函數(shù),那么無(wú)論存在多少隱藏層,則神經(jīng)網(wǎng)絡(luò)本質(zhì)上都將是從輸入到輸出線性連接。
3.2 執(zhí)行非線性激活
激活函數(shù)有助于對(duì)輸入和輸出之間的復(fù)雜關(guān)系進(jìn)行建模,使用它們可以實(shí)現(xiàn)高度非線性。一些常用的激活函數(shù)如下(其中 x
是輸入):
S
i
g
m
o
i
d
(
x
)
=
1
1
+
e
?
x
R
e
L
U
(
x
)
=
{
x
x
>
0
0
x
≤
0
T
a
n
h
(
x
)
=
e
x
?
e
?
x
e
x
+
e
?
x
L
i
n
e
a
r
(
x
)
=
x
Sigmoid(x)=\frac 1 {1+e^{-x}} \\ ReLU(x)=\left\{ \begin{aligned} x \quad x>0\\ 0 \quad x≤0\\ \end{aligned} \right. \\ Tanh(x)=\frac {e^x-e^{-x}} {e^x+e^{-x}} \\ Linear(x) = x
Sigmoid(x)=1+e?x1?ReLU(x)={xx>00x≤0?Tanh(x)=ex+e?xex?e?x?Linear(x)=x
應(yīng)用激活函數(shù)后,輸入值對(duì)應(yīng)的激活可視化如下:
使用 Sigmoid
激活函數(shù),通過(guò)對(duì)隱藏層應(yīng)用 sigmoid
激活
S
(
x
)
S(x)
S(x),可以得到以下結(jié)果:
a
11
=
s
i
g
m
o
i
d
(
1.0
)
=
0.73
a
12
=
s
i
g
m
o
i
d
(
1.3
)
=
0.78
a
13
=
s
i
g
m
o
i
d
(
0.8
)
=
0.69
a_{11} = sigmoid(1.0) = 0.73\\ a_{12} = sigmoid(1.3) = 0.78\\ a_{13} = sigmoid(0.8) = 0.69
a11?=sigmoid(1.0)=0.73a12?=sigmoid(1.3)=0.78a13?=sigmoid(0.8)=0.69
3.3 計(jì)算輸出層值
接下來(lái),我們將應(yīng)用激活函數(shù)后的隱藏層值通過(guò)隨機(jī)初始化的權(quán)重值連接到輸出層,使用激活后的隱藏層值和權(quán)重值計(jì)算網(wǎng)絡(luò)的輸出值:
計(jì)算隱藏層值和權(quán)重值乘積的總和,得到輸出值。此外,為了簡(jiǎn)化對(duì)前向傳播和反向傳播工作細(xì)節(jié)的理解,我們暫時(shí)忽略每個(gè)單元(節(jié)點(diǎn))中的偏置項(xiàng):
o u t p u t = 0.73 × 0.3 + 0.79 × 0.5 + 0.69 × 0.9 = 1.235 output = 0.73\times 0.3+0.79\times 0.5 + 0.69\times 0.9= 1.235 output=0.73×0.3+0.79×0.5+0.69×0.9=1.235
因?yàn)槲覀儚囊唤M隨機(jī)權(quán)重開(kāi)始,所以輸出節(jié)點(diǎn)的值與目標(biāo)值有較大差距,根據(jù)以上計(jì)算可以看到,差值為 1.235
(我們的目標(biāo)是令目標(biāo)值與模型輸出值之間的差值為 0
)。在下一小節(jié)中,我們將學(xué)習(xí)如何計(jì)算當(dāng)前狀態(tài)下網(wǎng)絡(luò)的損失值。
3.4 計(jì)算損失值
損失值( Loss values
,也稱為成本函數(shù) cost functions
)是我們需要在神經(jīng)網(wǎng)絡(luò)中優(yōu)化的值。為了了解如何計(jì)算損失值,我們分析以下兩種情況:
- 分類(離散)變量預(yù)測(cè)
- 連續(xù)變量預(yù)測(cè)
3.4.1 在連續(xù)變量預(yù)測(cè)過(guò)程中計(jì)算損失
通常,當(dāng)變量是連續(xù)的時(shí),可以計(jì)算實(shí)際值和預(yù)測(cè)值之差的平方的平均值作為損失值,也就是說(shuō),我們?cè)噲D通過(guò)改變與神經(jīng)網(wǎng)絡(luò)相關(guān)的權(quán)重值來(lái)最小化均方誤差:
J θ = 1 m ∑ i = 1 m ( y i ? y ^ i ) 2 y ^ i = η θ ( x i ) J_{\theta}=\frac 1m\sum_{i=1}^m(y_i-\hat y _i)^2\\ \hat y_i=\eta_{\theta}(x_i) Jθ?=m1?i=1∑m?(yi??y^?i?)2y^?i?=ηθ?(xi?)
其中,
y
i
y_i
yi? 是實(shí)際輸出,
y
^
i
\hat y_i
y^?i? 是由神經(jīng)網(wǎng)絡(luò)
η
\eta
η (權(quán)重為
θ
\theta
θ )計(jì)算得到的預(yù)測(cè)輸出,輸入為
x
i
x_i
xi?,
m
m
m 是數(shù)據(jù)集中訓(xùn)練時(shí)使用的樣本數(shù)。
關(guān)鍵點(diǎn)在于,對(duì)于每組不同的權(quán)重,神經(jīng)網(wǎng)絡(luò)都會(huì)得到不同的損失值,理想情況下,我們需要找到令損失為零的最佳權(quán)重集,在現(xiàn)實(shí)場(chǎng)景中,則需要找到盡可能令損失值接近于零的權(quán)重集。
在上一小節(jié)的示例中,假設(shè)預(yù)測(cè)結(jié)果是連續(xù)值,損失函數(shù)使用均方誤差,計(jì)算結(jié)果如下:
l o s s ( e r r o r ) = 1.23 5 2 = 1.52 loss(error)=1.235^2=1.52 loss(error)=1.2352=1.52
3.4.2 在分類(離散)變量預(yù)測(cè)過(guò)程中計(jì)算損失
當(dāng)要預(yù)測(cè)的變量是離散的(即變量只有幾個(gè)類別)時(shí),我們通常使用分類交叉熵 (categorical cross-entropy
) 損失函數(shù)。當(dāng)要預(yù)測(cè)的變量有兩個(gè)不同的值時(shí),損失函數(shù)為二元交叉熵 (binary cross-entropy
),二元交叉熵計(jì)算如下:
? 1 m ∑ i = 1 m ( y i ( l o g ( p i ) + ( 1 ? y i ) l o g ( 1 ? p i ) ) -\frac 1m\sum_{i=1}^m(y_i(log(p_i)+(1-y_i)log(1-p_i)) ?m1?i=1∑m?(yi?(log(pi?)+(1?yi?)log(1?pi?))
分類交叉熵計(jì)算如下:
? 1 m ∑ j = 1 C ∑ i = 1 m y i l o g ( p i ) -\frac 1m\sum_{j=1}^C\sum_{i=1}^my_ilog(p_i) ?m1?j=1∑C?i=1∑m?yi?log(pi?)
其中, y y y 是輸出對(duì)應(yīng)的真實(shí)值(即數(shù)據(jù)樣本的標(biāo)簽), p p p 是輸出的預(yù)測(cè)值, m m m 是數(shù)據(jù)樣本總數(shù), C C C 是類別總數(shù)。
可視化交叉熵?fù)p失的一種簡(jiǎn)單方法是查看預(yù)測(cè)矩陣。假設(shè)我們需要在圖像識(shí)別問(wèn)題中預(yù)測(cè)五個(gè)類別——狗、貓、馬、羊和牛。神經(jīng)網(wǎng)絡(luò)在最后一層必須包含五個(gè)神經(jīng)元,并使用 softmax
激活函數(shù)。此時(shí),網(wǎng)絡(luò)將輸出數(shù)據(jù)樣本屬于每個(gè)類別的概率。假設(shè)有五張圖像,預(yù)測(cè)概率如下所示,其中每行中突出顯示單元格對(duì)應(yīng)于圖像的真實(shí)標(biāo)簽(也稱目標(biāo)類別,target class
):
每一行中的概率總和為 1
。在第一行中,當(dāng)目標(biāo)是 Dog
,預(yù)測(cè)概率為 0.88
時(shí),對(duì)應(yīng)的損失值為 0.128
;類似地,我們也可以計(jì)算其他損失值,當(dāng)正確類別的概率較高時(shí),損失值較小。由于概率介于 0
和 1
之間,因此,當(dāng)概率為 1
時(shí),可能的最小損失為 0
,而當(dāng)概率為 0
時(shí),最大損失可以為無(wú)窮大,模型的最終損失是所有行(訓(xùn)練數(shù)據(jù)樣本)的損失平均值。
3.5 實(shí)現(xiàn)前向傳播
實(shí)現(xiàn)前向傳播的策略如下:
- 通過(guò)將輸入值乘以權(quán)重來(lái)神經(jīng)元輸出值
- 計(jì)算激活值
- 在每個(gè)神經(jīng)元上重復(fù)前兩個(gè)步驟,直到輸出層
- 將預(yù)測(cè)輸出與真實(shí)值進(jìn)行比較計(jì)算損失值
我們可以將以上過(guò)程封裝為一個(gè)函數(shù),將輸入數(shù)據(jù)、當(dāng)前神經(jīng)網(wǎng)絡(luò)權(quán)重和真實(shí)值作為函數(shù)輸入,并返回網(wǎng)絡(luò)的當(dāng)前損失值:
import numpy as np
def feed_forward(inputs, outputs, weights):
pre_hidden = np.dot(inputs, weights[0]) + weights[1]
hidden = 1/(1+np.exp(-pre_hidden))
pred_out = np.dot(hidden, weights[2]) + weights[3]
mean_squared_error = np.mean(np.square(pred_out - outputs))
return mean_squared_error
(1) 將輸入變量值 (inputs
)、權(quán)重(weights
,如果是首次迭代,則隨機(jī)初始化)和數(shù)據(jù)的實(shí)際輸出 (outputs
) 作為 feed_forward
函數(shù)的參數(shù):
import numpy as np
def feed_forward(inputs, outputs, weights):
由于為每個(gè)神經(jīng)元節(jié)點(diǎn)添加偏置項(xiàng),因此權(quán)重?cái)?shù)組不僅包含連接不同節(jié)點(diǎn)的權(quán)重,還包含與隱藏/輸出層中的節(jié)點(diǎn)相關(guān)的偏置項(xiàng)。
(2) 通過(guò)執(zhí)行輸入層和權(quán)重值 (weights[0]
) 的矩陣乘法(np.dot
)來(lái)計(jì)算隱藏層值,并將偏置值 (weights[1]
) 添加到隱藏層中,利用權(quán)重和偏置值就可以將輸入層連接到隱藏層:
pre_hidden = np.dot(inputs, weights[0]) + weights[1]
(3) 在獲得的隱藏層值 (pre_hidden
) 之上應(yīng)用 sigmoid
激活函數(shù):
hidden = 1/(1+np.exp(-pre_hidden))
(4) 通過(guò)對(duì)隱藏層激活值 (hidden
) 和權(quán)重 (weights[2]
,將隱藏層連接到輸出層)執(zhí)行矩陣乘法 (np.dot
) 計(jì)算輸出層值,然后在輸出上添加偏置項(xiàng) (weights[3]
):
pred_out = np.dot(hidden, weights[2]) + weights[3]
(5) 計(jì)算所有數(shù)據(jù)樣本的均方誤差值并返回:
mean_squared_error = np.mean(np.square(pred_out - outputs))
return mean_squared_error
其中,pred_out
是預(yù)測(cè)輸出,而 outputs
是輸入應(yīng)對(duì)應(yīng)的實(shí)際輸出。
4. 反向傳播
4.1 反向傳播流程
在前向傳播中,我們將輸入層連接到隱藏層,然后將隱藏層連接到輸出層。在第一次迭代時(shí),隨機(jī)初始化權(quán)重,然后計(jì)算網(wǎng)絡(luò)在當(dāng)前權(quán)重值下的損失。在反向傳播中,我們采用相反的方法。利用從前向傳播中計(jì)算的損失值,并以盡可能最小化損失值為目標(biāo)更新網(wǎng)絡(luò)權(quán)重,網(wǎng)絡(luò)權(quán)重更新步驟如下:
- 每次對(duì)神經(jīng)網(wǎng)絡(luò)中的每個(gè)權(quán)重進(jìn)行少量更改
- 測(cè)量權(quán)重變化 ( δ W \delta W δW) 時(shí)的損失變化 ( δ L \delta L δL)
- 計(jì)算 ? k δ L δ W -k\frac {\delta L}{\delta W} ?kδWδL? 更新權(quán)重(其中 k k k 為學(xué)習(xí)率,且為正值,是神經(jīng)網(wǎng)絡(luò)中重要的超參數(shù))
對(duì)特定權(quán)重所做的更新與損失值的減少成正比,也就是說(shuō),如果改變一個(gè)權(quán)重可以大幅減少損失,那么權(quán)重的更新就會(huì)較大,但是,如果改變權(quán)重僅能小幅減少損失,那么就只需要小幅度更新權(quán)重。
在整個(gè)數(shù)據(jù)集上執(zhí)行 n
次上述過(guò)程(包括前向傳播和反向傳播),表示模型進(jìn)行了 n
個(gè) epoch
的訓(xùn)練(執(zhí)行一次稱為一個(gè) epoch
)。
由于神經(jīng)網(wǎng)絡(luò)通??赡馨瑪?shù)以百萬(wàn)計(jì)的權(quán)重,因此更改每個(gè)權(quán)重的值,并檢查損失的變化在實(shí)踐中并不是最佳方法。上述步驟的核心思想是計(jì)算權(quán)重變化時(shí)的“損失變化”,即計(jì)算損失值關(guān)于權(quán)重的梯度。
在本節(jié)中,我們將通過(guò)一次少量更新一個(gè)權(quán)重來(lái)從零開(kāi)始實(shí)現(xiàn)梯度下降,但在實(shí)現(xiàn)反向傳播之前,我們首先了解神經(jīng)網(wǎng)絡(luò)的另一關(guān)鍵超參數(shù):學(xué)習(xí)率 (learning rate
)。
直觀地說(shuō),學(xué)習(xí)率有助于構(gòu)建更穩(wěn)定的算法。例如,在確定權(quán)重更新的大小時(shí),我們并不會(huì)一次性就對(duì)其進(jìn)行大幅度更改,而是采取更謹(jǐn)慎的方法來(lái)緩慢地更新權(quán)重。這使模型獲得更高的穩(wěn)定性;在之后的學(xué)習(xí)中,我們還將研究學(xué)習(xí)率如何幫助提高網(wǎng)絡(luò)穩(wěn)定性。
4.2 梯度下降
更新權(quán)重以減少誤差值的整個(gè)過(guò)程稱為梯度下降 (gradient descent
)。隨機(jī)梯度下降 (stochastic gradient descent
, SGD
) 是將誤差最小化的一種方法,其中隨機(jī) (stochastic
) 表示隨機(jī)選擇數(shù)據(jù)集中的訓(xùn)練數(shù)據(jù)樣本,并根據(jù)該樣本做出決策。除了隨機(jī)梯度下降外,還有許多其他優(yōu)化器可以用于減少損失值。之后的學(xué)習(xí)中,我們還將學(xué)習(xí)不同的優(yōu)化器。
接下來(lái),我們將學(xué)習(xí)如何使用 Python
從零開(kāi)始實(shí)現(xiàn)反向傳播,并介紹如何使用鏈?zhǔn)椒▌t進(jìn)行反向傳播。
4.3 實(shí)現(xiàn)梯度下降算法
(1) 定義前饋網(wǎng)絡(luò)并計(jì)算均方誤差損失值:
from copy import deepcopy
import numpy as np
def feed_forward(inputs, outputs, weights):
pre_hidden = np.dot(inputs, weights[0]) + weights[1]
hidden = 1/(1+np.exp(-pre_hidden))
pred_out = np.dot(hidden, weights[2]) + weights[3]
mean_squared_error = np.mean(np.square(pred_out - outputs))
return mean_squared_error
(2) 為每個(gè)權(quán)重和偏置項(xiàng)增加一個(gè)非常小的量 (0.0001
),并針對(duì)每個(gè)權(quán)重和偏差的更新計(jì)算一個(gè)平方誤差損失值。
創(chuàng)建 update_weights
函數(shù),通過(guò)執(zhí)行梯度下降來(lái)更新權(quán)重。函數(shù)的輸入是網(wǎng)絡(luò)的輸入 inputs
、目標(biāo)輸出 outputs
、權(quán)重 weights
和模型的學(xué)習(xí)率 lr
:
def update_weights(inputs, outputs, weights, lr):
由于權(quán)重需要在后續(xù)步驟中進(jìn)行操作,因此使用 deepcopy
確保我們可以處理多個(gè)權(quán)重副本,而不會(huì)影響實(shí)際權(quán)重,創(chuàng)建作為輸入傳遞給函數(shù)的原始權(quán)重集的三個(gè)副本—— original_weights
、temp_weights
和 updated_weights
:
original_weights = deepcopy(weights)
temp_weights = deepcopy(weights)
updated_weights = deepcopy(weights)
將 inputs
、outputs
和 original_weights
傳遞給 feed_forward
函數(shù),使用原始權(quán)重集計(jì)算損失值 (original_loss
):
original_loss = feed_forward(inputs, outputs, original_weights)
遍歷網(wǎng)絡(luò)的所有層:
for i, layer in enumerate(original_weights):
示例神經(jīng)網(wǎng)絡(luò)中包含四個(gè)參數(shù)列表,前兩個(gè)列表分別表示將輸入連接到隱藏層的權(quán)重和偏置項(xiàng)參數(shù),另外兩個(gè)表示連接隱藏層和輸出層的權(quán)重和偏置參數(shù)。循環(huán)遍歷所有參數(shù),因?yàn)槊總€(gè)參數(shù)列表都有不同的形狀,因此使用 np.ndenumerate
循環(huán)遍歷給定列表中的每個(gè)參數(shù):
for index, weight in np.ndenumerate(layer):
將原始權(quán)重集存儲(chǔ)在 temp_weights 中
,循環(huán)每一參數(shù)并為其增加一個(gè)較小值,并使用神經(jīng)網(wǎng)絡(luò)的新權(quán)重集計(jì)算新?lián)p失:
temp_weights = deepcopy(weights)
temp_weights[i][index] += 0.0001
_loss_plus = feed_forward(inputs, outputs, temp_weights)
在以上代碼中,將 temp_weights
重置為原始權(quán)重集,因?yàn)樵诿看蔚?,都需要更新一個(gè)參數(shù),以計(jì)算對(duì)參數(shù)進(jìn)行小量更新時(shí)的損失。
計(jì)算由于權(quán)重變化引起的梯度(損失值的變化):
grad = (_loss_plus - original_loss)/(0.0001)
這種對(duì)參數(shù)更新一個(gè)很小的量,然后計(jì)算梯度的過(guò)程就相當(dāng)于微分的過(guò)程。
通過(guò)損失變化來(lái)更新權(quán)重,并使用學(xué)習(xí)率 lr
令權(quán)重變化更穩(wěn)定:
updated_weights[i][index] -= grad*lr
所有參數(shù)值更新后,返回更新后的權(quán)重值——updated_weights
:
return updated_weights, original_loss
神經(jīng)網(wǎng)絡(luò)中的另一個(gè)需要考慮的超參數(shù)是計(jì)算損失值時(shí)的批大小 (batch size
)。在以上示例中,我們使用了所有數(shù)據(jù)點(diǎn)來(lái)計(jì)算損失值。然而,在實(shí)踐中,數(shù)據(jù)集中通常包含數(shù)數(shù)以萬(wàn)甚至百萬(wàn)計(jì)的數(shù)據(jù)點(diǎn),過(guò)多的數(shù)據(jù)點(diǎn)在計(jì)算損失值時(shí)的增量貢獻(xiàn)遵循收益遞減規(guī)律,與我們數(shù)據(jù)樣本總數(shù)相比,批大小要小得多。訓(xùn)練模型時(shí),一次使用一批數(shù)據(jù)點(diǎn)應(yīng)用梯度下降更新網(wǎng)絡(luò)參數(shù),直到我們?cè)谝淮斡?xùn)練周期 (epoch
) 內(nèi)遍歷所有數(shù)據(jù)點(diǎn)。構(gòu)建模型時(shí),批大小通常在 32
到 1024
之間。
4.4 使用鏈?zhǔn)椒▌t實(shí)現(xiàn)反向傳播
我們已經(jīng)學(xué)習(xí)了如何通過(guò)對(duì)權(quán)重進(jìn)行小量更新,然后計(jì)算權(quán)重更新前后損失的差異來(lái)計(jì)算與權(quán)重有關(guān)的損失梯度。當(dāng)網(wǎng)絡(luò)參數(shù)較多時(shí),以這種方式更新權(quán)重值需要進(jìn)行大量計(jì)算來(lái)得到損失值,因此需要較大的資源和時(shí)間。在本節(jié)中,我們將學(xué)習(xí)如何利用鏈?zhǔn)椒▌t來(lái)獲取與權(quán)重值有關(guān)的損失梯度。
在上一小節(jié)的示例中,第一次迭代輸出的預(yù)測(cè)值為 1.235
。將權(quán)重和隱藏層值以及隱藏層激活值分別表示為
w
w
w、
h
h
h 和
a
a
a:
在本節(jié)中,我們將了解如何使用鏈?zhǔn)椒▌t計(jì)算損失值關(guān)于
w
11
w_{11}
w11? 的梯度,可以使用相同的方式計(jì)算其他權(quán)重和偏置值。此外,為了便于了解鏈?zhǔn)椒▌t,我們只需要處理一個(gè)數(shù)據(jù)點(diǎn),其中輸入為 {1,1}
,輸出目標(biāo)值為 {0}
。
要計(jì)算損失值關(guān)于
w
11
w_{11}
w11? 的梯度,可以通過(guò)下圖了解計(jì)算梯度時(shí)要包括的所有中間組件(使用黑色標(biāo)記標(biāo)示——
h
11
h_{11}
h11?、
a
11
a_{11}
a11? 和
y
^
\hat y
y^?):
網(wǎng)絡(luò)的損失值表示如下:
L o s s M S E ( C ) = ( y ? y ^ ) 2 Loss_{MSE}(C)=(y-\hat y)^2 LossMSE?(C)=(y?y^?)2
預(yù)測(cè)輸出值 y ^ \hat y y^? 計(jì)算如下:
y ^ = a 11 ? w 21 + a 12 ? w 22 + a 13 ? w 23 \hat y=a_{11}*w_{21}+a_{12}*w_{22}+a_{13}*w_{23} y^?=a11??w21?+a12??w22?+a13??w23?
隱藏層激活值( sigmoid
激活)計(jì)算如下:
a 11 = 1 1 + e ? h 11 a_{11}=\frac 1 {1+e^{-h_{11}}} a11?=1+e?h11?1?
隱藏層值計(jì)算如下:
h 11 = x 1 ? w 11 + x 2 ? w 21 h_{11}=x_1*w_{11}+x_2*w_{21} h11?=x1??w11?+x2??w21?
計(jì)算損失值 C C C 的變化相對(duì)于權(quán)重 w 11 w_{11} w11? 的變化:
? C ? w 11 = ? C ? y ^ ? ? y ^ ? a 11 ? ? a 11 ? h 11 ? ? h 11 ? w 11 \frac {\partial C}{\partial w_{11}}=\frac {\partial C}{\partial \hat y}*\frac {\partial \hat y}{\partial a_{11}}*\frac {\partial a_{11}}{\partial h_{11}}*\frac {\partial h_{11}}{\partial w_{11}} ?w11??C?=?y^??C???a11??y^????h11??a11????w11??h11??
上式稱為鏈?zhǔn)椒▌t (chain rule
),在上式中我們建立了一個(gè)偏微分方程鏈,分別對(duì)四個(gè)分量執(zhí)行偏微分,并最終計(jì)算損失值相對(duì)于權(quán)重的導(dǎo)數(shù)值
w
11
w_{11}
w11?。上式中的各個(gè)偏導(dǎo)數(shù)計(jì)算如下。
損失值相對(duì)于預(yù)測(cè)輸出值 y ^ \hat y y^? 的偏導(dǎo)數(shù)如下:
? C ? y ^ = ? ? y ^ ( y ? y ^ ) 2 = ? 2 ? ( y ? y ^ ) \frac {\partial C}{\partial \hat y}=\frac {\partial}{\partial \hat y}(y-\hat y)^2=-2*(y-\hat y) ?y^??C?=?y^???(y?y^?)2=?2?(y?y^?)
預(yù)測(cè)輸出值 y ^ \hat y y^? 相對(duì)于隱藏層激活值 a 11 a_{11} a11? 的偏導(dǎo)數(shù)如下:
? y ^ ? a 11 = ? ? a 11 ( a 11 ? w 21 + a 12 ? w 22 + a 13 ? w 23 ) = w 21 \frac {\partial \hat y}{\partial a_{11}}=\frac {\partial}{\partial a_{11}}(a_{11}*w_{21}+a_{12}*w_{22}+a_{13}*w_{23})=w_{21} ?a11??y^??=?a11???(a11??w21?+a12??w22?+a13??w23?)=w21?
隱藏層激活值 a 11 a_{11} a11? 相對(duì)于隱藏層值 h 11 h_{11} h11? 的偏導(dǎo)如下:
? a 11 ? h 11 = a 11 ? ( 1 ? a 11 ) \frac {\partial a_{11}}{\partial h_{11}}=a_{11}*(1-a_{11}) ?h11??a11??=a11??(1?a11?)
隱藏層值 h 11 h_{11} h11? 相對(duì)于權(quán)重值 w 11 w_{11} w11? 的偏導(dǎo)如下:
? h 11 ? w 11 = ? ? w 11 ( x 1 ? w 11 + x 2 ? w 21 ) = x 1 \frac {\partial h_{11}}{\partial w_{11}}=\frac {\partial}{\partial w_{11}}(x_1*w_{11}+x_2*w_{21})=x_1 ?w11??h11??=?w11???(x1??w11?+x2??w21?)=x1?
因此,損失值相對(duì)于 w 11 w_{11} w11? 的梯度可以表示為:
? C ? w 11 = ? 2 ? ( y ? y ^ ) ? w 21 ? a 11 ? ( 1 ? a 11 ) ? x 1 \frac {\partial C}{\partial w_{11}}=-2*(y-\hat y)*w_{21}*a_{11}*(1-a_{11})*x_1 ?w11??C?=?2?(y?y^?)?w21??a11??(1?a11?)?x1?
從上式可以看出,我們現(xiàn)在能夠直接計(jì)算權(quán)重值的微小變化對(duì)損失值的影響(損失相對(duì)于權(quán)重的梯度),而無(wú)需重新計(jì)算前向傳播。接下來(lái),更新權(quán)重值:
u p d a t e d _ w e i g h t = o r i g i n a l _ w e i g h t ? l r ? g r a d i e n t _ o f _ l o s s updated\_weight=original\_weight-lr*gradient\_of\_loss updated_weight=original_weight?lr?gradient_of_loss
5. 合并前向傳播和反向傳播
在本節(jié)中,我們將構(gòu)建一個(gè)帶有隱藏層(連接輸入與輸出)的簡(jiǎn)單神經(jīng)網(wǎng)絡(luò),使用在上一小節(jié)中介紹的簡(jiǎn)單數(shù)據(jù)集,并利用 update_weights
函數(shù)執(zhí)行反向傳播以獲得最佳權(quán)重和偏置值。模型定義如下:
- 輸入連接到具有三個(gè)神經(jīng)元(節(jié)點(diǎn))的隱藏層。
- 隱藏層連接到具有一個(gè)神經(jīng)元的輸出層
接下來(lái),使用 Python
創(chuàng)建神經(jīng)網(wǎng)絡(luò):
(1) 導(dǎo)入相關(guān)庫(kù)并定義數(shù)據(jù)集:
import numpy as np
from copy import deepcopy
import matplotlib.pyplot as plt
x = np.array([[1,1]])
y = np.array([[0]])
(2) 隨機(jī)初始化權(quán)重和偏置值。
隱藏層中有三個(gè)神經(jīng)元,每個(gè)輸入節(jié)點(diǎn)都連接到隱藏層神經(jīng)元。因此,共有六個(gè)權(quán)重值和三個(gè)偏置值,每個(gè)隱藏層神經(jīng)元包含一個(gè)偏置和兩個(gè)權(quán)重(每個(gè)輸入到隱藏層神經(jīng)元的連接都對(duì)應(yīng)一個(gè)權(quán)重);最后一層有一個(gè)神經(jīng)元連接到隱藏層的三個(gè)單元,因此包含三個(gè)權(quán)重和一個(gè)偏置值。隨機(jī)初始化的權(quán)重如下:
W = [
np.array([[-0.0053, 0.3793],
[-0.5820, -0.5204],
[-0.2723, 0.1896]], dtype=np.float32).T,
np.array([-0.0140, 0.5607, -0.0628], dtype=np.float32),
np.array([[ 0.1528, -0.1745, -0.1135]], dtype=np.float32).T,
np.array([-0.5516], dtype=np.float32)
]
其中,第一個(gè)參數(shù)數(shù)組對(duì)應(yīng)于將輸入層連接到隱藏層的 2 x 3
權(quán)重矩陣;第二個(gè)參數(shù)數(shù)組表示與隱藏層的每個(gè)神經(jīng)元相關(guān)的偏置值;第三個(gè)參數(shù)數(shù)組對(duì)應(yīng)于將隱藏層連接到輸出層的 3 x 1
權(quán)重矩陣,最后一個(gè)參數(shù)數(shù)組表示與輸出層相關(guān)的偏置值。
(3) 在 100
個(gè) epoch
內(nèi)執(zhí)行前向傳播和反向傳播,使用以上部分中定義的 feed_forward
和 update_weights
函數(shù)。
在訓(xùn)練期間,更新權(quán)重并獲取損失值和更新后的權(quán)重值:
def feed_forward(inputs, outputs, weights):
pre_hidden = np.dot(inputs,weights[0])+ weights[1]
hidden = 1/(1+np.exp(-pre_hidden))
out = np.dot(hidden, weights[2]) + weights[3]
mean_squared_error = np.mean(np.square(out - outputs))
return mean_squared_error
def update_weights(inputs, outputs, weights, lr):
original_weights = deepcopy(weights)
temp_weights = deepcopy(weights)
updated_weights = deepcopy(weights)
original_loss = feed_forward(inputs, outputs, original_weights)
for i, layer in enumerate(original_weights):
for index, weight in np.ndenumerate(layer):
temp_weights = deepcopy(weights)
temp_weights[i][index] += 0.0001
_loss_plus = feed_forward(inputs, outputs, temp_weights)
grad = (_loss_plus - original_loss)/(0.0001)
updated_weights[i][index] -= grad*lr
return updated_weights, original_loss
(4) 繪制損失值:
losses = []
for epoch in range(100):
W, loss = update_weights(x,y,W,0.01)
losses.append(loss)
plt.plot(losses)
plt.title('Loss over increasing number of epochs')
plt.xlabel('Epochs')
plt.ylabel('Loss value')
plt.show()
損失值最初為 0.33
左右,然后逐漸下降到 0.0001
左右,這表明權(quán)重是根據(jù)輸入-輸出數(shù)據(jù)調(diào)整的,當(dāng)給定輸入時(shí),我們可以通過(guò)調(diào)整網(wǎng)絡(luò)參數(shù)得到預(yù)期目標(biāo)值。調(diào)整后的權(quán)重如下:
print(W)
'''輸出結(jié)果
[array([[ 0.01424004, -0.5907864 , -0.27549535],
[ 0.39883757, -0.52918637, 0.18640439]], dtype=float32), array([ 0.00554004, 0.5519136 , -0.06599568], dtype=float32), array([[ 0.3475135 ],
[-0.05529078],
[ 0.03760847]], dtype=float32), array([-0.22443289], dtype=float32)]
'''
使用 NumPy
數(shù)組從零開(kāi)始構(gòu)建網(wǎng)絡(luò)雖然不是最佳方法,但可以為理解神經(jīng)網(wǎng)絡(luò)的工作原理打下堅(jiān)實(shí)的基礎(chǔ)。
(5) 獲取更新的權(quán)重后,通過(guò)將輸入傳遞給網(wǎng)絡(luò)對(duì)輸入進(jìn)行預(yù)測(cè)并計(jì)算輸出值:
pre_hidden = np.dot(x,W[0]) + W[1]
hidden = 1/(1+np.exp(-pre_hidden))
pred_out = np.dot(hidden, W[2]) + W[3]
print(pred_out)
# [[-0.0174781]]
輸出為 -0.017
,這個(gè)值非常接近預(yù)期的輸出 0
,通過(guò)訓(xùn)練更多的 epoch
,pred_out
值會(huì)更接近 0
。
6. 神經(jīng)網(wǎng)絡(luò)訓(xùn)練過(guò)程總結(jié)
訓(xùn)練神經(jīng)網(wǎng)絡(luò)主要通過(guò)重復(fù)兩個(gè)關(guān)鍵步驟,即以給定的學(xué)習(xí)率進(jìn)行前向傳播和反向傳播,最終神經(jīng)網(wǎng)絡(luò)架構(gòu)得到最佳權(quán)重。
在前向傳播中,我們對(duì)輸入數(shù)據(jù)應(yīng)用一組權(quán)重,將其傳遞給定義的隱藏層,對(duì)隱藏層的輸出執(zhí)行非線性激活,然后通過(guò)將隱藏層節(jié)點(diǎn)值與另一組權(quán)重相乘來(lái)將隱藏層連接到輸出層,以估計(jì)輸出值;最終計(jì)算出對(duì)應(yīng)于給定權(quán)重集的損失。需要注意的是,第一次前向傳播時(shí),權(quán)重的值是隨機(jī)初始化的。
在反向傳播中,通過(guò)在損失減少的方向上調(diào)整權(quán)重來(lái)減少損失值(誤差),權(quán)重更新的幅度等于梯度乘以學(xué)習(xí)率。
重復(fù)前向傳播和反向傳播的過(guò)程,直到獲得盡可能小的損失,在訓(xùn)練結(jié)束時(shí),神經(jīng)網(wǎng)絡(luò)已經(jīng)將其權(quán)重
θ
\theta
θ 調(diào)整調(diào)整到近似最優(yōu)值,以便獲取期望的輸出結(jié)果。
小結(jié)
在本節(jié)中,我們了解了傳統(tǒng)機(jī)器學(xué)習(xí)與人工神經(jīng)網(wǎng)絡(luò)間的差異,并了解了如何在實(shí)現(xiàn)前向傳播之前連接網(wǎng)絡(luò)的各個(gè)層,以計(jì)算與網(wǎng)絡(luò)當(dāng)前權(quán)重對(duì)應(yīng)的損失值;實(shí)現(xiàn)了反向傳播以優(yōu)化權(quán)重達(dá)到最小化損失值的目標(biāo)。并實(shí)現(xiàn)了網(wǎng)絡(luò)的所有關(guān)鍵組成——前向傳播、激活函數(shù)、損失函數(shù)、鏈?zhǔn)椒▌t和梯度下降,從零開(kāi)始構(gòu)建并訓(xùn)練了一個(gè)簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-461928.html
系列鏈接
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(2)——PyTorch基礎(chǔ)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(3)——使用PyTorch構(gòu)建神經(jīng)網(wǎng)絡(luò)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(4)——常用激活函數(shù)和損失函數(shù)詳解
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(5)——計(jì)算機(jī)視覺(jué)基礎(chǔ)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(6)——神經(jīng)網(wǎng)絡(luò)性能優(yōu)化技術(shù)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(7)——批大小對(duì)神經(jīng)網(wǎng)絡(luò)訓(xùn)練的影響
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(8)——批歸一化
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(9)——學(xué)習(xí)率優(yōu)化
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(10)——過(guò)擬合及其解決方法
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(11)——卷積神經(jīng)網(wǎng)絡(luò)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(12)——數(shù)據(jù)增強(qiáng)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(13)——可視化神經(jīng)網(wǎng)絡(luò)中間層輸出
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(14)——類激活圖
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(15)——遷移學(xué)習(xí)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(16)——面部關(guān)鍵點(diǎn)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(17)——多任務(wù)學(xué)習(xí)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(18)——目標(biāo)檢測(cè)基礎(chǔ)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(19)——從零開(kāi)始實(shí)現(xiàn)R-CNN目標(biāo)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(20)——從零開(kāi)始實(shí)現(xiàn)Fast R-CNN目標(biāo)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(21)——從零開(kāi)始實(shí)現(xiàn)Faster R-CNN目標(biāo)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(22)——從零開(kāi)始實(shí)現(xiàn)YOLO目標(biāo)檢測(cè)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(23)——使用U-Net架構(gòu)進(jìn)行圖像分割
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(24)——從零開(kāi)始實(shí)現(xiàn)Mask R-CNN實(shí)例分割
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(25)——自編碼器(Autoencoder)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(26)——卷積自編碼器(Convolutional Autoencoder)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(27)——變分自編碼器(Variational Autoencoder, VAE)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(28)——對(duì)抗攻擊(Adversarial Attack)
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(29)——神經(jīng)風(fēng)格遷移
PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(30)——Deepfakes文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-461928.html
到了這里,關(guān)于PyTorch深度學(xué)習(xí)實(shí)戰(zhàn)(1)——神經(jīng)網(wǎng)絡(luò)與模型訓(xùn)練過(guò)程詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!