关于Transformer模型的Encoder-Decoder模块网上介绍的文章非常多,写的非常详尽,可谓汗牛充栋,尤其关于注意力计算这块,不仅给出了公式而且还有具体的计算步骤。关于Transformer模型我觉得大部分文章语焉不详的有两块(可能是我的理解力比较差):

一是关于FNN层的,就是FNN层是如何升维的。 升维使用的核函数是什么?为何升维能提升语义的表达并产生“记忆”功能?为何将维度升4倍,而不是6倍,8倍?

关于FNN层也有一些文章进行解读,大部分都会以CNN的卷积神经网络进行类比:即一个是Token mixer,关注在L这个维度的表达;一个是Channel mixer,专注于d这个维度的表达。至于为何升维4倍,没有什么理论基础,就像8头注意力一样,可能4倍的实验数据效果最好,是性价比最优的选择。

另一个是关于Decoder层最终输出的,就是如何给目标token打分的。相较于注意力机制的计算,大部分文章对最终输出这块几乎都是一笔带过,大体描述为:需要一个线性层(Linear)变换给目标词汇打分,然后使用Softmax对所有分数归一化,从而找出下一个token的概率分布,概率最高的就是要输出的token。

这种描述好像说了什么,但好像什么也没说。就好比说注意力机制就是计算各个token对其它token的打分,从而进行加权求和。大道理大方向是这么回事,但还是无法落地,也就是具体的计算步骤到底是什么?即使是给出了Python代码实现,也是对内部计算的封装,这就意味着你还是无法了解其具体的实现方法。

对于GPT这种Decoder-Only模型,因为没有Encoder模块协助全局语义关系的捕捉,因此其最终的输出要更加困难和复杂。它只能根据前面输入的所有token来预测下一个token。注意力机制解决的是已输入token间的关注度,从而提升各个token对现有上下文的理解程度,但这并意味着能直接预测出下一个token。

下面给出Decoder层最后输出token的计算方法。

1、假设已输入token: $$ \text{x}_1 、\text{x}_2、\text{x}_3 ,现在要预测下一个token: \text{x}_4 $$

2、经过Decoder模块上述3个token对应的特征向量为: $$\text{z}_1 、 \text{z}_2、\text{z}_3 $$

3、目标词汇表c,共有N个token:

\[\text{c}_1、\text{c}_2、\text{c}_3 、\text{c}_4 ......,\text{c}_{n-1} ,\text{c}_n
\]

现在的问题是: $$ Decoder层在预测下一个token时,是如何进行线性变换并在目标词汇表c中找出 \text{x}_4 的。 $$

1、计算当前每个输入token x与目标词汇表中每个c的注意力分数

\[\text{Attention Score} = \text{softmax}(\frac{QK^T}{\sqrt{d_k}})
\]

这一个步和注意力机制中的计算方式一样,就是计算当前已输入的每个x与目标词汇所有c的关注度,为了方便描述,不考虑QKV,只是计算向量间的内积:

\[对于第1个token:\text{x}_1,则有:\text{z}_1 \text{c}_1、\text{z}_1 \text{c}_2、\text{z}_1 \text{c}_3....., \text{z}_1 \text{c}_n
\]
\[对于第2个token:\text{x}_2,则有:\text{z}_2 \text{c}_1、\text{z}_2\text{c}_2、\text{z}_2 \text{c}_3....., \text{z}_2 \text{c}_n
\]
\[对于第3个token:\text{x}_3,则有:\text{z}_3 \text{c}_1、\text{z}_3\text{c}_2、 \text{z}_3 \text{c}_3 .....,\text{z}_3 \text{c}_n
\]

通过Softmax对关注度分数进行归一化操作。此时每个x会计算出目标词汇的注意力分数“Attenttion Score”。

注:上述的z是x经过Decoder模块运算后包含了注意力信息和上下文语义信息的向量,就是最后一步Linear的输入参数之一(见上图红色框)。

2、使用上述注意力分数来加权目标词汇的值向量并求和

