PyTorch常用參數初始化方法詳解


1. 均勻分布

torch.nn.init.uniform_(tensor, a=0, b=1)

從均勻分布U(a, b)中采樣,初始化張量。

參數:

  • tensor - 需要填充的張量
  • a - 均勻分布的下界
  • b - 均勻分布的上界

代碼示例:

>>> w = torch.Tensor(3, 5)
>>> torch.nn.init.uniform_(w)
tensor([[0.1755, 0.4399, 0.8769, 0.8465, 0.2909],
        [0.9962, 0.6918, 0.1033, 0.7028, 0.5835],
        [0.1754, 0.8796, 0.1900, 0.9504, 0.4433]])

均勻分布詳解:

若 x 服從均勻分布,即 x~U(a,b),其概率密度函數(表征隨機變量每個取值有多大的可能性)為,

\[f(x)=\begin{cases}\dfrac{1}{b-a},\quad a\lt x\lt b\\ 0,\quad 其他 \end{cases}\\ \]

則有期望和方差,

\[E(x) = \int_{-\infty}^{\infty} xf(x)dx=\frac{1}{2}(a+b)\\ D(x) = E(x^2)-[E(x)]^2 = \frac{(b-a)^2}{12} \]

2. 正態(高斯)分布

torch.nn.init.normal_(tensor, mean=0.0, std=1.0)

從給定的均值和標准差的正態分布\(N(mean, std^2)\)中生成值,初始化張量。

參數:

  • tensor - 需要填充的張量
  • mean - 正態分布的均值
  • std - 正態分布的標准偏差

代碼示例:

>>> w = torch.Tensor(3, 5)
>>> torch.nn.init.normal_(w, mean=0, std=1)
tensor([[-0.9444, -0.3295,  0.1785,  0.4165,  0.3658],
        [ 0.5130, -1.1455, -0.1335, -1.6953,  0.2862],
        [-2.3368,  0.2380, -2.2001, -0.5455,  0.8179]])

正態分布詳解:

若隨機變量x服從正態分布,即 \(x\sim N(\mu, \sigma^2)\), 其概率密度函數為,

\[f(x) = \frac{1}{\sigma\sqrt{2\pi}}\exp\left(-\frac{(x-\mu^2)}{2\sigma^2}\right) \]

正態分布概率密度函數中一些特殊的概率值:

  • 68.268949%的面積在平均值左右的一個標准差\(\sigma\)范圍內(\(\mu\pm\sigma\))
  • 95.449974%的面積在平均值左右兩個標准差\(2\sigma\)的范圍內(\(\mu\pm2\sigma\))
  • 99.730020%的面積在平均值左右三個標准差\(3\sigma\)的范圍內(\(\mu\pm3\sigma\))
  • 99.993666%的面積在平均值左右四個標准差\(4\sigma\)的范圍內(\(\mu\pm4\sigma\))

\(\mu=0, \sigma=1\)時的正態分布是標准正態分布

3. Xavier初始化

3.1 Xavier均勻分布初始化

torch.nn.init.xavier_normal_(tensor, gain=1.0)

又稱Glorot初始化,按照Glorot, X. & Bengio, Y.(2010)在論文Understanding the difficulty of training deep feedforward neural networks中描述的方法,從均勻分布U(−a, a)中采樣,初始化輸入張量tensor,其中a值由下式確定:

\[\rm a=gain\times\sqrt{\dfrac{6}{fan\_in+fan\_out}} \]

參數:

  • tensor - 需要初始化的張量
  • gain - 可選的放縮因子

代碼示例:

>>> w = torch.Tensor(3, 5)
>>> torch.nn.init.xavier_uniform_(w, gain=torch.nn.init.calculate_gain('relu'))
tensor([[ 0.2481, -0.8435,  0.0588,  0.1573,  0.2759],
        [ 0.2016, -0.5504, -0.5280, -0.3070,  0.0889],
        [-0.9897, -0.9890, -0.8091,  0.8624, -0.5661]])

3.2 Xavier正態分布初始化

torch.nn.init.xavier_normal_(tensor, gain=1.0)

又稱Glorot初始化,按照Glorot, X. & Bengio, Y.(2010)在論文Understanding the difficulty of training deep feedforward neural networks中描述的方法,從正態分布\(N(0, std^2)\)中采樣,初始化輸入張量tensor,其中std值由下式確定:

