pytorch基础知识-Batch Norm(下)

  • 2019 年 12 月 5 日
  • 筆記

本节继续介绍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后,收敛速度加快、精度提高。

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