Batch Normalization、Layer Normalization代码实现

这篇具有很好参考价值的文章主要介绍了Batch Normalization、Layer Normalization代码实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

      BN(Batch Normalization)主要目的是为了解决训练深层神经网络慢的问题。我们可以神经网络整体可以看成一个高阶的复杂函数,通过训练优化它的参数,可以用于拟合各种复杂的数据分布。一般而言,一个网络会有多层,其中的每一层都可以看成一个子函数,用于拟合其各自的子分布。由于下一层的输入来自上一层的输出,而随着训练过程中上一层网络参数的改动,它的输出也将发生变化,那么将会导致下一层学习更加慢,同时也会使得模型的训练更加难,这个现象在原文中被称为“internal covariate shif”现象,针对这一问题,作者提出了将上一层的输出进行标准化以调整下一层输入的分布,以减弱“internal covariate shif”的影响,BN一般用在卷积层之后,激活层之前。更多的细节可以参考原文Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift。

      由于BN涉及到跨样本间的计算,因而难免会受到batch size大小的影响;另一方面,在序列样本中(如文本、语音等),一般会进行padding对齐每条样本的长度,以便批量输入到模型中,此时在跨样本计算统计值的话,会引入噪声;为了解决以上两个问题,LN(Layer Normalization)就应运而生,单独对每条样本的特征进行正则化,详情可参考原文Layer Normalization。

      类似的还有Instance Normalization、Group Normalization、Switchable Normalization,这里就不多赘述了。

以下部分将会省略很多细节,直接进入代码实现部分。

批量正则化-BN

      BN是同时对所有样本的对应通道进行正则化,有多少个通道,就会有多少组均值和方差,单独对每个通道的值进行缩放,示意图如下:
Batch Normalization、Layer Normalization代码实现,batch,开发语言

假设数据格式为 V [ B , C , H , W ] V_[B,C,H,W_] V[B,C,H,W],分别表示 b a t c h _ s i z e batch\_size batch_size、通道数、高度、宽度,那么针对通过维度的任一个坐标 c ∈ [ 0 , C ) c\in [0, C) c[0,C),都会求出一组均值和方差

u c = 1 B ∗ H ∗ W ∑ b ∈ [ 0 , B ) h ∈ [ 0 , H ) w ∈ [ 0 , W ) V [ b , h , w ] u_c = \frac{1} {B*H*W} \sum_{b\in[0,B) h\in [0,H) w\in[0,W)} V_[b,h,w] uc=BHW1b[0,B)h[0,H)w[0,W)V[b,h,w]

θ c 2 = 1 B ∗ H ∗ W ∑ b ∈ [ 0 , B ) h ∈ [ 0 , H ) w ∈ [ 0 , W ) ( V [ b , h , w ] − u c ) 2 \theta^2_c = \frac{1} {B*H*W} \sum_{b\in[0,B) h\in [0,H) w\in[0,W)}(V_[b,h,w] - u_c)^2 θc2=BHW1b[0,B)h[0,H)w[0,W)(V[b,h,w]uc)2

接下来对该通道坐标的每一个值,进行缩放操作

V ^ [ : , c , : , : ] ← γ c . V [ : , c , : , : ] − u c θ c 2 + ϵ + β c \hat{V}_{[:, c, :, :]} \leftarrow \gamma_c . \frac{V_{[:,c,:,:]} - u_c } {\sqrt{\theta^2_c + \epsilon}} + \beta_c V^[:,c,:,:]γc.θc2+ϵ V[:,c,:,:]uc+βc

其中 ϵ \epsilon ϵ为一个非常小的常数,防止分母为0, γ c , β c \gamma_c,\beta_c γc,βc为该通道对应的参数。

import torch
from torch.nn import BatchNorm1d, BatchNorm2d, BatchNorm3d
import numpy as np
np.random.seed(0)

class myBatchNorm(torch.nn.Module):
    def __init__(self,
                 size, 
                 dim,
                 eps: float = 1e-6) -> None:
        super().__init__()
        self.gamma = torch.nn.Parameter(torch.ones(size))
        self.beta = torch.nn.Parameter(torch.zeros(size))
        self.eps = eps
        self.dim = dim

    def forward(self, tensor: torch.Tensor):  # pylint: disable=arguments-differ
        mean = tensor.mean(self.dim, keepdim=True)
        std = tensor.std(self.dim, unbiased=False, keepdim=True)
        return self.gamma * (tensor - mean) / (std + self.eps) + self.beta

