Transformer相关论文的阅读及PyTorch代码实现


摘要

Transformer abandons the traditional CNN and RNN, and the entire network structure is completely composed of Attention mechanism. To be exact, Transformer is only composed of self-Attenion and Feed Forward Neural Network. A trainable neural network based on Transformer can be built by stacking Transformer.
This week, I continued to learn the Transformer model, read and understood the Transformer related classic paper Attention Is All You Need; In terms of project engineering, Docking code, configuration environment and Run project successfully, Browsed the code of the project, and simply learned the development mode of ASP.NET: MVC; In terms of code, I understand and master the principle of Transformer Masked loss, and implement it line by line in PyTorch.

Transformer抛弃了传统的CNN和RNN,整个网络结构完全由Attention机制组成。准确地讲,Transformer仅由self-Attenion和Feed Forward Neural Network组成。一个基于Transformer的可训练的神经网络可以通过堆叠Transformer的形式进行搭建。
本周继续学习了Transformer模型,对Transformer相关经典论文《Attention Is All You Need》进行阅读和理解;在项目工程方面,对接代码、配置环境、跑通项目,对项目的代码进行了浏览,简单地学习了ASP.NET的开发模式:MVC;在代码方面,对Transformer Masked loss的原理理解并掌握,并在PyTorch中代码逐行实现。


一、文献阅读

文献题目:Attention Is All You Need
论文源地址:https://arxiv.org/abs/1706.03762
参考博客地址:https://zhuanlan.zhihu.com/p/48508221

1.Transformer详解

1.1 整体结构

如下图所示,Transformer的总体结构。(以论文中的机器翻译为例)
在这里插入图片描述
Transformer本质上是Encoder-Decoder的结构。
在这里插入图片描述
与论文设置相同,编码器和解码器都是由6个block组成,编码器的输出作为解码器的输入。
在这里插入图片描述
Transformer中的encoder由self-attention和Feed Forward Neural Network组成,数据首先经过self-attention,得到一个加权后的特征向量Attention(Q,K,V)。
在这里插入图片描述
得到特征向量后,它会被送入Feed Forward Neural Network。这里的Feed Forward Neural Network有两层,第一层激活函数为Relu,第二层是一个线性激活函数。
在这里插入图片描述
Encoder的结构:
在这里插入图片描述
Decoder的结构:
在这里插入图片描述
Self-Attention:当前翻译和已经翻译过的前文之间的关系;
Encoder-Decnoder Attention:当前翻译和编码的特征向量之间的关系。

1.2 输入编码

通过使用嵌入算法把输入的每一个字转化成向量,论文中使用的词嵌入的维度为dmodel = 512。
在这里插入图片描述
在最底层的block中,输入是我们转化后的向量,而在其他层中,输入是上一层的输出。
在这里插入图片描述
Transformer的关键属性:每一个位置的单词在编码器中只经过自己的路径。在self-attention中,这些路径存在依赖,而在Feed Forward Neural Network中没有这些依赖,因此这些路径在进入Feed Forward Neural Network时可进行并行计算。

1.3 Self-Attention

Attention的核心内容是给输入向量的每一个单词学习一个权重,以下为例:
The animal didn’t cross the street because it was too tired
通过加权后得到如下所示的情况:
在这里插入图片描述
在self-attention中,每个单词都是有3个不同的向量,它们分别是Query向量(Q),Key向量(K)和Value向量(V),长度均是64。这三个不同的矩阵是由嵌入向量Attention(Q,K,V)乘以三个不同的权值矩阵Wq,Wk,Wv得到,都是512 x 64。
在这里插入图片描述

什么是Query,Key,Value呢?

1.将单词转化为嵌入向量;
2.根据嵌入向量得到三个输入向量 q,k,v;
3.为每个向量计算一个score:score = q @ k;
4.为了梯度的稳定,Transformer使用了score归一化,即除以√dk;
5.对score施以softmax激活函数;
6.softmax点乘Value值v ,得到加权的每个输入向量的评分v;
7.相加之后得到最终的输出结果z = Σv。

把上面的步骤表示成下图:
在这里插入图片描述
实际的计算过程基于矩阵计算表示:
在这里插入图片描述
总结为下图的矩阵形式:
在这里插入图片描述
在self-attention需要强调的是其采用了残差网络中的short-cut结构,目的是解决深度学习中的退化问题。
在这里插入图片描述
将向量和self-attention可视化如下图所示:
在这里插入图片描述

1.4 Multi-Head Attention

