笔记 | 深入理解Transformer

news/2024/8/21 0:08:20

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

目录:

  • 背景知识

  • 高层次理解

  • 通过实例来理解Tensor

    • Encoding

  • 高层次理解Self-Attention

    • Self-Attention的细节

    • Self-Attention矩阵乘法

    • Multi-headed完善

    • 整体过程

  • 使用位置编码

    • 编码规则

  • 残差神经网络 Residuals

  • Decoder

  • Linear 和 Softmax层

  • 回顾训练过程

    • LossFunction

    • TargetModel Outputs

    • TrainedModel Outputs

一、背景知识

  • Transformer是Google 的论文 Attention is All You Need中提出

  • Google开源了一个基于TensorFlow的 Tensor2Tensor的第三方库

  • 哈佛大学用PyTorch 对 这篇文章进行了深度解读:http://nlp.seas.harvard.edu/2018/04/03/attention.html

二、高层次理解

首先将Transformer理解成一个黑盒子,黑盒子的功能是翻译,你输入一个语句,它对你的输入进行翻译操作。

       db88474da2ea2b02cc3be156e5053a97.png

黑盒子可以进行展开,由两部分组成:Encoders和Decoders

       18fd9c90bceb1a3c5b2a9ac83f6b10b9.png      

对黑盒子进一步细化,可以发现由6个Encoder和6个Decoder组成

       3a8106309dd74f4edf1bc8f5e53103f3.png      

对于每一个Encoder,他们结构都是相同的,但是权值不共享。每一层都包括两部分:自监督+全连接

       4a3bc9e2894da2ef77fb31a7e4f948e7.png      

Self-attention的输入会被传入一个全连接的前馈神经网络,每个encoder的前馈神经网络的参数都是相同的,但是作用相互独立。

Decoder部分也有相同的层级结构,但是中间多了一个Encoder-Decoder-Attention层,帮助专注于对应的那个语句。(与Seq2Seq模型类似)

       6f92580f27cb6769b0ed321aa2ff3f45.png      

三、通过实例来理解Tensor

首先做一个embedding使得输入的单词成为向量,具体可看这篇博客:

https://blog.csdn.net/qq_41664845/article/details/84313419

       0361e479c6704811220d73b6c535c9fd.png      

列表的大小和词向量的维度大小都是可以设置的超参数,一般设置训练数据集中最长的句子的长度。这个例子是把每个单词编码为512维的向量。

       7c85206943c588168abbedcbe48351d7.png      

可以观察到,x1,x2,x3输入后通过self-attention,分别得到了z1,z2,z3,这点就要注意,其实z1,z2,z3这3个是通过x1,x2,x3一起合作产生的。

Encoding

每一个Encoder接收一个512维的向量x作为输入,然后传递Self-Attention,产生一个等量的512维的z,再经过全连接神经网络,输出的r也是512维,然后传递给下一个encoder

       2de8737c7c6a97b4a81f21b13aef77d5.png      

注意,前馈神经网络的结构其实是一致的

四、高层次理解Self-Attention

假如输入:

The animal didn't cross the street because it was too tired

这句话

那么句子中的“it”如何和“animal”关联起来?

       93719003dbc9fa073ae83ff5c2e6b87a.png      

Self-Attention的细节

第一步:Q,K,V计算

对于每个单词,我们创建一个Query向量,一个Key向量和一个Value向量。这些向量是通过词嵌入乘以我们训练过程中创建的3个训练矩阵而产生的。

输入的向量维度是512维,新向量的维度64维。新向量的维度通过实际情况自己确定。

       4a0971e2bcc1fb9a6034af926b1365b4.png      

Multiplying x1 by the WQ weight matrix produces q1        3cec95067fe1483e00997d5e784b176d.png      

第二步:点乘

       6ca408d253cef29eacd3a2fa61606b45.png      

q1和k1点乘,q1和k2点乘,注意!!!是q1和k2!看清楚,不是q2

第三步、第四步:

将点乘的结果除以sqrt(dk)。这个里面向量是64,开方是8,那么就是除以8

然后进行Softmax的操作

       d7f637edce76532e59a5b3273902589a.png      

Softmax的操作得到的分数,就是当前单词在每个句子中每个单位位置的表示程度。

第五步、第六步:

将Values和Softmax的值相乘得到v1,v2,对当前词的关注度不变,对不相关的的进行降低。

累加加权的向量得到z1

       eaedf3a1bcaa6534adbe9a58db031401.png      