\[\rm std=gain\times\sqrt{\dfrac{2}{fan\_in+fan\_out}} \]

參數:

  • tensor - 需要初始化的張量
  • gain - 可選的放縮因子

代碼示例:

>>> w = torch.Tensor(3, 5)
>>> torch.nn.init.xavier_normal_(w)
tensor([[ 0.6707, -0.3928, -0.0894,  0.4096,  0.4631],
        [ 0.1267, -0.5806,  0.3407, -0.1110, -0.2400],
        [-0.4212,  0.2857, -0.1210, -0.2891,  0.7141]])

3.3 Xavier初始化方法的由來:

神經網絡的參數可以初始化全為0嗎?當然不能。如果初始化為全0,輸入經過每個神經元后的輸出都是一樣的,且后向傳播時梯度根本無法向后傳播(因為求梯度公式里有個乘積因子是參數w,全0的參數使得梯度全沒了,感興趣的可以去查看神經網絡的BP推導過程),這樣的模型訓練一萬年也沒有意義。

如果不能初始化為全0,那么我們應該如何初始化呢?

在深層神經網絡中,每一層的輸出都是下一層的輸入,為了使網絡中的信息更好的流動,應保證每層方差盡可能相等(可以把前向傳播過程看作是輸入和一系列參數的連乘,若數值過大容易進入飽和區,反向傳播時數值過大可能造成梯度爆炸,反之可能梯度消失)。因此,參數初始化就可以看作是從某個概率分布的區間中進行采樣的過程,則初始化問題轉化為求解特定概率分布的參數問題。

那么又如何保證每一層的方差盡可能相等呢?即\(Var(z^{l-1})=Var(z^l)\)

先考慮單層網絡,n為神經元的數量,輸出z的表達式為,

\[z=\sum\limits_{i=1}^n w_i x_i \]

根據概率統計中的方差公式,有,

\[Var(w_i x_i)=Var(w_i)Var(x_i)+E[w_i]^2Var(x_i)+E[x_i]^2Var(w_i) \]

當輸入\(x_i\)和權重\(w_i\)的均值都是0時,即\(E[x_i]=E[w_i]=0\)(可使用BatchNormalization將輸入的均值置0),上式簡化為,

\[Var(w_i x_i)=Var(w_i)Var(x_i) \\ Var(z) = \sum\limits_{i=1}^nVar(w_ix_i) = \sum\limits_{i=1}^nVar(w_i)Var(x_i) \]

進一步,假設隨機變量\(w_i\)\(x_i\)為獨立同分布,則

\[Var(z)=nVar(w)Var(x) \]

若是輸入輸出的方差一致,即\(Var(z)=Var(x)\),應有,

\[Var(w)=\dfrac{1}{n} \]

其中n為輸入層的神經元數量,即論文中的fan_in,而輸出層的神經元數量fan_out往往和fan_in不相等,考慮到反向傳播時是從后往前計算,所以論文中取了二者的均值,即令

\[Var(w)=\dfrac{2}{\rm fan\_in+fan\_out} \]

由概率論基礎知識知,若隨機變量x服從區間[a,b]上的均勻分布,則x的方差為,

\[Var(x)=\dfrac{(b-a)^2}{12} \]

代入上邊\(Var(w)\)的方差公式,可以解得\(b-a=\dfrac{2\sqrt6}{\sqrt{\rm fan\_in+fan\_out}}\),即得參數w均勻采樣情況下的采樣區間,

\[w\sim U(-\dfrac{\sqrt6}{\sqrt{\rm fan\_in+fan\_out}},\dfrac{\sqrt6}{\sqrt{\rm fan\_in+fan\_out}}) \]

以上就是采用Xavier初始化方法,對均勻分布的參數進行求解的過程。同理,可以推出正態分布采樣下的參數分布滿足,

\[w\sim N(0,\dfrac{2}{\rm fan\_in+fan\_out}) \]

由於Xavier初始化方法是基於“均值為0”這個假設推導出的,對於ReLU等激活函數,其輸出均大於等於0,\(E(x_i)=0\)的假設不再成立,所以Xavier初始化方法對ReLU通常效果不好。

4. kaiming初始化

4.1 kaiming均勻分布初始化

torch.nn.init.kaiming_uniform_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')

又稱He初始化,按照He, K. et al. (2015)在論文Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification中描述的方法,從均勻分布U(−bound, bound)中采樣,初始化輸入張量tensor,其中bound值由下式確定:

