Transformer知识点

news2024/10/5 17:15:55

Transformer知识点

  • 1.输入部分
    • 1.1文本嵌入层
    • 1.2位置编码器
  • 2.编码部分
    • 2.1掩码张量
    • 2.2注意力机制
    • 2.3多头注意力机制
    • 2.4前馈全连接层
    • 2.5规范化层
    • 2.6子层连接结构
    • 2.7编码器层
    • 2.8编码器
  • 3.解码部分
    • 1.编码器层
    • 2.编码器
  • 4.输出部分

结构如下图,包括四部分:输⼊部分,输出部分,编码器部分,解码器部分。

在这里插入图片描述

1.输入部分

输入部分包括两部分:源⽂本嵌⼊层及其位置编码器(左),⽬标⽂本嵌⼊层及其位置编码器(右)。

在这里插入图片描述

1.1文本嵌入层

文本嵌入层将⽂本中词汇的数字表示转变为向量表示,希望在这样的⾼维空间捕捉词汇间的关系。

import torch
import torch.nn as nn
import math
from torch.autograd import Variable
class Embeddings(nn.Module):#定义文本嵌入网络层
    def __init__(self,vocab,d_model):#1.定义网络结构和参数。d_model:词嵌入的维度;vocab:词表的大小
        super(Embeddings,self).__init__()#2.继承nn.Model的初始化函数
        self.lut=nn.Embedding(vocab,d_model)#3.用torch.nn的预定义层Embedding,获得一个词嵌入对象
        self.d_model=d_model
    def forward(self,x):#运行网络结构
        return self.lut(x)*math.sqrt(self.d_model)
d_model=512
vocab=1000
x=Variable(torch.LongTensor([[100,2,421,508],[491,998,1,221]]))#输入24纬表示的文本数据
emb=Embeddings(vocab,d_model)#实例化这个结构
emb_out=emb(x)#输入放到定义的embeddings结构里面运行,结果是[2, 4, 512]维度

1.2位置编码器

因为在Transformer的编码器结构中, 并没有针对词汇位置信息的处理,因此需要在Embedding层后加⼊位置编码器,将词汇位置不同可能会产⽣不同语义的信息加⼊到词嵌⼊张量中, 以弥补位置信息的缺失,感觉想图像里面的ax+b里面的b。

class PositionalEncoding(nn.Module):
    def __init__(self,d_model,dropout,max_len=5000):#位置编码器的结构,max_len:每个句子的最大长度
        super(PositionalEncoding,self).__init__()
        self.dropout=nn.Dropout(p=dropout)
        pe=torch.zeros(max_len,d_model)#初始化位置编码矩阵
        position=torch.arange(0,max_len).unsqueeze(1)#绝对位置矩阵:max_len*1的矩阵
        #利用绝对位置矩阵填充pe位置编码矩阵,
        div_term=torch.exp(torch.arange(0,d_model,2)*-(math.log(1000.0)/d_model))
        pe[:,0::2]=torch.sin(div_term*position)#偶数列的数据填充
        pe[:,1::2]=torch.cos(div_term*position)
        pe=pe.unsqueeze(0)#外层扩展一个维度
        self.register_buffer('pe',pe)#因为位置编码矩阵并不是模型结构中的超参或者参数,不需要随模型的优化更新,所以给他注册成为模型的buffer
    def forward(self,x):
        x=x+Variable(self.pe[:,:x.size(1)],requires_grad=False)#将矩阵的句子最大长度5000截取和输入句子一样长的长度,然后加到embedding后面
        return self.dropout(x)

dropout=0.1
max_len=160
pe=PositionalEncoding(d_model,dropout,max_len)
pe_out=pe(emb_out)

2.编码部分

由N个编码器层堆叠⽽成,每个编码器层由两个⼦层连接结构组成:
第⼀个⼦层连接结构包括⼀个多头⾃注意⼒⼦层和规范化层以及⼀个残差连接,
第⼆个⼦层连接结构包括⼀个前馈全连接⼦层和规范化层以及⼀个残差连接。
在这里插入图片描述