Self-Attention矩阵乘法

   第一步是去计算Query,Key和Value矩阵。X是x1和x2一起转化为的矩阵。

       9a42af9eb5c6b9bac6bcea935cec4d68.png      

然后一下子就操作得到后面的Z

       6066cadb1581bf7686e04554fe3bddc8.png      

Multi-headed 完善

  • 扩展了模型关注不同位置的能力

  • 提供投影到不同的子空间subspace

       3ddf4e3b8b28b257100bb3dcda74554f.png      

通过multi-headed attention,我们为每个“header”都独立维护一套Q/K/V的权值矩阵。

使用8个时间点去计算权值矩阵,得到8个不同的矩阵z

       d0fed0f396a20c35eee60092c90ed715.png      

把这8个矩阵链接在一起,然后再与矩阵Wo相乘

       4d92c73857dd667ca1f42b314fd30927.png      

整体过程

       a3404cb9189ce25cf1d49cbc1bb69579.png      

我们随意找两个不同的attention header的情况(8列,取下下图的2,3列),看一下关注点会有什么区别

       3221edc274293ec9ac3a75775d581242.png      

这两个时间戳上面,发现it最关注两个:animal和tire

将所有注意力都添加到图片上,可能不那么容易理解其中含义

       39574ea287367727e828f42701e68889.png      

五、使用位置编码

输入序列还要考虑单词的顺序的问题

transformer为每个输入单词的词嵌入了一个新的位置向量。

       947cb06f9727367850f635a133436466.png      

为了让模型知道单词的顺序信息,将位置编码的向量信息直接进行规则产生

比如嵌入的维度是4,实际编码效果如下:

       18cf81862a9193dbdd218ec483e4510c.png      

编码规则

       d642876a6e4924bec4ce398dbeb156a4.png      

       b4c5ca3aa2b4f46e14c33d0d2c427465.png      

比如20个单词,每个单词编码为512维度。

一共20行,那么每一行就表示一个词向量,包含512个值,每个值在-1到1之间。可视化显示:

       a6ee3988ac969690e7db8054aff2d768.png      

中心位置一分为2,主要是一半是正弦生成,一半是余弦生成。

对上述的Transformer2Transformer有细微改变显示的话:

       10d302d845006fe0f78ba564ed2caeba.png      

