pytorch批量归一化学习小总结

BN章节学习总结(新手小白,纯为记忆,大佬勿入=_=)

一、对卷积层做批量归一化和对全连接做批量归一化的区别

卷积层之后的输出是4维(m,c,p,q),全连接层之后的输出是2维(m,d)m是batchsize,d是神经元个数 。卷积是对 m x p x q 做归一化,全连接是对d做归一化 。

训练时,归一化是以batch为单位对每个batch计算均值和方差。测试时,使用移动平均估算整个训练数据的样本均值和方差。

这是因为预测时不是一batch一batch这样的预测,而是要对每个传入样本给出预测结果,所以没有训练时那样的均值和误差作为参考,所以估算整个样本训练集的均值和方差来对预测数据做标准化,使用的方法叫做移动平均法。

二、以下内容基于动手学深度学习pytorch版本BN章节的代码的解读:

1、batch_norm函数中的X是需要标准化的目标,可能是全连接层仿射变换后的输出,也可能是卷积层卷积之后的输出,我们需要把X标准化为期望为0方差为1的X_hat。

2、先判断是预测还是训练,moving_mean是训练集的样本均值,moving_var是训练集的样本标准差,训练集以batch为单位求每个batch的均值和标准差

3、在训练情况下,先看X的形状是2维还是4维,2维对应全连接仿射变换后的输出,4维对应的是卷积之后的输出。

4、tensor.mean(axis, keepdim)参数理解:

  • keepdim=True
    运算完之后的维度和原来一样,原来是三维数组现在还是三维数组(不过某一维度变成了1)。

  • keepdim=False
    运算完之后一般少一维度,求平均变为1的那一维没有了。

  • axis=k
    按第k维运算,其他维度不遍,第k维变为1。

  • 补充:有时候axis参数也可以写成dim参数,不清楚对不对,但试了一下发现结果一样。

5、卷积之后的4维输出怎么求mean,var?——除了通道维,其它维分别.mean(axis=自己的维度)套在一起即可表示4维(m,c,p,q)中的m x p x q个元素的均值和方差。(其实为啥这样我也不太清楚,希望有大佬可以在评论区讲一下)

6、移动平均法:前面说过测试时的BN使用的均值和方差是用训练数据集整体的均值和方差 ,但我们不能直接拿整个训练数据集去估计其期望和方差,不太现实。所以引入动量momentum(超参数,一个比例),用移动平均去接近训练集整体的期望和方差。

moving_mean = momentum * moving_mean+(1.0-momentum) * mean

moving_var = momentum * moving_var+(1.0-momentum) * var

训练之前先设定moving_mean和moving_var初值为0,然后训练过程中自己更新,训练完成后便可以在测试中使用

7、定义完batch_norm函数,再定义Batch_Norm类,该类主要是维护学习参数和超参数。其有两个输入参数:

  • num_features 参数有两种表示:1.全连接层输出神经元个数 2.卷积层通道数

  • num_dims 参数表示2维或者4维。

8、在Y=gamma * X_hat +beta中,gamma初值的形状是根据全连接层输出神经元形状(1,num_features) 或者全连接层输出的形状(1,num_features,1,1)来设定的。故跟X_hat的形状不相同,在按元素相乘是会用到广播机制,自动扩充,beta同理。

9、在Batch_Norm类中定义forward函数,将定义好的batch_norm函数定义在forward中,并返回Y;这样实例化后不用再关注batch_norm函数,直接forward就可以得到Y。


版权声明:本文为weixin_43901214原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。