Batch Normalization、Layer Normalization代码实现

目录

  • 前言
  • 批量正则化-BN
  • 层正则化-LN

前言

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是同时对所有样本的对应通道进行正则化,有多少个通道,就会有多少组均值和方差,单独对每个通道的值进行缩放,示意图如下:
在这里插入图片描述

假设数据格式为 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

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

$ \hat{V}{[:, c, :, :]} \leftarrow \gamma_c . \frac{V{[:,c,:,:]} - u_c } {\sqrt{\theta^2_c + \epsilon}} + \beta_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 = epsself.dim = dimdef forward(self, tensor: torch.Tensor):  # pylint: disable=arguments-differmean = tensor.mean(self.dim, keepdim=True)std = tensor.std(self.dim, unbiased=False, keepdim=True)return self.gamma * (tensor - mean) / (std + self.eps) + self.betaprint("-----一维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、序列长度、特征维度,那么一般会针对每个样本的每个序列点的特征进行标准化,当然也可以对每个样本整体进行标准化,示意图如下:
在这里插入图片描述

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

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 = epsself.dim = dimdef forward(self, tensor: torch.Tensor):  # pylint: disable=arguments-differmean = tensor.mean(self.dim, keepdim=True)std = tensor.std(self.dim, unbiased=False, keepdim=True)return self.gamma * (tensor - mean) / (std + self.eps) + self.betaprint("对整个样本进行正则化")
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)

输出如下:

对整个样本进行正则化
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>)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/624713.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

营销与经营一体,巨量引擎如何激发生意新未来?

12月6日&#xff0c;在第九届GDMS全球数字营销峰会上&#xff0c;巨量引擎发表了《营销经营一体&#xff0c;激发生意新未来》为主题的演讲&#xff0c;分享了巨量引擎如何在营销与经营一体化的背景下&#xff0c;通过极致的产品技术创新&#xff0c;激发生意新未来。 激发全渠…

ClientHttpRequestInterceptor报错Timeout waiting for connection from pool

restTemplate实现ClientHttpRequestInterceptor&#xff0c;报错org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool 代码如下&#xff1a; Configuration public class HttpConfig {private static final Integer RETRY_COUNT…

0基础学java-day26(满汉楼实战)

一、界面设计 1. 需求说明 2 界面设计 2.1 用户登录 2.2 显示餐桌状态 2.3 预订 2.4 显示菜品 2.5 点餐 2.6 查看账单 2.7 结账 3 分层设计 二、功能实现 1 工具类 1.1 构建如下的项目结构 1.2 导入相关的工具类和jar包 相关的工具类和jar包会放在评论区的百度网盘的链接…

VBA之Excel应用第五节:录制宏时,使用绝对引用和相对引用

《VBA之Excel应用》&#xff08;版权10178983&#xff09;是非常经典的&#xff0c;是我推出的第七套教程&#xff0c;定位于初级&#xff0c;目前是第一版修订。这套教程从简单的录制宏开始讲解&#xff0c;一直到窗体的搭建&#xff0c;内容丰富&#xff0c;实例众多。大家可…

基于JAVA+ssm开发的在线报名系统设计与实现【附源码】

基于JAVAssm开发的在线报名系统设计与实现【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 …

vue使用i18n实现国际化