import numpy as np
import matplotlib.pyplot as plt# https://github.com/jalammar/jalammar.github.io/blob/master/notebookes/transformer/transformer_positional_encoding_graph.ipynb
# Code from https://www.tensorflow.org/tutorials/text/transformer
def get_angles(pos, i, d_model):angle_rates = 1 / np.power(10000, (2 * (i//2)) / np.float32(d_model))return pos * angle_rates
def positional_encoding(position, d_model):angle_rads = get_angles(np.arange(position)[:, np.newaxis],np.arange(d_model)[np.newaxis, :],d_model)# apply sin to even indices in the array; 2iangle_rads[:, 0::2] = np.sin(angle_rads[:, 0::2])# apply cos to odd indices in the array; 2i+1angle_rads[:, 1::2] = np.cos(angle_rads[:, 1::2])pos_encoding = angle_rads[np.newaxis, ...]return pos_encodingtokens = 10
dimensions = 64
pos_encoding = positional_encoding(tokens, dimensions)
print (pos_encoding.shape)
plt.figure(figsize=(12,8))
plt.pcolormesh(pos_encoding[0], cmap='viridis')
plt.xlabel('Embedding Dimensions')
plt.xlim((0, dimensions))
plt.ylim((tokens,0))
plt.ylabel('Token Position')
plt.colorbar()
plt.show()

六、残差神经网络 Residuals

layer-normalization步骤        55e7d853f0b0c7b6ff37682188df58a8.png      

       8c747b206ff249339634073e6b345d70.png      

       89aff64787d4a424fa780221b8cb6d4e.png      

进一步可视化

       ca18b5ce0e02547fe412ebcf3c5e3839.png      

Decoder部分和这个是同样的。我们堆叠了2个Encoder和2个Decoder

       27f48f8a8c0bdbc3a609391ac968b2f3.png      

七、Decoder

Encoder将其转化为一组attention的集合(K,V)

       d6f182f8a9d92563b6814b0e0be14662.png      

八、Linear 和 Softmax层

线性层是一个简单的全连接神经网络,由Decoder产生的向量投影到一个更大的向量中,成为对数向量Logits.

假设实验模型的语料库一共1万个英语单词,那么Logits的矢量表示1万个小格子,每个小格子就表示了一个单词。

线性层之后是一个Softmax层,Softmax层可以通过转换将分数转换为概率,选取概率最高的作为索引,然后通过索引找到单词作为输出

       4a1e016eb946e36cd93bc81aca300617.png      

九、回顾训练过程

假设输出的词汇只有“a”、“am”、“I”、“thanks”、“student”、“<eos>结束符号”

       4377334422f78f6ffa3a51a98c43f72d.png      

一旦确定了输出的词汇表,就可以使用相同宽度的向量来表示词汇表中的单词,称为one-hot编码

举例子以句子中的“am”为例子,one-hot编码

       bdaf9d4569a66ffe7378dd413d519d10.png      

Loss Function

模型的参数权重是随机初始化的

       dad0b81ecc94edc49909656ce4bdd74f.png      

实际上做一个简单的减法就行

Target Model Outputs

       ea9d66687f05a5a9dbee80d55a59b771.png      

Trained Model Outputs

       a8415f804ba7886704b8bbe6a0e09b18.png      

虽然没有那么准确,但是通过比较可以找到最大的概率值

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

c0b41d29d233daf09ca6555eeedfcff5.png

cf6699c014905afd7abf028671c3d86d.png


http://lihuaxi.xjx100.cn/news/272510.html

相关文章

Pytorch翻车记录:单卡改多卡踩坑记!

点击上方“视学算法”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达作者丨哟林小平来源丨夕小瑶的卖萌屋编辑丨极市平台先说明一下背景&#xff0c;目前正在魔改以下这篇论文的代码&#xff1a;https://github.com/QipengGuo/GraphWriter-DGL…

写给Python开发者:机器学习十大必备技能

作者 | Pratik Bhavsar译者 | 明明如月&#xff0c;编辑 | 夕颜来源 | CSDN&#xff08;ID:CSDNnews&#xff09;有时候&#xff0c;作为一个数据科学家&#xff0c;我们常常忘记了初心。我们首先是一个开发者&#xff0c;然后才是研究人员&#xff0c;最后才可能是数学家。我…

ElasticSearch性能优化策略【转】

ElasticSearch性能优化主要分为4个方面的优化。 一、服务器部署 二、服务器配置 三、数据结构优化 四、运行期优化 一、服务器部署 1、增加1-2台服务器&#xff0c;用于负载均衡节点 elasticSearch的配置文件中有2个参数&#xff1a;node.master和node.data。这两个参 数搭配使…

Java中的文件路径

通常情况下&#xff0c;在Java项目中&#xff0c;我们使用的路径都是在拿到类加载路径后&#xff0c;根据相对位置&#xff0c;使用 FilePathTest.class.getResourceAsStream(relativePath)&#xff1b;拿到文件。今天小生不使用classPath&#xff0c;而是直接去使用相对路径来…

转:入侵网站必备-sql server

来源&#xff1a;http://www.bitscn.com/plus/view.php?aid28692 1.判断有无注入点 ; and 11 and 12 2.猜表一般的表的名称无非是admin adminuser user pass password 等.. and 0(select count(*) from *) and 0(select count(*) from admin) ---判断是否存在admin这张表 3.猜…

85.4% mIOU!NVIDIA:使用多尺度注意力进行语义分割,代码已开源!

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达下载论文PDF和源代码&#xff1a;链接&#xff1a;https://pan.baidu.com/s/17oy5JBnmDDOtKasfPrWNiQ 提取码&#xff1a;lk5z导读来自NVIDIA的SOTA语义分割文章&#xff…

Python赋值运算符(入门必读)

赋值运算符用来把右侧的值传递给左侧的变量&#xff08;或者常量&#xff09;&#xff1b;可以直接将右侧的值交给左侧的变量&#xff0c;也可以进行某些运算后再交给左侧的变量&#xff0c;比如加减乘除、函数调用、逻辑运算等。 [Python] 中最基本的赋值运算符是等号&#x…

Linux 4.18 内核新补丁移除了Lustre 文件系统

2019独角兽企业重金招聘Python工程师标准>>> 在 Linux 4.18 的维护周期中&#xff0c;内核暂存区得到了超过一千个的补丁&#xff0c;共有168000行新代码出现&#xff0c;同时有227000行代码被删除。 为了使内核暂存区变得更轻&#xff0c;Lustre 文件系统在这次变更…