欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 人工智能 > pytorch >内容正文

pytorch

【李宏毅深度学习CP10】Self-attention(part1)

发布时间:2024/1/1 pytorch 44 豆豆
生活随笔 收集整理的这篇文章主要介绍了 【李宏毅深度学习CP10】Self-attention(part1) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

学习心得

(1)传统的Attention是基于source端和target端的隐变量(hidden state)计算Attention的,得到的结果是源端的每个词与目标端每个词之间的依赖关系。但Self Attention不同,它分别在source端和target端进行,仅与source input或者target input自身相关的Self Attention,捕捉source端或target端自身的词与词之间的依赖关系;然后再把source端的得到的self Attention加入到target端得到的Attention中,捕捉source端和target端词与词之间的依赖关系。

(2)self Attention Attention比传统的Attention mechanism效果要好,主要原因之一是,传统的Attention机制忽略了源端或目标端句子中词与词之间的依赖关系,相对比,self Attention可以不仅可以得到源端与目标端词与词之间的依赖关系,同时还可以有效获取源端或目标端自身词与词之间的依赖关系。

文章目录

    • 学习心得
    • 一、复杂的Input时
    • 二、Vector Set as Input
      • 2.1 文字处理
        • 1)One-Hot的Encoding
        • 2)Word Embedding
      • 2.2声音信号
      • 2.3 图
      • 2.4 分子信息
    • 三、What is the output?
      • 3.1 每一个向量都有一个对应的Label
        • 1)词性标注
        • 2)语音识别
        • 3)Social Network
      • 3.2 一整个Sequence,只需要输出一个Label
        • 1)文字的情感分析
        • 2)语音识别
        • 3)图
      • 3.3 机器要自己决定,应该要输出多少个Label
    • 四、Sequence Labeling
    • 五、Self-Attention
      • Self-Attention过程
        • 1.怎么产生b1b^1b1这个向量
        • 2.计算α
        • 3.求b1b^1b1
    • Reference

一、复杂的Input时

到目前为止学的Network的输入都是一个向量(比如CV还是youtube视频等的输入都可以看做一个向量),而输出可能一个数值(如类别等)。

更复杂的去情况:输入是多个向量(且这个输入的向量的数目会改变),在上一节CNN我们还强调了假设输入的图片大小是相同。
现在我们假设我们的模型输入的Sequence的数目、长度都不一样。

二、Vector Set as Input

2.1 文字处理

Network的输入是一个句子,每个句子的长度不一样,单词也不一样。

如果把句子里的每个单词都描述成一个向量,那么模型model的输入就是一个vector set——该set的大小每次都不一样(句子的长度不同)。

1)One-Hot的Encoding

如何把一个词汇表示成一个向量——最简单的是One-Hot的Encoding

开一个很长的向量,其长度和世界上存在的词汇数相同,每一个维度对应到一个词汇,Apple就是100,Bag就是010,Cat就是001,以此类推。

缺点:它假设了所有的词汇之间没有关系的,从该向量看不到Cat和Dog都是动物所以他们比较接近,Cat和Apple一个动物一个植物,所以两者不太大关系。
在这个大向量里,没有任务的语义的信息。

2)Word Embedding

给每一个词汇一个向量(该向量是有语义的资讯的),如果把Word Embedding画出来,会看到如下图所示的所有动物聚集成一团,所有的植物聚集成一团,所有的动词聚集成一团。
可以参考:https://youtu.be/X7PH3NuYW0Q

ps:最小熵原理(六):词向量的维度应该怎么选择?——一个中大数学系硕士的博客(很多领域,主要是NLP),算法工程师。

2.2声音信号

一段声音讯号就是一排向量,我们可以把一段声音信号取一个范围(该范围称为一个window)。把该window里面的资讯描述成一个向量(称为一个Frame),通常这个window长度就是25个Millisecond。

把这一段的声音讯号变成一个Frame有很多种方法(此处不细讲)。
一小段25Millisecond里面的语音信号,为了描述一整段的声音信号,需要把这个window往右移一点,通常移动的大小是10个Millisecond。

一段声音讯号,你就是用一串向量来表示,而因為每一个Window啊,他们往右移都是移动10个Millisecond,所以一秒鐘的声音讯号有100个向量,所以一分鐘的声音讯号,就有这个100乘以60,就有6000个向量

2.3 图

社交网络就是一个图,可以看做是一堆向量组成的:
节点:每个节点可看做一个向量,如每个人的简历里面的性别、年龄、工作等,这些信息可以用一个向量来表示
边:两个人的关系连接,如是否为朋友等

2.4 分子信息

一个分子也可看做是一个图,一个分子可看做是一个图,分子上面的每个球就是一个原子(可以描述成一个向量)。一个原子可以用One-Hot Vector来表示,氢就是1000,碳就是0100,然后这个氧就是0010,所以一个分子就是一个Graph,它就是一堆向量。