\[\text{Context Vector} = \sum_{i} \text{Attention Score}_i \times \text{Value}_i
\]
\[对于第1个目标词汇\text{c}_1则有:\text{z}(c_1)= \text{z}_1 \text{c}_1+ \text{z}_2 \text{c}_1+\text{z}_3 \text{c}_1
\]
\[对于第2个目标词汇\text{c}_2则有:\text{z}(c_2)= \text{z}_1 \text{c}_2+ \text{z}_2 \text{c}_2+\text{z}_3 \text{c}_2
\]
\[对于第3个目标词汇\text{c}_3则有:\text{z}(c_3)= \text{z}_1 \text{c}_3+ \text{z}_2 \text{c}_3+\text{z}_3 \text{c}_3
\]

..........

\[对于第n个目标词汇\text{c}_n则有:\text{z}(c_n)= \text{z}_1 \text{c}_n+ \text{z}_2 \text{c}_n+\text{z}_3 \text{c}_n
\]

直观的理解就是将每个已输入token x对每个目标词汇c的值向量求和,从而产生新的目标向量: $$\text{z}(c_n)$$。这个新产生的目标向量融合了已输入所有token(本案例中的3个输入x)对其的关注度,并包含了当前上下文的语义信息,这一点非常重要。

到了这一步还是无法预测出下一个token,这时的输出是 N 个目标词汇 c 的新特征向量 $$\text{z}(c_n)$$。此时无法根据该值来预测下一个token。接下来,使用这个加权的上下文向量和当前解码器的隐藏状态来生成针对下一个token的分数,也就是下面最重要的一步,也是目前很多文档语焉不详的地方。

3、如何给每个目标词汇打分

\[\text{Score} = \text{Output Layer}([\text{Context Vector}; \text{Decoder Hidden State}])
\]

这个公式比较难以理解,其实就是: $$\text{c}_n与新产生的特征向量 \text{z}(c_n)进行内积,公式为: \text{Score}_n=\text{c}_n * \text{z}(c_n)$$

其目的就是计算目标token与该token在当前上下文中产生新特征后的投影大小。为何要这样计算呢?词汇表中的N个词(token)就意味着N个输出,但只有一个目标词汇的特征最能融入当前的上下文,融入新特征的向量与其自己的内积越大,则说明该词最合适。

到了这一步下面的工作就非常简单,只需要通过Softmax对N个目标词汇分数进行归一化,算出概率最大的就是要输出的token。

最后我想说的的是,以上都是我猜的,如果有误概不负责但欢迎指正。

关于Transformer中Decoder模块是如何预测下一个字符的算法的更多相关文章

  1. NLP之TextRNN(预测下一个单词)

    TextRNN @ 目录 TextRNN 1.基本概念 1.1 RNN和CNN的区别 1.2 RNN的几种结构 1.3 多对多的RNN 1.4 RNN的多对多结构 1.5 RNN的多对一结构 1.6 ...

  2. NLP之Bi-LSTM(在长句中预测下一个单词)

    Bi-LSTM @ 目录 Bi-LSTM 1.理论 1.1 基本模型 1.2 Bi-LSTM的特点 2.实验 2.1 实验步骤 2.2 实验模型 1.理论 1.1 基本模型 Bi-LSTM模型分为2个 ...

  3. cs224d 作业 problem set2 (三) 用RNNLM模型实现Language Model,来预测下一个单词的出现

      今天将的还是cs224d 的problem set2 的第三部分习题, 原来国外大学的系统难度真的如此之大,相比之下还是默默地再天朝继续搬砖吧 下面讲述一下RNN语言建模的数学公式: 给出一串连续 ...

  4. Vue中如何将数据传递到下一个页面(超级简单哒)

    先展示效果:注意URL中值是有变化的 一:在goodslist.vue文件夹绑定 <router-link :to="'/goodsinfo/'+subitem.artID" ...

  5. 关于selenium中的sendKeys()隔几秒发送一个字符

    看一下你的IEDriverServer.exe是不是64位的,我也遇到了这样的问题,换成32位的IEDriverServer.exe,瞬间速度快了

  6. 跟我一起学extjs5(13--运行菜单命令在tabPanel中显示模块)

    跟我一起学extjs5(13--运行菜单命令在tabPanel中显示模块)         上面设计好了一个模块的主界面,以下通过菜单命令的运行来把这个模块增加到主界面其中. 在MainModule. ...

  7. python中的模块和包

    模块 一 什么是模块 模块就是一组功能的集合体,可以通过导入模块来复用模块的功能. 比如我在同一个文件夹定义两个.py文件,分别命名为A.py和B.py,那么可以通过在A文件里通过import B来使 ...

  8. python中re模块的使用(正则表达式)

    一.什么是正则表达式? 正则表达式,又称规则表达式,通常被用来检索.替换那些符合某个模式(规则)的文本. 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合, ...

  9. python 历险记(五)— python 中的模块

    目录 前言 基础 模块化程序设计 模块化有哪些好处? 什么是 python 中的模块? 引入模块有几种方式? 模块的查找顺序 模块中包含执行语句的情况 用 dir() 函数来窥探模块 python 的 ...

  10. tensorflow中slim模块api介绍

    tensorflow中slim模块api介绍 翻译 2017年08月29日 20:13:35   http://blog.csdn.net/guvcolie/article/details/77686 ...

