文章目录
Seq2Seq Attention 注意力机制
要解决的问题
计算机如果听到一个长句直接回答,可能会有“失忆”或者“找不到重点”的问题
如何注意
情感分析简单例子,线条越粗的部分模型注意力越集中
翻译简单例子,这个方法在 decoder 用爱预测时,他会用爱这里的 state,结合上 encoder 中所有词的信息,生成一个注意力权重,比如模型会更加注意 encoder 中的爱和莫烦。 然后再结合这个权重,再次把权重施加到 encoder 中的每个 state,这样就有了对于不同 state step 的不一样关注度,注意力的结果(context)也在这里产生。 接着,把 context 和 decoder 那边的信息再次结合,最终输出注意后的答案。
补充:三种计算attention score的方式
这里的 h_t 是 decoder 见到输入生成的 hidden state, h_hat_s 是 encoder 见到输入时生成的 hidden state。 意思是将decoder每预测一个词, 我都拿着这个decoder现在的信息去和encoder所有信息做注意力的计算。三个公式的不同点就是是否要引入更多的学习参数和变量。
思考
为什么我们在训练的时候,不把每次decoder出来的词当做下次预测的输入,而使用真实标签作为decoder的输入呢?
对比上面两张图,上图是训练时的样子,decoder的输入是真实标签信息。下图是预测时的样子,decoder的输入是上一步预测的值。 预测时,因为缺少真实的label,只能拿着上一步预测的值作下一步预测的输入(废话)。 训练时,拿着真实的标签来预测会快很多。
Transformer
要解决的问题
比起经过RNN encoder后使用Attention,能不能绕过RNN,来直接在词向量阶段就开始使用注意力?其实理解一句话有以下两种方案:
- 我们可以选择先读一遍,基于读过之后的理解上,再为后续处理分配不同的注意力
- 我们不通读,而是跳着读关键词,直接用注意力方法找出并运用这些关键词。
研究发现,第二种方法在语言的理解上能够更上一筹,而且在同等量级的网络规模上,要比第一种方法快很多。还可以像多层RNN一样,在理解的基础上再次理解,一遍又一遍地注意到句子的不同部分,提炼对句子更深层的理解。
Attention Is All You Need
论文里这个图只画了一层attention,还有一个Nx,它可是要扩展成N个这种结构。 一般来说N的取值从个位数到十位数不等,大于20一般显卡就比较难顶。
Transformer 这种模型是一种 seq2seq 模型,是为了解决生成语言的问题。它也有一个 Encoder-Decoder 结构,只是它不像RNN中的 Encoder-Decoder。 之后我们将要介绍的 BERT 就是这个 Transformer 的Encoder部分,GPT就是它的 Decoder 部分。
Encoder 负责仔细阅读,Decoder 任务同Seq2Seq 的 decoder 任务一样,同时接收Encoder的理解和之前预测的结果信息,生成下一步的预测结果。
如何做attention
做这件事的核心目的是快速准确地找到核心内容,换句话说:用搜索(Query)找到关键内容(Key),在关键内容上花时间花功夫(Value)。
想象这是一个相亲画面,我有我心中有个喜欢女孩的样子,我会按照这个心目中的形象浏览各女孩的照片,如果一个女生样貌很像我心中的样子,我就注意这个人,并安排一段稍微长一点的时间阅读她的详细材料,反之我就安排少一点时间看她的材料。这样我就能将注意力放在我认为满足条件的候选人身上了。
我心中女神的样子就是Query,我拿着它(Query)去和所有的候选人(Key)做对比,得到一个要注意的程度(attention),根据这个程度判断我要花多久时间仔细阅读候选人的材料(Value)。 这就是Transformer的注意力方式。
如何增强注意力
为了增强注意力的能力,Transformer还做了一件事:从注意力修改成了注意力注意力注意力注意力。即多头注意力(Multi-Head Attention)。
多头注意力指的就是在同一层做注意力计算的时候,我多搞几次注意力。有点像我同时找了多个人帮我注意一下,这几个人帮我一轮一轮注意+理解之后, 再汇总所有人的理解,统一判断。
Decoder怎么样拿到Encoder对句子的理解
Encoder和Decoder都存在注意力,Encoder里的的注意力叫做自注意力(self-attention), 因为Encoder在这个时候只是自己和自己玩。而Decoder说:你把你get到的借我参考一下吧。 这时Self-attention在transformer中的意义才被凸显出来。
在Decoding时,decoder会向encoder借一下Key和Value,Decoder自己可以提供Query(已经预测出来的token)。使用我们刚刚提到的K,Q,V结合方式计算。
另: Decoder 先要经过Masked attention再和encoder的K,V结合,然后还有有一个feed forward计算,还要计算残差。
Masked attention: 不让decoder在训练的时候用后文的信息生成前文的信息;
Feed forward: 这个encoder,decoder都有,做一下非线性处理;
残差计算:这个也是encoder和decoder都有,为了更有效的backpropagation。
结果讨论
我们看到最后一层layer3, 这个就是decoder在结合encoder信息后的attention,生成的预测结果。我们很明显可以看到中英文日期对应的点上, 注意力都非常大。连线可以更加明显的看出来这样的关系。
Encoder 的 self-attention 看不出来太多信息,因为我们这个数据集在自注意上并不是很强调,X的语句内部没有多少相关的信息。所以训练出来的encoder self-attention 并不明显。
反而是decoder的self-attention还是有些信息的。因为decoder在做self-attention时, 实际上还是会多多少少接收到encoder attention的影响。
decoder的attention图,为什么是一个三角形?因在在上面提到的,预测时,不能让后文的信息影响到前文,就会用一个look_ahead_mask将后文的信息给遮盖住。这个mask长成这样:
为什么这个mask不是一个对角的三角形呢?原因是有些句子没那么长,也可以一起mask掉,我把这种叫做 pad_mask,像下图这样。
最后,还有一个问题,transformer的attention不像RNN,它没有捕捉到文字序列上的时序信息。那我们怎么让模型知道一句话的顺序呢? 这个有多种做法,比如让模型仔细学一个position embedding,或者你给一个有规律的position embedding就好了。下面展示的是可视化出来的Position Embedding: