前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度学习中的归一化技术全面总结

深度学习中的归一化技术全面总结

作者头像
deephub
发布2022-06-04 12:14:38
9210
发布2022-06-04 12:14:38
举报
文章被收录于专栏:DeepHub IMBADeepHub IMBA

训练深度神经网络是一项具有挑战性的任务。多年来,研究人员提出了不同的方法来加速和稳定学习过程。归一化是一种被证明在这方面非常有效的技术。

在这篇文章中,我将使用类比和可视化的方式来回顾这些方法中,这将帮助您了解它们的产生的原因和思维过程。

为什么要归一化?

例如,我们现在用两个特征构建一个简单的神经网络模型。这两个特征一个是年龄:范围在 0 到 65 之间,另一个是工资:范围从 0 到 10 000。我们将这些特征提供给模型并计算梯度。

不同规模的输入导致不同的权重更新和优化器的步骤向最小值的方向不均衡。这也使损失函数的形状不成比例。在这种情况下,就需要使用较低的学习速率来避免过冲,这就意味着较慢的学习过程。

所以我们的解决方案是输入进行归一化,通过减去平均值(定心)并除以标准偏差来缩小特征。

此过程也称为“漂白”,处理后所有的值具有 0 均值和单位方差,这样可以提供更快的收敛和更稳定的训练。

这是一个很好的解决方案,那么为什么我们不规范化网络中每一层的激活呢?

下面我们先看一下针对于激活的归一化方法

Batch Normalization

2015 年,Sergey Ioffe 和 Christian Szegedy[3] 采用了这个想法来解决内部协变量偏移问题。以前输入层分布由于权值的更新而不断变化。所以下面的层总是需要适应新的分布,它会导致收敛速度变慢和训练不稳定。

批量标准化提供了一种控制和优化每一层之后的分布的方法。该过程与输入归一化相同,但我们添加了两个可学习的参数,γ 和 β。

通过代码来说明要比枯燥的公式好的多,所以BN的代码如下:

代码语言:javascript
复制
def BatchNorm(x, gamma, beta, eps=1e-5):
    # x: input shape [N, C, H, W]

    N, C, H, W = x.shape
    mean = torch.mean(input=x, dim=[0,2,3], keepdim=True)
    var = torch.var(input=x, dim=[0,2,3], keepdim=True)
    # mean, var shape : [1, C, 1, 1]

    x = (x - mean) / torch.sqrt(var + eps)
    
    return x * gamma + beta

这两个参数是通过反向传播沿着网络学习的。他们通过缩放(γ)和移动(β)激活优化分布。

由于有固定的分布,所以可以提高学习率并加快收敛速度。除了计算提升之外,BN 还可以作为一种正则化技术。数据集统计数据的近似产生的噪声消除了对 Dropout 的需要。

但这是一把双刃剑。这种估计仅适用于较大的批次。当批次数量较少时,性能会急剧下降。

BN 的另一个缺点是对于批处理的依赖。如果我们传递了单个样本而不是批量的样本,网络必须使用预先计算的训练均值和方差,这可能会导致不同的结果。

这个问题的重要性促使人们创建替代方法以避免对批处理的依赖。

Layer Normalization

这是Geoffrey E. Hinton等人在2016年[4]中首次尝试减少对批大小的约束。提出这个方法的主要原因是无法找到将BN应用于递归神经网络,需要找到一个替代的方法。

在深度神经网络中,由于层数是固定的,因此很容易存储每个 BN 层的统计信息。然而在 RNN 中,输入和输出形状的长度不同。因此,在这种情况下,最好使用单个时间步长(样本)而不是整个批次的统计信息进行标准化。

代码语言:javascript
复制
def LayerNorm(x, gamma, beta, eps=1e-5):
    # x: input shape [N, C, H, W]
    
    N, C, H, W = x.shape
    mean = torch.mean(input=x, dim=[1,2,3], keepdim=True)
    var = torch.var(input=x, dim=[1,2,3], keepdim=True)
    # mean, var shape: [N, 1, 1, 1]

    x = (x - mean) / torch.sqrt(var + eps)
    
    return x * gamma + beta

在这种方法中,batch(N) 中的每个示例都在 [C, H, W] 维度上进行了归一化。与 BN 一样,它可以加速和稳定训练,并且不受批次的限制。此方法可用于批量为 1 的在线学习任务。

Instance Normalization

