层归一化、残差、前馈网络与激活函数简述

层归一化(LayerNorm)

概述

层归一化就是把一个样本的所有特征值,调整成均值为 0、方差为 1 的标准分布,然后再用两个可学习参数 γγγ 和 βββ 做缩放和平移。

它和 BatchNorm 的区别:BatchNorm 是在 batch 维度上做归一化,LayerNorm 是在单个样本的特征维度上做归一化,不依赖 batch 大小,适合序列模型。

公式

给定一个向量 x=x1,x2,...,xdx = x_1, x_2, \\dots, x_dx=x1,x2,...,xd:

μ=1d∑i=1dxi \mu = \frac{1}{d} \sum_{i=1}^{d} x_ iμ=d1i=1∑dxi

σ=1d∑i=1d(xi−μ)2+ϵ \sigma = \sqrt{\frac{1}{d} \sum_{i=1}^{d} (x_i - \mu)^2 + \epsilon} σ=d1i=1∑d(xi−μ)2+ϵ

x^i=xi−μσ \hat{x}_i = \frac{x_i - \mu}{\sigma} x^i=σxi−μ

LN(x)i=γix^i+βi \text{LN}(x)_i = \gamma_i \hat{x}_i + \beta_i LN(x)i=γix^i+βi

其中 ϵ\epsilonϵ 是很小的常数(如 10−510^{-5}10−5),防止除零。

数值例子

取向量 x=1.848,2.872,2.594,1.599x = 1.848, 2.872, 2.594, 1.599x=1.848,2.872,2.594,1.599。

第一步:均值

μ=1.848+2.872+2.594+1.5994=8.9134=2.22825 \mu = \frac{1.848 + 2.872 + 2.594 + 1.599}{4} = \frac{8.913}{4} = 2.22825 μ=41.848+2.872+2.594+1.599=48.913=2.22825

第二步:方差

σ2=(1.848−2.22825)2+(2.872−2.22825)2+(2.594−2.22825)2+(1.599−2.22825)24 \sigma^2 = \frac{(1.848 - 2.22825)^2 + (2.872 - 2.22825)^2 + (2.594 - 2.22825)^2 + (1.599 - 2.22825)^2}{4} σ2=4(1.848−2.22825)2+(2.872−2.22825)2+(2.594−2.22825)2+(1.599−2.22825)2

逐项计算:

  • 1.848−2.22825=−0.380251.848 - 2.22825 = -0.380251.848−2.22825=−0.38025,平方 =0.14459= 0.14459=0.14459
  • 2.872−2.22825=0.643752.872 - 2.22825 = 0.643752.872−2.22825=0.64375,平方 =0.41441= 0.41441=0.41441
  • 2.594−2.22825=0.365752.594 - 2.22825 = 0.365752.594−2.22825=0.36575,平方 =0.13377= 0.13377=0.13377
  • 1.599−2.22825=−0.629251.599 - 2.22825 = -0.629251.599−2.22825=−0.62925,平方 =0.39596= 0.39596=0.39596

总和 =1.08873= 1.08873=1.08873,除以 4:

σ2=0.27218 \sigma^2 = 0.27218 σ2=0.27218

σ=0.27218≈0.52171 \sigma = \sqrt{0.27218} \approx 0.52171 σ=0.27218 ≈0.52171

第三步:归一化 (忽略 ϵ\epsilonϵ)

x^i=xi−μσ \hat{x}_i = \frac{x_i - \mu}{\sigma} x^i=σxi−μ

  • x^1=−0.38025/0.52171≈−0.7288\hat{x}_1 = -0.38025 / 0.52171 \approx -0.7288x^1=−0.38025/0.52171≈−0.7288
  • x^2=0.64375/0.52171≈1.2339\hat{x}_2 = 0.64375 / 0.52171 \approx 1.2339x^2=0.64375/0.52171≈1.2339
  • x^3=0.36575/0.52171≈0.7010\hat{x}_3 = 0.36575 / 0.52171 \approx 0.7010x^3=0.36575/0.52171≈0.7010
  • x^4=−0.62925/0.52171≈−1.2061\hat{x}_4 = -0.62925 / 0.52171 \approx -1.2061x^4=−0.62925/0.52171≈−1.2061