2.1掩码张量

⾥⾯⼀般只有1和0的元素,代表位置被遮掩或者不被遮掩。训练时会把整个输出结果都⼀次性进⾏Embedding,但是理论上解码器的的输出却不是⼀次就能产⽣最终结果的,⽽是⼀次次通过上⼀次结果综合得出的,因此,未来的信息可能被提前利⽤,所以,我们会进⾏遮掩。

import numpy as np
import torch
import matplotlib.pyplot as plt
def subsequent_mask(size):
    attn_shape=(1,size,size)#定义mask是三维矩阵
    subsequent_mask=np.triu(np.ones(attn_shape),k=1).astype('uint8')
    return torch.from_numpy(1-subsequent_mask)#数值是1的下三角矩阵
size=20
sm=subsequent_mask(size)
plt.figure(figsize=(5,5))
plt.imshow(sm[0], cmap='viridis')  # 使用cmap参数指定颜色映射
plt.colorbar()
plt.clim(0, 1) 
plt.show()

在这里插入图片描述

2.2注意力机制

注意⼒机制是注意⼒计算规则能够应⽤的深度学习⽹络的载体, 除了注意⼒计算规则外,还包括⼀些必要的全连接层以及相关张量处理, 使其与应⽤⽹络融为⼀体。
在这里插入图片描述

注意⼒计算规则需要三个指定的输⼊Q(query), K(key), V(value), 然后通过公式得到注意⼒的计算结果,这个结果代表query在key和value作⽤下的表示. ⽽这个具体的计算规则有很多种。
在这里插入图片描述

def attention(query,key,value,mask=None,dropout=None):
    d_k=query.size(-1)#query的最后一纬尺寸,一般等于词嵌入维度
    scores=torch.matmul(query,key.transpose(-2,-1))/math.sqrt(d_k)#通过公式计算得到注意力的得分
    if mask is not None:
        scores=scores.masked_fill(mask==0,-1e9)
    p_attn=F.softmax(scores,dim=-1)
    if dropout is not None:
        p_attn=dropout(p_attn)
    return torch.matmul(p_attn,value),p_attn#返回最终的注意力表示query,和注意力张量
query=key=value=pe_out #三个值初始值一样就是自注意力
mask=Variable(torch.zeros(2,4,4))
attn,p_attn=attention(query,key,value,mask=mask)

2.3多头注意力机制

使⽤了⼀组线性变化层,即三个变换张量对Q,K,V分别进⾏线性变换,这些变换不会改变原有张量的尺⼨,因此每个变换矩阵都是⽅阵,得到输出结果后,多头的作⽤才开始显现,每个头开始从词义层⾯分割输出的张量,也就是每个头都想获得⼀组Q,K,V进⾏注意⼒机制的计算,但是句⼦中的每个词的表示只获得⼀部分,也就是只分割了最后⼀维的词嵌⼊向量. 这就是所谓的多头,将每个头的获得的输⼊送到注意⼒机制中, 就形成多头注意⼒机制。
这种结构设计能让每个注意⼒机制去优化每个词汇的不同特征部分,从⽽均衡同⼀种注意⼒机制可能产⽣的偏差,让词义拥有来⾃更多元的表达。
在这里插入图片描述

def clones(module,N):#定义多头的克隆结构
    return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])
class MultiHeadedAttention(nn.Module):
    def __init__(self,head,embedding_dim,dropout=0.1):
        super(MultiHeadedAttention,self).__init__()
        assert embedding_dim%head==0
        self.d_k=embedding_dim//head
        self.head=head
        self.linears=clones(nn.Linear(embedding_dim,embedding_dim),4)#q,k,v以及concat一共四个内部变化矩阵
        self.attn=None#最后的注意力张量
        self.dropout=nn.Dropout(p=dropout)
    def forward(self,query,key,value,mask=None):
        if mask is not None:
            mask=mask.unsqueeze(0)
        batch_size=query.size(0)
        query,key,value=[model(x).view(batch_size,-1,self.head,self.d_k).transpose(1,2) for model,x in zip(self.linears,(query,key,value))]
        x,self.attn=attention(query,key,value,mask=mask,dropout=self.dropout)
        x=x.transpose(1,2).contiguous().view(batch_size,-1,self.head*self.d_k)
        return self.linears[-1](x)
