权重初始化
目錄
1.為什么需要好的權重初始化
2.kaiming初始化的兩個方法
2.1先來個結論
2.2再來個源碼
3.推導的先驗知識
3.1用變量來看待問題
3.2幾個公式
4.kaiming初始化
4.1前向傳播時每層的方差都是1
4.2反向傳播時梯度的方差都是1
【導語】在CNN的訓練中,權重初始化是一個比較關鍵的點。好的權重初始化可以讓網絡的訓練過程更加穩定和高效。本文為大家介紹了kaiming初始化以及詳細的推導過程,希望可以讓大家更好的理解CNN初始化。
1.為什么需要好的權重初始化
網絡訓練的過程中, 容易出現梯度消失(梯度特別的接近0)和梯度爆炸(梯度特別的大)的情況,導致大部分反向傳播得到的梯度不起作用或者起反作用. 研究人員希望能夠有一種好的權重初始化方法: 讓網絡前向傳播或者反向傳播的時候, 卷積的輸出和前傳的梯度比較穩定. 合理的方差既保證了數值一定的不同, 又保證了數值一定的穩定.(通過卷積權重的合理初始化, 讓計算過程中的數值分布穩定)
2.kaiming初始化的兩個方法
2.1先來個結論
前向傳播的時候, 每一層的卷積計算結果的方差為1.
反向傳播的時候, 每一 層的繼續往前傳的梯度方差為1(因為每層會有兩個梯度的計算, 一個用來更新當前層的權重, 一個繼續傳播, 用于前面層的梯度的計算.)
2.2再來個源碼
方差的計算需要兩個值:gain和fan.?gain值由激活函數決定.?fan值由權重參數的數量和傳播的方向決定.?fan_in表示前向傳播,?fan_out表示反向傳播.
def?kaiming_normal_(tensor,?a=0,?mode='fan_in',?nonlinearity='leaky_relu'):fan?=?_calculate_correct_fan(tensor,?mode)?#?通過mode判斷是前向傳播還是反向傳播,?生成不同的一個fan值.gain?=?calculate_gain(nonlinearity,?a)#?通過判斷是哪種激活函數生成一個gain值std?=?gain?/?math.sqrt(fan)?#?通過fan值和gain值進行標準差的計算with?torch.no_grad():return?tensor.normal_(0,?std)下面的代碼根據網絡設計時卷積權重的形狀和前向傳播還是反向傳播, 進行fan值的計算.
def?_calculate_fan_in_and_fan_out(tensor):dimensions?=?tensor.dim()?#?返回的是維度if?dimensions?<?2:raise?ValueError("Fan?in?and?fan?out?can?not?be?computed?for?tensor?with?fewer?than?2?dimensions")if?dimensions?==?2:??#?Linearfan_in?=?tensor.size(1)?fan_out?=?tensor.size(0)else:num_input_fmaps?=?tensor.size(1)?#?卷積的輸入通道大小num_output_fmaps?=?tensor.size(0)?#?卷積的輸出通道大小receptive_field_size?=?1if?tensor.dim()?>?2:receptive_field_size?=?tensor[0][0].numel()?#?卷積核的大小:k*kfan_in?=?num_input_fmaps?*?receptive_field_size?#?輸入通道數量*卷積核的大小.?用于前向傳播fan_out?=?num_output_fmaps?*?receptive_field_size?#?輸出通道數量*卷積核的大小.?用于反向傳播return?fan_in,?fan_outdef?_calculate_correct_fan(tensor,?mode):mode?=?mode.lower()valid_modes?=?['fan_in',?'fan_out']if?mode?not?in?valid_modes:raise?ValueError("Mode?{}?not?supported,?please?use?one?of?{}".format(mode,?valid_modes))fan_in,?fan_out?=?_calculate_fan_in_and_fan_out(tensor)return?fan_in?if?mode?==?'fan_in'?else?fan_out下面是通過不同的激活函數返回一個gain值, 當然也說明了是recommend. 可以自己修改.
def?calculate_gain(nonlinearity,?param=None):r"""Return?the?recommended?gain?value?for?the?given?nonlinearity?function.The?values?are?as?follows:=================?====================================================nonlinearity??????gain=================?====================================================Linear?/?Identity?:math:`1`Conv{1,2,3}D??????:math:`1`Sigmoid???????????:math:`1`Tanh??????????????:math:`\frac{5}{3}`ReLU??????????????:math:`\sqrt{2}`Leaky?Relu????????:math:`\sqrt{\frac{2}{1?+?\text{negative\_slope}^2}}`=================?====================================================Args:nonlinearity:?the?non-linear?function?(`nn.functional`?name)param:?optional?parameter?for?the?non-linear?functionExamples:>>>?gain?=?nn.init.calculate_gain('leaky_relu',?0.2)??#?leaky_relu?with?negative_slope=0.2"""linear_fns?=?['linear',?'conv1d',?'conv2d',?'conv3d',?'conv_transpose1d',?'conv_transpose2d',?'conv_transpose3d']if?nonlinearity?in?linear_fns?or?nonlinearity?==?'sigmoid':return?1elif?nonlinearity?==?'tanh':return?5.0?/?3elif?nonlinearity?==?'relu':return?math.sqrt(2.0)elif?nonlinearity?==?'leaky_relu':if?param?is?None:negative_slope?=?0.01elif?not?isinstance(param,?bool)?and?isinstance(param,?int)?or?isinstance(param,?float):#?True/False?are?instances?of?int,?hence?check?abovenegative_slope?=?paramelse:raise?ValueError("negative_slope?{}?not?a?valid?number".format(param))return?math.sqrt(2.0?/?(1?+?negative_slope?**?2))else:raise?ValueError("Unsupported?nonlinearity?{}".format(nonlinearity))下面是kaiming初始化均勻分布的計算. 為啥還有個均勻分布??權重初始化推導的只是一個方差, 并沒有限定是正態分布, 均勻分布也是有方差的, 并且均值為0的時候, 可以通過方差算出均勻分布的最小值和最大值.
def?kaiming_uniform_(tensor,?a=0,?mode='fan_in',?nonlinearity='leaky_relu'):fan?=?_calculate_correct_fan(tensor,?mode)gain?=?calculate_gain(nonlinearity,?a)std?=?gain?/?math.sqrt(fan)bound?=?math.sqrt(3.0)?*?std??#?Calculate?uniform?bounds?from?standard?deviationwith?torch.no_grad():return?tensor.uniform_(-bound,?bound)3.推導的先驗知識
3.1用變量來看待問題
?
參照上面的卷積圖, 對輸入的特征圖進行3*3的卷積. 具體要研究的是輸出的一個點的方差(紫色點). 所以是通過黃色的輸入(3*3*3=27個)和綠色的卷積參數(3*3*3=27個)去計算一個輸出值(紫色輸出)的方差.?一個點對應于原論文里面的說法為a response. 感覺這個是理解權重初始化的重點. 基于獨立同分布的強假設: 輸入的每個值都是獨立同分布的, 所以和獨立同分布的參數進行卷積得到結果的分布也是相同的. 所以其他的3個輸出點的方差也是一樣的. 進一步說, 雖然輸入是4*4*3=48個不同的值. 但是我們可以這樣認為:?有一個滿足某分布的隨機變量, 然后隨機抽樣48次, 這48個值就可以組成了輸入, 且獨立同分布(也可稱輸入的每個像素點是獨立同分布的). 卷積的參數也可以這么認為. 那么我們可以用一個隨機變量x表示48個輸入, 也可以用一個隨機變量w表示27個卷積參數, 亦可以用一個隨機變量y表示4個輸出值.
3.2幾個公式
(1)式表示獨立隨機變量之和的方差等于各變量的方差之和, 如果和還是同分布的,那么
.
將這個應用在卷積求和的那一步(卷積先相乘, 再求和).
(2)式是通過期望求方差的公式, 方差等于平方的期望減去期望的平方. 如果, 那么.
(3)式是獨立變量乘積的一個公式(協方差為0). 如果, 那么.
4.kaiming初始化
kaiming初始化的推導過程只包含卷積和ReLU激活函數, 默認是vgg類似的網絡, 沒有殘差, concat之類的結構, 也沒有BN層.
此處,表示某個位置的輸出值,表示被卷積的輸入,有k*k*c形狀(對應于上圖的黃色部分), k表示卷積核的大小,c表示輸入的通道.令n=k*k*c,則n的大小表示一個輸出值是由多少個輸入值計算出來的(求方差的時候用到).W有d*n形狀, d表示的輸出通道的數量.下標l表示第幾層., f 表示激活函數ReLU, 表示前一層的輸出經過激活函數變成下一層的輸入.?表示網絡下一層的輸入通道數等于上一層的輸出通道數.(這里是對應原論文的翻譯了)
4.1前向傳播時每層的方差都是1
因為一個輸出的y是由n個輸入的x和其n個權重相乘再求和得到的(卷積的過程), 且假設權重數值之間是獨立同分布的,數值之間也是獨立同分布的,且和權重相互獨立。那么根據(1)式得
其中的y,w,x都表示隨機變量, l表示第幾層. 舉個例子,
其中,看作一個整體, 且1到6之間相互獨立, 就能得到,
又如果之間又是同分布的, 那么他們的方差就是相同的, 就能得到.
進一步,因為是相互獨立的, 所以根據(3)式,可將(4)式推導為
初始化的時候令權重的均值是0, 且假設更新的過程中權重的均值一直是0,則,但是是上一層通過ReLU得到的,所以.
通過(2)式可得,則(6)式推導為
接下來求, 通過第l-1層的輸出來求此期望, 我們有, 其中f表示ReLU函數.
因為的時候?, 所以可以去掉小于0的區間, 并且大于0的時候, 所以可得
現因為是假設在0周圍對稱分布且均值為0, 所以也是在0附近分布是對稱的, 并且均值為0(此處假設偏置為0,). 則, 進一步可以得到
現在通過公式(2),?,其中的均值是0, 則,那么(10)式可進一步推導為
將(11)式帶入(7)式則為
然后從第一層一直往前進行前向傳播, 可以得到某層的方差為
這里的就是輸入的樣本, 我們會將其歸一化處理, 所以, 現在讓每層輸出方差等于1, 即
舉例層卷積, 輸入大小為32*16*16, 分別表示通道數量、高、寬, 卷積核大小為64*32*3*3, 分別表示輸出通道數量、輸入通道數量、卷積核高、卷積核寬. 則該層的權重
,
偏置初始化為0.64*32*3*3=18432 個參數都是從這個分布里面采樣. 也對應了Pytorch里面的kaiming初始化只要傳卷積核的參數進去就行了, 可以看下源碼對應的計算.
4.2反向傳播時梯度的方差都是1
其中,?表示損失函數對其求導. 與正常的反向傳播推導不一樣, 這里假設表示d個通道,每個通道k*k大小,?,與正向傳播的時候一樣,?有c個通道,?有d個通道.?的大小為,所以的形狀為c*1.只差了一個轉置(涉及到反向傳播). 同樣的想法是, 一個的值是很多個求得到, 繼續通過多個獨立同分布變量求一個變量(梯度)的方差. 假設隨機變量都是獨立同分布的,的分布在0附近對稱的, 則對每層L,均值都是0, 即. 因為前向傳播的時候
所以反向傳播則為
又因為f是ReLU, 導數要么是0要么是1, 那么假設兩者各占一半, 同時假設相互獨立.那么
其中, 將概率分為了兩部分,一部分對應的ReLU導數為0,一部分對應的ReLU導數為1 (且這兩部分假設都是50%的可能). 公式(17)表示對于一個的取值, 有一半概率對應ReLU導數為0,一般對應為1. 根據(2)式又得
(19)式也可以通過(10)式用類似的方法求出. 那么,
所以,按照前向推導的方法,最后得出的公式是
按照前向傳播最后的示例, 此處的應該為
總結
- 上一篇: tensorflow+numpy 深度学
- 下一篇: Linux+pycharm下 安装ten