什么是Layer Normalization?
一、概念
前面的文章中,我们介绍了Batch Normalization。BN的目的是使得每个batch的输入数据在每个维度上的均值为0、方差为1(batch内,数据维度A的所有数值均值为0、方差为1,维度B、C等以此类推),这是由于神经网络的每一层输出数据分布都会发生变化,随着网络层数的增加,内部协变量的偏移程度会变大。我们在数据预处理阶段使用sklearn等工具进行的Normalization仅仅解决了第一层输入的问题,而隐藏层中各层的输入问题仍然存在。因此我们将BN嵌入到模型结构内部,用于把每一个batch的数据拉回正态分布。
然而,BN通过对每个维度进行正态分布处理,会使得各个维度之间的数值大小关系失真,也就是单一样本内部的特征关系被打乱了。显然,这对于处理文本向量等序列数据来说并不友好,文本向量内部的语义关系会受到BN的影响。因此,预训练模型、大语言模型等内部一般不会采用BN,而是采用Layer Normalization。
Layer Normalization对神经网络中每一层的输出进行归一化处理,确保单条样本内部各特征的均值为0、方差为1:
- 计算均值和方差:对每个样本的特征维度计算均值和方差。
- 归一化处理:使用计算出的均值和方差对当前样本进行归一化,使其均值为0,方差为1。
- 缩放和平移:引入可学习的参数进行尺度和偏移变换,以恢复模型的表达能力。
Layer Normalization能够减少训练过程中的梯度爆炸或消失问题,从而提高模型的稳定性和训练效率。尤其是在RNN和Transformer等序列模型中,LN所实现的稳定数据分布有助于模型层与层之间的信息流更加平滑。
二、LN示例
下面,我们给出一个LN的简单示例。与Batch Normalization不同,Layer Normalization不依赖于mini-batch,而是对每一个样本独立进行归一化,这使得它适用于各种数据规模,包括小批量和单个样本。
import torch
import torch.nn as nn# 构造一个单一样本,包含5个特征
sample = torch.tensor([2.0, 3.0, 5.0, 1.0, 4.0], requires_grad=True)
print("Original Sample:", sample)# 定义Layer Normalization层
# 特征数量(特征维度)为5
ln = nn.LayerNorm(normalized_shape=[5])# 应用Layer Normalization
sample_norm = ln(sample)
print("Normalized Sample:", sample_norm)# 检查均值和方差
mean = sample_norm.mean()
var = sample_norm.var()
print("Mean:", mean)
print("Variance:", var)
三、python应用
这里,我们在构建网络的过程中加入LN,并对比前后的数据差异。
import torch
import torch.nn as nn
import matplotlib.pyplot as plt# 设置随机种子以确保结果可复现
torch.manual_seed(0)# 创建一个简单的模型
class SimpleModel(nn.Module):def __init__(self):super(SimpleModel, self).__init__()self.linear = nn.Linear(100, 50) # 一个线性层self.ln = nn.LayerNorm(50) # Layer Normalization层def forward(self, x):x = self.linear(x)x = self.ln(x)return x# 创建模型实例
model = SimpleModel()# 生成模拟数据:100个样本,每个样本100个特征
x = torch.randn(100, 100, requires_grad=True)# 前向传播,计算LN前的数据
x_linear = model.linear(x)
x_linear = x_linear.detach()# 计算LN前的数据均值和方差
mean_before = x_linear.mean(dim=0)
var_before = x_linear.var(dim=0)# 应用LN
x_ln = model(x)
x_ln = x_ln.detach()# 计算LN后的数据均值和方差
mean_after = x_ln.mean(dim=0)
var_after = x_ln.var(dim=0)# 随机选择一个样本
sample_index = 0
single_sample_before = x_linear[sample_index].unsqueeze(0)
single_sample_after = x_ln[sample_index].unsqueeze(0)# 计算单个样本的均值和方差
mean_single_before = single_sample_before.mean()
var_single_before = single_sample_before.var()
mean_single_after = single_sample_after.mean()
var_single_after = single_sample_after.var()# 绘制LN前后数据的分布
fig, ax = plt.subplots(2, 3, figsize=(18, 12))# 绘制LN前的数据分布
ax[0, 0].hist(x_linear.detach().numpy().flatten(), bins=30, color='blue', alpha=0.7)
ax[0, 0].set_title('Before LN: Data Distribution')# 绘制LN后的数据分布
ax[0, 1].hist(x_ln.detach().numpy().flatten(), bins=30, color='green', alpha=0.7)
ax[0, 1].set_title('After LN: Data Distribution')# 绘制单个样本LN前的数据分布
ax[0, 2].hist(single_sample_before.detach().numpy().flatten(), bins=30, color='red', alpha=0.7)
ax[0, 2].set_title('Single Sample Before LN')# 绘制LN前的数据均值和方差
ax[1, 0].bar(range(50), var_before, color='blue', alpha=0.7)
ax[1, 0].set_title('Before LN: Variance per Feature')
ax[1, 0].set_xticks(range(0, 50, 5))# 绘制LN后的数据均值和方差
ax[1, 1].bar(range(50), var_after, color='green', alpha=0.7)
ax[1, 1].set_title('After LN: Variance per Feature')
ax[1, 1].set_xticks(range(0, 50, 5))# 绘制单个样本LN后的均值和方差
ax[1, 2].bar(range(1), var_single_after.item(), color='red', alpha=0.7)
ax[1, 2].set_title('Single Sample After LN: Variance')
ax[1, 2].set_xticks([])plt.tight_layout()
plt.show()# 打印LN前后的数据均值和方差
print(f"Mean before LN: {mean_before}")
print(f"Mean after LN: {mean_after}")
print(f"Variance before LN: {var_before}")
print(f"Variance after LN: {var_after}")
print(f"Mean of single sample before LN: {mean_single_before}")
print(f"Variance of single sample before LN: {var_single_before}")
print(f"Mean of single sample after LN: {mean_single_after}")
print(f"Variance of single sample after LN: {var_single_after}")
可见右下角子图,LN之后,单条样本内部已经拉成正态分布了。