Multi-Head Attention相当于多个不同的self-attention的集成,这里我们以8个为例。
Multi-Head Attention的输出有3步:
1.将数据 X 分别输入到8个self-attention中,得到8个加权后的特征矩阵。
2.将8个特征矩阵按列拼成一个大的特征矩阵
3.特征矩阵经过一层全连接后得到输出 Z。
在这里插入图片描述

1.5 Encoder-Decoder Attention

在Encoder-Decoder Attention中,Q来自于解码器的上一个输出,K和 V来自于与编码器的输出。

由于在机器翻译中,解码过程是一个顺序操作的过程,也就是说当解码第k个特征向量时,我们只能看到第k-1及其之前的解码结果,所以论文中把这种情况的multi-head attention叫做masked multi-head attention。

1.6 损失层

在解码器解码之后,解码的特征向量经过一层激活函数为softmax的全连接层之后得到反映每个单词概率的输出向量。

2.位置编码

我们的Transformer模型没有捕捉顺序序列的能力,也就是说无论句子怎么打乱,得到的结果都是类似的。为了解决这个问题,论文中提出了位置编码的概念。

位置编码常见模式有两种:一种是根据数据学习;另一种是自己设计编码规则。在论文中,作者使用了第二种方式,通常位置编码的长度为 dmodel 的特征向量,这样便于和词向量进行单位相加。
在这里插入图片描述
论文中的公式:
在这里插入图片描述
代码实现可以参考上一篇:https://blog.csdn.net/peaunt1/article/details/127040300?spm=1001.2014.3001.5501

二、项目工程

上报系统:前端由HTML+CSS+JS三件套构建,数据库SQL Server,开发语言C#,框架.net web开发。

ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架,它支持三种不同的开发模式:Web Pages(Web 页面)、MVC(Model View Controller 模型-视图-控制器)、Web Forms(Web 窗体)。

MVC是一种使用MVC设计创建 Web 应用程序的模式;Model(模型)表示应用程序核心(比如数据库记录列表)、View(视图)显示数据(数据库记录)、Controller(控制器)处理输入(写入数据库记录);MVC模式同时提供了对HTML、CSS和JavaScript的完全控制。

Model是应用程序中用于处理应用程序数据逻辑的部分,通常模型对象负责在数据库中存取数据。
View是应用程序中处理数据显示的部分,通常视图是依据模型数据创建的。
Controller是应用程序中处理用户交互的部分,通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。
MVC分层有助于管理复杂的应用程序,因为这意味着你可以在一个时间内专门关注某一个方面;MVC分层同时也简化了分组开发;不同的开发人员可同时开发视图、控制器逻辑和业务逻辑。

三、Transformer Masked loss的PyTorch逐行实现

首先初始化logits和label;
logits:batchsize=2, seqlen=3, vocab_size=4;
label:0-4之间的整数,size为batchsize * seqlen

import torch
import torch.nn as nn
import torch.nn.functional as F


logits = torch.randn(2, 3, 4)
label = torch.randint(0, 4, (2, 3))

在PyTorch中,希望logits的第1维是vocab_size,因此对logits的第1维和第2维进行转置。

logits = logits.transpose(1, 2)

我们将reducation=‘none’,这样就会得到6个单词的交叉熵。

loss = F.cross_entropy(logits, label, reduction='none')

查看loss的输出结果:

tensor([[2.6858, 0.2478, 3.3564],
        [0.8826, 0.8211, 1.9395]])

现在我们来对loss做maskd,假设tgt_len不是3 * 3,是2 * 3;
进行补0,扩维,再把两个tensor拼接在一起。

tgt_len = torch.Tensor([2, 3]).to(torch.int32)
mask = torch.cat([torch.unsqueeze(F.pad(torch.ones(L), (0, max(tgt_len) - L)), 0) for L in tgt_len])
loss = F.cross_entropy(logits, label, reduction='none') * mask
print(mask)
print(loss)

最后查看输出:

tensor([[1., 1., 0.],
        [1., 1., 1.]])
tensor([[1.5877, 3.2782, 0.0000],
        [0.4472, 2.1374, 1.4496]])

总结

Transformer的优点:虽然它只是一个全连接加Attention的结合体,但是它的设计有足够的创新,因为Transformer抛弃了在NLP中最根本的CNN和RNN,并且取得了非常不错的效果,Transformer的缺点:它失去的位置信息在NLP中是非常重要的,虽然在论文中给特征向量中加入Position Embedding,但这并不会改变Transformer结构上的缺陷。下周将完成手写一个最基础的神经网络,阅读相关文献,并在配合代码逐行实现,完成手动推导。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值