序列到序列的发展

基础的序列到序列

 
序列1到序列2,也叫一个序列对 (序列1,序列2)
在预测的时候,要求输入序列1,能输出序列2,序列2的预测过程大致是这样的:
根据序列1的信息,预测出序列2的第一个单词,
然后计算第一个单词在当前序列1的场景下,最大概率会出现哪个单词,
然后就这么一个单词一个单词却预测下去... 
有人说如果第一个单词预测错了,那后面的就全完了...
(有小概率,在错误的道路上再犯错,又回到正确道路上了...负负又得正了...仅人个观点...)

预测的序列是一个生成的过程,且依据的是概率... 
也有人把这个过程比喻为“狗尾续貂”... 

 
可以做的事情有:
翻译:标准的序列到序列
对话:对话机器人,尬聊,智能客服
信息提取:压缩,降维,文章摘要自动生成,自编码器
语音识别:声音信号转文本 
无线信号处理

序列到序列+注意力

 
RNN提取特征,
注意力作为一个辅助

基于注意力的序列到序列

 
注意力提取特征,
整体流程与基础的序列到序列一致 

transformer

 
注意力提取特征,
整体流程与基础的序列到序列 大致/大方向 一致 
增加/改变了一些地方 

 

    

 

    

 
下面这篇文章 以时间线 介绍了 传统NLP的发展历程,从最早的分词到2017年问世的transformer 
Transformer通俗笔记:从Word2Vec、Seq2Seq逐步理解到GPT、BERT

 

    

 


 

  

 


transformer基础逻辑

数据的样子

 
import jieba

seq1= "你现阶段的目标是?"
seq2=  "不上班还有钱花"

sentence1 = jieba.lcut(seq1)
word2id = {}
word2id["PAD"] = 0  # 补长度 是为了批次处理
len_add = len(word2id)
word2id.update({word:(index+len_add) for index,word in enumerate(set(sentence1))}) 


sentence2 = jieba.lcut(seq2)
len_add = len(word2id)
word2id.update({word:(index+len_add) for index,word in enumerate(set(sentence2))})

解码序列每个单词与编码序列所有单词的关系

 
sentence1
['你', '现阶段', '的', '目标', '是', '?']

sentence2
['不', '上班', '还有', '钱花']

核心:求sentence2每个单词 相对sentence1所有单词的注意力/特征 
输入:sentence1,sentence2
输出:[seq_len2,embedding_dim]矩阵,每个维数为embedding_dim的向量都是 sentence2相应单词 相对sentence1的特征向量

 
如此,编码序列的单词向量一定程度上包含有本身与整个句子之间的信息,

除了解码序列相对编码序列外,
还有解码序列相对解码序列,编码序列相对编码序列
这三组关系,也是需要去训练,让模型去学习的

解码序列前一个单词与后一个单词的关系

 
编码序列预测出 解码序列的第1个单词:['你', '现阶段', '的', '目标', '是', '?'] -- ['不']

然后依次为:
['你', '现阶段', '的', '目标', '是', '?'] +  ['不'] -- [ '上班']

['你', '现阶段', '的', '目标', '是', '?'] + ['不', '上班']  -- ['还有']

['你', '现阶段', '的', '目标', '是', '?'] + ['不', '上班', '还有']  -- ['钱花']

['你', '现阶段', '的', '目标', '是', '?'] + ['不', '上班', '还有', '钱花']  -- OVER

解码序列相对解码序列的自注意力

 
补码的意义在于去掉PAD
编码序列的每个单词 对应编码序列的所有单词
但解码序列是 已知的所有单词生成下一个单词,再后面的单词是未知的,尚不清楚... 

训练时拿到了全体数据库,是知道的,是程序员知道...
但训练的过程是生成式的,即参数学习...修改的过程...只涉及已生成的单词,程序只知道已生成的

你说程序还不是人设计的,就给它设计成提前知道所有单词,让参数直接学习解码器的所有单词,
在预测时,才使用已知单词,这样可以吗?
这是本人的另外一个猜测,尚未实验...但猜测是可行的,说不定更快... 

未来大概率发生的事,大概率会成真... 预定的未来... 

transformer的主逻辑

 
x0  -- 编码序列相对编码序列的自注意力 -- x1 
y0  -- 解码序列相对解码序列的自注意力 -- y1 

y1 相对x1 的注意力 y2 

y2 -- 线性变换+激活函数处理 -- y3 

y3 -- 全连接分类,映射到单词词典的标签索引上 -- y4 

y4中最大值索引对应词典的单词,即模型要预测的单词 

transformer与seq to seq的核心差异

seq to seq简要回顾

 
seq to seq 是在RNN的基础上发展而来的,
RNN的缺点是上下文依赖能力弱,它做出的改良方案是:
想办法让解码序列的每个元素带上编码序列的信息

实施细节
求编码序列的上下文向量,然后让解码序列的每个单词与 这个上下文向量,拼接,注意是拼接 

效果
比RNN有明显提升,但仍然处理不了太长的序列 

transformer做出的改良/改变

 
seq to seq 处理不了太长序列的原因是什么?
是梯度消失,
由于参与计算的数值大多是0-1之间,大于1则会梯度爆炸,小于0,
计算层多了,梯度就消失了,数据算着算着也没了,或固定不变

尽管有BN,层归一化等技巧,但效果仍不好,

终于,transformer来了... 

将拼接改为  相加+ 

数据流过多个层之后,变得小了,那么就加到原来的数据层上,让原来的数据产生微小的改变

数据每经过一次注意力计算,就产生一次微小的改变,这也叫短接,一条计算路径长,一条计算路径短

至于梯度,梯度以短路径的梯度为主,因为长路径的梯度消失了... 

这就从根本上解决了梯度消失的问题,所以transformer可以设计到上千层... 

缺点也有,因为每次计算改变量小,所以需要计算很多很多次... 

参考