四、总结
BN和LN都是缓解深度学习模型梯度消失或者梯度爆炸重要技巧,实际建模过程中我们也可以通过对比加入BN或者LN前后的模型表现来调整最终的模型架构。但值得注意的是,在选择BN或者LN的时候,我们需要想清楚到底单一维度的正态分布对当前任务来说更有意义还是说单一样本内部数值的正态分布更有意义。
相关文章:
什么是Layer Normalization?
一、概念 前面的文章中,我们介绍了Batch Normalization。BN的目的是使得每个batch的输入数据在每个维度上的均值为0、方差为1(batch内,数据维度A的所有数值均值为0、方差为1,维度B、C等以此类推),这是由于神…...
17. Threejs案例-Three.js创建多个立方体
17. Threejs案例-Three.js创建多个立方体 实现效果 知识点 WebGLRenderer (WebGL渲染器) WebGLRenderer 是 Three.js 中用于渲染 WebGL 场景的核心类。它负责将场景中的对象渲染到画布上。 构造器 new THREE.WebGLRenderer(parameters) 参数类型描述parametersObject可选…...
RK3568 Android14 打开蓝牙时默认同意
1、最近给一个项目做了一款基础功能的自动测试,在打开蓝牙时,有一个是否同意的提示框要去掉,即默认同意打开蓝牙。 2、路径: packages/apps/Settings/src/com/android/settings/bluetooth/RequestPermissionActivity.java// Sho…...
多模态视频大模型Aria在Docker部署
多模态视频大模型Aria在Docker部署 契机 ⚙ 闲逛HuggingFace的时候发现一个25.3B的多模态大模型,支持图片和视频。刚好我有H20的GPU所以部署来看看效果,因为我的宿主机是cuda-12.1所以为了防止环境污染采用docker部署,通过一系列的披荆斩棘…...
Ant-Design-Vue 全屏下拉日期框无法显示,能显示后小屏又位置错乱
问题1:在全屏后 日期选择器的下拉框无法显示。 解决:在Ant-Design-Vue的文档中,很多含下拉框的组件都有一个属性 getPopupContainer可以用来指定弹出层的挂载节点。 在该组件上加上 getPopupContainer 属性,给挂载到最外层盒子上。 <temp…...
AMR移动机器人赋能制造业仓储自动化升级
在当今制造业的激烈竞争中,智能化、数字化已成为企业转型升级的关键路径。一家制造业巨头,凭借其庞大的生产体系和多个仓库资源,正以前所未有的决心和行动力,在制造业智能化浪潮中勇立潮头,开启了降本增效的新篇章。这…...
【PHP项目实战】活动报名系统
目录 项目介绍 开发语言 后端 前端 项目截图(部分) 首页 列表 详情 个人中心 后台管理 项目演示 项目介绍 本项目是一款基于手机浏览器的活动报名系统。它提供了一个方便快捷的活动报名解决方案,无需下载和安装任何APP,…...
【HarmonyOS】Component组件引入报错 does not meet UI component syntax.
【HarmonyOS】Component组件引入报错 一、问题背景 有时会碰到引入组件时,无法import引入组件,导致引入的组件报错。 或者提示does not meet UI component syntax. (不符合UI组件语法。) 如下图所示,在引入组件时&a…...
vue3项目最新eslint9+prettier+husky+stylelint+vscode配置
一、eslint9和prettier通用配置 安装必装插件 ESlint9.x pnpm add eslintlatest -DESlint配置 vue 规则 , typescript解析器 pnpm add eslint-plugin-vue typescript-eslint -DESlint配置 JavaScript 规则 pnpm add eslint/js -D配置所有全局变量 globals pnpm add globa…...
备赛蓝桥杯--算法题目(3)
1. 2的幂 231. 2 的幂 - 力扣(LeetCode) class Solution { public:bool isPowerOfTwo(int n) {return n>0&&n(n&(-n));} }; 2. 3的幂 326. 3 的幂 - 力扣(LeetCode) class Solution { public:bool isPowerOfT…...
CSS中要注意的样式效果
1. 应用过渡效果 transition: var(--aa); 2.告诉浏览器元素可能会发生变换,从而优化性能。 will-change: transform; 3.使元素不响应鼠标事件。 pointer-events: none; 4.隐藏水平方向上的溢出内容 overflow-x: hidden; 5.定义一个元素的宽度和高度之间的比…...
【NIPS2024】Unique3D:从单张图像高效生成高质量的3D网格
背景(现有方法的不足): 基于Score Distillation Sampling (SDS)的方法:从大型二维扩散模型中提取3D知识,生成多样化的3D结果,但存在每个案例长时间优化问题/不一致问题。 目前通过微…...
使用Kubernetes部署Spring Boot项目
目录 前提条件 新建Spring Boot项目并编写一个接口 新建Maven工程 导入 Spring Boot 相关的依赖 启动项目 编写Controller 测试接口 构建镜像 打jar包 新建Dockerfile文件 Linux目录准备 上传Dockerfile和target目录到Linux 制作镜像 查看镜像 测试镜像 上传镜…...
基于VTX356语音识别合成芯片的智能语音交互闹钟方案
一、方案概述 本方案旨在利用VTX356语音识别合成芯片强大的语音处理能力,结合蓝牙功能、APP或小程序,打造一款功能全面且智能化程度高的闹钟产品。除了基本的时钟显示和闹钟提醒功能外,还拥有正计时、倒计时、日程安排、重要日提醒以及番茄钟…...
git将一个项目的文件放到另一个项目的文件夹下
现有productA与productB项目,现将productA、productB放到productC下的mall-web文件下,目前只能实现保留productA的提交记录,暂不能实现保留两个的提交记录 一.克隆最新的productC的库,这里指mall-web 二.将productA复制到mall-we…...
Cannon.js 从入门到精通
开发领域:前端开发 | AI 应用 | Web3D | 元宇宙 技术栈:JavaScript、React、ThreeJs、WebGL、Go 经验经验:6 年 前端开发经验,专注于图形渲染和 AI 技术 开源项目:智简未来、数字孪生引擎 github 大家好!我…...
深入理解 TCP 标志位(TCP Flags)
深入理解 TCP 标志位(TCP Flags) 1. 简介 在网络安全和网络分析领域,TCP标志位(TCP Flags)是理解网络行为和流量模式的关键概念。特别是在使用工具如Nmap进行端口扫描时,理解这些标志位的意义和用法至关重…...
K8S,StatefulSet
有状态应用 Deployment实际上并不足以覆盖所有的应用编排问题? 分布式应用,它的多个实例之间,往往有依赖关系,比如:主从关系、主备关系。 还有就是数据存储类应用,它的多个实例,往往都会在本地…...
JavaScript动态网络爬取:深入解析与实践指南
引言 随着互联网技术的发展,越来越多的网站采用动态加载技术来提供丰富的用户体验。这些动态内容的加载依赖于JavaScript,给传统的网络爬虫带来了挑战。JavaScript动态网络爬取技术应运而生,它允许开发者模拟用户行为,获取动态加…...
MySql:Centos7安装MySql
目录 安装之前,清除MySql残留文件 下载MySql的官方yum源 安装MySql 服务 MySql配置 常见问题 本次安装基于Centos7,平台为云服务器,由XShell软件演示。 注意,请将用户切换为Root用户。 安装之前,清除MySql残留文…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
nnUNet V2修改网络——暴力替换网络为UNet++
更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