head=8
embedding_dim=512
dropout=0.2
query=key=value=pe_out
mask=Variable(torch.zeros(8,4,4))#头数,输入的文本数据长度
mha=MultiHeadedAttention(head,embedding_dim,dropout)
mha_out=mha(query,key,value,mask)
print(mha_out.size())#torch.Size([2, 4, 512])

2.4前馈全连接层

注意⼒机制可能对复杂过程的拟合程度不够, 通过增加两层线性层的全连接⽹络来增强模型的能⼒。

class PositionwiseFeedForward(nn.Module):
    def __init__(self,d_model,d_ff,dropout=0.1):#d_ff是第一层的输出维度也是第二层的输入维度
        super(PositionwiseFeedForward,self).__init__()
        self.w1=nn.Linear(d_model,d_ff)
        self.w2=nn.Linear(d_ff,d_model)
        self.dropout=nn.Dropout(dropout)
    def forward(self,x):
        return self.w2(self.dropout(F.relu(self.w1(x))))
d_model=512
d_ff=64
dropout=0.2
ff=PositionwiseFeedForward(d_model,d_ff,dropout)
ff_out=ff(mha_out)

2.5规范化层

是所有深层⽹络模型都需要的标准⽹络层,因为随着⽹络层数的增加,通过多层的计算后参数可能开始出现过⼤或过⼩的情况,这样可能会导致学习过程出现异常,模型可能收敛⾮常的慢. 因此都会在⼀定层数后接规范化层进⾏数值的规范化,使其特征数值在合理范围内。

class LayerNorm(nn.Module):
    def __init__(self,d_model,eps=1e-6):
        super(LayerNorm,self).__init__()
        self.a2=nn.Parameter(torch.ones(d_model))#缩放参数,nn.Parameter封装代表他们是模型的参数
        self.b2=nn.Parameter(torch.zeros(d_model))#位移参数
        self.eps=eps
    def forward(self,x):
        mean=x.mean(-1,keepdim=True)#在最后一个维度上求mean,并保持输出维度与输入维度一致
        std=x.std(-1,keepdim=True)
        return self.a2*(x-mean)/(std+self.eps)+self.b2
d_model=512
eps=1e-6
ln=LayerNorm(d_model,eps)
ln_out=ln(ff_out)

2.6子层连接结构

在每个编码器层中,都有两个⼦层,这两个⼦层加上周围的链接结构就形成了两个⼦层连接结构。感觉像是两个残差网络,这里把多头和前馈抽象成sublayer结构,然后这两个子层就可以封装成一个类。
在这里插入图片描述

class SublayerConnection(nn.Module):
    def __init__(self,size,dropout=0.1):#size一般是词嵌入维度
        super(SublayerConnection,self).__init__()
        self.norm=LayerNorm(size)
        self.dropout=nn.Dropout(p=dropout)
    def forward(self,x,sublayer):
        return x+self.dropout(sublayer(self.norm(x)))
size = 512
dropout = 0.2
head = 8
d_model = 512
x=pe_out#x是输入层的位置编码的输出
mask=Variable(torch.zeros(8,4,4))#8个多头,24纬向量的输入
self_attn=MultiHeadedAttention(head,d_model)#多头注意力结构
sublayer=lambda x:self_attn(x,x,x,mask)#qkv都是x,所以是自注意力,
sc=SublayerConnection(size,dropout)
sc_out=sc(x,sublayer)#([2, 4, 512])

2.7编码器层

作为编码器的组成单元, 每个编码器层完成⼀次对输⼊的特征提取过程, 即编码过程。也就是将两个子连接层连接起来的结构,如图所示。
在这里插入图片描述

