LayerNorm计算公式:
y=x−E(x)Var⁡(x)+ϵ∗γ+βy=\frac{x-E(x)}{\sqrt{\operatorname{Var}(x)+\epsilon}} * \gamma+\beta y=Var(x)+ϵ

xE(x)γ+β

一般有两种计算LayerNorm的方式,这两种方式的区别在与进行归一化操作的维度不同,假设输入的tensor维度为NxCxHxW,则两种计算方式分别如下:

(1)计算一个batch中所有channel中所有参数的均值和方差,然后进行归一化,操作维度为CxHxW,一般常用于CV领域(不过CV领域更长用的是BN
(2)计算一个batch中所有channel中的每一个参数的均值和方差进行归一化,操作维度为C,一般常用于NLP领域

计算LayerNorm,pytorch中有现成的计算API:

torch.nn.LayerNorm(normalized_shape, eps=1e-05, elementwise_affine=True)

normalized_shape: 输入尺寸
[∗×normalized_shape[0]×normalized_shape[1]×…×normalized_shape[−1]],归一化的维度,int(最后一维)list(list里面的维度)
eps: 为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5。
elementwise_affine: 布尔值,当设为true,给该层添加可学习的仿射变换参数。

第一种归一化方法(CV中使用的LayerNorm

对所有channel所有像素计算;

计算一个batch中所有channel中所有参数的均值和方差,然后进行归一化,即对CxHxW维度上的元素进行归一化(如下图蓝色区域部分所示,蓝色区域部分元素使用相同的mean合var进行归一化操作)

调用API计算示例如下:

N, C, H, W = 2, 3, 4, 5
input = torch.randn(N, C, H, W)
# Normalize over the last three dimensions (i.e. the channel and spatial dimensions) as shown in the image below
layer_norm = nn.LayerNorm([C, H, W])
out=layer_norm(input)
print('out shape: {}'.format(out.shape))
print('out data: {}'.format(out))
"""
out shape: torch.Size([2, 3, 4, 5])
out data: tensor([[[[-0.1054,  0.5613,  0.9684, -0.7211, -3.3157],[ 0.1993, -0.3108,  0.1403,  0.4901, -0.4136],[-0.8457, -1.1607, -0.7967,  0.2736, -1.2216],[-0.3253,  1.3176,  0.1544, -0.5213,  0.7506]],[[ 1.6987, -2.3863,  0.7939,  0.2268,  0.3961],[-0.3590,  0.1052, -0.3119,  0.2033, -2.2351],[ 0.5327,  1.5541,  0.8168,  1.3824, -1.7577],[-0.1080,  0.1581,  0.3912,  0.3980, -0.5219]],[[-0.7660, -0.3298,  0.3871,  0.0186,  1.0544],[-0.1583,  0.0251, -1.4124, -0.0570,  1.1680],[ 1.3687, -0.1523,  1.2398, -0.1628,  0.8833],[ 1.5717, -1.2190,  0.5367,  0.9975, -1.0882]]],[[[ 1.0945,  0.1024, -1.8453,  0.1361,  1.6499],[ 0.2284,  0.1938, -0.3570,  1.7049, -0.7654],[-0.9878, -0.6431, -0.3868,  1.5572,  0.4809],[ 0.7264, -0.1426, -1.6283, -0.1583, -1.1346]],[[ 0.0462, -1.4155,  0.6029, -0.1333,  0.2013],[-0.2044, -1.0898,  1.5928,  0.0257,  0.2310],[ 1.0854, -0.2363, -0.3721, -1.2205, -0.6438],
...[ 0.9354,  0.6988, -0.2594,  0.0404, -1.9282],[ 1.0362, -0.4182, -2.1887,  0.4830,  0.5986],[ 0.0198, -0.7105, -1.1114,  0.7437,  0.7484]]]],grad_fn=<AddcmulBackward>)
"""

对应的,手动计算LayerNorm,在CHW维度上进行归一化操作如下:

ln_mean=input.reshape([batch_size,-1]).mean(dim=1,keepdim=True).unsqueeze(2).unsqueeze(3) #计算后维度N*1*1*1
ln_std=input.reshape([batch_size,-1]).std(dim=1,keepdim=True,unbiased=False).unsqueeze(2).unsqueeze(3) #计算后维度N*1*1*1ln_y=(input-ln_mean)/(ln_std+1e-5)
print('out shape: {}'.format(ln_y.shape))
print('out data: {}'.format(ln_y))
"""
out shape: torch.Size([2, 3, 4, 5])
out data: tensor([[[[-0.1054,  0.5613,  0.9684, -0.7211, -3.3157],[ 0.1993, -0.3108,  0.1403,  0.4901, -0.4136],[-0.8457, -1.1607, -0.7967,  0.2736, -1.2216],[-0.3253,  1.3176,  0.1544, -0.5213,  0.7506]],[[ 1.6987, -2.3863,  0.7939,  0.2268,  0.3961],[-0.3590,  0.1052, -0.3119,  0.2033, -2.2351],[ 0.5327,  1.5541,  0.8167,  1.3824, -1.7577],[-0.1080,  0.1581,  0.3912,  0.3980, -0.5219]],[[-0.7660, -0.3298,  0.3871,  0.0186,  1.0544],[-0.1583,  0.0251, -1.4124, -0.0570,  1.1680],[ 1.3686, -0.1523,  1.2397, -0.1628,  0.8833],[ 1.5717, -1.2190,  0.5367,  0.9975, -1.0882]]],[[[ 1.0945,  0.1024, -1.8453,  0.1361,  1.6499],[ 0.2284,  0.1938, -0.3570,  1.7049, -0.7654],[-0.9878, -0.6431, -0.3868,  1.5572,  0.4809],[ 0.7264, -0.1426, -1.6283, -0.1583, -1.1346]],[[ 0.0462, -1.4155,  0.6029, -0.1333,  0.2013],[-0.2044, -1.0898,  1.5928,  0.0257,  0.2310],[ 1.0854, -0.2363, -0.3721, -1.2205, -0.6438],
...[[-0.8811, -0.9786, -0.8169, -0.8120,  0.8833],[ 0.9354,  0.6988, -0.2594,  0.0404, -1.9282],[ 1.0362, -0.4182, -2.1887,  0.4830,  0.5986],[ 0.0198, -0.7105, -1.1114,  0.7437,  0.7484]]]])
"""

第二种归一化方法(NLP中常用的LayerNorm

计算一个batch中所有channel中的每一个参数的均值和方差进行归一化,即只在C维度上进行归一化计算(与CV中在CxHxW维度上计算不同)

下面是调用API计算的示例:

batch_size=2
time_steps=3
embedding_dim=4inputx=torch.randn(batch_size,time_steps,embedding_dim)#N*L*C
layer_norm=nn.LayerNorm(embedding_dim,elementwise_affine=False)
ln_y=layer_norm(inputx)
print('out shape: {}'.format(ln_y.shape))
print('out data: {}'.format(ln_y))
"""
out shape: torch.Size([2, 3, 4])
out data: tensor([[[ 0.8237, -0.3322, -1.4888,  0.9972],[ 1.5845, -0.0058, -1.1379, -0.4408],[-1.5878,  0.7535,  0.9477, -0.1134]],[[-0.0703,  0.3985, -1.5393,  1.2111],[ 1.0949,  0.0075,  0.4960, -1.5985],[ 0.0843, -0.0753, -1.4164,  1.4074]]])
"""

下面是对应的手动计算方式:

inputx_mean=inputx.mean(dim=-1,keepdim=True)                #只在维度C上计算均值,计算后维度为N*L*1
inputx_std=inputx.std(dim=-1,keepdim=True,unbiased=False)   #只在维度C上计算标准差,计算后维度为N*L*1
verify_ln_y=(inputx-inputx_mean)/(inputx_std+1e-5)
print('out shape: {}'.format(verify_ln_y.shape))
print('out data: {}'.format(verify_ln_y))
"""
out shape: torch.Size([2, 3, 4])
out data: tensor([[[ 0.8237, -0.3322, -1.4888,  0.9972],[ 1.5845, -0.0058, -1.1379, -0.4408],[-1.5878,  0.7535,  0.9477, -0.1134]],[[-0.0703,  0.3985, -1.5393,  1.2111],[ 1.0949,  0.0075,  0.4960, -1.5984],[ 0.0843, -0.0753, -1.4164,  1.4074]]])
"""

LayerNorm的理解相关推荐

  1. 深入理解NLP中LayerNorm的原理以及LN的代码详解

    想来大厂字节跳动的同学不要错过这次2024届的暑期实习招聘,「2023年4月30日」就截止了: ❤️ 粉丝专属内推码:JYT8RH3 ❤️

  2. 10分钟带你深入理解Transformer原理及实现

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自|深度学习这件小事 基于 Transformer<A ...

  3. Pytorch归一化方法讲解与实战:BatchNormalization、LayerNormalization、nn.BatchNorm1d和LayerNorm()和F.normalize()

    文章目录 LayerNormalization BatchNormalization F.normalize 这些Normalization的作用都是让数据保持一个比较稳定的分布,从而加速收敛.Bat ...

  4. lstm代码_贼好理解,这个项目教你如何用百行代码搞定各类NLP模型

    机器之心报道 参与:思源.贾伟 NLP 的研究,从词嵌入到 CNN,再到 RNN,再到 Attention,以及现在正红火的 Transformer,模型已有很多,代码库也成千上万.对于初学者如何把握 ...

  5. 【论文解读】A Survey on Visual Transformer及引文理解

    A Survey on Visual Transformer阅读,以及自己对相关引文的理解. Transformer 作为NLP领域的大杀器,目前已经在CV领域逐渐展露锋芒,大有替代CNN的趋势,在图 ...

  6. 知乎搜索框背后的Query理解和语义召回技术

    一只小狐狸带你解锁 炼丹术&NLP 秘籍 前言 随着用户规模和产品的发展, 知乎搜索面临着越来越大的 query 长尾化挑战,query 理解是提升搜索召回质量的关键.本次分享将介绍知乎搜索在 ...

  7. 卷积在计算机中实现+pool作用+数据预处理目的+特征归一化+理解BN+感受野理解与计算+梯度回传+NMS/soft NMS

    一.卷积在计算机中实现 1.卷积 将其存入内存当中再操作(按照"行先序"): 这样就造成混乱. 故需要im2col操作,将特征图转换成庞大的矩阵来进行卷积计算,利用矩阵加速来实现, ...

  8. 腾讯基于预训练模型的文本内容理解实践

    分享嘉宾:赵哲博士 腾讯 高级研究员 编辑整理:张书源 爱丁堡大学 出品平台:DataFunTalk 导读:预训练已经成为自然语言处理任务的重要组成部分,为大量自然语言处理任务带来了显著提升.本文将围 ...

  9. BERT通俗笔记:从Word2Vec/Transformer逐步理解到BERT

    前言 我在写上一篇博客<22下半年>时,有读者在文章下面评论道:"july大神,请问BERT的通俗理解还做吗?",我当时给他发了张俊林老师的BERT文章,所以没太在意. ...

最新文章

  1. 计算机主机的作用和性能指标,Cpu是什么 cpu性能指标主要有哪几个方面【详细介绍】...
  2. 选频放大电路对于150kHz导航信号进行放大检波
  3. 摩托罗拉指控苹果iPhone 4S和iCloud侵犯6项专利
  4. 用Docker容器自带的tensorflow serving部署模型对外服务
  5. Leetcode--130. 被围绕的区域(java)
  6. Xcode常见的编译、运行等错误的解决
  7. @Pathvariable的参数允许为空的问题的解决
  8. 熟练掌握如何设置空闲超时时间.
  9. 如何使用 python glob model
  10. 16_多易教育之《yiee数据运营系统》用户画像-标签体系设计篇
  11. 怎么在wps里做计算机,解决方案:如何在wps中制作电子小报
  12. 用php搭建微信公众号淘客三合一系统
  13. oracle认证考试试题及答案,Oracle DBA认证考试存储管理试题及答案
  14. 【HDU4960】Another OCD Patient
  15. 苏宁、长虹、格力,为何“玩不好”旧家电?
  16. 2023京东年货节全民炸年兽活动最详细规则
  17. JzxxOJ Problem 4209: 寻找雷劈数 题解
  18. 汽车钥匙芯片工作原理 浅谈汽车钥匙芯片作用及分类
  19. 给大家介绍下,这是我的流程图软件 —— draw.io
  20. Ubuntu安装ping工具

热门文章

  1. selenium使用账号密码模拟登陆淘宝,使用账号密码
  2. 耳机左右声道接反的问题
  3. 【二、FreeBSD的系统按装步骤】(基于FreeBSD虚拟机安装好的基础之上)
  4. 玩游戏不慎被盗vx号的小白在线求助腾讯的大佬们
  5. maven打包项目时报错:Cannot create resource output directory
  6. 访达前往文件夹_Mac实用技巧之:访达/Finder
  7. Java8 之熟透 Lambda 表达式
  8. 1、输入年份,判断是否是闰年?
  9. 【聆思CSK6 视觉AI开发套件试用】基于CSK6011a_nano的虚拟打砖块交互系统
  10. mac用什么软件测试硬盘好坏,mac如何测试硬盘速度-mac测试硬盘速度教程 - 河东软件园...