三、What is the output?

输入是一堆向量,它可以是文字,可以是语音,可以是Graph,这样输出是有三种可能的。

3.1 每一个向量都有一个对应的Label

这种情况是说输入和输出一样数量。
当你的模型,看到输入是四个向量的时候,它就要输出四个Label,而每一个Label,它可能是一个数值,那就是Regression的问题,如果每个Label是一个Class,那就是一个Classification的问题

1)词性标注

在文字处理上的,POS Tagging就是词性标註,你要让机器自动决定每一个词汇 它是什麼样的词性,它是名词 还是动词 还是形容词等等。
如现在给出句子:I saw a saw并不是“我看一个看”,而是“我看到一个锯子”,这个第二个saw当名词用的时候,它是锯子,那所以机器要知道,第一个saw是个动词,第二个saw虽然它也是个saw,但它是名词,但是每一个输入的词汇,都要有一个对应的输出的词性

2)语音识别

参照作业2

虽然我们作业二,没有给大家一个完整的Sequence,我们是把每一个每一个每一个Vector分开给大家了,但是串起来就是一段声音讯号裡面,有一串Vector,每一个Vector你都要决定,它是哪一个Phonetic,这是一个语音辨识的简化版

3)Social Network

你的Model要决定每一个节点,它有什麼样的特性,比如说他会不会买某一个商品,这样我们才知道要不要推荐某一个商品给他

3.2 一整个Sequence,只需要输出一个Label

1)文字的情感分析

如果是文字的话,我们就说Sentiment Analysis。Sentiment Analysis就是给机器看一段话,它要决定说这段话是正面的还是负面的
比如在淘宝上商家要分析用户评价,不可能分析每一句话。这个是Sentiment Analysis给一整个句子,只需要一个Label,那Positive或Negative,那这个就是第二类的输出

2)语音识别

那如果是语音的例子的话呢,在作业四裡面我们会做语者辨认,机器要听一段声音,然后决定他是谁讲的

3)图

或者是如果是Graph的话呢,今天你可能想要给一个分子,然后要预测说这个分子,比如说它有没有毒性,或者是它的亲水性如何,那这就是给一个Graph 输出一个Label

3.3 机器要自己决定,应该要输出多少个Label

我们不知道应该输出多少个Label,机器要自己决定,应该要输出多少个Label,可能你输入是N个向量,输出可能是N’个Label

这种任务又叫做sequence to sequence的任务,在作业五会有sequence to sequence的作业,所以这个之后我们还会再讲

  • 翻译就是sequence to sequence的任务,因為输入输出是不同的语言,它们的词汇的数目本来就不会一样多
  • 或者是语音辨识也是,真正的语音辨识也是一个sequence to sequence的任务,输入一句话,然后输出一段文字,这也是一个sequence to sequence的任务

四、Sequence Labeling

ps:第二种类型有作业四,感兴趣可以去看看作业四的程式,因為上课时间有限,所以这次是先只讲第一个类型(每一个向量都有一个对应的Label),也就是输入跟输出数目一样多的状况(又叫做Sequence Labeling),你要给Sequence裡面的每一个向量,都给它一个Label,那要怎麼解Sequence Labeling的问题呢。那直觉的想法就是我们就拿个Fully-Connected的Network

然后虽然这个输入是一个Sequence,但我们就各个击破,不要管它是不是一个Sequence,把每一个向量,分别输入到Fully-Connected的Network裡面。然后Fully-Connected的Network就会给我们输出,那现在看看,你要做的是Regression还是Classification,產生正确的对应的输出,就结束了,

缺陷:后面这一个saw跟前面这个saw完全一模一样。既然Fully-Connected的Network输入同一个词汇,它没有理由输出不同的东西。但实际上,你期待第一个saw要输出动词,第二个saw要输出名词,但对Network来说它不可能做到,因為这两个saw 明明是一模一样的,你叫它一个要输出动词,一个要输出名词,它会非常地困惑,完全不知道要怎麼处理

有没有可能让Fully-Connected的Network,考虑更多的,比如说上下文的Context的资讯呢。这是有可能的,你就把前后几个向量都串起来,一起丢到Fully-Connected的Network就结束了

在作业二裡面,我们不是只看一个Frame,去判断这个Frame属於哪一个Phonetic,也就属於哪一个音标,而是看这个Frame的前面五个加后面五个,也就总共看十一个Frame,来决定它是哪一个音标

所以我们可以给Fully-Connected的Network,一整个Window的资讯,让它可以考虑一些上下文的,跟我现在要考虑的这个向量,相邻的其他向量的资讯