print("-----一维BN------")
val_tensor = torch.from_numpy(np.random.randn(1, 3, 4)).float()
BN1 = BatchNorm1d(3, affine=False)(val_tensor)
print(BN1)
myBN1 = myBatchNorm((1, 3, 1), (0, 2))(val_tensor)
print(myBN1)

print("-----二维BN------")
val_tensor = torch.from_numpy(np.random.randn(1, 3, 4, 5)).float()
BN2 = BatchNorm2d(3, affine=False)(val_tensor)
print(BN2)
myBN2 = myBatchNorm((1, 3, 1, 1), (0, 2, 3))(val_tensor)
print(myBN2)

print("-----三维BN------")
val_tensor = torch.from_numpy(np.random.randn(1, 2, 3, 4, 5)).float()
BN3 = BatchNorm3d(2, affine=False)(val_tensor)
print(BN3)
myBN3 = myBatchNorm((1, 2, 1, 1, 1), (0, 2, 3, 4))(val_tensor)
print(myBN3)

输出如下:

-----一维BN------
tensor([[[ 0.5905, -1.3359, -0.5187,  1.2640],
         [ 1.3397, -1.2973,  0.4893, -0.5317],
         [-0.9773, -0.1110, -0.5604,  1.6487]]])
tensor([[[ 0.5905, -1.3359, -0.5187,  1.2640],
         [ 1.3397, -1.2973,  0.4893, -0.5317],
         [-0.9773, -0.1110, -0.5604,  1.6488]]], grad_fn=<AddBackward0>)
-----二维BN------
tensor([[[[ 0.4834, -0.1121,  0.1880,  0.0854,  1.1662],
          [-0.4165,  0.0662, -1.0209, -2.6032,  0.3834],
          [ 0.5797, -0.9166,  1.8886, -1.5800, -0.1828],
          [-0.3997,  1.2022,  1.1431, -0.0811,  0.1268]],

         [[-0.5048, -1.5601,  0.0165,  0.5033,  1.5403],
          [ 1.5133, -0.0216,  0.0605, -0.6600, -1.0187],
          [-1.2951,  2.2359, -0.1397, -0.0706, -0.8572],
          [ 1.1031, -1.2059,  0.1470, -0.5122,  0.7259]],

         [[-0.2520, -1.2639,  0.4771,  1.1667,  0.6201],
          [ 0.9766, -0.4386, -0.0283, -0.4962, -0.0235],
          [-0.7087, -2.0882,  0.7877, -0.0873, -1.9430],
          [ 1.2188, -0.8510,  0.5981,  1.6211,  0.7145]]]])
tensor([[[[ 0.4834, -0.1121,  0.1880,  0.0854,  1.1662],
          [-0.4165,  0.0662, -1.0209, -2.6032,  0.3834],
          [ 0.5797, -0.9166,  1.8886, -1.5800, -0.1828],
          [-0.3997,  1.2022,  1.1431, -0.0811,  0.1268]],

         [[-0.5048, -1.5601,  0.0165,  0.5033,  1.5403],
          [ 1.5133, -0.0216,  0.0605, -0.6600, -1.0187],
          [-1.2951,  2.2359, -0.1397, -0.0706, -0.8572],
          [ 1.1031, -1.2059,  0.1470, -0.5122,  0.7260]],

         [[-0.2520, -1.2639,  0.4771,  1.1667,  0.6201],
          [ 0.9766, -0.4386, -0.0283, -0.4962, -0.0235],
          [-0.7087, -2.0882,  0.7877, -0.0873, -1.9430],
          [ 1.2188, -0.8510,  0.5981,  1.6211,  0.7145]]]],
       grad_fn=<AddBackward0>)