\[\rm bound=gain\times\sqrt{\dfrac{3}{fan\_mode}} \]

參數:

  • tensor - 需要初始化的張量
  • a - 這層之后使用的rectifier的斜率系數,用來計算\(\rm gain=\sqrt{\dfrac{2}{1+a^2}}\) (此參數僅在參數nonlinearity為'leaky_relu'時生效)
  • mode - 可以為“fan_in”(默認)或“fan_out”。“fan_in”維持前向傳播時權值方差,“fan_out”維持反向傳播時的方差
  • nonlinearity - 非線性函數(nn.functional中的函數名),pytorch建議僅與“relu”或“leaky_relu”(默認)一起使用。

代碼示例:

>>> w = torch.Tensor(3, 5)
>>> torch.nn.init.kaiming_uniform_(w, mode='fan_in', nonlinearity='relu')
tensor([[-0.3387,  0.8507,  0.5339, -0.2552,  0.4829],
        [ 0.6565, -0.7444, -0.2138, -0.9352, -0.1449],
        [-0.7871,  0.4095,  0.3562, -0.2796, -0.8638]])

4.1 kaiming正態分布初始化

torch.nn.init.kaiming_normal_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')

又稱He初始化,按照He, K. et al. (2015)在論文Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification中描述的方法,從正態分布\(N(0, std^2)\)中采樣,初始化輸入張量tensor,其中std值由下式確定:

\[\rm std=\dfrac{gain}{\sqrt{fan\_mode}} \]

參數:

  • tensor - 需要初始化的張量
  • a - 這層之后使用的rectifier的斜率系數,用來計算\(\rm gain=\sqrt{\dfrac{2}{1+a^2}}\) (此參數僅在參數nonlinearity為'leaky_relu'時生效)
  • mode - 可以為“fan_in”(默認)或“fan_out”。“fan_in”維持前向傳播時權值方差,“fan_out”維持反向傳播時的方差
  • nonlinearity - 非線性函數(nn.functional中的函數名),pytorch建議僅與“relu”或“leaky_relu”(默認)一起使用。

代碼示例:

>>> w = torch.Tensor(3, 5)
>>> torch.nn.init.kaiming_normal_(w, mode='fan_out', nonlinearity='relu')
tensor([[ 0.0251,  0.5042,  1.7288,  0.8096, -0.2114],
        [ 0.0527,  0.2605,  0.8833,  0.4466,  1.8076],
        [-1.1390, -0.8388, -1.0632,  0.0480, -0.2835]])

6. 正交矩陣初始化

torch.nn.init.orthogonal_(tensor, gain=1)

用一個(半)正交矩陣初始化輸入張量,參考Saxe, A. et al. (2013) - Exact solutions to the nonlinear dynamics of learning in deep linear neural networks。輸入張量必須至少有2維,對於大於2維的張量,超出的維度將被flatten化。

正交初始化可以使得卷積核更加緊湊,可以去除相關性,使模型更容易學到有效的參數。

參數:

  • tensor - 需要初始化的張量
  • gain - 可選的放縮因子

代碼示例:

>>> w = torch.Tensor(3, 5)
>>> torch.nn.init.orthogonal_(w)
tensor([[ 0.1725,  0.7215, -0.3494, -0.3499,  0.4530],
        [ 0.7070,  0.0384, -0.0893, -0.3016, -0.6322],
        [-0.0815,  0.6231,  0.7038,  0.2127, -0.2542]])

7. 稀疏矩陣初始化

torch.nn.init.sparse_(tensor, sparsity, std=0.01)

將2維的輸入張量作為稀疏矩陣填充,其中非零元素由正態分布\(N(0,0.01^2)\)生成。 參考Martens, J.(2010)的 Deep learning via Hessian-free optimization

參數:

  • tensor - 需要填充的張量
  • sparsity - 每列中需要被設置成零的元素比例
  • std - 用於生成非零元素的正態分布的標准偏差

代碼示例:

>>> w = torch.Tensor(3, 5)
>>> torch.nn.init.sparse_(w, sparsity=0.1)
tensor([[ 0.0030,  0.0000,  0.0049, -0.0161,  0.0000],
        [-0.0081, -0.0022,  0.0000,  0.0112,  0.0060],
        [ 0.0000, -0.0211,  0.0161,  0.0000,  0.0147]])


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM