Pytorch常用技巧

转载自 https://www.pytorchtutorial.com/pytorch-goodies/ 

    本文总结了一些网上大家贡献的 PyTorch 编程技巧、常见代码等,包含模型统计数据、参数初始化、参数正则化等常用方法。如果你在 PyTorch 编程中刚好遇到这些问题,希望这篇总结能帮助到你。如果你有好的代码,欢迎在评论区分享给大家哦。

文章目录 [隐藏]

模型统计数据(Model Statistics)

统计参数总数量

 

1

num_params = sum(param.numel() for param in model.parameters())

参数初始化(Weight Initialization)

PyTorch 中参数的默认初始化在各个层的 reset_parameters() 方法中。例如:nn.Linear 和 nn.Conv2D,都是在 [-limit, limit] 之间的均匀分布(Uniform distribution),其中 limit 是 1. / sqrt(fan_in) ,fan_in 是指参数张量(tensor)的输入单元的数量

下面是几种常见的初始化方式。

Xavier Initialization

Xavier初始化的基本思想是保持输入和输出的方差一致,这样就避免了所有输出值都趋向于0。这是通用的方法,适用于任何激活函数。

 

1

2

3

4

# 默认方法

for m in model.modules():

    if isinstance(m, (nn.Conv2d, nn.Linear)):

        nn.init.xavier_uniform(m.weight)

也可以使用 gain 参数来自定义初始化的标准差来匹配特定的激活函数:

 

1

2

3

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网络中,假定每一层有一半的神经元被激活,另一半为0。推荐在ReLU网络中使用。

 

1

2

3

4

# 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)

主要用以解决深度网络下的梯度消失、梯度爆炸问题,在RNN中经常使用的参数初始化方法。

 

1

2

3

for m in model.modules():

    if isinstance(m, (nn.Conv2d, nn.Linear)):

        nn.init.orthogonal(m.weight)

 

Batchnorm Initialization

在非线性激活函数之前,我们想让输出值有比较好的分布(例如高斯分布),以便于计算梯度和更新参数。Batch Normalization 将输出值强行做一次 Gaussian Normalization 和线性变换:

实现方法:

 

1

2

3

4

for m in model:

    if isinstance(m, nn.BatchNorm2d):

        nn.init.constant(m.weight, 1)

        nn.init.constant(m.bias, 0)

 

参数正则化(Weight Regularization)

L2/L1 Regularization

机器学习中几乎都可以看到损失函数后面会添加一个额外项,常用的额外项一般有两种,称作L1正则化L2正则化,或者L1范数L2范数

L1 正则化和 L2 正则化可以看做是损失函数的惩罚项。所谓 “惩罚” 是指对损失函数中的某些参数做一些限制。

  • L1 正则化是指权值向量 w 中各个元素的绝对值之和,通常表示为 ||w||1
  • L2 正则化是指权值向量 w 中各个元素的平方和然后再求平方根,通常表示为 ||w||2

下面是L1正则化和L2正则化的作用,这些表述可以在很多文章中找到。

  • L1 正则化可以产生稀疏权值矩阵,即产生一个稀疏模型,可以用于特征选择
  • L2 正则化可以防止模型过拟合(overfitting);一定程度上,L1也可以防止过拟合

L2 正则化的实现方法:

 

1

2

3

4

5

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 正则化的实现方法:

 

1

2

3

4

5

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

 

1

2

3

4

5

6

7

8

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

简单来讲就是对 w 的指直接进行限制。

 

1

2

3

4

5

6

def 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))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值