-----三维BN------
tensor([[[[[ 0.8306, -1.5469,  0.0926, -0.9961, -1.1823],
           [-0.8900, -0.6223, -0.2541, -1.4771,  0.5917],
           [ 0.1560, -1.8487,  1.1800,  1.5882,  0.8701],
           [-0.4905, -1.3826,  0.7456, -0.7141,  0.9138]],

          [[-0.1018,  0.6676,  0.0465,  0.3972, -0.2998],
           [ 1.4780, -0.1832,  0.0922,  1.5754, -1.6599],
           [-1.5826,  0.6604, -1.4851,  1.6360, -0.7245],
           [-1.0588,  1.6152,  1.1722,  1.5598,  0.5970]],

          [[-1.1727,  1.6023, -0.5787,  0.4932,  0.6382],
           [-0.4656,  0.3046,  0.6131,  0.0666, -1.4112],
           [-0.0117,  1.0179, -1.0059, -0.4602, -0.7461],
           [ 1.5415,  0.3629,  0.0977, -1.0813,  0.2297]]],


         [[[-0.5496,  0.1743, -0.5101,  0.8350,  0.7327],
           [-0.0719,  0.5476, -0.9788, -1.3869,  0.5920],
           [ 0.3125,  0.7926,  2.5845,  1.1098, -0.7940],
           [ 1.2866, -1.2072, -0.3315,  0.0717,  1.8979]],

          [[-0.6218, -0.7055,  0.0407, -0.5384,  1.2965],
           [-0.9653, -1.0345, -0.3071, -0.3689,  2.1195],
           [ 1.1148,  0.2314, -1.1145,  1.0072, -0.8836],
           [-1.4418,  1.3594,  0.4665,  1.0856,  0.4684]],

          [[ 1.0199, -0.5257, -0.9185,  0.8403, -0.6819],
           [-0.5652, -0.3253,  0.1596, -0.2212, -1.2677],
           [-0.5181, -2.1374,  0.7825, -1.5005, -0.9904],
           [ 0.1951, -0.6164,  1.7233, -1.1836,  0.4154]]]]])
tensor([[[[[ 0.8306, -1.5469,  0.0926, -0.9961, -1.1823],
           [-0.8900, -0.6223, -0.2541, -1.4771,  0.5917],
           [ 0.1560, -1.8487,  1.1800,  1.5882,  0.8701],
           [-0.4905, -1.3826,  0.7456, -0.7141,  0.9138]],

          [[-0.1018,  0.6676,  0.0465,  0.3972, -0.2998],
           [ 1.4780, -0.1832,  0.0922,  1.5754, -1.6599],
           [-1.5826,  0.6604, -1.4851,  1.6360, -0.7245],
           [-1.0588,  1.6153,  1.1722,  1.5598,  0.5970]],

          [[-1.1727,  1.6024, -0.5787,  0.4932,  0.6382],
           [-0.4656,  0.3046,  0.6131,  0.0666, -1.4112],
           [-0.0117,  1.0179, -1.0059, -0.4602, -0.7461],
           [ 1.5415,  0.3629,  0.0977, -1.0813,  0.2297]]],


         [[[-0.5496,  0.1743, -0.5101,  0.8350,  0.7327],
           [-0.0719,  0.5476, -0.9788, -1.3870,  0.5920],
           [ 0.3125,  0.7926,  2.5845,  1.1098, -0.7940],
           [ 1.2866, -1.2072, -0.3315,  0.0717,  1.8979]],

          [[-0.6218, -0.7055,  0.0407, -0.5384,  1.2965],
           [-0.9653, -1.0346, -0.3071, -0.3689,  2.1195],
           [ 1.1148,  0.2314, -1.1145,  1.0072, -0.8836],
           [-1.4418,  1.3594,  0.4665,  1.0856,  0.4684]],

          [[ 1.0199, -0.5257, -0.9185,  0.8403, -0.6819],
           [-0.5652, -0.3253,  0.1596, -0.2212, -1.2677],
           [-0.5181, -2.1374,  0.7825, -1.5005, -0.9904],
           [ 0.1951, -0.6164,  1.7233, -1.1836,  0.4154]]]]],
       grad_fn=<AddBackward0>)

层正则化-LN

      LN是逐个样本进行正则化,假设数据格式为 V [ B , T , C ] V_[B,T,C_] V[B,T,C],分别表示 b a t c h _ s i z e batch\_size batch_size、序列长度、特征维度,那么一般会针对每个样本的每个序列点的特征进行标准化,当然也可以对每个样本整体进行标准化,示意图如下:
Batch Normalization、Layer Normalization代码实现,batch,开发语言

下面以对每个样本的每个序列点进行标准化为例进行公示的演示。

u b , t = 1 C ∑ c ∈ [ 0 , C ) V [ b , t , c ] u_{b,t} = \frac{1} {C} \sum_{c\in[0,C)} V_[b,t,c] ub,t=C1c[0,C)V[b,t,c]

θ b , t 2 = 1 C ∑ c ∈ [ 0 , C ) ( V [ b , t , c ] − u b , t ) 2 \theta^2_{b,t} = \frac{1} {C} \sum_{c\in[0,C)}(V_[b,t,c] - u_{b,t})^2 θb,t2=C1c[0,C)(V[b,t,c]ub,t)2