随机推荐

  1. 即时通讯技术文集(第34期):IM群聊技术合集(Part1) [共15篇]

    为了更好地分类阅读 52im.net 总计1000多篇精编文章,我将在每周三推送新的一期技术文集,本次是第34 期. [- 1 -] 快速裂变:见证微信强大后台架构从0到1的演进历程(一) [链接]  ...

  2. 这些小 Bug,99% 的程序员都写过!

    "程序怎么运行不了,不应该啊?" "程序怎么能运行了,不应该啊!" 这句话是不是让程序员朋友们的 DNA 动了呢?今天鱼皮分享一些新手程序员常犯的小 Bug,很 ...

  3. dotnet最小webApi开发实践

    dotnet最小webApi开发实践 软件开发过程中,经常需要写一些功能验证代码.通常是创建一个console程序来验证测试,但黑呼呼的方脑袋界面,实在是不讨人喜欢. Web开发目前已是网络世界中的主 ...

  4. JAVA根据集合中属性判断是否包含元素

    boolean isContain = list.stream().anyMatch(item -> item.getKey().equals(key));

  5. SQL统计数据之总结

    一.查询SQL SELECT t1.规则编号 AS 编码, t1.规则描述 AS 名称, SUM( CASE WHEN t3.DATA_SOURCES = '00' THEN 1 ELSE 0 END ...

  6. python语法第二篇

    练习:输入一个长字符串,判断其中数字的个数. # 输入一个长字符串,判断其中数字的个数. s1 = input("请输入一个包含字母和数字的字符串:") # wdqwddwq78d ...

  7. C# 窗口鼠标穿透以及取消窗口鼠标穿透

    private const int WS_EX_TRANSPARENT = 0x20; private const int GWL_EXSTYLE = -20; /// <summary> ...

  8. 微服务实战系列(七)-网关springcloud gateway-copy

    1. 场景描述 springcloud刚推出的时候用的是netflix全家桶,路由用的zuul,但是据说zull1.0在大数据量访问的时候存在较大性能问题,2.0就没集成到springcloud中了, ...

  9. 第八章 (Nginx+Lua)流量复制/AB测试/协程

    流量复制 在实际开发中经常涉及到项目的升级,而该升级不能简单的上线就完事了,需要验证该升级是否兼容老的上线,因此可能需要并行运行两个项目一段时间进行数据比对和校验,待没问题后再进行上线.这其实就需要进 ...

  10. 在OERV也可以玩MC(下)

      话接上回,上期讲述了在OERV安装HMCL的历程,这期讲讲HMCL的打包.   Show openEuler:24.09 / HMCL - 开源软件构建与测试.在这个网站里,可以看到有好几个文件, ...