集团网站建设网络公司,互利互通网站建设,做网站和推广工资多少,深圳网站优化方案目录 一、正则化之weight_decay#xff08;L2正则#xff09;
1.1 正则化及相关概念
1.2 正则化策略#xff08;L1、L2#xff09;
#xff08;1#xff09;L1正则化
#xff08;2#xff09;L2正则化
1.3 L2正则项——weight_decay
二、正则化之Dropout
2.1 Dr…
目录 一、正则化之weight_decayL2正则
1.1 正则化及相关概念
1.2 正则化策略L1、L2
1L1正则化
2L2正则化
1.3 L2正则项——weight_decay
二、正则化之Dropout
2.1 Dropout概念
2.2 nn.Dropout
三、归一化之Batch NormalizationBN层
3.1 Batch Normalization介绍
3.2 Pytorch的Batch Normalization 1d/2d/3d实现
1nn.BatchNorm1d input B * 特征数 * 1d特征
2nn.BatchNorm1d input B * 特征数 * 2d特征
3nn.BatchNorm1d input B * 特征数 * 3d特征
四、归一化之Normalization_layers
4.1Layer NormalizationLN
nn.LayerNorm
4. 2Instance NormalizationIN
nn.InstanceNorm
4.3 Group NormalizationGN
nn.GroupNorm 前期回顾
Pytorch学习笔记1基本概念、安装、张量操作、逻辑回归
Pytorch学习笔记2数据读取机制DataLoader与Dataset
Pytorch学习笔记3图像的预处理transforms
Pytorch学习笔记4模型创建Module、模型容器Containers、AlexNet构建
Pytorch学习笔记5torch.nn---网络层介绍卷积层、池化层、线性层、激活函数层
Pytorch学习笔记6模型的权值初始化与损失函数
Pytorch学习笔记7优化器、学习率及调整策略、动量 一、正则化之weight_decayL2正则
1.1 正则化及相关概念
Regularization中文翻译过来可以称为正则化或者是规范化。什么是规则闭卷考试中不能查书这就是规则一个限制。同理在这里规则化就是说损失函数加上一些限制通过这种规则去规范他们再接下来的循环迭代中不要自我膨胀。
介绍正则化之前我们先来了解泛化误差
泛化误差可分解为偏差、方差与噪声泛化性能是由学习算法的能力、数据的充分性以及学习任务本身的难度所共同决定的。即泛化误差偏差方差噪声 偏差度量了学习算法的期望预测与真实结果的偏离程度即刻画了学习算法本身的拟合能力方差度量了同样大小的训练集的变动所导致的学习性能的变化即刻画了数据扰动所造成的影响噪声表达了在当前任务上任何学习算法所能够达到的期望泛化误差的下界即刻画了学习问题本身的难度。那么偏差、方差与我们的数据集划分到底有什么关系呢 1、训练集的错误率较小而验证集/测试集的错误率较大说明模型存在较大方差可能出现了过拟合2、训练集和测试集的错误率都较大且两者相近说明模型存在较大偏差可能出现了欠拟合3、训练集和测试集的错误率都较小且两者相近说明方差和偏差都较小这个模型效果比较好。所以我们最终总结方差一般指的是数据模型得出来了能不能对未知数据的扰动预测准确。而偏差说明在训练集当中就已经误差较大了基本上在测试集中没有好的效果。
通过分析我们可以看出正则化是用来防止模型过拟合而采取的手段。我们对代价函数增加一个限制条件限制其较高次的参数大小不能过大。 1.2 正则化策略L1、L2 1L1正则化
L1正则化又称Lasso Regression是指权值向量w中各个元素的绝对值之和。比如向量A[1-13] 那么A的L1范数为 |1||-1||3|。 L1正则化可以让一部分特征的系数缩小到0所以L1适用于特征之间有关联的情况可以产生稀疏权值矩阵很多权重为0则一些特征被过滤掉即产生一个稀疏模型可以用于特征选择。L1也可以防止过拟合。 QL1为什么会产生一个稀疏权值矩阵呢 L1正则化是权值的 绝对值之和所以L1是带有绝对值符号的函数因此是不完全可微的。机器学习的任务就是要通过一些方法比如梯度下降求出损失函数的最小值。当我们在原始损失函数后添加L1正则化项时相当于对损失函数做了一个约束。 公式如下 λ是正则化系数是一个超参数调节惩罚的力度越大则惩罚力度越大。
此时我们的任务变成在约束下求出取最小值的解。
考虑二维的情况即只有两个权值和 此时对于梯度下降法求解函数的过程可以画出等值线同时L1正则化的函数可以在二维平面上画出来。如下图 蓝色圆圈线是Loss中前半部分待优化项的等高线就是说在同一条线上其取值相同且越靠近中心其值越小。黄色菱形区域是L1正则项约束条件。
带有正则化的loss函数的最优解要在黄色菱形区域和蓝色圆圈线之间折中也就是说最优解出现在图中优化项等高线与约束条件相交处。从图中可以看出当待优化项的等高线逐渐向正则项约束区域扩散时L1正则化的交点大多在坐标轴上则很多特征维度上其参数w为0因此会产生稀疏解而正则化前面的系数可以控制图形的大小。越小约束项的图形越大上图中的黄色方框越大约束项的图形就越小可以小到黑色方框只超出原点范围一点点这是最优点的值中的可以取到很小的值。 2L2正则化
L2正则化指权值向量中各个元素的平方和然后再求平方根对参数进行二次约束参数w变小但不为零不会形成稀疏解 。它会使优化求解稳定快速使权重平滑。所以L2适用于特征之间没有关联的情况。 同样L2正则化的函数也可以在二维平面上画出来圆心就是样本值半径就是误差而约束条件则就是红色边界。等高线与约束条件相交的地方就是最优解。 蓝色圆圈线和上面一样
黄色圆形区域是L2正则项约束条件。
同样最优解出现在图中优化项等高线与正则化区域相交处。从图中可以看出当待优化项的等高线逐渐向正则项限制区域扩散时L2正则化的交点大多在非坐标轴上二维平面下L2正则化的函数图形是个圆与方形相比被磨去了棱角。因此与相交时使得或等于零的机率小了许多这就是为什么L2正则化不具有稀疏性的原因。
总结
1使用L1正则化在取得最优解的时候w1的值为0相当于去掉了一个特征而使用L2正则化在取得最优解的时候特征参数都有其值。
2L1会趋向于产生少量的特征而其他的特征都为0而L2会选择更多的特征特征值都趋近于0。 1.3 L2正则项——weight_decay
从直观上讲L2正则化(weight_decay)使得训练的模型在兼顾最小化分类或其他目标的Loss的同时使得权重w尽可能地小从而将权重约束在一定范围内减小模型复杂度同时如果将w约束在一定范围内也能够有效防止梯度爆炸。
L2 Regularization weight decay权值衰减
第一个wi1为未加正则项的权重计算方式
第二个wi1加入正则项之后的权重计算方式化简后的公式如下wi的系数小于1实现了权重的衰减 Pytorch中的 weight decay 是在优化器中实现的在优化器中加入参数weight_decay即可参数中的weight_decay等价于正则化系数λ 。
例如下面的两个随机梯度优化器一个是没有加入正则项一个加入了正则项区别仅仅在于是否设置了参数weight_decay的值
optim_normal torch.optim.SGD(net_normal.parameters(), lrlr_init, momentum0.9)
optim_wdecay torch.optim.SGD(net_weight_decay.parameters(), lrlr_init, momentum0.9, weight_decay1e-2)我们来看看输出结果
可以看到模型迭代1000次后红线的loss基本为0而蓝线的loss是0.035左右虽然红线的loss很低但是它产生了过拟合现象。 二、正则化之Dropout
2.1 Dropout概念
Dropout(随机失活)正常神经网络需要对每一个节点进行学习而添加了Dropout的神经网络通过删除部分单元随机即暂时将其从网络中移除以及它的所有传入和传出连接。将Dropout应用于神经网络相当于从神经网络中采样了一个“更薄的”网络即单元个数较少。如下图所示Dropout是从左图采样了一个更薄的网络如图右 我们有时候之所以会出现过拟合现象就是因为我们的网络太复杂了参数太多了并且我们后面层的网络也可能太过于依赖前层的某个神经元加入Dropout之后 首先网络会变得简单减少一些参数并且由于不知道浅层的哪些神经元会失活导致后面的网络不敢放太多的权重在前层的某个神经元这样就减轻了一个过渡依赖的现象 对特征少了依赖 从而有利于缓解过拟合。
注意事项
数据尺度变化只在训练的时候开启Dropout而测试的时候是不用Dropout的也就是说模型训练的时候会随机失活一部分神经元 而测试的时候我们用所有的神经元那么这时候就会出现这个数据尺度的问题首先介绍一下drop_prob就是随机失活概率。
实现细节
训练时所有权重乘以1/(1-p)即除以1-p测试时所有权重乘以1-drop_probdrop_prob 0.31-drop_prob 0.72.2 nn.Dropout
nn.Dropout
功能Dropout层 参数
p被舍弃概率失活概率
代码及输出结果
红色曲线出现了过拟合
蓝色曲线没有过拟合
Dropout实现了类似L2的权重衰减的功能 三、归一化之Batch NormalizationBN层
3.1 Batch Normalization介绍
Batch Normalization简称BN是google团队在2015年论文《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》提出的。这是一个神经网络训练的技巧它不仅可以加快了模型的收敛速度而且更重要的是在一定程度缓解了深层网络中“梯度弥散特征分布较散”的问题从而使得训练深层网络模型更加容易和稳定。所以目前BN已经成为几乎所有卷积神经网络的标配技巧了。
从字面意思看来Batch Normalization就是对每一批数据进行归一化确实如此对于训练中某一个batch的数据{x1,x2,…,xn}注意这个数据是可以输入也可以是网络中间的某一层输出。在BN出现之前我们的归一化操作一般都在数据输入层对输入的数据进行求均值以及求方差做归一化但是BN的出现打破了这一个规定我们可以在网络中任意一层进行归一化处理因为我们现在所用的优化方法大多都是min-batch SGD所以我们的归一化操作就称为Batch Normalization。 为什么加了BN之后就不用精心设计权值初始化了呢
我们来看看代码
from tools.common_tools import set_seedset_seed(1) # 设置随机种子class MLP(nn.Module):def __init__(self, neural_num, layers100):super(MLP, self).__init__()self.linears nn.ModuleList([nn.Linear(neural_num, neural_num, biasFalse) for i in range(layers)])self.bns nn.ModuleList([nn.BatchNorm1d(neural_num) for i in range(layers)])self.neural_num neural_numdef forward(self, x):for (i, linear), bn in zip(enumerate(self.linears), self.bns):x linear(x)# x bn(x)x torch.relu(x)if torch.isnan(x.std()):print(output is nan in {} layers.format(i))breakprint(layers:{}, std:{}.format(i, x.std().item()))return xdef initialize(self):for m in self.modules():if isinstance(m, nn.Linear):# method 1nn.init.normal_(m.weight.data, std1) # normal: mean0, std1# method 2 kaiming# nn.init.kaiming_normal_(m.weight.data)neural_nums 256
layer_nums 100
batch_size 16net MLP(neural_nums, layer_nums)
# net.initialize()inputs torch.randn((batch_size, neural_nums)) # normal: mean0, std1output net(inputs)
print(output)
输出结果
不进行权值初始化导致梯度消失 接下来我们进行权值初始化来观察一下梯度的变化情况
代码
net.initialize()
输出结果
采用标准正态分布的初始化方法可以发现发生了梯度爆炸 因为此时用到的激活函数是RELU所以使用kaiming初始化方法
代码
# method 2 kaiming
nn.init.kaiming_normal_(m.weight.data)
输出结果
梯度在0.6左右 以上使我们第六节讲的内容Pytorch学习笔记6模型的权值初始化与损失函数刚才我们按照权值初始化的方法来防止梯度爆炸在这中间考虑到relu我们就得用Kaiming初始化考虑到tanh我们还得用Xavier 这样就相当麻烦了。
那么我们假设不用权值初始化而是在网络层的激活函数前加上BN呢
代码
x bn(x)
输出结果
可以发现BN依然可以保证数据的尺度并且好处就是我们不用再考虑用什么样的方式进行权值的初始化。 3.2 Pytorch的Batch Normalization 1d/2d/3d实现
Pytorch中提供了三种BatchNorm方法
nn.BatchNorm1dnn.BatchNorm2dnn.BatchNorm3d
上面三个BatchNorm方法都继承_BatchNorm类 参数
num_features一个样本特征维度通道数eps分母修正项为数值稳定性而加到分母上的值一般设置比较小的数1e的-5次方防止除以0导致错误momentum移动平均的动量值通常设置为0.1affine是否需要affine transform布尔变量控制是否需要进行Affine,默认为打开track_running_states是训练状态还是测试状态。如果在训练状态均值、方差需要重新估计如果在测试状态会采用当前的统计信息均值、方差固定的但训练时这两个数据是会根据batch发生改变。
这里其他几个参数都不重要只需要看num_features就可以了。num_features就是你需要归一化的那一维的维度。
BatchNorm的三个方法也是有属性的
running_mean: 均值running_var: 方差weight: affine transform中的γbias: affine transforom中的β接下来我们详细介绍一下这三个方法。
1nn.BatchNorm1d input B * 特征数 * 1d特征 nn.BatchNorm1d本身不是给定输入矩阵输出归一化结果的函数而是定义了一个方法再用这个方法去做归一化。 代码
# nn.BatchNorm1d ## 输入和输出的尺度是一样的
m nn.BatchNorm1d(2)
m1 nn.BatchNorm1d(2,affineFalse)
input torch.randn(2,2)
output m(input)
output1 m1(input)print(output,output1)
print(output.shape,output1.shape) 2nn.BatchNorm1d input B * 特征数 * 2d特征
通常卷积神经网络输出的特征图就是2d形式。 代码
# nn.BatchNorm2d ## 输入和输出的形状是一样的[N,C,H,W] [N,C,H,W]
# 因为Batch Normalization是在通道 C维度上计算统计量因此也称为Spatial Batch Normalization
m nn.BatchNorm2d(2, affineFalse)
input torch.randn(2,2,3,3)
output m(input)
print(output)
3nn.BatchNorm1d input B * 特征数 * 3d特征
这个在时空序列中会用到。 代码
# nn.BatchNorm3d #
# [N, C, D, H, W] 输入等于输出
m nn.BatchNorm3d(100)
input torch.randn(20,100,35,45,10)
output m(input)
print(output.shape) 四、归一化之Normalization_layers
常见的Normalization
首先我们来介绍一下深度网络中的数据维度。深度网络中的数据维度一般是( N , C , H , W ) 或者( N , H , W , C ) 格式N 是batch sizeH / W是feature的高/宽C是feature的channel。
Batch NormalizationBN取不同样本的同一个通道的特征做归一化逐特征维度归一化。这个就是对batch维度进行计算。所以假设5个100通道的特征图的话就会计算出100个均值方差。5个batch中每一个通道就会计算出来一个均值方差。Layer NormalizationLN取的是同一个样本的不同通道做归一化逐个样本归一化。5个10通道的特征图LN会给出5个均值方差。Instance NormalizationIN仅仅对每一个图片的每一个通道做归一化逐个通道归一化。也就是说对【HW】维度做归一化。假设一个特征图有10个通道那么就会得到10个均值和10个方差要是一个batch有5个样本每个样本有10个通道那么IN总共会计算出50个均值方差。Group NormalizationGN这个是介于LN和IN之间的一种方法。假设Group分成2个那么10个通道就会被分成5和5两组。然后5个10通道特征图会计算出10个均值方差。我们来用表格进行一下对比
名称操作维度优点缺点适用情况BN (N,H,W)减轻对初始值的依赖提高网络的训练效率。可以使用更高色学习速率依赖Batch的大小当Batch太小计算的均值和方差不稳定深度固定的CNN/DNN等神经网络LN(C,H,W)抛弃对Batch大小的依赖由于其根据不同的通道进行了归一化因此对相似度较大的特征LN会降低模型的表达能力mini_Batch较小的场景、动态网络结构、RNNIN (H,W) 对于样式转换任务IN在丢弃图像对比度信息方面优于BN IN还可以看作是将LN单独应用于每个通道就像通道的数量为1的LN一样其大部分实际用效果较差 风格化类的图像应用GNLN与IN的中间体由于GN可利用跨通道的依赖关系因此其优于IN因为它允许对每一组通道学习不同的分布所以它也比LN好当批大小较小时GN始终优于BN当批处理大小非常大时GN的伸缩性不如BN可能无法匹配BN的性能Batch较小本人实验batch的大小小于10可使用GN4.1Layer NormalizationLN
起因BN不适用于变长的网络如RNN网络神经元长度不一样
思路逐层计算均值和方差在相同样本中计算均值和方差
注意事项
不再有running_mean和running_vargamma和beta为逐元素BN中的gamma和beta的维度为特征个数
对于该变长网络如果进行BN只能计算前三个均值和方差再多计算就会因为神经元得缺失而出现偏差。 nn.LayerNorm 主要参数
normalized_shape该层特征形状eps分母修正项为数值稳定性而加到分母上的值一般设置比较小的数1e的-5次方防止除以0导致错误elementwise affine是否需要affine transform布尔变量控制是否需要进行Affine,默认为打开
注意当输入是卷积的特征图则求平均数的数据为channelHW
代码
# nn.layer norm #batch_size 2num_features 3 # 每个数据的特征个数features_shape (2, 2) # 特征维度feature_map torch.ones(features_shape) # 2Dfeature_maps torch.stack([feature_map * (i 1) for i in range(num_features)], dim0) # 3Dfeature_maps_bs torch.stack([feature_maps for i in range(batch_size)], dim0) # 4D# feature_maps_bs shape is [8, 6, 3, 4], B * C * H * Wln nn.LayerNorm(feature_maps_bs.size()[1:], elementwise_affineTrue) # LN不需要将batch_size传入# ln nn.LayerNorm(feature_maps_bs.size()[1:], elementwise_affineFalse) # 注意elementwise_affine的具体作用elementwise_affine的作用是不适用affine transform# ln nn.LayerNorm([6, 3, 4])# ln nn.LayerNorm([6, 3])output ln(feature_maps_bs)print(Layer Normalization)print(ln.weight.shape) # 维度为[6,3,4]print(feature_maps_bs[0, ...])print(output[0, ...])
输出结果 图片来源翻滚的小强 4. 2Instance NormalizationIN
起因BN在图像生成Image Generation中不适用
思路逐Instancechannel计算均值和方差 图像生成中一个batch不同图像有不同的迁移风格所以不能对图片的batch进行BN所以提出了逐通道的IN。
下面通过一个示意图分析IN的具体作用如果现在有三个样本每个样本有三个特征图每个特征图的大小为2*2因为每个样本代表的风格是不同的不能将batch_size大小的图片进行BN。 IN通过逐通道每个特征图计算均值和方差如上图中第一个样本有三个特征图在每一个特征图中计算均值和方差。
nn.InstanceNorm 主要参数
num_features一个样本特征维度通道数eps分母修正项为数值稳定性而加到分母上的值一般设置比较小的数1e的-5次方防止除以0导致错误momentum移动平均的动量值通常设置为0.1affine是否需要affine transform布尔变量控制是否需要进行Affine,默认为打开track_running_stats是训练状态还是测试状态。如果在训练状态均值、方差需要重新估计如果在测试状态会采用当前的统计信息均值、方差固定的但训练时这两个数据是会根据batch发生改变。代码
nn.InstanceNorm的使用和BN差不多同样有nn.InstanceNorm1dnn.InstanceNorm2dnn.InstanceNorm3d其使用方法和BN使用方法差不多
# nn.instance norm 2d #batch_size 3num_features 3momentum 0.3features_shape (2, 2)feature_map torch.ones(features_shape) # 2Dfeature_maps torch.stack([feature_map * (i 1) for i in range(num_features)], dim0) # 3Dfeature_maps_bs torch.stack([feature_maps for i in range(batch_size)], dim0) # 4Dprint(Instance Normalization)print(input data:\n{} shape is {}.format(feature_maps_bs, feature_maps_bs.shape))instance_n nn.InstanceNorm2d(num_featuresnum_features, momentummomentum)for i in range(1):outputs instance_n(feature_maps_bs)print(outputs)# print(\niter:{}, running_mean.shape: {}.format(i, bn.running_mean.shape))# print(iter:{}, running_var.shape: {}.format(i, bn.running_var.shape))# print(iter:{}, weight.shape: {}.format(i, bn.weight.shape))# print(iter:{}, bias.shape: {}.format(i, bn.bias.shape))
输出结果因为IN是基于通道计算均值和方差因此得到的output的均值和方差为零。 图片来源翻滚的小强 4.3 Group NormalizationGN
起因小batch样本中BN估计的均值和方差不准确思路数据不够通道来凑注意事项
不再有running_mean和running_vargamma和beta为逐通道(channel)
应用场景大模型小batch size任务大模型任务占据很大的内存batch_size只能很小。 如图batch_size非常少如果用BN因为batch_size非常小导致估计的均值和方差不准确会导致BN失效。GN会在通道上进行分组再基于分组后得到的数据计算均值和方差。
nn.GroupNorm 主要参数
num_groups分组数通常为2的n次方num_channels通道数特征数eps分母修正项为数值稳定性而加到分母上的值一般设置比较小的数1e的-5次方防止除以0导致错误affine是否需要affine transform布尔变量控制是否需要进行Affine,默认为打开
代码
# nn.grop norm #batch_size 2num_features 4num_groups 4 # 3 Expected number of channels in input to be divisible by num_groupsfeatures_shape (2, 2)feature_map torch.ones(features_shape) # 2Dfeature_maps torch.stack([feature_map * (i 1) for i in range(num_features)], dim0) # 3Dfeature_maps_bs torch.stack([feature_maps * (i 1) for i in range(batch_size)], dim0) # 4Dgn nn.GroupNorm(num_groups, num_features)outputs gn(feature_maps_bs)print(Group Normalization)print(gn.weight.shape)print(outputs[0])
输出 本文参考 [PyTorch 学习笔记] 6.2 Normalization - 知乎 (zhihu.com) 系统学习Pytorch笔记九正则化与标准化大总结