假设 γ=1,1,1,1\gamma = 1, 1, 1, 1γ=1,1,1,1,β=0,0,0,0\beta = 0, 0, 0, 0β=0,0,0,0,则 LayerNorm 输出为:

LN(x)=−0.7288,1.2339,0.7010,−1.2061 \text{LN}(x) = -0.7288, 1.2339, 0.7010, -1.2061 LN(x)=−0.7288,1.2339,0.7010,−1.2061

残差连接(Residual Connection)

概述

残差连接就是把子层的输入直接加到子层的输出上

Output=x+Sublayer(x) \text{Output} = x + \text{Sublayer}(x) Output=x+Sublayer(x)

这样信息有一条"捷径"可以直接流过,不需要经过子层的变换。

作用

缓解梯度消失:反向传播时,梯度可以通过捷径直接回传;

保留恒等映射:如果子层学不到有用变换,至少可以输出 xx,不会比不加层更差;

让深层网络可训练:原始 Transformer 有 6 层编码器 + 6 层解码器,没有残差很难训练。

数值例子

假设子层(多头注意力)输出为 Z1=0.848,2.872,1.594,1.599Z_1 = 0.848, 2.872, 1.594, 1.599Z1=0.848,2.872,1.594,1.599,原始输入为 x=1,0,1,0x = 1, 0, 1, 0x=1,0,1,0。

残差相加:

x+Z1=1+0.848,0+2.872,1+1.594,0+1.599=1.848,2.872,2.594,1.599x + Z_1 = 1 + 0.848, 0 + 2.872, 1 + 1.594, 0 + 1.599 = 1.848, 2.872, 2.594, 1.599x+Z1=1+0.848,0+2.872,1+1.594,0+1.599=1.848,2.872,2.594,1.599

这个结果正好是上面 LayerNorm 例子的输入。所以实际顺序是:

输出=LayerNorm(x+MultiHeadAttention(x))\text{输出} = \text{LayerNorm}(x + \text{MultiHeadAttention}(x))输出=LayerNorm(x+MultiHeadAttention(x))

这就是原始论文的 Post-Norm 结构。

前馈网络(Feed Forward Network, FFN)与激活函数

FFN 是什么?

FFN 是 Transformer 中每个位置独立经过的一个小型全连接网络:

FFN(x)=Linear2(ReLU(Linear1(x))) FFN(x) = Linear_2(ReLU(Linear_1(x))) FFN(x)=Linear2(ReLU(Linear1(x)))

原始论文中:

  • 输入/输出维度:dmodel=512d_{model} = 512dmodel=512
  • 中间层维度:dff=2048d_{ff} = 2048dff=2048(扩展 4 倍)
  • 第一层线性:512→2048512 \to 2048512→2048
  • 激活函数:ReLU
  • 第二层线性:2048→5122048 \to 5122048→512

为什么用 ReLU?

特性 说明
非线性 没有非线性,多层线性叠加还是线性模型
计算简单 ReLU(x)=max⁡(0,x)\text{ReLU}(x) = \max(0, x)ReLU(x)=max(0,x),导数只有 0 或 1
梯度好 正区间梯度恒为 1,缓解梯度消失
稀疏激活 负值输出 0,带来稀疏性

数值例子

为了手算,假设中间维度也是 4(实际是 4 倍),且两层线性都是单位阵,偏置为 0。

则 FFN 等价于对输入做 ReLU。

取 LayerNorm 的输出:

LN(x)=−0.7288,1.2339,0.7010,−1.2061 LN(x) = -0.7288, 1.2339, 0.7010, -1.2061 LN(x)=−0.7288,1.2339,0.7010,−1.2061

第一层线性(单位阵):

y1=LN(x)=−0.7288,1.2339,0.7010,−1.2061 y_1 = \text{LN}(x) = -0.7288, 1.2339, 0.7010, -1.2061 y1=LN(x)=−0.7288,1.2339,0.7010,−1.2061

ReLU:

y1relu=max⁡(0,−0.7288),max⁡(0,1.2339),max⁡(0,0.7010),max⁡(0,−1.2061)=0,1.2339,0.7010,0 \begin{aligned} y_1^{\text{relu}} &= \\max(0, -0.7288), \\max(0, 1.2339), \\max(0, 0.7010), \\max(0, -1.2061) \\ &= 0, 1.2339, 0.7010, 0 \end{aligned} y1relu=max(0,−0.7288),max(0,1.2339),max(0,0.7010),max(0,−1.2061)=0,1.2339,0.7010,0

