4.7 權重初始化方法
良好的模型權重初始化,有利於模型的訓練,在torch.nn.init中提供了數十個初始化方法,本小節對它們進行介紹。
回顧上一小節中VGG的初始化代碼,先總結出權重初始化的流程與步驟。
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode="fan_out", nonlinearity="relu")
if m.bias is not None:
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.BatchNorm2d):
nn.init.constant_(m.weight, 1)
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.Linear):
nn.init.normal_(m.weight, 0, 0.01)
nn.init.constant_(m.bias, 0)
Copy
首先對每一個子module進行遍歷,對不同的網路層進行設置對應的權重初始化方法,初始化方法採用的是nn.init.xxx函數。
接下來nn.init.xxx就是本節的主角,下面依次介紹nn.init.xxx函數。
主要分為三部分:
- Xavier 系列
- kaiming 系列
- 常數方法
Xavier 系列
- torch.nn.init.xavieruniform(tensor, gain=1.0)
xavier 初始化方法中服從均勻分佈 U(-a,a) ,分佈的參數 a = gain * sqrt(6/fan_in+fan_out),
這裡有一個 gain,表示增益,其大小取決於啟動函數的類型。本方法也稱為 Glorot initialization。
- torch.nn.init.xaviernormal(tensor, gain=1.0)
xavier初始化方法中服從正態分佈,
mean=0,std = gain * sqrt(2/fan_in + fan_out)
Xavier初始化方法的理論分析可見《Understanding the difficulty of training deep feedforward neural networks - Glorot, X. & Bengio, Y. (2010),》
Kaiming系列
3.### torch.nn.init.kaiminguniform(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
此為均勻分佈,U~(-bound, bound), bound = sqrt(6/(1+a^2)*fan_in)
其中,a為啟動函數的負半軸的斜率,relu是0
mode- 可選為fan_in 或 fan_out, fan_in使正向傳播時,方差一致; fan_out使反向傳播時,方差一致
nonlinearity- 可選 relu 和 leaky_relu ,預設值為 :leaky_relu
- torch.nn.init.kaimingnormal(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
此為0均值的正態分佈,N~ (0,std),其中std = sqrt(2/(1+a^2)*fan_in)
其中,a為啟動函數的負半軸的斜率,relu是0
mode- 可選為fan_in 或 fan_out, fan_in使正向傳播時,方差一致;fan_out使反向傳播時,方差一致
nonlinearity- 可選 relu 和 leaky_relu ,預設值為: leaky_relu
Kaiming系列的初始化方法理論分析可參閱《Delving deep into rectifiers: Surpassing human-level performance on ImageNet classification - He, K. et al. (2015》
其它方法
- 均勻分佈初始化
torch.nn.init.uniform_(tensor, a=0, b=1)
使值服從均勻分佈U(a,b)
- 正態分佈初始化
torch.nn.init.normal_(tensor, mean=0, std=1)
使值服從正態分佈N(mean, std),預設值為0,1
- 常數初始化
torch.nn.init.constant_(tensor, val)
使值為常數val nn.init.constant_(w, 0.3)
- 單位矩陣初始化
torch.nn.init.eye_(tensor)
將二維tensor初始化為單位矩陣(the identity matrix)
- 正交初始化
torch.nn.init.orthogonal_(tensor, gain=1)
使得tensor是正交的,論文:Exact solutions to the nonlinear dynamics of learning in deep linear neural networks” - Saxe, A. et al. (2013)
- 稀疏初始化
torch.nn.init.sparse_(tensor, sparsity, std=0.01)
從正態分佈N~(0. std)中進行稀疏化,使每一個column有一部分為0
sparsity- 每一個column稀疏的比例,即為0的比例
nn.init.sparse_(w, sparsity=0.1)
- 全零初始化
torch.nn.init.zeros_(tensor)
所有參數置零。
- 全1初始化
torch.nn.init.ones_(tensor)
所有參數置一。
- 狄拉克初始化
torch.nn.init.dirac_(tensor, groups=1)
採用狄拉克函數進行權重初始化,
- 增益計算
torch.nn.init.calculate_gain(nonlinearity, param=None)
返回各啟動函數對應的增益值,該值用於調整權重初始化的方差。
nonlinearity |
gain |
---|---|
Linear / Identity |
1 |
Conv{1,2,3}D |
1 |
Sigmoid |
1 |
Tanh |
35 |
ReLU |
2 |
Leaky Relu |
1+negative_slope22 |
SELU |
43 |
小結
本小節將torch.nn.init中包含的初始化方法進行了分類介紹,主要分為Xavier和Kaiming方法與其它常數方法,並且回顧了torchvision中如何對一個模型所有層進行權重初始化的流程,希望對大家有所幫助。