接下来,进行对应的缩放操作

V ^ [ b , t , : ] ← γ t . V [ b , t , : ] − u b , t θ b , t 2 + ϵ + β t \hat{V}_{[b, t, :]} \leftarrow \gamma_t . \frac{V_{[b,t,:]} - u_{b,t} } {\sqrt{\theta^2_{b,t} + \epsilon}} + \beta_t V^[b,t,:]γt.θb,t2+ϵ V[b,t,:]ub,t+βt
其中 ϵ \epsilon ϵ为一个非常小的常数,防止分母为0,注意 γ t , β t \gamma_t,\beta_t γtβt为所有样本共享。

import torch
from torch.nn import LayerNorm as LN
import numpy as np
np.random.seed(0)

val = np.random.randn(2, 3, 4)
val_tensor = torch.from_numpy(val).float()
class myLayerNorm(torch.nn.Module):
    def __init__(self,
                 size,
                 dim,
                 eps: float = 1e-6) -> None:
        super().__init__()
        self.gamma = torch.nn.Parameter(torch.ones(size))
        self.beta = torch.nn.Parameter(torch.zeros(size))
        self.eps = eps
        self.dim = dim

    def forward(self, tensor: torch.Tensor):  # pylint: disable=arguments-differ
        mean = tensor.mean(self.dim, keepdim=True)
        std = tensor.std(self.dim, unbiased=False, keepdim=True)
        return self.gamma * (tensor - mean) / (std + self.eps) + self.beta

print("对整个样本进行正则化")
LN2 = LN([3, 4])(val_tensor)
myLN2 = myLayerNorm((3, 4), (1, 2))(val_tensor)
print("torchNL")
print(LV2)

print("myML")
print(myLN2)

print("对每个样本的每个序列点进行正则化")
LN1 = LN(4)(val_tensor)
print(LN1)
myLN2 = myLayerNorm((4), 2)(val_tensor)
print(myLN2)

输出如下:文章来源地址https://www.toymoban.com/news/detail-792767.html

对整个样本进行正则化
torchNL
tensor([[[ 1.1009, -0.3772,  0.2498,  1.6177],
         [ 1.2131, -1.8700,  0.2188, -0.9749],
         [-0.9227, -0.3659, -0.6548,  0.7652]],

        [[ 0.7022,  0.0685,  0.3878,  0.2786],
         [ 1.4288, -0.2555,  0.2582, -0.8987],
         [-2.5826,  0.5957,  0.8047, -0.7878]]],
       grad_fn=<NativeLayerNormBackward0>)
myML
tensor([[[ 1.1009, -0.3772,  0.2498,  1.6177],
         [ 1.2131, -1.8700,  0.2188, -0.9749],
         [-0.9227, -0.3659, -0.6548,  0.7652]],

        [[ 0.7022,  0.0685,  0.3878,  0.2786],
         [ 1.4288, -0.2555,  0.2582, -0.8987],
         [-2.5826,  0.5957,  0.8047, -0.7878]]], grad_fn=<AddBackward0>)
对每个样本的每个序列点进行正则化
tensor([[[ 0.5905, -1.3359, -0.5187,  1.2640],
         [ 1.3397, -1.2973,  0.4893, -0.5317],
         [-0.9773, -0.1110, -0.5604,  1.6487]],

        [[ 1.4983, -1.2706,  0.1247, -0.3525],
         [ 1.5190, -0.4557,  0.1465, -1.2098],
         [-1.5448,  0.8043,  0.9587, -0.2182]]],
       grad_fn=<NativeLayerNormBackward0>)
tensor([[[ 0.5905, -1.3359, -0.5187,  1.2640],
         [ 1.3397, -1.2973,  0.4893, -0.5317],
         [-0.9773, -0.1110, -0.5604,  1.6488]],

        [[ 1.4985, -1.2707,  0.1247, -0.3525],
         [ 1.5190, -0.4557,  0.1465, -1.2098],
         [-1.5448,  0.8043,  0.9587, -0.2182]]], grad_fn=<AddBackward0>)

