pytorch基础知识-Batch Norm(下)

本节继续介绍Batch Normalization。

上图是对前节课所讲的小结,通过Normalize将[6, 3, 784]分为3个通道的[6, 784]数据。使得数据结果整体分布于(0~正负1)区间内。

那么在pytorch中是如何实现的呢?

import torch import torch.nn as nn import torch.nn.functional as F  x = torch.rand(100, 16, 784) # 这里直接将28*28变为一维的784 layer = nn.BatchNorm1d(16) # 一维直接使用.BatchNorm1d即可 # 因为Batch Norm的参数直接是由channel数量得来的, # 因此这里直接给定了channel的数量为16,后续会输出16个channel的统计信息 out = layer(x) # 进行前向计算 print(layer.running_mean) # 进行权值计算并输出

输出为

tensor([0.0500, 0.0499, 0.0499, 0.0499, 0.0500, 0.0500, 0.0501, 0.0497, 0.0501,         0.0500, 0.0500, 0.0500, 0.0502, 0.0501, 0.0499, 0.0501])

可以自行对上述结果进行验证,该结果的平均值恰好为0.5。

Batch Normalize的规范化写法为

首先第一步先统计了当前规范化的均值和方差。接下来进行Normalize的操作,即将x值减去均值再除以根号下方差的平方与一个很小的误差。最好再进行缩放,缩放成一个适宜的分布。

再以代码示例

import torch import torch.nn as nn import torch.nn.functional as F  x = torch.rand(1, 16, 28, 28) # 这里是28*28的数据 layer = nn.BatchNorm2d(16) # 二维直接使用.BatchNorm2d # 因为Batch Norm的参数直接是由channel数量得来的, # 因此这里直接给定了channel的数量为16,后续会输出16个channel的统计信息 out = layer(x) # 进行前向计算 print(layer.running_mean) # 进行权值计算并输出

输出为

tensor([0.0514, 0.0501, 0.0520, 0.0496, 0.0498, 0.0517, 0.0510, 0.0506, 0.0517,         0.0501, 0.0509, 0.0491, 0.0486, 0.0505, 0.0516, 0.0495])

若想查看层间的参数

print(layer.weight)

输出为

tensor([0.7385, 0.5807, 0.7299, 0.6045, 0.7796, 0.5302, 0.4739, 0.2357, 0.6040,         0.7084, 0.6688, 0.7167, 0.7097, 0.6144, 0.8577, 0.0428],        requires_grad=True)

这里的weight即为σ值

这里还可以设置一些参数,如添加;training=True(表明当前的模式), affine=True(设置参数自动更新学习)。

Batch Norm同样需要手动给予参数

layer.eval() # 调用不同的模式,以完成参数是否自动更新学习 BatchNorm1d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)

Batch Norm具有相当优异的使用效果,如下图所示

使用了Batch Norm后,收敛速度加快、精度提高。

上右图可看出尖峰的偏差对比左侧变小了很多。