Normalization layers

介绍

归一化层,主要有这几种方法,BatchNorm(2015年)、LayerNorm(2016年)、InstanceNorm(2016年)、GroupNorm(2018年);
将输入的图像shape记为[N,C,H,W],这几个方法主要区别是:

  • BatchNorm:batch方向做归一化,计算NHW的均值,对小batchsize效果不好;(BN主要缺点是对batchsize的大小比较敏感,由于每次计算均值和方差是在一个batch上,所以如果batchsize太小,则计算的均值、方差不足以代表整个数据分布)

  • LayerNorm:channel方向做归一化,计算CHW的均值;(对RNN作用明显)

  • InstanceNorm:一个batch,一个channel内做归一化。计算HW的均值,用在风格化迁移;(因为在图像风格化中,生成结果主要依赖于某个图像实例,所以对整个batch归一化不适合图像风格化中,因而对HW做归一化。可以加速模型收敛,并且保持每个图像实例之间的独立。)

  • GroupNorm:将channel方向分group,然后每个group内做归一化,算(C//G)HW的均值;这样与batchsize无关,不受其约束。

Normalization layers

1. BatchNorm详解

torch.nn.BatchNorm1d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
torch.nn.BatchNorm3d(num_features, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)

参数:

num_features:输入的特征数,该期望输入的大小为’N x C [x L]’
eps: 为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5。
momentum: 动态均值和动态方差所使用的动量。默认为0.1。
affine: 布尔值,当设为true,给该层添加可学习的仿射变换参数。
track_running_stats:布尔值,当设为true,记录训练过程中的均值和方差;

实现公式:
y=\frac{x-E[x]}{\sqrt{Var[x]+\epsilon}}*\gamma+\beta\tag{1.1}

# 示例代码
import torch
import torch.nn as nn

"""
BatchNorm1d(时域)

Input: (N, C) or (N, C, L)
Output: (N, C) or (N, C, L)(same shape as input)
"""
# input = torch.randn(2, 10, 100)
input = torch.randn(2, 10)
# with learnable parameters
m1 = nn.BatchNorm1d(10)
# without learnable parameters
m2 = nn.BatchNorm1d(10, affine=False)

output1 = m1(input)
print(output1.shape)

output2 = m2(input)
print(output2.shape)

"""
BatchNorm2d(空域)

Input: (N, C, H, W)
Output: (N, C, H, W)(same shape as input)
"""
input = torch.randn(2, 10, 35, 45)
# with learnable parameters
m1 = nn.BatchNorm2d(10)
# without learnable parameters
m2 = nn.BatchNorm2d(10)

output1 = m1(input)
print(output1.shape)

output2 = m2(input)
print(output2.shape)

"""
BatchNorm3d(时空域)

Input: (N, C, D, H, W)
Output: (N, C, D, H, W)(same shape as input)
"""
input = torch.randn(2, 10, 20, 35, 45)
# with leanable parameters
m1 = nn.BatchNorm3d(10)
# without learnable parameters
m2 = nn.BatchNorm3d(10)

output1 = m1(input)
print(output1.shape)

output2 = m2(input)
print(output2.shape)

# 结果
torch.Size([2, 10])
torch.Size([2, 10])
torch.Size([2, 10, 35, 45])
torch.Size([2, 10, 35, 45])
torch.Size([2, 10, 20, 35, 45])
torch.Size([2, 10, 20, 35, 45])

2. GroupNorm详解

torch.nn.GroupNorm(num_groups, num_channels, eps=1e-05, affine=True)

参数:

num_groups:需要划分的groups
num_features:输入的特征数,输入的大小为’N x C x *’
eps: 为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5
momentum: 动态均值和动态方差所使用的动量。默认为0.1
affine: 布尔值,当设为true,给该层添加可学习的仿射变换参数

实现公式:
y=\frac{x-E[x]}{\sqrt{Var[x]+\epsilon}}*\gamma+\beta\tag{2.1}

# 示例代码
"""
GroupNorm

Input: (N, C, *)where C=num_channels
Output: (N, C, *)(same shape as input)
"""
input = torch.randn(2, 6, 10, 10)
# separate 6 channels into 3 groups
m1 = nn.GroupNorm(3, 6)
# Separate 6 channels into 6 groups (equivalent with InstanceNorm)
m2 = nn.GroupNorm(6, 6)
# Put all 6 channels into a single group (equivalent with LayerNorm)
m3 = nn.GroupNorm(1, 6)

output1 = m1(input)
print(output1.shape)

output2 = m2(input)
print(output2.shape)

output3 = m3(input)
print(output3.shape)

# 结果
torch.Size([2, 6, 10, 10])
torch.Size([2, 6, 10, 10])
torch.Size([2, 6, 10, 10])

3. InstanceNorm详解

torch.nn.InstanceNorm1d(num_features, eps=1e-05, momentum=0.1, affine=False, track_running_stats=False)
torch.nn.InstanceNorm2d(num_features, eps=1e-05, momentum=0.1, affine=False, track_running_stats=False)
torch.nn.InstanceNorm3d(num_features, eps=1e-05, momentum=0.1, affine=False, track_running_stats=False)

参数:

num_features:输入的特征数,输入的大小为’N x C [x L]’
eps:为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5
momentum: 动态均值和动态方差所使用的动量。默认为0.1
affine: 布尔值,当设为true,给该层添加可学习的仿射变换参数
track_running_stats:布尔值,当设为true,记录训练过程中的均值和方差;

实现公式:
y=\frac{x-E[x]}{\sqrt{Var[x]+\epsilon}}*\gamma+\beta\tag{3.1}

# 示例代码
"""
InstanceNorm1d

Input: (N, C, L)
Output: (N, C, L)(same shape as input)
"""
input = torch.randn(20, 100, 40)
# without learnable parameters
m1 = nn.InstanceNorm1d(100)
# with learnable parameters
m2 = nn.InstanceNorm1d(100, affine=True)

output1 = m1(input)
print(output1.shape)

output2 = m2(input)
print(output2.shape)

"""
InstanceNorm2d

Input: (N, C, H, W)
Output: (N, C, H, W)(same shape as input)
"""
input = torch.randn(20, 100, 35, 45)
# without learnable parameters
m1 = nn.InstanceNorm2d(100)
# with learnable parameters
m2 = nn.InstanceNorm2d(100, affine=True)

output1 = m1(input)
print(output1.shape)

output2 = m2(input)
print(output2.shape)

"""
InstanceNorm3d

Input: (N, C, D, H, W)
Output: (N, C, D, H, W)(same shape as input)
"""
input = torch.randn(20, 100, 35, 45)
# without learnable parameters
m1 = nn.InstanceNorm2d(100)
# with learnable parameters
m2 = nn.InstanceNorm2d(100, affine=True)

output1 = m1(input)
print(output1.shape)

output2 = m2(input)
print(output2.shape)

# 结果
torch.Size([20, 100, 40])
torch.Size([20, 100, 40])
torch.Size([20, 100, 35, 45])
torch.Size([20, 100, 35, 45])
torch.Size([20, 100, 35, 45])
torch.Size([20, 100, 35, 45])

4. LayerNorm详解

torch.nn.LayerNorm(normalized_shape, eps=1e-05, elementwise_affine=True)

参数:

normalized_shape:输入尺寸
[∗×normalized_shape[0]×normalized_shape[1]×…×normalized_shape[−1]]
eps:为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5。
elementwise_affine:布尔值,当设为true,给该层添加可学习的仿射变换参数

实现公式:
y=\frac{x-E[x]}{\sqrt{Var[x]+\epsilon}}*\gamma+\beta\tag{4.1}

# 示例代码
"""
LayerNorm

Input: (N, *)
Output: (N, *)(same shape as input)
"""
input = torch.randn(20, 5, 10, 10)
# with learnable parameters
m1 = nn.LayerNorm(input.size()[1:])
# without learnable parameters
m2 = nn.LayerNorm(input.size()[1:], elementwise_affine=False)
# normalize over last two dimensions
m3 = nn.LayerNorm([10, 10])
# normalize over last dimension of size 10
m4 = nn.LayerNorm(10)

output1 = m1(input)
print(output1.shape)

output2 = m2(input)
print(output2.shape)

output3 = m3(input)
print(output3.shape)

output4 = m4(input)
print(output4.shape)

# 结果
torch.Size([20, 5, 10, 10])
torch.Size([20, 5, 10, 10])
torch.Size([20, 5, 10, 10])
torch.Size([20, 5, 10, 10])

论文链接

  1. BatchNorm
    https://arxiv.org/pdf/1502.03167.pdf
  2. LayerNorm
    https://arxiv.org/pdf/1607.06450v1.pdf
  3. InstanceNorm
    https://arxiv.org/pdf/1607.08022.pdf
  4. GroupNorm
    https://arxiv.org/pdf/1803.08494.pdf
  5. SwitchableNorm
    https://arxiv.org/pdf/1806.10779.pdf
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354