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

【AI学习从零至壹】Transformer

Transformer

  • Positional Encoding
  • Self Attention
    • multi-head
    • scaled dot-product attention
  • Add & Norm
    • Decoder的两层multi-head attention
  • Transformer构建Seq2Seq模型

transformer论文
Transformer架构已经成为许多应⽤中的主导架构,它堆叠了许多层“self-attentionˮ模块。同⼀层中对每个模块使⽤标量积来计算其查询向量与该层中其他模块的关键向量之间的匹配。匹配被归⼀化为总和1,然后使⽤产⽣的标量系数来形成前⼀层中其他模块产⽣的值向量的凸组合。结果向量形成下⼀计算阶段的模块的输⼊。
在这里插入图片描述

Positional Encoding

常⻅的NLP模型都会使⽤TextCNN或RNN来进⾏位置相关信息的训练和提取,但Transformer中并没有这样的结构。所以作者是想要通过Positional Encoding的来解决这样的问题。
具体操作是位置编码和Input Embedding的维度相同,相加后作为模型的输⼊。

# 位置编码矩阵
class PositionalEncoding(nn.Module):def __init__(self, emb_size, dropout, maxlen=5000):super().__init__()# 行缩放指数值den = torch.exp(- torch.arange(0, emb_size, 2) * math.log(10000) / emb_size)# 位置编码索引 (5000,1)pos = torch.arange(0, maxlen).reshape(maxlen, 1)# 编码矩阵 (5000, emb_size)pos_embdding = torch.zeros((maxlen, emb_size))pos_embdding[:, 0::2] = torch.sin(pos * den)pos_embdding[:, 1::2] = torch.cos(pos * den)# 添加和batch对应维度 (1, 5000, emb_size)pos_embdding = pos_embdding.unsqueeze(-2)# dropoutself.dropout = nn.Dropout(dropout)# 注册当前矩阵不参与参数更新self.register_buffer('pos_embedding', pos_embdding)

Self Attention

transformer 的 self-attention 结构可以理解为: multi-head scaled dot-product attention

multi-head

在这里插入图片描述
multi-head就是将⼀组向量拆分为多组,并⾏计算。这样做的好处可以理解为:模型在不同的表⽰⼦空间⾥学习到相关的信息。
在这里插入图片描述
多头的本质就是 拆分后进⾏ 运算,之后再合并的过程。
torch.nn.MultiheadAttention源码链接
torch.nn.functional.multi_head_attention_forward()源码链接

scaled dot-product attention

⼀组query(Q) 和⼀组key-value(K-V)之间的映射,这⾥的 Q, K , V 都是原始输⼊经过线性变换得到的向量。
在这里插入图片描述
在这里插入图片描述

torch.nn.functional._scaled_dot_product_attention()源码链接
关于mask,有两个地⽅需要注意:
第1个是模型中的mask参数,通过将模型中不需要计算的值转换为很⼤的负数,在通过softmax后结果变为了0。
第2个是只有在decoder中才会设置mask。通过倒三⻆形的mask。⽬的是不让模型在训练时看到后⾯的信息,这也是decoder和encoder训练的不同点之⼀。
Scaled ⼀词在公式中的表⽰就是 表达式要除以 ,这么做的原因是当 增⼤时, 的值增⻓幅度会⼤幅加⼤,导致softmax后的梯度很⼩,模型效果变差。
假设 query 和 key 向量中的元素都是相互独⽴的均值为 0,⽅差为 1 的随机变量,那么这两个向量的内积 假设 query 和 key 向量中的元素都是相互独⽴的均值为 0,⽅差为 1 的随机变量,那么这两个向量的内积 的均值为0,⽅差为 。当除以 后,⽅差从 变为1,从⽽softmax反向运算的梯度不趋向于0。

Add & Norm

在这里插入图片描述
Add就是残差连接,把输⼊层和multi-head attention输出进⾏拼接
torch.nn.TransformerEncoderLayer源码链接
关于Batch Normalization和Layer Normalization有⼀个通俗化的解释:Batch Normalization 的处理对象是对⼀批样本, Layer Normalization 的处理对象是单个样本。Batch Normalization 是
对这批样本的同⼀维度特征做归⼀化, Layer Normalization 是对这单个样本的所有维度特征做归⼀化。
在CNN⽹络中,图像通过卷积层提取的信息,属于同⼀卷积核批次的feature map。所以通常会使⽤Batch Normalization。
在RNN和attention⽹络中,我们提取的语料维度信息都是同⼀语句批次的特征。所以使⽤Layer Normalization做归⼀化是有效的 。

Decoder的两层multi-head attention

在这里插入图片描述
第⼀层是Masked Multi-Head Attention,通过Mask掩码来遮挡⼀部分的信息。
第⼆层是把Decoder的上⼀层输出作为Q,Encoder的输出导⼊作为K和V。

Transformer构建Seq2Seq模型

