PyTorch常用的初始化和正则

PyTorch常用的初始化和正则,第1张

统计参数总数量

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

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

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

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

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

参考资料:

He initialization的思想是:在ReLU网络中,假定每一层有一半的神经元被激活,另一半为0。推荐在ReLU网络中使用。

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

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

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

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

L1 正则化是指权值向量 w 中各个元素的绝对值之和,通常表示为 ||w||1

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

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

L1 正则化可以产生稀疏权值矩阵,即产生一个稀疏模型,可以用于特征选择

L2 正则化可以防止模型过拟合(overfitting);一定程度上,L1也可以防止过拟合

在使用pytorch预训练模型的时候发现预训练模型的输出层没有激活函数,为了提高模型的训练效果需要自己添加。以ResNet50为例:

输出的模型为:

可以看到最后的输出层是没有激活函数的,因此我们需要队fc层进行修改:

网络模型的fc层就变成了

Date: 2020/10/12

Coder: CW

Foreword:

在将模型用于推断时,我们通常都会将 model.eval() 和 torch.no_grad() 一起使用,那么这两者可否单独使用?它们的区别又在哪里?你清楚吗?之前 CW 对这块也有些迷糊,于是自己做了实验,最终得到了结论,实验过程就不在本文叙述了,仅抛出结论作为参考。

Pytorch 的模型都继承自 torch.nn.Module ,这个类有个 training 属性,而这个方法会将这个属性值设置为False,从而影响一些模型在前向反馈过程中的 *** 作,比如 BN 和 Dropout 层。在这种情况下,BN层不会统计每个批次数据的均值和方差,而是直接使用在基于训练时得到的均值和方差;Dropout层则会让所有的激活单元都通过。

同时, 梯度的计算不受影响 ,计算流依然会存储和计算梯度, 反向传播后仍然能够更新模型的对应的权重 (比如BN层的weight和bias依然能够被更新)。

通常是通过上下文的形式使用:

这种情况将停止autograd模块的工作,即 不会自动计算和存储梯度 ,因此 能够起到加速计算过程和节省显存的作用 ,同时也说明了 不能够进行反向传播以更新模型权重 。

由上可知,在推断时将 model.eval() 与 torch.no_grad() 搭配使用,主要是出于以下几点考虑:

i). 模型中使用了诸如 BN 和 Dropout 这样的网络层,需要使用 model.eval() 来改变它们在前向过程中的 *** 作;

ii). 为了加速计算过程和节省显存,使用torch.no_grad()


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/bake/11951804.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-19
下一篇 2023-05-19

发表评论

登录后才能评论

评论列表(0条)

保存