Datawhale X 李宏毅苹果书 AI夏令营 Task 3- 3.7 批量归一化 + 4 卷积神经网络 + 6 自注意力机制 + 19 ChatGPT + HW4 Self-Attention

3.7 批量归一化

  • 批量归一化(Batch Normalization,BN)的作用是让误差表面变得平整。

    • 不同参数给损失函数带来的斜率变化的差异,源自不同参数取值范围的差异,即量纲的不同
      • 假如权重有一个小变化 Δ ω \Delta \omega Δω,参数 x 1 x_1 x1取值1,参数 x 2 x_2 x2取值100, Δ ω × x 1 \Delta \omega \times {x_1} Δω×x1 Δ ω × x 2 \Delta \omega \times {x_2} Δω×x2有一个数量级上的差异,给损失函数带来的斜率变化也会有很大差异
    • 解决思路:让不同维度的参数取值范围相同,这一类方法叫做特征归一化(feature normalization),常用方法是Z值归一化(Z-score normalization)
    • 对不同特征的同一维度做归一化,让它们的数值在0上下,这样可以构造一个好的误差表面
      • 注意是对不同特征同一维度的数据做归一化,而不是同一个特征内部数据做归一化
      • 归一化的目标是让不同特征之间的数据具有可比性
      • 特征内部的归一化会破坏特征内部样本之间的相对信息
  • 深度网络中间运算产生的 z i z^i zi a i a^i ai(如图)也是特征,也要做归一化

    • 如果激活函数用sigmoid,适合对 z i z^i zi做归一化,因为sigmoid在0附近斜率大,把 z i z^i zi的值挪到0附近,算梯度时会得到大的值
    • 特征归一化放在激活函数之前、之后在实现上没有太大的差别。
      深度学习中间层的特征归一化
  • 原本独立的 x ~ 1 \widetilde{x}^1 x 1 x ~ 2 \widetilde{x}^2 x 2 x ~ 3 \widetilde{x}^3 x 3,因为均值 μ \mu μ和标准差 σ \sigma σ产生了关联,改变其中一个 z i z^i zi值,其他的 z ~ i \widetilde{z}^i z i也会连带产生变化,如图

  • 实际实现时只对一个批量里面的数据做归一化,所以称为批量归一化。适用于批量大的,因为够大的批量才算得出 μ \mu μ σ \sigma σ。批量如果比较大、足以表示整个数据集的分布,只需在一个批量上而不是整个数据集上做特征归一化作为近似。

  • 批量归一化之后,网络还可以学习缩放和偏移参数 γ \gamma γ β \beta β,调整归一化后的数据,使其具有合适的尺度和偏移: z ^ i = γ ⊙ z ^ i + β \hat{z}^i = \gamma \odot \hat{z}^i + \beta z^i=γz^i+β

    • 需要加加 γ \gamma γ β \beta β,是因为归一化后 z ^ \hat{z} z^平均值为0,会带来一些问题,比如
      • 激活函数的输入会常落在非线性函数的平坦区域,这些区域梯度接近于零,会导致梯度消失
      • 网络层输出的变化范围被限制在一个较小的区域内,导致模型的表达能力受限,无法有效表达复杂的模式或特征
      • 训练中中间层输出平均值为0,可能导致正权重和负权重的更新不对称,导致训练不稳定,或者梯度朝某个方向偏移
    • 实际训练中会在已经找到一个比较好的误差表面、走到一个比较好的位置后,再把 γ \gamma γ β \beta β慢慢地加进去,不会导致最初参数取值范围不同
  • 测试时没有批量,可直接用训练阶段所有批量的 μ t \mu^t μt σ t \sigma^t σt 的平均值 μ ‾ \overline{\mu} μ σ ‾ \overline{\sigma} σ

    • 计算方法为移动平均(moving average) μ ‾ → p μ ‾ + ( 1 − p ) μ t \overline{\mu} \rightarrow p\overline{\mu} +(1-p)\mu^t μpμ+(1p)μt
    • p p p 为超参数,PyTorch里常设置为0.1
  • 做批量归一化后误差表面会比较平滑、容易训练,可以把学习率设大一点

