知识来源:强烈推荐!台大李宏毅自注意力机制和Transformer详解!_哔哩哔哩_bilibili
先抛出一个问题:为什么需要用自注意力机制呢?
答:因为输入如果是多个向量,则需要知道那一部分是需要重点关注的。
前言
从输入的角度进行理解
如果输入是多个向量(比如一段话、一段音频、一个graph),可以使用one-hot的编码方式,但这样会使维度变得很大,因此可以使用embedding(带有语义的表达方式)来表示输入。
从输出的角度进行理解
主要分为三种,1.有多少输入就会有多少输出,也叫做Sequence Labeling。2.有一个输出。3.不管有多少输入,输出的数量是可变的,这样的任务也称为seq2seq任务(比如翻译、语音辨识)。
针对Sequence Labeling描述问题
在做语义分析任务时,两个saw的FC很难生成不同的语义,这样便需要设置windows来分析上下文。
如果有个任务不是只考虑windows就能够解决的,需要分析整个sequence才能够解决应该怎么办呢?sequence大小不一,可能会很大。如果把windows设置的比较大,则FC的参数量会很大,容易过拟合。这时候就需要用到self-attention。
一、Self-Attention
将整个sequence都放入Self-attention中,输出考虑过上下文的对应输出向量。
Self-attention不只是能用一次,而且能重叠,多次使用:
在self-attention内部中会计算出与others的关联度,用α表示。具体如何计算这个关联度的方法如下:
需要一个计算attention的模组,拿两个向量作为输出,α作为输出。这样的模组有很多种,比较常见的是Dot-product(最常见,transformer中也用的这个)和Additive。
把Dot-product计算模组放入self-attention中,并在最后做一个softmax(也不一定用softmax,有人用relu也有了很好的输出效果):
最后根据计算出来的α来抽取重要的信息:a乘上V得到新的向量,新的向量与α(softmax之后的相关度)相乘得到最后的信息。
得到Q、K、V的过程(可以理解为输入矩阵都需要乘一个参数矩阵,然后就可以得到Q、K、V):
最后总结出每一步的矩阵,可以发现整个过程中,只需要学习W^q,W^k,W^v的参数:
二、进阶版Self-Attention——Multi-head Self-Attention
以两个输入举例,在计算出q、k、v后,再分别乘两个矩阵,分别得到两个q、k、v并进行计算,如下:
在此之前,都只是包含顺序的信息,如果想在self-attention中加入位置的信息,可以应用Positional Encoding:
三、Self-Attention与其他模块的对比与应用