第二层线性(单位阵):

FFN(x)=0,1.2339,0.7010,0 \text{FFN}(x) = 0, 1.2339, 0.7010, 0 FFN(x)=0,1.2339,0.7010,0

这些组件在多头注意力中的作用

text 复制代码
输入 x
  ↓
多头自注意力 (Multi-Head Self-Attention)
  ↓
残差连接:x + Attention(x)
  ↓
层归一化:LayerNorm(x + Attention(x))
  ↓
前馈网络:FFN(...)
  ↓
残差连接:LN_out + FFN(LN_out)
  ↓
层归一化:LayerNorm(LN_out + FFN(LN_out))
  ↓
输出

各组件作用:

组件 作用
多头注意力 让序列内每个位置关注其他位置,捕捉依赖关系
残差连接 提供信息捷径,稳定梯度,让深层网络可训练
层归一化 标准化分布,加速收敛,防止梯度消失/爆炸
前馈网络 对每个位置独立做非线性变换,增强表示能力
ReLU 引入非线性,计算高效,梯度友好

例子:一个编码器层

输入

x=1,0,1,0 x = 1, 0, 1, 0 x=1,0,1,0

多头注意力输出

Attn(x)=Z1=0.848,2.872,1.594,1.599 Attn(x) = Z_1 = 0.848, 2.872, 1.594, 1.599 Attn(x)=Z1=0.848,2.872,1.594,1.599

残差 + LayerNorm

残差:

x+Z1=1.848,2.872,2.594,1.599x + Z_1 = 1.848, 2.872, 2.594, 1.599x+Z1=1.848,2.872,2.594,1.599

LayerNorm(计算过程见第一节):

LN1=−0.7288,1.2339,0.7010,−1.2061 \text{LN}_1 = -0.7288, 1.2339, 0.7010, -1.2061 LN1=−0.7288,1.2339,0.7010,−1.2061

前馈网络

第一层线性(单位阵):

y1=−0.7288,1.2339,0.7010,−1.2061y_1 = -0.7288, 1.2339, 0.7010, -1.2061y1=−0.7288,1.2339,0.7010,−1.2061

ReLU:

y1relu=0,1.2339,0.7010,0y_1^{\text{relu}} = 0, 1.2339, 0.7010, 0y1relu=0,1.2339,0.7010,0

第二层线性(单位阵):

FFN=0,1.2339,0.7010,0\text{FFN} = 0, 1.2339, 0.7010, 0FFN=0,1.2339,0.7010,0

第二次残差 + LayerNorm

残差:

LN1+FFN=−0.7288,1.2339,0.7010,−1.2061+0,1.2339,0.7010,0=−0.7288,2.4678,1.4020,−1.2061 \begin{aligned} \text{LN}_1 + \text{FFN} &= -0.7288, 1.2339, 0.7010, -1.2061 + 0, 1.2339, 0.7010, 0 \\ &= -0.7288, 2.4678, 1.4020, -1.2061 \end{aligned} LN1+FFN=−0.7288,1.2339,0.7010,−1.2061+0,1.2339,0.7010,0=−0.7288,2.4678,1.4020,−1.2061

LayerNorm:

  • 均值:

    μ=−0.7288+2.4678+1.4020−1.20614=1.93494=0.483725 \mu = \frac{-0.7288 + 2.4678 + 1.4020 - 1.2061}{4} = \frac{1.9349}{4} = 0.483725 μ=4−0.7288+2.4678+1.4020−1.2061=41.9349=0.483725

  • 方差:

    • −0.7288−0.483725=−1.212525-0.7288 - 0.483725 = -1.212525−0.7288−0.483725=−1.212525,平方 = 1.4702
    • 2.4678−0.483725=1.9840752.4678 - 0.483725 = 1.9840752.4678−0.483725=1.984075,平方 = 3.9365
    • 1.4020−0.483725=0.9182751.4020 - 0.483725 = 0.9182751.4020−0.483725=0.918275,平方 = 0.8432
    • −1.2061−0.483725=−1.689825-1.2061 - 0.483725 = -1.689825−1.2061−0.483725=−1.689825,平方 = 2.8555