Dmitry Ulyanov 等人在 2016 年的论文 [5] 中介绍了Instance Normalization。这是另一种尝试减少对批处理的依赖以改善样式传输网络的结果。

代码语言:javascript
复制
def InstanceNorm(x, gamma, beta, eps=1e-5):
    # x: input shape [N, C, H, W]

    N, C, H, W = x.shape
    mean = torch.mean(input=x, dim=[2,3], keepdim=True)
    var = torch.var(input=x, dim=[2,3], keepdim=True)
    # mean, var  shape: [N, C, 1, 1]

    x = (x - mean) / torch.sqrt(var + eps)
    
    return x * gamma + beta

跨批次和通道的标准化允许从图像中删除特定的对比度信息,这有助于泛化。

这种方法在 Pix2Pix 或 CycleGAN 等生成模型中广受欢迎,并成为著名的 StyleGAN2 中使用的自适应实例归一化的先驱。

Group Normalization

Group Normalization 在 2018[1] 论文中被引入,它直接解决了 CNN 的 BN 限制。主要针对的是分布式学习,其中批次被分成许多机器。这些是在少数例子上训练的,比如 6-8,在某些情况下,甚至是 1-2。

GN 可以理解为Layer 和Instance的混合。GN 将通道分成组并在它们之间进行标准化。该方案使计算独立于批量大小。

代码语言:javascript
复制
def GroupNorm(x, gamma, beta, G, eps=1e-5):
    # x: input features with shape [N, C, H, W]
    # G : number of groups

    N, C, H, W = x.shape
    x = torch.reshape(input=x, shape=[N, G, C // G, H, W])
    mean = torch.mean(input=x, dim=[2,3,4], keepdim=True)
    var = torch.var(input=x, dim=[2,3,4], keepdim=True)
    # mean, var shape : [N, G, 1, 1, 1]

    x = (x - mean) / torch.sqrt(var + eps)

    x = torch.reshape(input=x, shape=[N, C, H, W])

    return x * gamma + beta

GN 优于在小批量上训练的 BN,但无法击败大批量的结果,但是这是一个很好的起点。

上面的针对于激活的归一化方法我们基本上都听说过也经常会用到,下面我们来介绍针对权重的归一化方法。

Weight Standardization

我们已经对输入和层输出进行了标准化,唯一剩下的就是权重。因为它们可以在没有任何控制的情况下变大,尤其是当我们无论如何都要标准化输出时。通过标准化权重,我们实现了更平滑的损失和更稳定的训练。

代码语言:javascript
复制
def WeightStand(w, eps=1e-5):
    # w: input features shape [Cin, Cout, kernel_size, kernel_size]

    mean = torch.mean(input=w, dim=[0,2,3], keepdim=True)
    var = torch.var(input=w, dim=[0,2,3], keepdim=True)
    # mean, var shape : [1, Cout, 1, 1]
    
    w = (w - mean) / torch.sqrt(var + eps)
    
    return w

权重的标准化是Group Normalization的一个很好的辅助。在仅使用一个样本的 BN(大批量)情况下,将这些方法结合起来会产生更好的结果。

除此以外,有人还提出了BCN方法,称为批处理通道规范化。简而言之,每一层同时使用BN和GN。

总结

归一化是深度学习中的一个基本概念。它加快了计算速度并稳定了训练。多年来发展了许多不同的技术。本篇文章整理了目前与它相关的方法,希望对你有所帮助

引用

[1] Group Normalization

[2] Micro-Batch Training with Batch-Channel Normalization and Weight Standardization

[3] Batch Normalization: Accelerating Deep Network Training b y Reducing Internal Covariate Shift

[4] Layer Normalization

[5] Instance Normalization: The Missing Ingredient for Fast Stylization

[6] Deep Residual Learning for Image Recognition

作者:Maciej Balawejder

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DeepHub IMBA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么要归一化?
  • Batch Normalization
  • Layer Normalization
  • Instance Normalization
  • Group Normalization
  • Weight Standardization
  • 总结
相关产品与服务
批量计算
批量计算(BatchCompute,Batch)是为有大数据计算业务的企业、科研单位等提供高性价比且易用的计算服务。批量计算 Batch 可以根据用户提供的批处理规模,智能地管理作业和调动其所需的最佳资源。有了 Batch 的帮助,您可以将精力集中在如何分析和处理数据结果上。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档