class EncoderLayer(nn.Module):
    def __init__(self,size,self_attn,feed_forward,dropout):#size是词嵌入维度
        super (EncoderLayer, self).__init__()
        self.self_attn=self_attn
        self.feed_forward=feed_forward
        self.sublayers=clones(SublayerConnection(size,dropout),2)
        self.size=size
    def forward(self,x,mask):
        x=self.sublayers[0](x,lambda x:self.self_attn(x,x,x,mask))
        return self.sublayers[1](x,self.feed_forward)
self_attn=MultiHeadedAttention(head,d_model)#第一个子层,多头自注意力
ff=PositionwiseFeedForward(d_model,d_ff,dropout)#第二个子层,前馈全连接
el=EncoderLayer(size,self_attn,ff,dropout)
el_out=el(x,mask)#torch.Size([2, 4, 512])

2.8编码器

N个编码器层堆叠⽽成。
在这里插入图片描述

class Encoder(nn.Module):
    def __init__(self,layer,N):#初始化的两个参数分别是编码器层结构和编码器层数
        super(Encoder,self).__init__()
        self.layers=clones(layer,N)
        self.norm=LayerNorm(layer.size)#初始化一个规范化层,用在编码器的最后
    def forward(self,x,mask):
        for layer in self.layers:
            x=layer(x,mask)
        return self.norm(x)
N=9#编码器层一共9个
en=Encoder(el,N)
en_out=en(x,mask)#torch.Size([2, 4, 512])

3.解码部分

解码器由N个解码器层堆叠⽽成,每个解码器层由三个⼦层连接结构组成:
第⼀个⼦层连接结构包括⼀个多头⾃注意⼒⼦层和规范化层以及⼀个残差连接。
第⼆个⼦层连接结构包括⼀个多头注意⼒⼦层和规范化层以及⼀个残差连接。
第三个⼦层连接结构包括⼀个前馈全连接⼦层和规范化层以及⼀个残差连接。
在这里插入图片描述

1.编码器层

class DecoderLayer(nn.Module):
    def __init__(self,size,self_attn,src_attn,feed_forward,dropout):#词嵌入维度,多头自注意力对象,多头注意力对象,前馈全连接对象
        super(DecoderLayer, self).__init__()
        self.size=size
        self.self_attn=self_attn
        self.src_attn=self_attn
        self.feed_forward=feed_forward
        self.sublayers=clones(SublayerConnection(size,dropout),3)#克隆3个子层连接对象
    def forward(self,x,memory,source_mask,target_mask):#上一层的输出,编码器的语义存储变量memory,源数据掩码张量,目标数据掩码张量
        x=self.sublayers[0](x,lambda x:self.self_attn(x,x,x,target_mask))#第一个子层,多头自注意力
        x=self.sublayers[1](x,lambda x:self.src_attn(x,memory,memory,source_mask))#第二个子层,常规多头注意力
        return self.sublayers[2](x,self.feed_forward)
head = 8
size = 512
d_model = 512
d_ff = 64
dropout = 0.2
self_attn = src_attn = MultiHeadedAttention(head, d_model, dropout)
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
x = pe_out#输入层的输出
memory = en_out#编码层的输出
mask = Variable(torch.zeros(8, 4, 4))
source_mask = target_mask = mask
dl = DecoderLayer(size, self_attn, src_attn, ff, dropout)
dl_result = dl(x, memory, source_mask, target_mask)#torch.Size([2, 4, 512])

2.编码器

class Decoder(nn.Module):
    def __init__(self,layer,N):#解码器层对象,解码器层数
        super(Decoder,self).__init__()
        self.layers=clones(layer,N)
        self.norm=LayerNorm(layer.size)
    def forward(self,x,memory,source_mask,target_mask):
        for layer in self.layers:
            x=layer(x,memory,source_mask,target_mask)
        return self.norm(x)