利⽤Pytorch中的Transformer模型来实现Seq2Seq,只依赖其内部的Transformer类还不够。我们还需要为其添加输⼊和输出端结构,才能实现完整的模型功能。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
import math# 位置编码矩阵
class PositionalEncoding(nn.Module):def __init__(self, emb_size, dropout, maxlen=5000):super().__init__()# 行缩放指数值den = torch.exp(- torch.arange(0, emb_size, 2) * math.log(10000) / emb_size)# 位置编码索引 (5000,1)pos = torch.arange(0, maxlen).reshape(maxlen, 1)# 编码矩阵 (5000, emb_size)pos_embdding = torch.zeros((maxlen, emb_size))pos_embdding[:, 0::2] = torch.sin(pos * den)pos_embdding[:, 1::2] = torch.cos(pos * den)# 添加和batch对应维度 (1, 5000, emb_size)pos_embdding = pos_embdding.unsqueeze(-2)# dropoutself.dropout = nn.Dropout(dropout)# 注册当前矩阵不参与参数更新self.register_buffer('pos_embedding', pos_embdding)def forward(self, token_embdding):token_len = token_embdding.size(1)  # token长度# (1, token_len, emb_size)add_emb = self.pos_embedding[:token_len, :] + token_embddingreturn self.dropout(add_emb)class Seq2SeqTransformer(nn.Module):def __init__(self, d_model, nhead, num_enc_layers, num_dec_layers, dim_forward, dropout, enc_voc_size, dec_voc_size):super().__init__()# transformerself.transformer = nn.Transformer(d_model=d_model,nhead=nhead,num_encoder_layers=num_enc_layers,num_decoder_layers=num_dec_layers,dim_feedforward=dim_forward,dropout=dropout,batch_first=True)# encoder input embeddingself.enc_emb = nn.Embedding(enc_voc_size, d_model)# decoder input embeddingself.dec_emb = nn.Embedding(dec_voc_size, d_model)# predict generate linearself.predict = nn.Linear(d_model, dec_voc_size)  # token预测基于解码器词典# positional encodingself.pos_encoding = PositionalEncoding(d_model, dropout)def forward(self, enc_inp, dec_inp, tgt_mask, enc_pad_mask, dec_pad_mask):# multi head attention之前基于位置编码embedding生成enc_emb = self.pos_encoding(self.enc_emb(enc_inp))dec_emb = self.pos_encoding(self.dec_emb(dec_inp))# 调用transformer计算outs = self.transformer(src=enc_emb, tgt=dec_emb, tgt_mask=tgt_mask,src_key_padding_mask=enc_pad_mask, tgt_key_padding_mask=dec_pad_mask)# 推理return self.predict(outs)# 推理环节使用方法def encode(self, enc_inp):enc_emb = self.pos_encoding(self.enc_emb(enc_inp))return self.transformer.encoder(enc_emb)def decode(self, dec_inp, memory, dec_mask):dec_emb = self.pos_encoding(self.dec_emb(dec_inp))return self.transformer.decoder(dec_emb, memory, dec_mask)if __name__ == '__main__':# 模型数据# 一批语料: encoder:decoder# <s></s><pad>corpus= "人生得意须尽欢,莫使金樽空对月"chs = list(corpus)enc_tokens, dec_tokens = [],[]for i in range(1,len(chs)):enc = chs[:i]dec = ['<s>'] + chs[i:] + ['</s>']enc_tokens.append(enc)dec_tokens.append(dec)# 构建encoder和docoder的词典# 模型训练数据: X:([enc_token_matrix], [dec_token_matrix] shifted right),# y [dec_token_matrix] shifted# 1. 通过词典把token转换为token_index# 2. 通过Dataloader把encoder,decoder封装为带有batch的训练数据# 3. Dataloader的collate_fn调用自定义转换方法,填充模型训练数据#    3.1 encoder矩阵使用pad_sequence填充#    3.2 decoder前面部分训练输入 dec_token_matrix[:,:-1,:]#    3.3 decoder后面部分训练目标 dec_token_matrix[:,1:,:]# 4. 创建mask#    4.1 dec_mask 上三角填充-inf的mask#    4.2 enc_pad_mask: (enc矩阵 == 0)#    4.3 dec_pad_mask: (dec矩阵 == 0)# 5. 创建模型(根据GPU内存大小设计编码和解码器参数和层数)、优化器、损失# 6. 训练模型并保存
http://www.dtcms.com/a/292279.html

相关文章:

  • AI入门学习-特征工程
  • 钢铁之躯的智慧觉醒:Deepoc具身智能如何重塑工业机械臂的“工艺直觉”
  • 虚幻 5 与 3D 软件的协作:实时渲染,所见所得
  • ClearML库详解:从实验跟踪到模型部署的全流程管理
  • FPGA自学——存储器模型
  • 立式数控深孔钻的工艺及光学检测方法 —— 激光频率梳 3D 轮廓检测
  • C语言---VSCODE的C语言环境搭建
  • 腾讯研究院 | AI 浪潮中的中国品牌优势解码:华为、小米、大疆、科大讯飞等品牌从技术破壁到生态领跑的全维突围
  • 宽带丢包重传高优化
  • 论文笔记 | Beyond Pick-and-Place: Tackling Robotic Stacking of Diverse Shapes
  • 2025.7.25论文阅读
  • 基于AutoJawSegment项目的CBCT图像分割实践指南
  • ES--为什么没有完全删除?
  • 机器人氩弧焊保护气降成本的方法
  • KGF60N65KDF-U/H KEC:650V超级硅MOSFET,超低导通电阻+超快开关速 电源设计专用!
  • 基于Spark图计算的社会网络分析系统
  • 一款基于 WPF 开源、功能全面的串口调试工具
  • 刘强东突然重仓机器人赛道,京东连投3家机器人公司
  • n8n - 为技术团队提供安全的自动化工作流
  • 16:00开始面试,16:06就出来了,问的问题有点变态。。。
  • iOS WebView 调试实战 localStorage 与 sessionStorage 同步问题全流程排查
  • Elasticsearch服务器开发(第2版) - 读书笔记 第一章 Elasticsearch集群入门
  • 传统RNN模型
  • NLP自然语言处理的一些疑点整理
  • 【CVPR 2025】即插即用DarkIR, 频域-空间协同的高效暗光恢复!
  • 深度学习 ---参数初始化以及损失函数
  • 从0到1学Pandas(一):Pandas 基础入门
  • Mixed Content错误:“mixed block“ 问题
  • React + ts 中应用 Web Work 中集成 WebSocket
  • linux初识网络及UDP简单程序