目录
- NLP三大特征抽取器(CNN/RNN/TF)比较
- 1. NLP任务
- 1.1 NLP任务特点
- 1.2 NLP任务类型
- 2. RNN
- 2.1 为什么RNN能够成为解决NLP问题的主流特征抽取器?
- 2.2 RNN目前面临的两个严重问题
- 3. CNN
- 3.1 早期CNN模型结构
- 3.2 目前主流CNN模型
- 4. Transformer
- 4.1 论文来源:Attention is all you need
- 4.2 Tansformer的组成
- 4.3 Transformer效果好的原因
- 4.4 Transformer针对NLP任务特点的解决方案
- 4.5 Transformer两个版本
- 4.6 Transformer问题
- 5. CNN,RNN,Transformer实验对比
- 5.1 语义特征提取能力
- 5.2 长距离特征捕获能力
- 5.3 任务综合特征抽取能力
- 5.4 并行计算能力及运行效率
- 6. CNN,RNN,Transformer三者融合策略
- 6.1 Bi-RNN融入Transformer BLock
- 6.2 CNN融入Transformer BLock
NLP三大特征抽取器(CNN/RNN/TF)比较
参考知乎张俊林:https://zhuanlan.zhihu.com/p/54743941
1. NLP任务
1.1 NLP任务特点
- 输入是一个线性序列
- 输入是不定长的
- 单词或句子的相对位置关系很重要,两个词位置互换可能导致完全不同的意思
- 句子中的长距离特征对于理解语义非常关键
特征抽取器是否具备长距离特征捕获能力对于解决NLP任务十分关键。
1.2 NLP任务类型
- 序列标注
- 分词、POS Tag、NER、语义标注。。。
- 特点:句子中每个单词要求模型根据上下文都要给出一个分类类别。
- 分类任务
- 文本分类、情感计算。。。
- 特点:不管文章有多长,总体给出一个分类类别即可。
- 句子关系判断
- Entailment、QA、语义改写、自然语言推理。。。
- 特点:给定两个句子,模型判断出两个句子是否具备某种语义关系。
- 生成式任务
- 机器翻译、文本摘要、看图说话、写诗造句。。。
- 特点:输入文本内容后,需要自主生成另外一段文字。
2. RNN
核心是每个输入对应隐层节点,而隐层节点之间形成了线性序列,信息由前向后在隐层之间逐步向后传递。
2.1 为什么RNN能够成为解决NLP问题的主流特征抽取器?
- 典型的RNN应用技术
- 原始的RNN存在问题
- 反向传播路径长,存在优化困难,导致梯度消失或梯度爆炸
原始的RNN采取线性序列结构不断从前往后收集输入信息,但这种线性序列结构在反向传播的时候存在优化困难问题,因为反向传播路径太长,容易导致严重的梯度消失或梯度爆炸问题。
- 引入LSTM和GRU模型
- 增加中间状态信息直接向后传播,缓解梯度消失
- Attention机制
- 叠加网络,加深网络深度
- Encoder-Decoder框架
- RNN特别适合NLP这种线性序列应用场景
- RNN结构是一个可以接纳不定长输入的由前向后进行信息线性传导的网络结构。
- 引入LSTM和GRU的门控单元后,对于捕获长距离特征非常有效。
2.2 RNN目前面临的两个严重问题
- RNN的并行技术能力差
- 原因
- RNN本质特征:T时刻的隐藏状态St依赖T-1时刻的隐藏状态S(t-1)的输出,这就形成了序列依赖关系。
只能先把第1时间步的算完,才能算第2时间步的结果,造成RNN无法并行计算,只能按照时间步一个单词一个单词往后走。
CNN和Transformer不存在这种序列依赖问题,并行计算能力不是问题,每个时间步的操作可以并行一起计算。
- 改进
改进RNN并行计算的思路,即选择打断还是不打断隐层连接的问题。
如果选择打断,RNN本质上是CNN模型,在打断片段里仍然采取RNN结构,这样无疑会拉慢速度,所以这是个两难的选择,与其这样不如直接换成其它模型。
如果选择不打断,貌似只能在隐层神经元之间进行并行,而这样做的缺点是:一方面并行能力上限很低;另外一方面里面依然存在的序列依赖估计仍然是个问题。
- 思路1:仍然保留任意连续时间步(T-1到T时刻)之间的隐层连接
- 改进1:SRU,但并行程度上限
论文“Simple Recurrent Units for Highly Parallelizable Recurrence”中提出的SRU方法,它最本质的改进是把隐层之间的神经元依赖由全连接改成了哈达马乘积,这样T时刻隐层单元本来对T-1时刻所有隐层单元的依赖,改成了只是对T-1时刻对应单元的依赖,于是可以在隐层单元之间进行并行计算,但是收集信息仍然是按照时间序列来进行的。所以其并行性是在隐层单元之间发生的,而不是在不同时间步之间发生的。
- 思路2:部分打断连续时间步(T-1到T时刻)之间 的隐层连接
- 改进2:Sliced RNN
部分打断,比如每隔2个时间步打断一次,通过层深来建立远距离特征之间的联系。
Sliced RNN本质上是简化版本的CNN。论文给出了速度对比实验,SRNN速度比GRU模型快5到15倍,但比DC-CNN模型仍然平均慢了大约3倍。
- 新模型的出现
3. CNN
3.1 早期CNN模型结构
最早将CNN引入NLP的是Kim在2014年做的工作,论文Convolutional neural networks for sentence classification。
结构特点:1个输入层,1个卷积层,1个Pooling层,一个输出层。
- 结构
- 输出层
- Pooling层
- 降维
Pooling 层则对Filter的特征进行降维操作,形成最终的特征。一般在Pooling层之后连接全联接层神经网络,形成最后的分类过程。
- 卷积层
- filters
特征抽取层,设定参数F指定卷积层包含多少个卷积核(filter)。
对于某个Filter来说,可以想象有一个d*k大小的移动窗口从输入矩阵的第一个字开始不断往后移动,其中k是Filter指定的窗口大小,d是Word Embedding长度。对于某个时刻的窗口,通过神经网络的非线性变换,将这个窗口内的输入值转换为某个特征值,随着窗口不断往后移动,这个Filter对应的特征值不断产生,形成这个Filter的特征向量。这就是卷积核抽取特征的过程。
- 输入层
- word embedding
输入的字或者词用Word Embedding的方式表达,这样本来一维的文本信息输入就转换成了二维的输入结构,假设输入X包含n个字符,而每个字符的Word Embedding的长度为d,那么输入就是d*n的二维向量。
- 存在问题
- 无法捕获远距离特征
原始的CNN网络(Kim)的单卷积层无法捕获长距离特征。
- 改进
- 方法1:Dilated CNN捕获长距离特征
CNN捕获特征的关键在于卷积核覆盖的滑动窗口(大小为k),捕获到的是单词的k-gram片段信息,k决定能捕获多远距离的特征。
仍然使用单个卷积层,滑动窗口大小k为3,只能接受3个输入单词,但是要捕获距离为5的特征,如果卷积核窗口仍然覆盖连续区域,肯定不行。Dilated CNN采取跳跃覆盖的策略,比如在k=3,从输入X1开始,跳着选,第二个是X3,第三个是X5。 - 方法2:增大卷积核的kernel size,加深CNN网络深度,以此来增加输入的长度覆盖
- Max Pooling层抛弃了位置信息
Max Pooling层,这块其实与CNN能否保持输入句子中单词的位置信息有关系。
RNN因为是线性序列结构,所以很自然它天然就会把位置信息编码进去。
CNN的卷积核是能保留特征之间的相对位置的,滑动窗口从左到右滑动,捕获到的特征也是如此顺序排列,所以它在结构上已经记录了相对位置信息了。但是如果卷积层后面立即接上Pooling层的话,Max Pooling的操作逻辑是:从一个卷积核获得的特征向量里只选中并保留最强的那一个特征,所以到了Pooling层,位置信息就被扔掉了,这在NLP里其实是有信息损失的。
- 改进
- 抛弃Pooling层,靠全卷积层来叠加网络深度
3.2 目前主流CNN模型
CNN的主体结构,通常由1-D卷积层来叠加深度,使用Skip Connection来辅助优化,也可以引入Dilated CNN等手段。
- 结构特点
TCN(论文:An Empirical Evaluation of Generic Convolutional and Recurrent Networks for Sequence Modeling),集成了几项技术:利用Dilated CNN拓展单层卷积层的输入覆盖长度,利用全卷积层堆叠层深,使用Skip Connection辅助优化,引入Casual CNN让网络结构看不到T时间步后的数据。
ConvS2S结构由1-D卷积层来叠加深度,使用Skip Connection来辅助优化,引入Dilated CNN,卷积核里引入GLU门控非线性函数等手段。
- 使用Conv1D卷积层叠加深度
- 卷积核里引入GLU门控非线性函数
- 使用Skip Connection辅助优化
- 引入Dilated CNN 拓展单层卷积层的输入覆盖长度
- 引入Casual CNN让网络结构看不到T时间步后的数据
- CNN的并行计算能力强
- 对于某个卷积核来说,每个滑动窗口位置之间没有依赖关系,所以完全可以并行计算。
- 不同的卷积核之间也没什么相互影响,所以也可以并行计算。
- CNN的位置编码
- 方法1:不用专门在输入对position进行编码:CNN的卷积层保留了相对位置信息,中间层不插入Pooling层即可。
- 方法2:在输入部分给每个单词增加一个position embedding,将单词的position embedding和词向量embedding叠加起来形成单词输入。
4. Transformer
4.1 论文来源:Attention is all you need
“Attention is all you need"论文中说的的Transformer指的是完整的Encoder-Decoder框架。
Encoder部分目的比较单纯,就是从原始句子中提取特征,而Decoder部分则功能相对比较多,除了特征提取功能外,还包含语言模型功能,以及用attention机制表达的翻译模型功能。
4.2 Tansformer的组成
Transformer的Encoder部分是由若干个相同的Transformer Block堆叠成的。
- Transformer Block
- Add & Normalize
- Feed Forward
- Add & Normalize
- Self-Attention
4.3 Transformer效果好的原因
- Multi-head self attention
- Skip Connection
- LayerNorm
- Feed Forward
4.4 Transformer针对NLP任务特点的解决方案
- 输入是不定长的
- 设定输入的最大长度,如果句子没有那么长,用Padding填充
- 位置信息编码
- Transformer在输入端将position信息用位置函数进行编码
- bert模型给每个单词一个Position embedding,再和单词embedding加起来形成单词的输入embedding
- 中长距离依赖特征
- self-attention在集成信息时使当前单词和句子中任意单词发生联系
4.5 Transformer两个版本
- Transformer base
- 12个Block叠加
- Transformer Big
- 24个Block叠加
4.6 Transformer问题
- 计算复杂度
- 对于长输入的任务,Transformer的计算复杂度O(n^2*d)巨大,导致速度慢
- 改进方向:把长输入切断分成K份,强制把长输入切短,再套上Transformer作为特征抽取器,高层可以用RNN或者另外一层Transformer来接力,形成Transformer的层级结构,这样可以把n平方的计算量极大减少。
- Transformer整体结构复杂
- 改进方向:深刻认识作用机理,简化结构。
5. CNN,RNN,Transformer实验对比
5.1 语义特征提取能力
- Transformer>>原生CNN==原生RNN
原生的RNN和CNN模型,就是说可以在经典的结构上增加attention,堆叠层次等各种改进,但是不包含对本身结构特别大的变动。
从语义特征提取能力来说,目前实验支持如下结论:Transformer在这方面的能力非常显著地超过RNN和CNN(在考察语义类能力的任务WSD中,Transformer超过RNN和CNN大约4-8个绝对百分点),RNN和CNN两者能力差不太多。
5.2 长距离特征捕获能力
- Transformer>原生RNN>>原生CNN
在长距离特征捕获能力方面,目前在特定的长距离特征捕获能力测试任务中(主语-谓语一致性检测,比如we………are…),实验支持如下结论:原生CNN特征抽取器在这方面极为显著地弱于RNN和Transformer,Transformer微弱优于RNN模型(尤其在主语谓语距离小于13时),能力由强到弱排序为Transformer>RNN>>CNN; 但在比较远的距离上(主语谓语距离大于13),RNN微弱优于Transformer,所以综合看,可以认为Transformer和RNN在这方面能力相近,而CNN则显著弱于前两者。
5.3 任务综合特征抽取能力
语义特征和长距离特征作为单向能力评估,更重要的是在具体任务中引入不同特征抽取器,然后比较效果差异,以此来综合评定三者的综合能力。
机器翻译是最有代表性的任务,因为机器翻译基本上是对NLP各项处理能力综合要求最高的任务之一,要想获得高质量的翻译结果,对于两种语言的词法,句法,语义,上下文处理能力,长距离特征捕获等等更方面都需要考虑进来才行。
- (以机器翻译任务为代表)Transformer>>原生CNN==原生RNN
从综合特征抽取能力角度衡量,Transformer显著强于RNN和CNN,而RNN和CNN的表现差不太多,如果一定要在这两者之间比较的话,通常CNN的表现要稍微好于RNN的效果。
5.4 并行计算能力及运行效率
- 并行计算能力
- Transformer==原生CNN>>原生RNN
CNN和Transformer,不存在网络中间状态不同时间步输入的依赖关系,并行计算能力很强。
RNN在并行计算方面有严重缺陷,这是它本身的序列依赖特性导致的。
- 计算效率
- 单层
- 计算量:Self-attention < 原生RNN < 原生CNN
- 计算效率:Self attention > 原生RNN > 原生CNN
三者的计算量:
self-attention: O(n^2d)
原生CNN: O(knd^2)
原生RNN: O(nd^2)
n是句子长度
d是embedding size
取决于n和d的平均值哪个大。
一般情况下,句子长度小于常用的embedding size(128-512),计算量:
self-attention < RNN <CNN
- Transformer Block整体
- 计算量:Transformer Block > CNN > RNN
Transformer Block里其实包含了好几层, 其中的skip connection后的Add操作及LayerNorm操作不太耗费计算量,我先把它忽略掉,后面的FFN操作相对比较耗时,它的时间复杂度应该是O(n*d^2)。
所以如果把Transformer Block多层当作一个整体和RNN及CNN单层对比的话,计算量:
Transformer Block > CNN > RNN
- 计算速度
Transformer Base > 原生CNN > Transformer Big > 原生RNN
6. CNN,RNN,Transformer三者融合策略
6.1 Bi-RNN融入Transformer BLock
- self-attention模块用Bi-RNN替换
- 引入RNN构件会触发Transformer结构的并行计算能力问题
6.2 CNN融入Transformer BLock
- self-attention模块用CNN替换
- 引入depth-seperate CNN等新变形的CNN结构上趋同于Transformer