|
**基础的序列到序列
序列1到序列2,也叫一个序列对 (序列1,序列2)
在预测的时候,要求输入序列1,能输出序列2,序列2的预测过程大致是这样的:
根据序列1的信息,预测出序列2的第一个单词,
然后计算第一个单词在当前序列1的场景下,最大概率会出现哪个单词,
然后就这么一个单词一个单词却预测下去...
有人说如果第一个单词预测错了,那后面的就全完了...
(有小概率,在错误的道路上再犯错,又回到正确道路上了...负负又得正了...仅人个观点...)
预测的序列是一个生成的过程,且依据的是概率...
也有人把这个过程比喻为“狗尾续貂”...
可以做的事情有:
翻译:标准的序列到序列
对话:对话机器人,尬聊,智能客服
信息提取:压缩,降维,文章摘要自动生成,自编码器
语音识别:声音信号转文本
无线信号处理
序列到序列+注意力
RNN提取特征,
注意力作为一个辅助
基于注意力的序列到序列
注意力提取特征,
整体流程与基础的序列到序列一致
transformer
注意力提取特征,
整体流程与基础的序列到序列 大致/大方向 一致
增加/改变了一些地方
下面这篇文章 以时间线 介绍了 传统NLP的发展历程,从最早的分词到2017年问世的transformer
<a href="https://blog.csdn.net/v_JULY_v/article/details/127411638" target="_blank">Transformer通俗笔记:从Word2Vec、Seq2Seq逐步理解到GPT、BERT</a>
mytab('ulseq_char', 'tbseq_char');
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可以设计到上千层...
缺点也有,因为每次计算改变量小,所以需要计算很多很多次...
参考
|