前言
本文是筆者在學習吳恩達的深度學習課程時所碰到的問題。在課程中僅概述了此問題的發生原因,藉此引導出隨機初始化神經網路權重的必要性,並沒有給出嚴謹的數學推導。筆者試著把中間缺少的數學推導過程補上,並將之記錄於此。
“為何不能用0來初始化神經網路?”,這個問題的答案簡單來說,是因為這樣做的話,會造成weight symmetry的問題。也就是說網路同一層中的每個神經元都發揮一樣的功能,而這個問題在訓練過程中是會持續存在的。
那為什麼邏輯回歸模型可以用0來初始化呢?答案就在於兩者模型架構的不同——也就是有沒有隱藏層的區別。
以下我們將實際觀察兩種模型的前向及反向傳播過程,並從中找出問題發生的原因。
邏輯回歸的前向傳播
邏輯回歸模型並沒有隱藏層,輸入向量與權重向量做內積後加上偏置量得到z值。把z值丟到sigmoid激活函數中可得到激活值a,最後便可利用這個a值與label(即y)做運算得到loss。
其中
a=sigmoid(z)=1+e−z1
且
L(a,y)=−(ylog(a)+(1−y)log(1−a))
邏輯回歸的反向傳播
反向傳播是計算loss對模型中各參數的梯度(偏微分)的過程。得到梯度以後,便可以使用SGD, Momentum, AdaGrad, RMSProp, Adam等算法來學習模型的參數。
以下是邏輯回歸模型的反向傳播的計算過程:
損失函數L對a的微分為:
dadL=−ay+1−a1−y
損失函數L對z的微分為:
dzdL=dadLdzda
其中
dadL己在上上式得到,以下計算
dzda的部份。
dzda=((1+e−z)−1)′=−(1+e−z)−2∗(−e−z)=(1+e−z)−2∗e−z=1+e−z1∗1+e−ze−z=1+e−z1∗(1−1+e−z1)=a∗(1−a)
於是便可以得到
dzdL=(−ay+1−a1−y)∗(a∗(1−a))=a−y
最後是損失函數對weight及bias的微分:
dwdL=dzdL∗dwdz=dzdL∗xT
dbdL=dzdL∗dbdz=dzdL
以0初始化邏輯回歸模型
如果我們以0來初始化模型權重,那麼在第一個epoch中各權重的值都會是相同的。但是在接下來的權重更新過程中,這個對稱就會被打破,原因如下。
第一次權重更新
dwdL是由
dzdL(=a−y)與
xT做矩陣乘法得來,而這兩個矩陣中的元素並不存在什麼規律,因此
dwdL矩陣並不在在symmetry的情況。
在權重更新的過程,即
w=w−alpha∗dwdL,
w中的元素也不會都是相同的值,所以weight symmetry在第一個epoch結束時便可成功打破!
扫描二维码关注公众号,回复:
4226520 查看本文章
神經網路的前向傳播
如下圖,計算過程與邏輯回歸模型雷同,差別只在於多了一個隱藏層。
神經網路的反向傳播
此處沿用課程中的符號表示法:
- 將samples的維度皆擺在最後一維,如X的維度為(#features, #samples)。
- 將
dXdL簡寫為
dX。
dA[2]=−A[2]Y+1−A[2]1−Y
dZ[2]=A[2]−Y
dW[2]=m1dZ[2]A[1]T
db[2]=m1np.sum(dZ[2],axis=1,keepdims=True)
dA[1]=W[2]TdZ[2]=W[2]T(A[2]−Y)
dZ[1]=dA[1]∗σ′(Z[1])=W[2]T(A[2]−Y)∗A[1]∗(1−A[1])
dW[1]=m1dZ[1]XT
db[1]=m1np.sum(dZ[1],axis=1,keepdims=True)=m1np.sum(W[2]T(A[2]−Y)∗A[1]∗(1−A[1]),axis=1,keepdims=True)
神經網路的權重更新
W[2]=W[2]−αdW[2]=W[2]−αm1(A[2]−Y)A[1]T
W[1]=W[1]−αdW[1]=W[1]−αm1(W[2]T(A[2]−Y)∗A[1]∗(1−A[1]))XT
其中
W[2]的形狀為
(n[2],
n[1]),
W[1]的形狀為
(n[1],
n[0])。
A[2]及
y的形狀為
(n[2],m),
A[1]的形狀為
(n[1],m).
Z[2]的形狀為
(n[2],m),
Z[1]的形狀為
(n[1],m).
XT的形狀為
(n[0],m).
注意上面二式中特別以
∗符號表示的皆為逐元素相乘,其餘乘法為純量乘法或矩陣乘法。
以0初始化神經網路
假設
m=5,n[0]=3,n[1]=4,n[2]=2。
我們將
W[1],
b[1],
W[2]和
b[2]皆設為0矩陣,並且將學習率設為0.01。
因為
b[1]和
b[2]是什麼值與weight symmetry並無直接關係,因此在下文中僅考慮
W[1]及
W[2]的權重更新。
第一次權重更新
前向傳播
依據前向傳播的公式,可以得到:
A[2]=σ(b[2])(全是0.5,形狀為(n[2],m)的矩陣)
,及
A[1]=σ(b[1])(全是0.5,形狀為(n[1],m)的矩陣)
反向傳播
首先回憶
dW[2]=m1dZ[2]A[1]T。
其中
dZ[2]等於
A[2]−Y,這一項中的各元素並沒有什麼規律。
但是因為
A[1]T中的每個元素都一樣,
做矩陣乘法後,
dW[2]中的每個column都一樣。
而權重更新後的
W[2]中的每個column也都是一樣的。
再來看
W[1]及
b[1]。因為
dW[1]及
db[1]的中都有一項
W[2],所以在矩陣乘法後它們都會變成0矩陣。因此在第一次更新中
W[1]及
b[1]仍維持原本的值。下圖為更新後的
W[1]。
第二次權重更新
因為
W[1]跟
b[1]在第一次更新中仍然是0矩陣,因此
A[1]仍然是一個全是0.5的矩陣。
與第一次更新時的情況一樣,經過矩陣乘法得到的
dW[2]當中的每個column都一樣。
因此第二次更新後的
W[2]也是各column都一樣。
再來看
W[1]的更新過程。因為前一輪的
W[2]T中的各row都一樣,
與不規則的
A[2]−y
做矩陣乘法後會得到一個各row都一樣的
dA[1]。
將這個矩陣與
A[1]∗(1−A[1])
做逐元素相乘後的得到的
dZ[1]中各row仍然一樣:
而
dW[1]=m1dZ[1]XT:
因此更新後的
W[1]中的每個row都是一樣的。
第三次權重更新
因為
W[1]中的各row都是一樣的,所以
A[1]也是一樣。
我們可以接著看出
dW[2]=m1dZ[2]A[1]T中的各column都是一樣的。
因此更新後的
W[2]也是各column都一樣,
接著來看
W[1]的更新過程:
第二次更新後的
W[2]T中的各row都是一樣的,
做運算後得到的
dZ[1]中的各row也是一樣的。
而
dW[1]=m1dZ[1]XT:
最後我們得到更新後的
W[1],它的各row也都是一樣的:
因此在本次權重更新中,weight symmetry仍然未被打破。
我們可以預見,只要前一輪的
W[1]各row一樣,更新後的
W[2]的各column就會一樣;並且只要前一輪的
W[2]各column一樣,更新後的
W[1]的各row就會一樣。這個情況會不斷地輪迴,無法被打破。
結論
讓我們來看看到底是什麼原因造成了無法打破的weight symmetry。
在這之前,我們先來回顧一下為何邏輯回歸模型中不會出現這種情況。
我們發現,用來更新權重的
dwdL是由
dzdL=a−y與
x相乘得來,而
a−y與
x兩個矩陣中的每個元素都不同,因此他們相乘得到的
dwdL便不會有對稱的問題。
而在神經網路中,因為第二層的
dZ[2]=(A[2]−Y)與第零層的
X無法直接接觸,它們中間隔了其它具有weight symmetry特性的矩陣,所以weight symmetry無法消除,而這就是我們必須隨機初始化神經網路權重的真正原因!
注:以上實驗結果來自NN zero_initialization.py,需要的同學可以前往參看。