c = copy.deepcopy
attn = MultiHeadedAttention(head, d_model)
ff = PositionwiseFeedForward(d_model, d_ff, dropout)
layer = DecoderLayer(d_model, c(attn), c(attn), c(ff), dropout)
N = 8
x = pe_out
memory = en_out
de = Decoder(layer, N)
de_result = de(x, memory, source_mask, target_mask)#torch.Size([2, 4, 512])

4.输出部分

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1116692.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

COSCon'23 开源社文创丨 给开源人一点“color see see”

成都城市限定 “小O在成都”行李箱贴纸 成都限定行李箱贴纸把小O和特色元素相融合 当小O遇到成都 在云端漫步的蓝色小章鱼 掉落到这座热情似火的城市, 结识了大熊猫朋友 学会了四川麻将 吃到了红油串串... 快带着小O来一场自由的旅游吧! “你也要尝尝竹子…

UE4 材质实操记录

TexCoord的R通道是从左到右的递增量,G通道是从上到下的递增量,R通道减去0.5,那么左边就是【-0.5~0】区间,所以左边为全黑,Abs取绝对值,就达到一个两边向中间的一个递减的效果,G通道同理&#xf…

山西电力市场日前价格预测【2023-10-21】

日前价格预测 预测说明: 如上图所示,预测明日(2023-10-21)山西电力市场全天平均日前电价为385.30元/MWh。其中,最高日前电价为723.78元/MWh,预计出现在18: 15。最低日前电价为208.67元/MWh,预计…

001.C语言基础学习

之前只学过python,在这里我的本意是想学C,但是没有C语言的基础,听起来比较吃力,所以就快速过一下C语言。这是一个零基础入门的笔记,高手可以绕过。 0.Visual studio2022的使用 创建第一个C语言项目和源文件 https://…

【PACS系统源码】与医院HIS系统双向数据交换,实现医学影像集成与影像后处理功能

​医院医学影像PACS系统源码,集成三维影像后处理功能,包括三维多平面重建、三维容积重建、三维表面重建、三维虚拟内窥镜、最大/小密度投影、心脏动脉钙化分析等功能。系统功能强大,代码完整。 PACS系统与医院HIS实现双向数据交换&#xff0c…

【diffusion model】扩散模型入门

写在最前,参加DataWhale 10月组队学习。 参考资料: HuggingFace 开源diffusion-models-class 1.扩散模型介绍 2.调用模型生成一张赛博风格的猫咪图片 2.1 安装依赖包 %pip install -qq -U diffusers datasets transformers accelerate ftfy pyarrow9…

Vercel 如何使用 Amazon EventBridge 调度器在2个月内发布 Cron 作业

Vercel 使用 Amazon EventBridge 调度器实施 Cron 作业,使他们的客户能够大规模创建、管理和运行计划任务。该功能很快就获得了广泛采用,发布后仅几个月,每周 cron 调用次数就超过 700 万次。本文将介绍他们是如何取得这一成就的,…

d3dx9_43.dll丢失有什么办法可以解决,解决d3dx9_43.dll丢失

通常d3dx9_43.dll丢失都是在运行游戏时汤出的d3dx9_43.dll找不到的错误窗口,因为d3dx9_43.dll文件更多是在使用游戏时会被调用的dll文件,d3dx9_43.dll是属于DirectX9的一个组件,DirectX9是游戏系统中的一个重要程序,所以当d3dx9_4…

MySQL数据库下载与安装使用

文章目录 MySQL数据库下面是各个版本完整的生命周期。下载MySQL安装包安装和使用MySQL一些基础MySQL使用命令 MySQL数据库 这里我选择的是免安装绿色解压版本 现在各位开发者使用的MySQL,大部分版本都是 5.7,根据官方说明,MySQL 5.7 将于 202…

零售创新:社交媒体如何改变跨境电商游戏规则?

在当今数字化的时代,社交媒体已经成为了我们日常生活中不可或缺的一部分。Facebook、Instagram、Twitter、WeChat等平台不仅让我们与朋友家人保持联系,还成为了一个新的商业战场。特别是在跨境电商领域,社交媒体的崛起正在彻底改变游戏规则。…

团购页面.