安装 npm install vue-i18nnext在src下创建一个名为i18n的文件夹,并按照下图创建需要的文件 i18n/locales/en.json {"common": {"BUTTON_OK": "OK","BUTTON_CANCEL": "Cancel","BUTTON_SUBMIT": "Submit…

linux后台进程的总结

文章目录 方案1 nohup &方案2 screen 方案1 nohup & 1、单独使用 nohup 执行脚本&#xff0c;如下图所示&#xff0c;终端会被接管&#xff0c;就是标准输入stdin 被关闭了&#xff0c;使用ctrlc会导致终止执行&#xff0c;但是可以关闭这个终端&#xff0c;重新打开终…

二叉树题目:从前序与后序遍历序列构造二叉树

文章目录 题目标题和出处难度题目描述要求示例数据范围 前言解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;从前序与后序遍历序列构造二叉树 出处&#xff1a;889. 从前序与后序遍历序列构造二叉树 难度 7 级 题目描述…

react项目运行卡在编译:您当前运行的TypeScript版本不受@TypeScript eslint/TypeScript estree的官方支持

1.问题 错误信息具体如下&#xff1a; 搜索了一下&#xff0c;是typescript版本的问题&#xff0c;提示我版本需要在3.3.0和4.5.0中间&#xff0c;我查看了package.json&#xff0c;显示版本为4.1.3&#xff0c;然后一直给我提示我的版本是4.9.5&#xff0c;全局搜索一下&…

FPGA——时序分析与约束(Quartus II)

FPGA时序分析与约束 FPGA结构基础数据传输模型Quartus II 时序报告Quartus II 中TimeQuest的操作实操 时序分析&#xff1a;通过分析FPGA内部各个存储器之间的数据和时钟传输路径&#xff0c;来分析数据延迟和时钟延迟的关系&#xff0c;保证所有寄存器都可以正确寄存数据。 数…

Ubuntu配置NFS客户端和服务端详解——手把手配置

Ubuntu配置NFS客户端和服务端 如果您想实现远程访问并修改 ROS 主机中 Ubuntu 上的文件&#xff0c;可以通过 NFS挂载的方式。虚拟机上的 Ubuntu 系统可以通过 NFS 的方式来访问 ROS 主机中Ubuntu 系统的文件&#xff0c;NFS 分为服务器挂载和客户端访问。这里虚拟机上的 Ubun…

基于多反应堆的高并发服务器【C/C++/Reactor】(中)HttpRequest 提取请求行、解析请求行和优化 以及解析请求头并存储

### 知识点1&#xff1a;读取网络数据 客户端发送给服务器的通信数据通过封装的bufferSocketRead函数读取读取的数据存储在struct Buffer结构体实例中&#xff0c;可将该实例作为参数传递给解析函数 回顾Buffer.c中的bufferSocketRead函数 // 写内存 2.接收套接字数据 int b…

腾讯云服务器新版活动报价表,3年核5年适合长期使用

腾讯云服务器优惠价格表_一年、3年、包月和1小时费用_最新报价 腾讯云服务器租用优惠价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器646元15个…

【复现】Tenda信息泄露漏洞_19

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 Tenda远端WEB管理是为了在外网&#xff08;其他网络&#xff09;可以访问路由器&#xff0c;从而进行管理。 电脑可以通过网线连接…

HTML---JAVAscript对向和原型链

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 一.JavaSceipt对象概述 JavaScript是一种基于对象的编程语言&#xff0c;每个值都是一个对象。JavaScript中的对象是一种无序的键值对集合&#xff0c;其中每个键都是唯一的。 JavaScript的…

浅析Pe2shellcode

编者注&#xff1a;本文仅供学习研究&#xff0c;严禁从事非法活动&#xff0c;任何后果由使用者本人负责。 前言 众所周知&#xff0c;对shellcode免杀是很流行的技术&#xff0c;但是直接对exe的免杀方法相对稀缺&#xff0c;如果我们能将exe转为shellcode&#xff0c;然后用…

基于ssm的中文学习系统的设计与实现+jsp论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本中文学习系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&am…

电脑桌面便签在哪设置?备忘录软件哪个好?

好记性不如烂笔头&#xff01;相信很多打工族在电脑面前办公的时候&#xff0c;都需要随时记录工作中的事项&#xff0c;有的用TXT记录&#xff0c;有的手写笔记&#xff0c;还有一些用电脑桌面便签类软件。而当我们待办事项繁多的时候&#xff0c;手写或文本记录并不能有效帮我…

去不了哈尔滨? 来看这里VR全景线上云体验

如果你无法亲自前往哈尔滨&#xff0c;那么不要失望&#xff0c;因为现在有一种全新的方式让你在家就能领略到哈尔滨的美丽景色。 冰城客户端、哈尔滨新闻网承办的“激情迎亚冬 冰雪暖世界——2024年哈尔滨冰雪乐园” 运用720云VR打造的沉浸式体验产品正式上线&#xff0c;将带…

[我的Rust库更新]get_local_info 0.2.3

今天收到西安城市开发者社区的文章收录通知&#xff0c;谢谢社区的肯定。 随即发布0.2.3版本&#xff0c;增加峰值算法。 get_local_info是一个获取linux本地信息的Rust三方库&#xff0c;其目标是降低获取本地linux系统信息的难度。支持银河麒麟10、UOS、鸿蒙等国产系统。 项…