4 卷积神经网络

  • 把图像输入模型

    • 先用三维张量描述图像,三维分别为图像的宽、高、通道(channel)数
    • 把三维张量展平(flattening),所有的元素按顺序排列,变成一个长度为宽 × \times × × \times × 通道数的一维向量
  • 全连接网络的权重数 = = = 图像的宽 × \times × × \times × 通道数 × \times × 神经元数,更多的参数带来更好的弹性和能力,也更容易过拟合

    • 全连接网络如果只想看一个范围,可以把连接到其他输入特征的权重设为 0,这样网络的弹性会变小
  • 图像本身的特性让图像模型不需要全连接

    • 模式(pattern)可以代表某种物体,不需要检测整张图像
      • 用合适大小的感受野(receptive field)来检测模式,通常为 3 × 3 × 3 3 \times 3 \times 3 3×3×3
      • 多个神经元可以守备同一个感受野
      • 移动感受野的量称为步幅(stride),通常不会设太大,以保证感受野之间有重叠,防止模式出现在两个不重叠感受野的交界上而检测不到
    • 同样的模式可能会出现在图像的不同区域
      • 检测同一个模式的神经元工作内容一样,只是各自守备的范围不一样,不用单独训练每一个神经元的参数,让它们参数共享(parameter sharing),即权重相同
      • 这组共用的权重值就是一个滤波器(filter)
      • 卷积层(convolutional layer) = = = 感受野 + + + 参数共享,用到卷积层的网络叫卷积神经网络
      • 一个滤波器会产生一组数字,所有滤波器产生的数字放在一起称为特征映射(feature map),即一张图像通过一个卷积层会产生一个特征映射
      • 特征映射可以看作是一张新的图像,它的宽、高要根据输入图像的尺寸、滤波器的尺寸、步幅(stride)和填充(padding)来计算,通道数为滤波器的数目。
        • 假设输入图像的大小为 H in × W in H_{\text{in}} \times W_{\text{in}} Hin×Win,滤波器的大小为 F × F F \times F F×F,步幅为 S S S,填充为 P P P。那么卷积层的输出特征图的空间维度 H out × W out H_{\text{out}} \times W_{\text{out}} Hout×Wout 可以通过以下公式计算:

          输出高度(Height of the feature map, H out H_{\text{out}} Hout):
          H out = ⌊ H in − F + 2 P S ⌋ + 1 H_{\text{out}} = \left\lfloor \frac{H_{\text{in}} - F + 2P}{S} \right\rfloor + 1 Hout=SHinF+2P+1
          输出宽度(Width of the feature map, W out W_{\text{out}} Wout):
          W out = ⌊ W in − F + 2 P S ⌋ + 1 W_{\text{out}} = \left\lfloor \frac{W_{\text{in}} - F + 2P}{S} \right\rfloor + 1 Wout=SWinF+2P+1

      • 大小为 3 × 3 3\times3 3×3 的滤波器虽然小,但经过层层网络后它看的范围会越来越大,所以网络够深就可以检测到比较大的模式
        • 如果每个卷积层的滤波器大小都为 3 × 3 3\times3 3×3,第二层输入的每一个值都是由第一层的一个 3 × 3 3\times3 3×3 区域计算而来,那么第二层的 3 × 3 3\times3 3×3 区域在原始图像上覆盖的范围是 5 × 5 5\times5 5×5,如图
        • 依此类推,层数越深, 3 × 3 3\times3 3×3 区域所覆盖的原始图像范围会越来越大
    • 下采样不影响模式检测
      • 用汇聚(pooling)把图像的宽和高变小,常用的有最大汇聚(max pooling)、平均汇聚(mean pooling)
      • 假设要检测的是非常微细的东西,下采样会让它损失必要信息,影响模型的性能
  • CNN 如果能用在一个问题上,这个问题要具备跟图像共通的特性

    • 只需要看小范围就可以知道很多重要的模式
    • 同样的模式可能会出现在不同的位置
  • CNN 不能处理图像放大缩小或者是旋转的问题

    • 肉眼看起来两张图像一模一样,但如果把它们“拉直”成向量,里面的数值不一样
    • 做图像识别时要做数据增强,即让卷积神经网络看过不同大小的模式、看过物体旋转后的样子
    • Special Transformer Layer 网络架构可以处理这个问题

