模型統(tǒng)計(jì)數(shù)據(jù)(Model Statistics)
統(tǒng)計(jì)參數(shù)總數(shù)量
num_params = sum(param.numel() for param in model.parameters())
參數(shù)初始化(Weight Initialization)
PyTorch 中參數(shù)的默認(rèn)初始化在各個(gè)層的 reset_parameters() 方法中抱婉。例如:nn.Linear 和 nn.Conv2D档叔,都是在 [-limit, limit] 之間的均勻分布(Uniform distribution),其中 limit 是 1. / sqrt(fan_in) 蒸绩,fan_in 是指參數(shù)張量(tensor)的輸入單元的數(shù)量
下面是幾種常見(jiàn)的初始化方式。
Xavier Initialization
Xavier初始化的基本思想是保持輸入和輸出的方差一致铃肯,這樣就避免了所有輸出值都趨向于0患亿。這是通用的方法,適用于任何激活函數(shù)。
# 默認(rèn)方法
for m in model.modules():
if isinstance(m, (nn.Conv2d, nn.Linear)):
nn.init.xavier_uniform(m.weight)
也可以使用 gain 參數(shù)來(lái)自定義初始化的標(biāo)準(zhǔn)差來(lái)匹配特定的激活函數(shù):
for m in model.modules():
if isinstance(m, (nn.Conv2d, nn.Linear)):
nn.init.xavier_uniform(m.weight(), gain=nn.init.calculate_gain(\\'relu\\'))
參考資料:
He et. al Initialization
He initialization的思想是:在ReLU網(wǎng)絡(luò)中步藕,假定每一層有一半的神經(jīng)元被激活惦界,另一半為0。推薦在ReLU網(wǎng)絡(luò)中使用咙冗。
# he initialization
for m in model.modules():
if isinstance(m, (nn.Conv2d, nn.Linear)):
nn.init.kaiming_normal(m.weight, mode=\\'fan_in\\')
正交初始化(Orthogonal Initialization)
主要用以解決深度網(wǎng)絡(luò)下的梯度消失沾歪、梯度爆炸問(wèn)題,在RNN中經(jīng)常使用的參數(shù)初始化方法
for m in model.modules():
if isinstance(m, (nn.Conv2d, nn.Linear)):
nn.init.orthogonal(m.weight)
Batchnorm Initialization
在非線性激活函數(shù)之前雾消,我們想讓輸出值有比較好的分布(例如高斯分布)灾搏,以便于計(jì)算梯度和更新參數(shù)。Batch Normalization 將輸出值強(qiáng)行做一次 Gaussian Normalization 和線性變換:
for m in model:
if isinstance(m, nn.BatchNorm2d):
nn.init.constant(m.weight, 1)
nn.init.constant(m.bias, 0)
參數(shù)正則化(Weight Regularization)
L2/L1 Regularization
機(jī)器學(xué)習(xí)中幾乎都可以看到損失函數(shù)后面會(huì)添加一個(gè)額外項(xiàng)立润,常用的額外項(xiàng)一般有兩種狂窑,稱作L1正則化和L2正則化,或者L1范數(shù)和L2范數(shù)桑腮。
L1 正則化和 L2 正則化可以看做是損失函數(shù)的懲罰項(xiàng)泉哈。所謂 “懲罰” 是指對(duì)損失函數(shù)中的某些參數(shù)做一些限制。
L1 正則化是指權(quán)值向量 w 中各個(gè)元素的絕對(duì)值之和破讨,通常表示為 ||w||1
L2 正則化是指權(quán)值向量 w 中各個(gè)元素的平方和然后再求平方根丛晦,通常表示為 ||w||2
下面是L1正則化和L2正則化的作用,這些表述可以在很多文章中找到提陶。
L1 正則化可以產(chǎn)生稀疏權(quán)值矩陣采呐,即產(chǎn)生一個(gè)稀疏模型,可以用于特征選擇
L2 正則化可以防止模型過(guò)擬合(overfitting)搁骑;一定程度上斧吐,L1也可以防止過(guò)擬合
- L2 正則化的實(shí)現(xiàn)方法:
reg = 1e-6
l2_loss = Variable(torch.FloatTensor(1), requires_grad=True)
for name, param in model.named_parameters():
if \'bias\' not in name:
l2_loss = l2_loss (0.5 * reg * torch.sum(torch.pow(W, 2)))
- L1 正則化的實(shí)現(xiàn)方法:
reg = 1e-6
l1_loss = Variable(torch.FloatTensor(1), requires_grad=True)
for name, param in model.named_parameters():
if \'bias\' not in name:
l1_loss = l1_loss (reg * torch.sum(torch.abs(W)))
- Orthogonal Regularization
reg = 1e-6
orth_loss = Variable(torch.FloatTensor(1), requires_grad=True)
for name, param in model.named_parameters():
if \'bias\' not in name:
param_flat = param.view(param.shape[0], -1)
sym = torch.mm(param_flat, torch.t(param_flat))
sym -= Variable(torch.eye(param_flat.shape[0]))
orth_loss = orth_loss (reg * sym.sum())
- Max Norm Constraint
簡(jiǎn)單來(lái)講就是對(duì) w 的指直接進(jìn)行限制。
ef max_norm(model, max_val=3, eps=1e-8):
for name, param in model.named_parameters():
if \'bias\' not in name:
norm = param.norm(2, dim=0, keepdim=True)
desired = torch.clamp(norm, 0, max_val)
param = param * (desired / (eps norm))