到了这里,关于Batch Normalization、Layer Normalization代码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【深度学习】5-3 与学习相关的技巧 - Batch Normalization

    如果为了使各层拥有适当的广度,“强制性”地调整激活值的分布会怎样呢?实际上, Batch Normalization 方法就是基于这个想法而产生的 为什么Batch Norm这么惹人注目呢?因为Batch Norm有以下优点: 可以使学习快速进行(可以增大学习率)。 不那么依赖初始值(对于初始值不用那么神

    2024年02月10日
    浏览(25)
  • DNNGP模型解读-early stopping 和 batch normalization的使用

    一、考虑的因素(仅代表个人观点) 1.首先我们看到他的这篇文章所考虑的不同方面从而做出的不同改进,首先考虑到了对于基因组预测的深度学习方法的设计 ,我们设计出来这个方法就是为了基因组预测而使用,这也是主要目的,所以要抓住事物的主要方面。 2.DNNGP相比于

    2024年02月12日
    浏览(28)
  • pytorch10:正则化(weight_decay、dropout、Batch Normalization)

    往期回顾 pytorch01:概念、张量操作、线性回归与逻辑回归 pytorch02:数据读取DataLoader与Dataset、数据预处理transform pytorch03:transforms常见数据增强操作 pytorch04:网络模型创建 pytorch05:卷积、池化、激活 pytorch06:权重初始化 pytorch07:损失函数与优化器 pytorch08:学习率调整策略

    2024年02月01日
    浏览(35)
  • 深入理解ECAPA-TDNN——兼谈Res2Net、ASP统计池化、SENet、Batch Normalization

    ECAPA-TDNN是说话人识别中基于TDNN的神经网络,是目前最好的单体模型之一 关于TDNN,可以参考深入理解TDNN(Time Delay Neural Network)——兼谈x-vector网络结构 TDNN本质上是1维卷积,而且常常是1维膨胀卷积,这样的一种结构非常注重context,也就是上下文信息,具体而言,是在frame

    2024年02月03日
    浏览(29)
  • Spring Boot + Spring Batch 实现批处理任务,保姆级教程!(场景实战)

    来源:blog.csdn.net/qq_35387940/article/details/108193473 概念词就不多说了,我简单地介绍下 , spring batch 是一个 方便使用的 较健全的 批处理 框架。 为什么说是方便使用的,因为这是 基于spring的一个框架,接入简单、易理解、流程分明。 为什么说是较健全的, 因为它提供了往常我

    2024年02月11日
    浏览(30)
  • 【目标检测】epoch、、batch、、batch_size理解

    1 epoch         当一个完整的数据集通过神经网络一次并且返回一次的过程称为一个epoch。 然而,当一个epoch对于计算机太过庞大时,就需要把它分成多个小块。 2 batch         在不能将数据一次性通过神经网络的适合,就需要将数据集分成几个batch。 3 batch_size      

    2024年02月16日
    浏览(22)
  • [论文笔记]Layer Normalization

    这是论文神作Layer Normalization的阅读笔记。训练深层神经网络是昂贵的,减少训练时间的一种方法是归一化神经元的激活。 批归一化(Batch normalization,BN)利用小批量的训练样本中神经元累加输入的分布来计算均值和方差,然后用这些统计量来对每个训练样本中神经元的累加输入

    2024年02月12日
    浏览(23)
  • 深度学习中epoch、batch、batch size和iterations详解

    1.epoch 在训练一个模型时所用到的全部数据; 备注:一般在训练时都要使用多于一个的epoch,因为在神经网络中传递完整的数据集仅仅一次是不够的,只有将完整的数据集在同样的神经网络中传递多次,才会得到比较优秀的训练效果,当然也不行,容易过拟合,所以要根据实

    2023年04月25日
    浏览(27)
  • 7.5.tensorRT高级(2)-RAII接口模式下的生产者消费者多batch实现

    杜老师推出的 tensorRT从零起步高性能部署 课程,之前有看过一遍,但是没有做笔记,很多东西也忘了。这次重新撸一遍,顺便记记笔记。 本次课程学习 tensorRT 高级-RAII 接口模式下的生产者消费者多 batch 实现 课程大纲可看下面的思维导图 这节课我们利用上节课学到的 RAII

    2024年02月12日
    浏览(28)
  • hana odata batch

    sap 博客有写 odata batch 处理前,先看一张图   In this blog post,we are going to see how to send a Odata Batch Request to the SAP Cloud for Customer system using POSTMAN Tool. Answers to expect from this post? How to use batch request in the POSTMAN Tool What all are the Pre-requisites needs to be done before making a batch call. What is the for

    2024年02月02日
    浏览(19)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包