<!DOCTYPE html> <html><head><title>团购</title><meta http-equiv"content-type" content"text/html; charsetutf-8"/><meta name"apple-mobile-web-app-capable" content"yes"/><lin…

yxy销售网站后台管理系统

springbootmybatisthymeleaf 第一个练习的项目就是小商品零售平台后台管理系统&#xff0c;但是当时由于业务不熟练&#xff0c;需求分析先不做好&#xff0c;导致在开发的过程中出现了很多问题。 这次首先把需求确定&#xff0c;详细的做好前期准备工作&#xff0c;再来进行…

acme.sh: 未找到命令解决办法丨acme命令安装ssl证书

在Freessl申请的ssl证书现在都是需要acme命令了&#xff0c;服务器没有自带所以会出现这个报错&#xff0c;首先 1、安装并下载&#xff1a; curl https://get.acme.sh | sh -s emailmyexample.com2、进入到安装目录,创建指令别名&#xff1a; cd /root/.acme.sh/ alias acm…

一些经典的神经网络(第19天)

1. 经典神经网络&#xff08;LeNet&#xff09; LeNet是早期成功的神经网络&#xff1b; 先使用卷积层来学习图片空间信息 然后使用全连接层来转到到类别空间 【通过在卷积层后加入激活函数&#xff0c;可以引入非线性、增加模型的表达能力、增强稀疏性和解决梯度消失等问题…

防水款无源NFC卡片

产品参数&#xff1a; PN29_T 产品参数 产品型号 PN29_T 尺寸(mm) 85.8*41*2.9mm 显示技术 电子墨水屏 显示区域(mm) 29(H) * 66.9(V) 分辨率(像素) 296*128 像素尺寸(mm) 0.227*0.226 显示颜色 黑/白 视觉角度 180 工作温度 0-50℃ 电池 无需电池 工作…

linux性能分析(四)CPU篇(一)基础

一 CPU篇 遗留&#xff1a; 负载与cpu关系、负载与线程的关系? ① CPU 相关概念 1、physical 物理CPU个数 --> 一般一个实体 2、cpu 核数 3、逻辑CPU个数 逻辑核 4、超线程 super thread 技术 5、各种cpu的计算方式物理 physical CPU的个数&#xff1a; physical id逻…

el-dropdown 在火狐浏览器,下拉框先被其他元素覆盖1s后才置于最上层?

问题描述&#xff1a; element-ui组件&#xff0c;el-dropdown使用火狐浏览器打开时&#xff0c;下拉框会被其他元素覆盖&#xff0c;大约1s后才会完全置于最上层。 原因&#xff1a; 目前只觉得是官网自带的问题&#xff0c;有大佬知道更好的解决办法&#xff0c;请随时留言&a…

01_introduction_to_diffusers_CN

&#x1f917; Diffusers 介绍 来源&#xff1a;https://github.com/huggingface/diffusion-models-class/blob/main/unit1/01_introduction_to_diffusers.ipynb 预备知识 在进入 Notebook 之前&#xff0c;你需要: &#x1f4d6; 阅读第一单元的材料&#x1f917; 在 Hugg…

安科瑞智能操控装置产品在上海特斯拉工厂配电工程的应用

安科瑞 崔丽洁 1 概述 2018年10月17日&#xff0c;上海市临港管委会表示&#xff0c;特斯拉&#xff08;上海&#xff09;有限公司已成功摘得上海临港装备产业区Q01-05地块864885平方米&#xff08;合计1297.32亩&#xff09;的工业用地&#xff0c;并与上海市规划和国土资源管…

bpf对内核的观测

目录 1 bpftrace常用命令1.1 列出bpftrace 相关命令的list1. 2bpftrace -e 是执行1.3 查看参数 -lv 2 bpftrace 可以用到的变量3 高级3.1 内置函数3.2 文件系统3.3 内核内存 栈3.4 Malloc 调用 统计3.5 系统调用 brk 的 统计3.6 脚本调用 4 应用5 怎么串联起来呢 bpftrace 总的…