但是这样子的方法还是有极限,作业二就算是给你Sequence的资讯,你考虑整个Sequence,你可能也很难再做的更好啦,作业二考虑前后五个Frame,其实就可以得到很不错的结果了,所以你要过Strong Baseline,重点并不在於考虑整个Sequence,你就不需要往那个方向想了,用助教现有给你的Data,你就可以轻易的过Strong Baseline,

但是真正的问题,但是如果今天我们有某一个任务,不是考虑一个Window就可以解决的,而是要考虑一整个Sequence才能够解决的话,那要怎麼办呢

那有人可能会想说这个很容易,我就把Window开大一点啊,大到可以把整个Sequence盖住就结束了。但是,今天Sequence的长度是有长有短的,我们刚才有说,我们输入给我们的Model的Sequence的长度,每次可能都不一样

如果你今天说我真的要开一个Window,把整个Sequence盖住,那你可能要统计一下你的训练资料,然后看看你的训练资料裡面,最长的Sequence有多长,然后开一个Window比最长的Sequence还要长,你才有可能把整个Sequence盖住——但是你开一个这麼大的Window,意味著你的Fully-Connected的Network,它需要非常多的参数,那可能不只运算量很大,可能还容易Overfitting

五、Self-Attention

所以有没有更好的方法,来考虑整个Input Sequence的资讯呢——Self-Attention
Self-Attention的运作方式就是,Self-Attention会吃一整个Sequence的资讯

然后你Input几个Vector,它就输出几个Vector,比如说你这边Input一个深蓝色的Vector,这边就给你一个另外一个Vector。这边给个浅蓝色,它就给你另外一个Vector,这边输入4个Vector,它就Output 4个Vector。
——那这4个Vector有什麼特别的地方呢,这4个Vector,他们都是考虑一整个Sequence以后才得到的。所以这边每一个向量,我们特别给它一个黑色的框框代表说它不是一个普通的向量

如此一来你这个Fully-Connected的Network,它就不是只考虑一个非常小的范围,或一个小的Window,而是考虑整个Sequence的资讯,再来决定现在应该要输出什麼样的结果,这个就是Self-Attention。
Self-Attention不是只能用一次,你可以叠加很多次。所以可以把Fully-Connected的Network,跟Self-Attention交替使用

  • Self-Attention处理整个Sequence的资讯
  • Fully-Connected的Network,专注於处理某一个位置的资讯
  • 再用Self-Attention,再把整个Sequence资讯再处理一次
  • 然后交替使用Self-Attention跟Fully-Connected

有关Self-Attention,最知名的相关的文章,就是《Attention is all you need》.那在这篇Paper裡面呢,Google提出了Transformer这样的Network架构

之后会讲到,Transformer裡面一个最重要的Module就是Self-Attention。像Self-Attention这样的架构最早并不是在《Attention is all you need》(把Self-Attention这个Module,把它发扬光大)。因為其实很多更早的Paper,就有提出过类似的架构,只是不见得叫做Self-Attention,比如说叫做Self-Matching,或者是叫别的名字。

Self-Attention过程

那Self-Attention是怎麼运作的呢
Self-Attention的Input,它就是一串的Vector,那这个Vector可能是你整个Network的Input,它也可能是某个Hidden Layer的Output,所以我们这边不是用xxx来表示它,

我们用aaa来表示它,代表它有可能是前面已经做过一些处理,它是某个Hidden Layer的Output,那Input一排a这个向量以后,Self-Attention要Output另外一排b这个向量——那这每一个b都是考虑了所有的a以后才生成出来的,所以这边刻意画了非常非常多的箭头,告诉你b1b^1b1考虑了a1a^1a1a4a^4a4产生的,b2b^2b2考虑a1a^1a1a4a^4a4产生的,b3、b4b^3 、b^4b3b4也是一样,考虑整个input的sequence,才产生出来的。

1.怎么产生b1b^1b1这个向量

(剩下b1b2b3b4b^1 b^2 b^3 b^4b1b2b3b4剩下的向量同理)
这里有一个特别的机制,这个机制是根据a1a^1a1这个向量,找出整个很长的sequence裡面,到底哪些部分是重要的,哪些部分跟判断a1a^1a1是哪一个label是有关係的,哪些部分是我们要决定a1a^1a1的class,决定a1a^1a1的regression数值的时候,所需要用到的资讯

每一个向量跟a1a^1a1的关联的程度,用一个数值叫α来表示

这个self-attention的module,怎麼自动决定两个向量之间的关联性呢,你给它两个向量a1a^1a1a4a^4a4,它怎麼决定a1a^1a1a4a^4a4有多相关,然后给它一个数值α呢,那这边呢你就需要一个计算attention的模组

这个计算attention的模组,就是拿两个向量作為输入,然后它就直接输出α那个数值,

2.计算α

