首页 > 编程知识 正文

attention机制详解,attention机制的作用

时间:2023-05-04 16:55:59 阅读:199668 作者:3033

好,在讲attention之前,大家有必要了解两个知识点,词向量和RNN。

什么是词向量呢?也就是把语言向量化来作为模型的输入。

什么是RNN呢,也就是循环神经网络,看下面这个示意图,这里的每一个X代表每一步的输入,A代表运算过程,可以看到,每一步的计算输出都被作为下一步的输入,另个需要说明一点,每个A里的参数都是一样的,这就是为什么这种模型叫作循环神经网络。

那现在进入今天的主题,attention机制是什么呢,其实它经常是以seq2seq+attention这种形式出现的,也注是说,一般是配合着sequence2sequence模型来使用的,所以在讲attention之前,我们首先要来了解下这个东西,seq2seq。

什么seq2seq呢,很简单,有点英语基础我们就能理解,seq是序列的意思,也就是从一个序列变到另一个序列。大家想一想,有什么场景是适用的,比如,机器翻译,文章摘要,闲聊。为了让大家有一个场景的代入感,那我们下面的讲解就是围绕机器翻译来讲的。

那么这个seq2seq model里面到底是什么成分呢?其实模型包含一个编码器,以及一个解码器。大家听到这种专业术语的时候,千万不要有畏惧心理,其实专业术语就是用来吓人的,咱们从语言的角度来解析一下,很快就能明白。

我们一个个地来看,编是什么意思,即编写,编辑,码,密码,符号,器,容器,工具,方法,总结来说,编写密码符号的方法,通俗地讲,什么意思呢,就是把看得懂的东西变成看不懂的东西。那么在我们这里的场景下是什么意思,我们之前输出的是一句法语,是人类看得懂的,经过编码器之后,就变成一个矩阵了,而矩阵是我们看不懂的。而解码器呢,也就是编码的反过程了,也就是把这个矩阵又变成我们人类看得懂的语言,所以经过了解码器,我们就得到了一句英语。

示意图如下:

接下来,我们要讲难一点的东西了。我们要具体地来看看,从一句法语到英语的全过程到底是怎么实现的。

首先,我们输出的是这句法语,为了显示方便,这里用一个四维的词向量来表示,实际应用中呢,词向量是有几百维的。

之前有讲过,需要大家明白RNN模型,然后前面又讲了编码器,解码器之类的,其实啊,这两个器就是用RNN模型来做的。当然现在编码器解码器都用更高级复杂的模型来做的,比如说transformer, 现在很火的bert就是基于这个来做的,用RNN来做是最基础最简单的方法。

下面是RNN的示意图:

RNN模型是接收两个输入向量的,一个是input vector, 就是那句法语里面的单词的词向量,那这个hidden state又是什么东西呢?可能大家会比较困惑。现在我们先暂时放开这个模型,来想想,state是什么呢?是一种状态,状态又是什么呢?我们在生活中什么时候会使用到状态这个词的呢?比如,我们问别人,哎,你今天状态怎么样,你最近状态怎么样?有没有发现,状态,好像和时间是有很大关系的。那现在再问大家一个问题,时间会改变什么?时间会改变什么状态?时间会改变一个人的记忆状态,改变一个人对这个世界的理解状态,为什么,因为随着时间的进行,你接触到了更多的东西,你有了更多的记忆,同时,你对事物的理解也会发生变化,对吗。那好,现在再回过头来看看我们这个RNN模型,我们这个第一次的输入,hidden state #0在一般情况下是随机初始化的,相当于我们一生下来,这是一个随机的过程,没有什么记忆,也不具备对外物的理解。现在,请看这里的第一步,我们把初始状态和第一个单词一起输入到这个模型当中,进行了一系列的运算,然后又输出了下一个状态,有了前面的铺垫,相信大家都明白了,我们这第二个状态是不是就有了对于这个单词的理解和记忆呢。这里的每一步输入单词都是一个时间点,随着时间的进行,机器记忆和理解的单词?就越来越多了。那么到最后这一个state, 便有了对这句话的记忆。好了,现在,我想问大家一个问题,为什么不干脆一下子把单词都存到记忆里呢,而要一个个时间点地来输入呢?很简单,保存语序信息。

这里面每一步的计算过程,其实也不复杂,公式是这样的:
我们假设H为隐状态,X为单词向量输入。W1, W2,B为参数,f为非线性函数。
f(W1H+W2X+B) -> H

这就是最原始最初的seq2seq, 大家有没有感觉这种操作有点不太靠谱呢,怎么看怎么有点悬呢。对,事实证明这种简单的方式确实不太靠谱。这就好比,我给你一句法文,让你过一遍之后凭着记忆把它翻译成英语。如果是短点的句子还好,如果给你来一个什么定语状语补语都有的一个超级长句,光凭这最后的记忆状态,这是不是就有些困难啦。

所以呢,我们要做两点改进:

首先,既然光凭最后的记忆状态不够,那我们就把之前的记忆状态也加进来用嘛,这就好比让你翻译的时候也能看到原文;

不过这还不够,我还希望我在翻译的时候能给我划一下重点。什么是划重点呢,也就是说,我在接下来生成每一个单词的时候有人能告诉我接下来这个词是和原文中哪些词是有关系的。那这样一来,我们的翻译工作是不是省力多了,正确率也好多了呢?那么,这里所说的划重点,就是我们今天的主题,attention机制,是不是很简单。

首先,正如上面所说,在翻译过程中生成每一个单词的时候,我们把三个隐状态都拿来用,并且给每个状态划重点,比如在这里,翻译第一个单词的时候,原文中的第一个隐状态比后两个要重要些,经过一层softmax之后,我们就把重要性转化成了权重,分别与对应的隐状态相乘,然后求和。那么最终,我们就得到了一个,既包含了很多记忆状态,有划过重点的向量。
示意图如下:


接下来,我们再来看看这个编码器即翻译过程具体又是怎么实现的。之前我们说过,解码器也是一个RNN模型,在每一步需要两个输入,那么在第一步,输入的隐状态也同样是随机初始化的,而这个最初输入的单词,我们一般用一个特殊符号的向量。同样地,这两个输入经过计算之后,得到下一个状态,这个时候,我们再把之前得到的那个既包含了很多记忆状态,有划过重点的向量拿过来,把这两者结合,再去生成一个单词。那么到生成第二个单词的时候,也是基于同样的原理,我们把之前生成的隐状态以及单词作为输入,同时结合attention机制,来产生我们的第二个单词。以此类推,我们就翻译出了整个句子。
示意图如下:

那具体要怎么来划这个重点?对于这个权重的计算,也是基于一种求相似度的原理,不同的attention机制有不同的算法。

我们在这里介绍的是最最基本的seq2seq+attention模型,在具体的应用中,我们会使用更复杂的编码器和解码器。比如Google于2016年部署到线上的基于神经网络的机器翻译系统,是基于LSTM(一个更复杂的RNN模型),同时也增加了神经网络的层数。

参考
各种attention总结: https://blog.csdn.net/c9yv2cf9i06k2a9e/article/details/80652382

通俗讲解:http://jacoxu.com/encoder_decoder/

基于seq2seq的聊天机器人:https://blog.csdn.net/irving_zhang/article/details/79088143

pytorch教程:https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutorial.html

英法翻译:https://blog.csdn.net/m0_37306360/article/details/79318644

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。