Lecture 7-9 机器翻译 seq2seq Attention Transformer Pretraining and Post-training (RLHF, SFT, DPO)
LSTM
RNN存在梯度消失和梯度爆炸问题(vanishing/exploding gradients) 梯度消失:由于梯度趋于零, 导致神经网络无法基于梯度更新参数 因而不能很好的更新隐状态, 失去了对于远时间步信息的”记忆” 通过使用激活函数等方法, 可以缓解这一问题, 但无法彻底解决. 因此需要考虑其他架构, 使得拥有更好的记忆能力
梯度爆炸 由于梯度溢出, 导致神经网络每次更新的”步子迈得过大”, 使得训练效果不理想, 且不稳定 解决方法:梯度裁剪 这个方法简单粗暴:
- 为梯度设定一个阈值, 作为上限
- 如果梯度范数大于预设的阈值),就缩放梯度,使它的大小等于阈值,但方向不变。
g_hat ← ∂E/∂θ
if g_hat ≥ threshold then
g_hat ← threshold / g_hat * g_hat end if
LSTMs 长短期记忆网络
LSTM 网络中引入了门控机制 , 用于控制信息的流动和保留
遗忘门
这里虽然叫遗忘门, 但其实是”记忆门”, 用来控制记忆/遗忘多少单元状态的东西 接受前一个隐状态, 通过 U_f 对当前输入进行评估, 综合计算求和, 经过 Sigmoid, 得到在区间 0 - 1内的数值 越接近 0,越遗忘;越接近 1,越保留
输入门
决定新的输入要向细胞中写入多少东西 运算方法差不多 越接近 0, 新内容写入越少; 越接近 1, 新内容写入越多.
输出门
决定当前细胞内容有多少要被输出到隐状态中 越接近 0, 代表输出门关闭, 当前状态内容输出到隐状态中越少; 越接近 1, 代表输出门打开, 当前状态内容输出到隐状态中越多.
机器翻译
传统机器翻译SMT
早期的(1950s)机器翻译的思路十分简单,通过设置大量的翻译规则,构建一个大型的双语对照表,来将源语言翻译成目标语言。这个固然简单,也自然效果很一般。因此我们不展开描述。
后来(1990s-2010s)我们有了更为先进复杂的机器翻译技术——「统计机器翻译」(Statistical Machine Translation, SMT)。
SMT的主要思想就是从大量的数据中学习一个概率模型P(y | x),其中x是源语言(source language),y是目标语言(target language),即x翻译成y的概率有多大。在翻译时,我们只需要通过求argmaxyP(y | x)就行了,即找到概率最大的那个y,就是x的最佳翻译了。 |
P(y)就是求y这个句子的概率,这就是一个语言模型(LM)。而后者P(x | y)则被称为翻译模型(TM)。LM可以通过目标语言的语料进行训练,TM则需要通过平行语料(parallel corpus,即源和目标两种语言的互相对照的语料。对于TM的学习,一般我们会进一步进行分解,考虑两种语言之间的各种对齐方式(alignment),即在原有的翻译模型上,引入一个隐变量a,得到P(x,a | y),可以理解为给定句子y,按照对齐方式a翻译成x的概率。具体什么是对齐方式alignment呢?它的意思就是在两种语言A和B之间,A的词是跟B的词怎么对应的。 |
在学习了LM和TM这两个模型之后,是不是就完事儿了呢?当然没有,别忘了公式里还有一个argmax,我们要找出最佳的翻译是什么。根据LM和TM寻找最佳y的过程,就称为“decoding”即解码。一个最直接的方法就是,遍历所有可能的y,选择概率最大的那个,当然就是最佳的翻译。明显这种方式带来的开销是我们无法忍受的。如果学习过CRF或者HMM,我们应该知道对于这种解码的过程,我们一般使用动态规划、启发式搜索的方法来处理。
统计机器翻译——SMT,在深度学习时代之前一直是机器翻译的巅峰技术。但是,SMT的门槛也是很高的,那些表现优异的SMT模型,通常都是极其复杂的,里面涉及到大量的特征工程、海量的专家知识。幸好,在深度学习时代,我们有了更好的方法:神经机器翻译(Neural Machine Translation,NMT)。
神经机器翻译(NMT)
深度学习把那些需要大量人力的工作都吃掉了。NMT就是这样,企图就是用一个简洁的神经网络结构就把机器翻译这么大的一个工程给包下来。 NMT使用的神经网络结构,是一种被称为sequence-to-sequence的结构,即seq2seq。它还有另外一个常见的名字:Encoder-Decoder结构。
seq2seq的结构的Encoder部分读取输入文本,在机器翻译中即源语言文本。通过Encoder编码成一个表示向量,即context vector,然后交给Decoder来进行解码,翻译成目标语言。在训练和预测时我们都可以使用这样的结构,没有其他的花里胡哨的东西,因此总体上看起来比SMT要简洁明了得多。
seq2seq结构详解
在Encoder端,我们将source文本的词序列先经过embedding层转化成向量,然后输入到一个RNN结构(可以是普通RNN,LSTM,GRU等等)。另外,这里的RNN也可以是多层、双向的。经过了RNN的一系列计算,最终隐层的输入,就作为源文本整体的一个表示向量,称为「context vector」。
Decoder端的操作就稍微复杂一些了。首先,Decoder的输入是什么呢?Decoder的输入,训练和测试时是不一样的! 「在训练时,我们使用真实的目标文本,即“标准答案”作为输入」(注意第一步使用一个特殊的<start>
字符,表示句子的开头)。每一步根据当前正确的输出词、上一步的隐状态来预测下一步的输出词。
预测时Encoder端没什么变化。在Decoder端,由于此时没有所谓的“真实输出”或“标准答案”了,所以只能自产自销:每一步的预测结果,都送给下一步作为输入,直至输出<end>
就结束。你会发现这时的Decoder就是一个语言模型。由于这个语言模型是根据context vector来进行文本的生成的,因此这种类型的语言模型被称为“条件语言模型”:Conditional LM。正因为如此在训练过程中,我们可以使用一些预训练好的语言模型来对Decoder的参数进行初始化,从而加快迭代过程。
很多人可能会感到疑惑:为什么在训练的时候不能直接使用这种语言模型的模式,使用上一步的预测来作为下一步的输入呢? 我们称这两种模式,根据标准答案来decode的方式为teacher forcing,而根据上一步的输出作为下一步输入的decode方式为free running。 其实,free running是可以的。从理论上没有任何的问题,但是在实践中人们发现这样训练很难实现。因为没有任何的引导,一开始会完全是瞎预测,正所谓“一步错,步步错”并且训练起来就很费劲。这个时候,如果我们能够在每一步的预测时让老师来指导一下,即提示一下上一个词的正确答案,decoder就可以快速步入正轨,训练过程也可以更快收敛。因此把这种方法称为teacher forcing。