计算这个α的数值有各种不同的做法

  • 比较常见的做法呢,叫做用dot product,输入的这两个向量分别乘上两个不同的矩阵,左边这个向量乘上WqW^qWq这个矩阵得到矩阵qqq,右边这个向量乘上WkW^kWk这个矩阵得到矩阵kkk
    再把qqqkkk做dot product,就是把他们做element-wise 的相乘,再全部加起来以后就得到一个 scalar,这个scalar就是α,这是一种计算α的方式

  • 有另外一个叫做Additive的计算方式,它的计算方法就是,把同样这两个向量通过WqW^qWq WkW^kWk,得到qqqkkk,那我们不是把它做Dot-Product,是把它这个串起来,然后丢到这个过一个Activation Function

然后再通过一个Transform,然后得到α。总之有非常多不同的方法,可以计算Attention,可以计算这个α的数值,可以计算这个关联的程度。但是在接下来的讨论裡面,我们都只用左边这个方法,这也是今日最常用的方法,也是用在Transformer裡面的方法

要把这边的a1a^1a1去跟这边的a2a3a4a^2 a^3 a^4a2a3a4,分别都去计算他们之间的关联性,也就是计算他们之间的α

(1)你把a1a^1a1乘上WqW^qWq得到q1q^1q1,那这个q有一个名字,我们叫做Query,它就像是你搜寻引擎的时候,去搜寻相关文章的问题,就像搜寻相关文章的关键字,所以这边叫做Query
(2)a2a3a4a^2 a^3 a^4a2a3a4你都要去把它乘上WkW^kWk,得到kkk这个Vector,kkk这个Vector叫做Key,那你把这个Query q1,跟这个Key k2,算Inner-Product就得到α
(3)我们这边用α1,2α_{1,2}α1,2来代表说,Query是1提供的,Key是2提供的时候,这个1跟2他们之间的关联性,这个α这个关联性叫做Attention的Score,叫做Attention的分数,

接下来也要跟a3a4a^3 a^4a3a4来计算

a3a_3a3乘上WkW^kWk,得到另外一个Key也就是k3k^3k3,a4a^4a4乘上WkW^kWk得到k4k^4k4,然后你再把k3k^3k3这个Key,跟q1q^1q1这个Query做Inner-Product,得到1跟3之间的关联性,得到1跟3的Attention,你把k4k^4k4q1q^1q1做Dot-Product,得到α1,4α_{1,4}α1,4,得到1跟4之间的关联性
其实一般在实作时候,q1q^1q1也会跟自己算关联性,自己跟自己计算关联性这件事情有多重要,你可以自己在做作业的时候试试看,看这件事情的影响大不大了


计算出a1跟每一个向量的关联性以后,接下来这边会接入一个Soft-Max这个Soft-Max跟分类的时候的那个Soft-Max是一模一样的,所以Soft-Max的输出就是一排α,所以本来有一排α,通过Soft-Max就得到α′α'α
这边你不一定要用Soft-Max,用别的替代也没问题,比如说有人尝试过说做个ReLU,这边通通做个ReLU,那结果发现还比Soft-Max好一点,所以这边你不一定要用Soft-Max,这边你要用什麼Activation Function都行,你高兴就好,你可以试试看,那Soft-Max是最常见的,那你可以自己试试看,看能不能试出比Soft-Max更好的结果

3.求b1b^1b1


接下来得到这个α′α'α以后,我们就要根据这个α′α'α去抽取出这个Sequence裡面重要的资讯,根据这个α我们已经知道说,哪些向量跟a1a^1a1是最有关係的,怎麼抽取重要的资讯呢,

  • 首先把a1a^1a1a4a^4a4这边每一个向量,乘上WvW^vWv得到新的向量,这边分别就是用v1v2v3v4v^1 v^2 v^3 v^4v1v2v3v4来表示
  • 接下来把这边的v1v^1v1v4v^4v4,每一个向量都去乘上Attention的分数,都去乘上α′α'α
  • 然后再把它加起来,得到b1b^1b1
    b1=∑iα1,i′vib^1=\sum_i\alpha'_{1,i}v^ib1=iα1,ivi

如果某一个向量它得到的分数越高,比如说如果a1a^1a1a2a^2a2的关联性很强,这个α′α'α得到的值很大,那我们今天在做Weighted Sum以后,得到的b1b^1b1的值,就可能会比较接近v2v^2v2。所以谁的那个Attention的分数最大,谁的那个vvv就会Dominant你抽出来的结果。以上就是怎麼从一整个Sequence 得到b1b^1b1

Reference

(1)李宏毅深度学习2021课程
(2)Self-Attention机制全方位总结:https://zhuanlan.zhihu.com/p/79115586
(3)Self-attention + transformer 和其他一些总结:https://www.cnblogs.com/illlioo/p/14752174.html
(4)https://github.com/Kyubyong/transformer

总结

以上是生活随笔为你收集整理的【李宏毅深度学习CP10】Self-attention(part1)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。