6 自注意力机制

19 ChatGPT

  • ChatGPT 的特点
    • 每次的输出都不一样,再问一样的问题可能会得到很不一样的答案
    • 可以继续追问,前面的对话会自动成为后面对话的context
  • 对 ChatGPT 回答的误解
    • 是“罐头信息”,即开发者事先编好的答案,有人问问题时它从里面随机挑一个拿出来
    • 是从网络搜索来的
  • 文字生成和考虑context
    • 原理:以一个句子作为输入,给每一个后面可能接的符号一个概率,输出概率分布后,根据概率分布采样词汇
    • 很复杂,可能有1700亿参数
  • ChatGPT 的学习过程
    • 如果只依赖人类能提供的监督式学习数据,机器的知识会很少,很多问题都回答不了
    • 开发者从网络上爬到的45TB原始数据中选了570GB做训练,得到了GPT3,这一过程是预训练
      • 机器学习需要成对的数据如果是用一些方法无痛生成,这种学习方式就叫做自监督学习,通过自监督式学习得到的
        模型又叫做基石模型
      • ChatGPT 可能不需要翻译引擎,因为在多种语言上做过预训练之后,接下来只要教模型某一个语言的某一个任务,它就可以自动学会其他语言以及同样的任务
    • GPT3经过人类的介入,使用监督式学习得到了ChatGPT,这一过程是微调
    • ChatGPT 除了有监督式的学习,还用了强化学习中常见的 PPO 算法,有助于人类偷懒,以及解决人类自己都不知道答案的问题
  • 催生的新研究
    • 如何使用prompting精准提出需求
    • 神经编辑(neural editing),即如何让机器修改一个错误,而不要弄错更多地方
    • 判断输出的内容是否由 AI 生成
    • Machine unlearning,让模型忘记它读到的机密信息

