本系列文章希望对google BERT模型做一点解读。打算采取一种由点到线到面的方式,从基本的元素讲起,逐渐展开。
讲到BERT就不能不提到Transformer,而self-attention则是Transformer的精髓所在。简单来说,可以将Transformer看成和RNN类似的特征提取器,而其有别于RNN、CNN这些传统特征提取器的是,它另辟蹊径,采用的是attention机制对文本序列进行特征提取。
所以我们从self-Attention出发。
Attention is all your need
尽管attention机制由来已久,但真正令其声名大噪的是google 2017年的这篇名为《attention is all your need》的论文。
让我们从一个简单的例子看起:
假设我们想用机器翻译的手段将下面这句话翻译成中文:
“The animal didn’t cross the street because it was too tired”
当机器读到“it”时,“it”代表“animal”还是“street”呢?对于人类来讲,这是一个极其简单的问题,但是对于机器或者说算法来讲却十分不容易。
self-Attention则是处理此类问题的一个解决方案,也是目前看起来一个比较好的方案。当模型处理到“it”时,self-Attention可以将“it”和“animal‘联系到一起。
它是怎么做到的呢?
通俗地讲,当模型处理一句话中某一个位置的单词时,self-Attention允许它看一看这句话中其他位置的单词,看是否能够找到能够一些线索,有助于更好地表示(或者说编码)这个单词。
如果你对RNN比较熟悉的话,我们不妨做一个比较。RNN通过保存一个隐藏态,将前面词的信息编码后依次往后面传递,达到利用前面词的信息来编码当前词的目的。而self-Attention仿佛有个上帝之眼,纵观全局,看看上下文中每个词对当前词的贡献。

Self-Attention in Detail
首先,来看下怎样使用向量来计算self-attention,紧接着看如何用矩阵来计算self-attention。
使用向量
如下图所示,一般而言,输入的句子进入模型的第一步是对单词进行embedding,每个单词对应一个embedding。对于每个embedding,我们创建三个向量,Query、Key和Value向量。我们如何来创建三个向量呢?如图,我们假设embedding的维度为4,我们希望得到一个维度为3的Query、Key和Value向量,只需将每个embedding乘上一个维度为4*3的矩阵即可。这些矩阵就是训练过程中要学习的。

我们用一个例子来说明:
首先要明确一点,self-attention其实是在计算每个单词对当前单词的贡献,也就是对每个单词对当前单词的贡献进行打分score。假设我们现在要计算下图中所有单词对第一个单词"Thinking"的打分。那么分分数如何计算呢,只需要将该单词的Query向量和待打分单词的Key向量做点乘即可。比如,第一个单词对第一个单词的分数为q1× k1,第二个单词对第一个单词的分数为q1×k2。

接着就是Value向量登场的地方了。将上面的分数分别和Value向量相乘,注意这里是对应位置相乘。


- 创建Query、Key、Value向量
- 计算每个单词在当前单词的分数
- 将分数归一化后与Value相乘
- 求和
值得注意的是,上面阐述的过程实际上是Attention机制的计算流程,对于self-Attention,Query=Value。
Matrix Calculation of Self-Attention
其实矩阵计算就是将上面的向量放在一起,同时参与计算。
首先,将embedding向量pack成一个矩阵X。假设我们有一句话有长度为10,embedding维度为4,那么X的维度为(10 × 4).



jalammar的博客十分通俗易懂,且切中要害,本系列内容不乏很多翻译自jalammar的博客。