归一化解释:https://zhuanlan.zhihu.com/p/35005794
- Batch Normalization (BN) 就被添加在每一个全连接和激励函数之间
- BatchNorm:batch方向做归一化,算NHW的均值
- LayerNorm:channel方向做归一化,算CHW的均值
- InstanceNorm:一个channel内做归一化,算H*W的均值
- GroupNorm:将channel方向分group,然后每个group内做归一化,算(C//G)HW的均值
归一化解决的问题
1. Internal Covariate Shift
训练深度网络的时候经常发生训练困难的问题,因为,每一次参数迭代更新后,上一层网络的输出数据经过这一层网络计算后,数据的分布会发生变化,为下一层网络的学习带来困难.
2. covariate shift
描述的是由于训练数据和测试数据存在分布的差异性,给网络的泛化性和训练速度带来了影响.输入数据分布不一致的现象,对数据做归一化当然可以加快训练速度,能对数据做去相关性,突出它们之间的分布相对差异就更好了.
批归一化
- 在小批量(mini-batch)的训练案例上使用一个神经元总结输入的分布计算均值与方差,然后用它们归一这一神经元在每个训练案例上的总结输入。这减少了前馈神经网络中的训练时间。然而,batch normalization 的效果依赖于 mini-batch 的大小。
层归一化
1.通过计算来自单一训练案例中一层神经元的所有总结输入的均值与方差(用于归一化的),将 batch normalization 调换为层归一化(layer normalization)。如同 batch normalization,我们也给每一个神经元自己的适应偏差( adaptive bias)与增益,它们在归一化之后、非线性(non-linearity)之前被使用。不同于 batch normalization,层归一化在训练以及测试时间上表现出完全同样的计算能力.
组归一化
- pytorch版本
def GroupNorm(x, gamma, beta, G, eps=1e-5):
N, C, H, W = x.shape
x = x.view([N,G,C//G,H,W])
mean = x.sum(2,keepdim=True).sum(3,keepdim=True).sum(4,keepdim=True)/(H*W*C//G)
var = torch.pow((x-mean),2).sum(2,keepdim=True).sum(3,keepdim=True).sum(4,keepdim=True)/(H*W*C//G)
x = (x-mean)/torch.sqrt(var+eps)
x = x.view([N,C,H,W])
return x*gamma+beta
import torch
import torch.nn as nn
class GroupBatchnorm2d(nn.Module):
def __init__(self, c_num, group_num = 16, eps = 1e-10):
super(GroupBatchnorm2d,self).__init__()
self.group_num = group_num
self.gamma = nn.Parameter(torch.ones(c_num, 1, 1))
self.beta = nn.Parameter(torch.zeros(c_num, 1, 1))
self.eps = eps
def forward(self, x):
N, C, H, W = x.size()
x = x.view(N, self.group_num, -1)
mean = x.mean(dim = 2, keepdim = True)
std = x.std(dim = 2, keepdim = True)
x = (x - mean) / (std+self.eps)
x = x.view(N, C, H, W)
return x * self.gamma + self.beta
- tensorflow版本