HW4 Self-Attention

  • 模型的任务是使用transformer架构,把输入音频文件分类为不同的演讲者

  • 模型的框架

  • 直接运行初始代码得到的准确率

    Step 70000, best model saved. (accuracy=0.4945)
    
  • 分类结果的统计条形图

  • 可优化的参数

    • Transformer编码器
      • num_layers:Transformer编码层的数量,更多层可以捕获更复杂的特征,但也更容易过拟合
      • 规范:层归一化组件
      • Transformer编码器层
        • d_model:输入的预期特征数量,更大的维度能够捕获更多的特征
        • nhead:多头注意力的数量,增加头的数量能够让模型从多个不同的子空间中提取特征
        • dim_feedforward:feedforward网络模型的维度(默认=2048),增加它的维度可以提高模型的容量
        • dropout:dropout的比率(默认=0.1),适当增加 Dropout 可提高模型的泛化能力
    • 数据加载器
      • batch_size,适度增加 Batch size 能加速训练
    • 学习速率时间表
      • optimizer: 基类是torch.optim.Optimizer,可选具体的torch.optim.SGD、torch.optim.Adam、torch.optim.RMSprop
      • num_warmup_steps: 预热步数,较大的预热步数可以让学习率在初期更加平滑增长,有助于稳定训练。但这个模型比较小,可以设置较小的值比如500以内,以便尽快进入正式的学习阶段
      • num_training_steps: 训练的总步数,通常等于数据集的批次数乘以训练轮数。增加总步数,余弦衰减的周期会拉长,学习率下降得更缓慢
      • num_cycles: 控制余弦函数的周期数,默认值为0.5表示一个完整的下降周期,如果为1.0会有一个完整的余弦曲线
    • 参数调整:num_layers设置为2,nhead设置为4
    • 准确率比初始程序的0.4945高一点
      Step 70000, best model saved. (accuracy=0.5088)
      
    • 分类结果的统计条形图
      在这里插入图片描述
  • 构造 Transformer 的变体 Conformer

    • Conformer 结合了卷积神经网络(CNN)和 Transformer,使用卷积层捕获局部信息,同时用 Transformer 的自注意力机制来捕获长距离依赖关系
    • 原本的 Transformer 代码如下
      import torch
      import torch.nn as nn
      import torch.nn.functional as F
      
      
      class Classifier(nn.Module):
          def __init__(self, d_model=80, n_spks=600, dropout=0.1):
              super().__init__()
              # Project the dimension of features from that of input into d_model.
              self.prenet = nn.Linear(40, d_model)
              # TODO:
              #   Change Transformer to Conformer.
              #   https://arxiv.org/abs/2005.08100
              self.encoder_layer = nn.TransformerEncoderLayer(
                  d_model=d_model, dim_feedforward=256, nhead=2
              )
              # self.encoder = nn.TransformerEncoder(self.encoder_layer, num_layers=2)
      
              # Project the the dimension of features from d_model into speaker nums.
              self.pred_layer = nn.Sequential(
                  nn.Linear(d_model, d_model),
                  nn.Sigmoid(),
                  nn.Linear(d_model, n_spks),
              )
      
          def forward(self, mels):
              """
              args:
                  mels: (batch size, length, 40)
              return:
                  out: (batch size, n_spks)
              """
              # out: (batch size, length, d_model)
              out = self.prenet(mels)
              # out: (length, batch size, d_model)
              out = out.permute(1, 0, 2)
              # The encoder layer expect features in the shape of (length, batch size, d_model).
              out = self.encoder_layer(out)
              # out: (batch size, length, d_model)
              out = out.transpose(0, 1)
              # mean pooling
              stats = out.mean(dim=1)
      
              # out: (batch, n_spks)
              out = self.pred_layer(stats)
              return out
      
    • 改为Conformer
      import torch
      import torch.nn as nn
      import torch.nn.functional as F
      from conformer import ConformerBlock  # 假设你已经安装了 Conformer 库
      
      
      class Classifier(nn.Module):
          def __init__(self, d_model=80, n_spks=600, dropout=0.1):
              super().__init__()
              # Project the dimension of features from that of input into d_model.
              self.prenet = nn.Linear(40, d_model)
              # TODO:
              #   Change Transformer to Conformer.
              #   https://arxiv.org/abs/2005.08100
              
              # 第一处修改,用 ConformerBlock 替换 TransformerEncoderLayer
              # dim 特征维度,dim_head 每个头的维度,heads 自注意力机制中的头数,ff_mult 前馈网络的倍数,conv_kernel_size 卷积层的核大小
              self.encoder_layer = ConformerBlock(
                  dim=d_model, dim_head=64, heads=4, ff_mult=4, conv_kernel_size=31
              )        
              # Project the the dimension of features from d_model into speaker nums.
              self.pred_layer = nn.Sequential(
                  nn.Linear(d_model, d_model),
                  nn.Sigmoid(),
                  nn.Linear(d_model, n_spks),
              )
      
          def forward(self, mels):
              """
              args:
                  mels: (batch size, length, 40)
              return:
                  out: (batch size, n_spks)
              """
              # out: (batch size, length, d_model)
              out = self.prenet(mels)
              # out: (length, batch size, d_model)
              out = out.permute(1, 0, 2)
              # The encoder layer expect features in the shape of (length, batch size, d_model).
              out = self.encoder_layer(out)
              # out: (batch size, length, d_model)
              # 第二处修改,将 ConformerBlock 层处理后的张量再转换回原始的顺序
              out = out.permute(1, 0, 2)
              # mean pooling
              stats = out.mean(dim=1)
      
              # out: (batch, n_spks)
              out = self.pred_layer(stats)
              return out
      
    • 准确率比初始程序的0.4945高一点
      Step 70000, best model saved. (accuracy=0.5282)
      
    • 分类结果的统计条形图
  • 实现 Self-Attention Pooling 和 Additive Margin Softmax,以进一步提高性能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值