什么是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残留文…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
字符串哈希+KMP
P10468 兔子与兔子 #include<bits/stdc.h> using namespace std; typedef unsigned long long ull; const int N 1000010; ull a[N], pw[N]; int n; ull gethash(int l, int r){return a[r] - a[l - 1] * pw[r - l 1]; } signed main(){ios::sync_with_stdio(false), …...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...
C# WPF 左右布局实现学习笔记(1)
开发流程视频: https://www.youtube.com/watch?vCkHyDYeImjY&ab_channelC%23DesignPro Git源码: GitHub - CSharpDesignPro/Page-Navigation-using-MVVM: WPF - Page Navigation using MVVM 1. 新建工程 新建WPF应用(.NET Framework) 2.…...