总和 = 9.1054,除以 4:

σ2=2.27635 \sigma^2 = 2.27635 σ2=2.27635

σ=2.27635≈1.5088 \sigma = \sqrt{2.27635} \approx 1.5088 σ=2.27635 ≈1.5088

  • 归一化:
    • −1.212525/1.5088≈−0.8036-1.212525 / 1.5088 \approx -0.8036−1.212525/1.5088≈−0.8036
    • 1.984075/1.5088≈1.31501.984075 / 1.5088 \approx 1.31501.984075/1.5088≈1.3150
    • 0.918275/1.5088≈0.60860.918275 / 1.5088 \approx 0.60860.918275/1.5088≈0.6086
    • −1.689825/1.5088≈−1.1200-1.689825 / 1.5088 \approx -1.1200−1.689825/1.5088≈−1.1200

假设 γ=1\gamma = 1γ=1,β=0\beta = 0β=0,最终输出:

Output=−0.8036,1.3150,0.6086,−1.1200 \text{Output} = -0.8036, 1.3150, 0.6086, -1.1200 Output=−0.8036,1.3150,0.6086,−1.1200

这就是"你"经过一个完整 Transformer 编码器层后的表示。

总结

概念 通俗解释 数值例子中的体现
LayerNorm 把向量标准化成均值 0、方差 1,再缩放平移 1.848,2.872,2.594,1.599→−0.7288,1.2339,0.7010,−1.20611.848, 2.872, 2.594, 1.599 \to -0.7288, 1.2339, 0.7010, -1.20611.848,2.872,2.594,1.599→−0.7288,1.2339,0.7010,−1.2061
残差 输入直接加到子层输出上 x+Z1=1.848,2.872,2.594,1.599x + Z_1 = 1.848, 2.872, 2.594, 1.599x+Z1=1.848,2.872,2.594,1.599
FFN 两层线性 + 激活,逐位置独立处理 ReLU 后 0,1.2339,0.7010,00, 1.2339, 0.7010, 00,1.2339,0.7010,0
ReLU max⁡(0,x)\max(0, x)max(0,x),非线性、简单、梯度好 负值变 0,正值不变
在多头注意力中的作用 注意力负责交互,残差和 LayerNorm 稳定训练,FFN 增强表示 最终输出 −0.8036,1.3150,0.6086,−1.1200-0.8036, 1.3150, 0.6086, -1.1200−0.8036,1.3150,0.6086,−1.1200

一句话: 多头注意力让模型"看"序列中其他位置,残差连接保证信息不丢、梯度好传,层归一化让分布稳定,前馈网络和 ReLU 给每个位置独立的非线性变换。四者配合,Transformer 才能堆得很深、训得很稳。

相关推荐
Ai-_Man1 小时前
您您这可以把Dola的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。用AI导出鸭,答案是可以的
开发语言·前端·人工智能·小程序
Java后端的Ai之路1 小时前
Python进阶探索23 - Python中的Time与Datetime模块
开发语言·数据库·python·datetime·time
小此方1 小时前
Linux网络(十九):TCP流量控制与滑动窗口详解,超时重传和快重传到底有什么区别
linux·运维·服务器·网络·网络协议·tcp/ip
海宇服务1 小时前
零信任架构实战:基于海宇运营商近3个月欠费次数构建自动化履约能力评估管线
运维·人工智能·架构·自动化
天涯明月19931 小时前
世界模型:原理、范式与工程实践
大数据·人工智能·大模型·具身智能·世界模型
沫璃染墨1 小时前
《从零入门Linux系统篇(五十四):线程篇·七——互斥锁底层原理:从原子交换到线程竞争与锁实现》
linux·运维·服务器·开发语言·c++·驱动开发·系统架构
秦先生在广东2 小时前
构建 Agent 就绪的数据库 OKF 知识包:Python 编译器实战
人工智能
秦先生在广东2 小时前
初创企业低成本增长的数字营销实战指南
人工智能
秦先生在广东2 小时前
开源权重的质变时刻:技术超越、政策博弈与商业模式重构
人工智能