1.前言
在自然语言处理领域,近几年最火的是什么?是BERT!谷歌团队2018提出的用于生成词向量的BERT算法在NLP的11项任务中取得了非常出色的效果,堪称2018年深度学习领域最振奋人心的消息。而BERT算法又是基于Transformer,Transformer又是基于attention机制。这次咱们从Encoder-Decoder->Attention->Transformer逐步讲解,一步一步深入,将他们一网打尽,写这篇博客既是对我自己学习的一个总结,也希望或许能对你有所帮助!!!
因为涉及的内容较多,我决定将博客分为上下两篇,上篇主要介绍Attention,下篇介绍Transformer。
那么废话不多说,开始咱们上篇 Attention详解。
2.Encoder-Decoder
2.1Encoder-Decoder简介
Encoder-Decoder框架顾名思义也就是编码-解码框架,目前大部分attention模型都是依附于Encoder-Decoder框架进行实现,在NLP中Encoder-Decoder框架主要被用来处理序列-序列问题。也就是输入一个序列,生成一个序列的问题。这两个序列可以分别是任意长度。具体到NLP中的任务比如:
文本摘要,输入一篇文章(序列数据),生成文章的摘要(序列数据)
文本翻译,输入一句或一篇英文(序列数据),生成翻译后的中文(序列数据)
问答系统,输入一个question(序列数据),生成一个answer(序列数据)
基于Encoder-Decoder框架具体使用什么模型实现,由大家自己决定~用的较多的应该就是seq2seq模型和Transformer了。
2.2Encoder-Decoder结构原理
上图就是Encoder-Decoder框架在NLP领域中抽象后的最简单的结构图。
Encoder:编码器,对于输入的序列<x1,x2,x3…xn>进行编码,使其转化为一个语义编码C,这个C中就储存了序列<x1,x2,x3…xn>的信息。
Encoder究竟是如何编码的呢?
编码方式有很多种,在文本处理领域主要有RNN/LSTM/GRU/BiRNN/BiLSTM/BiGRU,可以依照自己的喜好来选择编码方式,这也是为什么我在之前的博客里先写了RNN/LSTM/GRU的详解,不搞懂RNN/LSTM/GRU的原理,这个Encoder部分那肯定是看不懂地。
我们以RNN为例来具体说明一下:
以上图为例,输入<x1,x2,x3,x4>,通过RNN生成隐藏层的状态值<h1,h2,h3,h4>,如何确定语义编码C呢?最简单的办法直接用最后时刻输出的ht作为C的状态值,这里也就是可以用h4直接作为语义编码C的值,也可以将所有时刻的隐藏层的值进行汇总,然后生成语义编码C的值,这里就是C=q(h1,h2,h3,h4),q是非线性激活函数。
得到了语义编码C之后,接下来就是要在Decoder中对语义编码C进行解码了。
Decoder:解码器,根据输入的语义编码C,然后将其解码成序列数据,解码方式也可以采用RNN/LSTM/GRU/BiRNN/BiLSTM/BiGRU。Decoder和Encoder的编码解码方式可以任意组合,并不是说我Encoder使用了RNN,Decoder就一定也需要使用RNN才能解码,Decoder可以使用LSTM,BiRNN这些。
Decoder究竟是如何解码的呢?
基于seq2seq模型有两种解码方式:
[论文1]Cho et al., 2014 . Learning Phrase Representations using RNN Encoder-Decoder for Statistical Machine Translation.
论文1中指出,因为语义编码C包含了整个输入序列的信息,所以在解码的每一步都引入C。文中Ecoder-Decoder均是使用RNN,在计算每一时刻的输出yt时,都应该输入语义编码C,即ht=f(ht-1,yt-1,C),p(yt)=f(ht,yt−1,C)。ht为当前t时刻的隐藏层的值,yt-1为上一时刻的预测输出,作为t时刻的输入,每一时刻的语义编码C是相同地。
[论文2]Sutskever et al., 2014. Sequence to Sequence Learning with Neural Networks.
论文2的方式相对简单,只在Decoder的初始输入引入语义编码C,将语义编码C作为隐藏