复杂的输入
假设我们今天要Network的输入是一个句子,每一个句子的长度都不一样,每个句子里面词汇的数目都不一样。
一段声音讯号其实是一排向量,我们会把一段声音讯号取一个范围,这个范围叫做一个Window,
一小段25个毫秒里面的语音讯号,为了要描述一整段的声音讯号,你会把这个Window往右移一点,通常移动的大小是10个毫秒。
一个Graph 一个图,也是一堆向量,我们知道说Social Network就是一个Graph,在Social Network上面每一个节点就是一个人,然后节点跟节点之间的edge就是他们两个的关系连接,比如说是不是朋友等等,而每一个节点可以看作是一个向量,所以一个Social Network 一个Graph,你也可以看做是一堆的向量所组成的。
What is the output?
1. 每一个向量都有一个对应的Label
2. 一整个Sequence,只需要输出一个Label
3. 机器要自己决定,应该要输出多少个Label
Sequence Labeling
那这种输入跟输出数目一样多的状况又叫做Sequence Labeling,你要给Sequence裡面的每一个向量,都给它一个Label,那要怎么解Sequence Labeling的问题呢?
self attention

然后你Input几个Vector,它就输出几个Vector,比如说你这边Input一个深蓝色的Vector,这边就给你一个另外一个Vector。那这4个Vector有什么特别的地方呢,这4个Vector,他们都是考虑一整个Sequence(context上下文)以后才得到的。
Self-Attention不是只能用一次,你可以叠加很多次。
Self-Attention过程
那这每一个b都是考虑了所有的a以后才生成出来的,所以这边刻意画了非常非常多的箭头。
那接下来呢就是要跟大家说明,怎么产生b这个向量。
这里有一个特别的机制,这个机制是根据a1这个向量,找出整个很长的sequence裡面,到底哪些部分是重要的,哪些部分跟判断a1是哪一个label是有关係的,哪些部分是我们要决定的class,决定的regression数值的时候,所需要用到的资讯。
每一个向量跟a1的关联的程度,用一个数值叫α来表示。
这个self-attention的module,怎麼自动决定两个向量之间的关联性呢?
比较常见的做法呢,叫做用dot product,输入的这两个向量分别乘上两个不同的矩阵,左边这个向量乘上这个矩阵得到矩阵,右边这个向量乘上这个矩阵得到矩阵再把跟做内积,就是把他们做element-wise 的相乘,再全部加起来以后就得到一个 scalar,这个scalar就是α,这是一种计算α的方式
有另外一个叫做Additive的计算方式,它的计算方法就是,把同样这两个向量通过,wq和wk得到q跟k,那我们不是把它做Dot-Product,是把它这个串起来,然后丢到这个过一个Activation Function然后再通过一个Transform,然后得到α。

但是在接下来的讨论裡面,我们都只用左边这个方法,这也是今日最常用的方法,也是用在Transformer裡面的方法(舒服)。
那你就要把这边的a1去跟这边的a2,a3,a4,分别都去计算他们之间的关联性,也就是计算他们之间的α。
你把乘上wq得到q,那这个q有一个名字,我们叫做Query,它就像是你搜寻引擎的时候,去搜寻相关文章的问题,就像搜寻相关文章的关键字,所以这边叫做Query。然后接下来呢,a2,a3,a4你都要去把它乘上wk,得到这个Vector,这个Vector叫做Key,那你把这个Query q1,跟这个Key k2,算Inner-Product就得到α。
我们这边用a1,2来代表说,Query是1提供的,Key是2提供的时候,这个1跟2他们之间的关联性,这个α这个关联性叫做Attention的Score,叫做Attention的分数。
算出和每一个向量的Attention的分数,包括自己,然后接一个softmax,生成a~。
生成最终的b1
- 首先把a1到a4这边每一个向量,乘上得到新的向量,这边分别就是用v来表示
- 接下来把这边的v1到v4,每一个向量都去乘上Attention的分数,都去乘上a point
- 然后再把它加起来,得到b1
矩阵表示
我们现在已经知道每一个 a 都产生 q k v三个向量。
如果要用矩阵运算表示这个操作的话,是什麼样子呢
我们每一个 a,都乘上一个矩阵,我们这边用wq来表示它,得到 ,每一个 a 都要乘上wq得到qi,这些不同的 a 你可以把它合起来,当作一个矩阵来看待。
a1,a2,a3,a4这些向量组成了矩阵I,反过来看a1,a2,a3,a4是这个矩阵的分块矩阵。
同理k向量和a向量也是这样的矩阵相乘。
现在需要q向量和k向量做内积得到attention score
现在需要把attention score和矩阵v相乘 得到转化的b
Multi-head Self-attention

- 先把 a 乘上一个矩阵得到 q
- 再把 q 乘上另外两个矩阵,分别得到q1跟q2,那这边还有 这边是用两个上标,i 代表的是位置,然后这个 1 跟 2 代表是,这个位置的第几个 q,所以这边有qi1跟qi2 ,代表说我们有两个 head。
- 然后你去做相同的事情,相当于你把这件事情做了两遍。
Positional Encoding(尚待研究的问题)
那讲到目前為止,你会发现说 Self-attention 的这个 layer,它少了一个也许很重要的资讯,这个资讯是位置的资讯,对一个 Self-attention layer 而言,每一个 input,它是出现在 sequence 的最前面,还是最后面,它是完全没有这个资讯的。
你为每一个位置设定一个 vector,叫做 positional vector,这边用ei来表示,上标 i 代表是位置,每一个不同的位置,就有不同的 vector,就是e1是一个 vector,不同的位置都有一个它专属的 e,然后把这个 e 加到ai上面,就结束了。

self-attention vs rnn
- 对 RNN 来说,假设最右边这个黄色的 vector,要考虑最左边的这个输入,那它必须要把最左边的输入存在 memory 裡面,然后接下来都不能够忘掉,一路带到最右边,才能够在最后一个时间点被考虑
- 但对 Self-attention 来说没有这个问题,它只要这边输出一个 query,这边输出一个 key,只要它们 match 得起来,天涯若比邻,你可以从非常远的 vector,在整个 sequence 上非常远的 vector,轻易地抽取资讯,所以这是 RNN 跟 Self-attention,一个不一样的地方
还有另外一个更主要的不同是,RNN 今天在处理的时候, input 一排 sequence,output 一排 sequence 的时候,RNN 是没有办法平行化的



