当前位置: 首页 > article >正文

Chapter4.2:Normalizing activations with layer normalization

文章目录

  • 4 Implementing a GPT model from Scratch To Generate Text
    • 4.2 Normalizing activations with layer normalization

4 Implementing a GPT model from Scratch To Generate Text

4.2 Normalizing activations with layer normalization

通过层归一化(Layer Normalization)对激活值进行归一化处理。

  • Layer normalization (LayerNorm):将激活值中心化到均值为 0,归一化方差为 1,稳定训练并加速收敛。

    应用位置

    1. transformer block 中的 multi-head attention module 前后。

    2. 最终输出层之前。

    下图提供了LayerNormalization的直观概述

    从一个小例子看看LayerNormalization发生了什么

    torch.manual_seed(123)
    
    batch_example = torch.randn(2, 5) 
    
    layer = nn.Sequential(nn.Linear(5, 6), nn.ReLU())
    out = layer(batch_example)
    print(out)
    print(out.shape)
    
    # 计算均值和方差
    mean = out.mean(dim=-1, keepdim=True)
    var = out.var(dim=-1, keepdim=True)
    
    print("Mean:\n", mean)
    print("Variance:\n", var)
    
    out_norm = (out - mean) / torch.sqrt(var)
    print("Normalized layer outputs:\n", out_norm)
    
    mean = out_norm.mean(dim=-1, keepdim=True)
    var = out_norm.var(dim=-1, keepdim=True)
    print("Mean:\n", mean)
    print("Variance:\n", var)
    
    """输出"""
    tensor([[0.2260, 0.3470, 0.0000, 0.2216, 0.0000, 0.0000],
            [0.2133, 0.2394, 0.0000, 0.5198, 0.3297, 0.0000]],
           grad_fn=<ReluBackward0>)
    
    torch.Size([2, 6])
    
    Mean:
     tensor([[0.1324],
            [0.2170]], grad_fn=<MeanBackward1>)
    
    Variance:
     tensor([[0.0231],
            [0.0398]], grad_fn=<VarBackward0>)
    
    Normalized layer outputs:
     tensor([[ 0.6159,  1.4126, -0.8719,  0.5872, -0.8719, -0.8719],
            [-0.0189,  0.1121, -1.0876,  1.5173,  0.5647, -1.0876]],
           grad_fn=<DivBackward0>)
    
    Mean:
     tensor([[9.9341e-09],
            [0.0000e+00]], grad_fn=<MeanBackward1>)
    Variance:
     tensor([[1.0000],
            [1.0000]], grad_fn=<VarBackward0>)
    

    归一化会独立应用于两个输入(行)中的每一个;使用 dim=-1 表示在最后一个维度(在本例中为特征维度)上进行计算,而不是在行维度上进行计算。

    关闭科学计数法

    torch.set_printoptions(sci_mode=False) #关闭科学计数法
    print("Mean:\n", mean)
    print("Variance:\n", var)
    
    """输出"""
    Mean:
     tensor([[    0.0000],
            [    0.0000]], grad_fn=<MeanBackward1>)
    Variance:
     tensor([[1.0000],
            [1.0000]], grad_fn=<VarBackward0>)
    
  • LayerNorm 类实现:基于归一化思路,实现一个 LayerNorm 类,稍后我们可以在 GPT 模型中使用它

    class LayerNorm(nn.Module):
        def __init__(self, emb_dim):
            super().__init__()
            self.eps = 1e-5
            self.scale = nn.Parameter(torch.ones(emb_dim))
            self.shift = nn.Parameter(torch.zeros(emb_dim))
    
        def forward(self, x):
            mean = x.mean(dim=-1, keepdim=True)
            var = x.var(dim=-1, keepdim=True, unbiased=False)
            norm_x = (x - mean) / torch.sqrt(var + self.eps)
            return self.scale * norm_x + self.shift
    

    层归一化公式(上面的例子中 γ = 1 \gamma = 1 γ=1 β = 0 \beta=0 β=0 ϵ = 0 \epsilon = 0 ϵ=0
    L a y e r N o r m ( x i ) = γ ⋅ x i − μ σ 2 + ϵ + β LayerNorm(x_i) = \gamma \cdot \frac{x_i-\mu}{\sqrt{\sigma^2 + \epsilon}} + \beta LayerNorm(xi)=γσ2+ϵ xiμ+β
    其中

    1. μ 、 σ 2 \mu 、 \sigma^2 μσ2 分别x在layer维度上的均值和方差

    2. γ 、 β \gamma 、\beta γβ 是可学习的缩放平移参数

    3. ϵ \epsilon ϵ 是一个小常数,用于防止除零错误。

    scaleshift:可训练参数,用于在归一化后调整数据的缩放和偏移。

    有偏方差:在上述方差计算中,设置 unbiased=False,意味着使用公式 ∑ i ( x − x ‾ ) n \frac{\sum_i(x- \overline x)}{n} ni(xx),不包含贝塞尔校正。其中 n 是样本大小(此处为特征或列的数量);该公式不包含贝塞尔校正(即在分母中使用 n-1),因此提供的是方差的有偏估计。(对于 LLMs,嵌入维度 n 非常大,使用 n 和 n-1 之间的差异可以忽略不计,GPT-2 是在归一化层中使用有偏方差进行训练的,因此为了与后续章节中加载的预训练权重兼容,我们也采用了这一设置。)

    ln = LayerNorm(emb_dim=5)
    out_ln = ln(batch_example)
    mean = out_ln.mean(dim=-1, keepdim=True)
    var = out_ln.var(dim=-1, unbiased=False, keepdim=True)
    
    print("Mean:\n", mean)
    print("Variance:\n", var)
    
    """输出"""
    Mean:
     tensor([[    -0.0000],
            [     0.0000]], grad_fn=<MeanBackward1>)
    Variance:
     tensor([[1.0000],
            [1.0000]], grad_fn=<VarBackward0>)
    
  • 所以、本节至此,我们介绍了实现GPT架构所需的构建块之一,如下图中打勾的部分



http://www.kler.cn/a/467252.html

相关文章:

  • 关于数组的一些应用--------数组作函数的返回值(斐波那契数列数列的实现)
  • 2017年IMO几何预选题第7题
  • 使用Python的xml.etree.ElementTree模块解析和操作 XML 数据
  • 2025年电气、自动化与人工智能(ICEAAI 2025)
  • wordpress报错open_basedir restriction in effect
  • Docker部署Kafka
  • 如何解决数据库和缓存不一致的问题
  • SQL-leetcode-183. 从不订购的客户
  • qt中如何判断字符串是否为数字,整数,浮点数?
  • 【LVGL】给SquareLineStudio导出的Arduino工程添加物理按键
  • 树莓派4b如何连接ov7670摄像头
  • pyinstaller冻结打包多进程程序的bug:无限创建进程直至系统崩溃
  • Computed在Vue2、Vue3写法的不同
  • 奇怪的Python:为何 list 和 dict 的元素顺序从 Python 3.7 开始保持插入顺序?
  • ROS小记
  • 提升汽车金融租赁系统的效率与风险管理策略探讨
  • DELL EMC Unity 存储系统扩容之传统池扩容
  • CSS clip-path 属性
  • Vue项目整合与优化
  • 2024秋语法分析作业-B(满分25分)