机器翻译:基础与模型学习笔记——神经机器翻译
人工神经网络和神经语言建模
深度学习与人工神经网络
提到神经网络,绕不开的两个关键词便是深度学习和分布式表示。分布式早期的思想是“一个复杂系统任何部分的输入都应该是多个特征共同表示的结果”。也就是说,通过将单词、短语等数据转化成向量作为模型的输入,从而代表整个个体。
对数据进行分布式处理后,利用深度神经网络进行端到端的学习,形成输入-特征提取-分类-输出的流水线,性能优于传统模型,最新的transformer对常用的PTB数据集上的困惑度结果进步巨大。
神经网络基础
想要做到端到端的学习,一定要统一输入的格式,也就是输入数据的范数相同。范数的常见表达式如下:
lp(x)==∥x∥p(∑i=1n∣xi∣p)p1
其中最为常见的就是l1和l2范数(欧几里得范数)。广义上将,范数是将向量映射到非负值的函数,起作用是衡量向量x到坐标原点的距离。当然对矩阵进行大小衡量时,Frobenius范数更加适用。
下面对特征提取+分类部分进行分析。从初始的感知机到多层神经网络,激活函数起到了重要的作用。常见的激活函数类型如下所示:
- Softplus:可以看作是ReLU函数的平滑,和脑神经元的激活频率函数相似;
- Sigmoid:早期的神经网络输出层中较为普遍,常用于实现二分类,但是对复杂特征处理的不是很好,逐渐被ReLU代替;(梯度消失、不以0为中心)
- tanh:经常和Sigmod同时出现在二分类模型,位于输出层(梯度消失)
- ReLU:修正线性单元,改善了梯度消失问题,加速了收敛速度。(Dead ReLU问题、不以0为中心)
- Gaussian:任何地方可微,具有良好的梯度,容易收敛;(复杂、易过拟合、局部最小值优化困难);
- Identity:在实际情况中很少使用;
神经网络的张量实现
说是张量,其实看成多维数组就完事了,不过确实有个点需要注意:
张量之间的计算:
除了简单的矩阵相乘、相加等操作,还有广播机制:如果两个数组的后缘难度的轴长度相符或其中一方的长度为1,则认为他们是广播兼容的。这里多说无益,通过下图可以了解。
神经网络的参数训练
参数通过训练集进行训练,训练的结果和实际结果进行比较,根据损失函数度量模型的好坏。基于损失函数的微调也十分常见。
设计好了评价标准,如何调优参数呢?这里涉及到了梯度的概念,梯度下降法向着变化最大的方向进行优化,也就是损失函数更小的方向移动,从而获得最优解。
**批量梯度下降:**每一次迭代所有样本进行参数更新,显然更新的成本很大。
J(θ)=n1i=1∑nL(x[i],y[i];θ)
**随机梯度下降:**每次迭代只使用一个样本对参数进行更新,这样导致了收敛缓慢。
**小批量梯度下降:**如何避免上述两个问题?利用部分随机样本进行参数优化。这里将数据划分成不同的批次进行计算,充分利用GPU。
J(θ)=m1i=j∑j+m−1L(x[i],y[i];θ)
基于梯度的方法,产生了许多改进的优化器:
**Momentum:**对原有的梯度下降进行了加权平均处理,考虑前几层的更新时产生的梯度动量变化,使下降的过程更加平滑。
vtθt+1==βvt−1+(1−β)∂θt∂Jθt−αvt
**AdaGrad:**基本思想是构造学习率衰减,使得模型快速收敛。但是中后期梯度的平方过大,很有可能使得结果提前收敛,因此对数据的特点要求比较高。
ztθt+1==zt−1+∂θt∂J⋅∂θt∂Jθt−ηzt1⋅∂θt∂J
**RMSProp:**对AdaGrad算法进行改进,在迭代过程中学习率变化比较随机,避免了过早衰减。
ztθt+1==γzt−1+(1−γ)∂θt∂J⋅∂θt∂Jθt−zt+ϵη⋅∂θt∂J
**Adam:**真正的缝合,上诉所有算法的合并结果。当然,初始的学习率还是通过人工进行设置的。
vtztθt+1===βvt−1+(1−β)∂θt∂Jγzt−1+(1−γ)∂θt∂J⋅∂θt∂Jθt−zt+ϵηvt
基于循环神经网络的模型
神经机器翻译的发展简史
相较于前一时期的统计机器翻译,神经机器翻译有较多的优点:
- 离散和连续的区别:传统的统计机器翻译模型关注于如何利用词串之间的组合性来表示更大的词串。
- 隐含结构假设:在每一次模型建立前都会进行假设,如IBM模型的三大假设,在后续的迭代过程中就是对假设进行更改。显而易见的是,更改假设并没有完全解决差异问题。
- 特征工程和网络设计:对词组的组合进行数学表述需要构建特征,普适性很差。
- 规则集:耗费成本大。
编码器-解码器框架
说白了就是加了个编译器的中间代码生成,承上启下,将离散化的数据转化成连续空间的信息,便于计算特征和求解,解码器根据得到的向量进行预测。
基于循环神经网络的翻译建模
从数学模型上看,神经机器翻译的目标和统计模型目标一样,即在源语言确定条件下的最佳译文:
y^=argmaxyP(y∣x)P(y∣x) = j=1∏nP(yj∣y<j,x)
计算后验概率,循环神经网络正合适:
- 词嵌入:one-hot编码转为实数向量;
- 源序列表示:词向量通过RNN的最后输出;
- 目标序列生成:softmax获取所有单词分布,计算输出;
softmax方法和onehot不再赘述,关注点在于RNN的原序列的表示,这里每一个神经元的输出都可以描述为:
ht=f(xtU+ht−1W+b)
其中f为激活函数,h为当前的向量状态。很明显,如果处理较长的序列(长文本生成),RNN很容易产生遗忘现象,因此推出LSTM:
- 遗忘门:忘记部分历史,其中Wf、bf分别为权值和偏置,人为进行设定,最终得到的ft代表历史信息能够进入神经元计算的有多少;
- 输入门:生成需要添加的信息,其中it是门控参数,代表当前信息能够进入神经元计算的有多少;ct代表当前输入的总信息是多少;
- 记忆更新:对当前信息进行汇总,由选择的历史信息和选择的输入构成;
- 输出:最后利用前一个状态、当前输入和当前选择获得信息获取最终输出;
说实话我觉得上面的过程比较冗杂,之后提出的GRU参数更少,是常见的模型,为双向模型生成文本提高了效率。
注意力机制
核心:针对不同目标语言单词生成不同的上下文向量,对接收到的信息进行甲醛处理,对更重要的信息赋予更高的权重即更高的关注度,弱化贡献度较低的信息对结果的影响。上下文向量求解如下所示:
Cj=i∑αi,jhi
那么,权重是如何计算的呢?
- 计算hi和当前位置上一个单元的目标语言输出的相关性,方法很多:向量乘、余弦相似度等等;
- 利用softmax归一化得到权重;
在softmax阶段,transformer论文中相关性被描述为qkv的表述形式:
Attention(Q,K,V)=Softmax(dkQK⊤)V
qkv是通过同样的输入矩阵X线性变换得到的,这里整体利用了模糊搜索的思想,将q和k进行相似度的计算,查询的结果也不再是计算出来的v,而是所有单元加权得到的v。
训练及推断
整体:采用的还是梯度下降的方法更新参数,需要探讨的是损失衡量、参数初始化以及优化。
**损失函数:**常用交叉熵损失函数,和softmax的适配性很好(softmax将输出转化成概率分布,交叉熵能够衡量不同分布的距离)
基于卷积神经网络的模型
卷积神经网络已经很熟悉了,但是我属实没想到会和自然语言处理相关,因为之前的项目涉及的方法要么是基于RNN,要么是基于transformer。卷积神经网络最大的特点在于具有局部连接和权值共享的特性。
常见的卷积神经网络包括基本的填充和卷积操作,其中填充是对初始特征矩阵边缘进行0扩充,从而保证部分边缘特征在结果中放大。
在生成不定长序列的过程中,全连接层进行输出明显是不行的。因此,针对一维序列的卷积方法使用多个不同的卷积核来对序列进行特征提取。需要注意的是,卷积核是不同含义的词嵌入,用于提取相似的特征。给我的感觉就像是缩句。
翻译模型的卷积实现
常见的卷积实现的翻译模型就是ConvS2S模型,利用卷积神经网络分别对源语言端和目标语言端的序列进行特征提取。模块构成如下图所示:
下面对各个模块的功能进行梳理:
位置编码:基础的词嵌入+位置编码,为了更好地引入词序信息,模型引入了位置编码p。编码的维度和词嵌入的维度相同,主要是将位置信息进行表示,不同序列中的相同位置都对应一个位移的位置编码向量。
门控卷积神经网络:门控部分主要是有激活函数构成,对于多个卷积核得到的结果,我们如何进行取舍呢?通过门控单元我们可以对卷积输出进行控制,确定保留哪些信息。下例就对门控进行了解释:
AB==x∗W+bWx∗V+bVy=A⊗σ(B)
其中W,V分别代表两个卷积核,其中b代表偏置矩阵,对于结果y,他是通过A和B的按位乘运算得到的。需要注意的是,激活函数将B映射为0-1范围内的实数。
残差网络:底层信息传递上层。第i层的输入hi等于第i-1层的输出F(i-1)加上第i-1层的输入h(i-1)。
hl+1=F(hl)+hlhl+1=Al⊗σ(Bl)+hl
多步注意力机制:多步体现在ConvS2S选用了点乘注意力,通过类似残差链接的方式奖注意力操作的输入和输出同时作用于下一层的计算。
αijl=∑i′=1mexp(hi′djl)exp(hidjl)
其中hi代表源语言端第i个位置的隐藏层状态,而dj:
djlzjl==zjlWdl+bdl+gjConv(sjl)
zj代表第l层卷积网络输出中第j个位置的表示,sj为源语言的j位置表示,gj代表目标语言端的词嵌入,Conv代表卷积操作。
基于自注意力的模型
背景:基本的卷积神经网络和循环神经网络在多层进行信息传递时往往会产生偏差,损失较大。究其原因就是对词嵌入之间的依赖关系没有把握准确。
由于上文已经对注意力机制的公式推导进行了详细的论述,这里直接对transformer模型进行介绍。
编码器:自注意力子层、前馈神经网络、残差连接(从输入直接到输出的额外连接)和层标准化。
解码器:引入了编码-解码注意力子层,相较于编码器的注意力子层,这里完成了调序的工作,帮助模型使用源语言句子的标识信息生成目标语言不同的位置信息。
基于点乘的多头注意力机制
上述结构中的注意力模块就是通过点乘实现的,下面我们对公式进行分布讲解:
Attention(Q,K,V)=Softmax(dkQKT+Mask)V
首先对Q和转置之后的K进行点乘操作,提高运算效率的同时得到句子内部各个位置之间的相关性,接着进行放缩减小相关性矩阵的方差,MASK遮盖矩阵中的无用信息,最后归一化,进行模糊搜索。
多头注意力机制
原理:将qkv平均分成h份,每一份进行独立计算。最后将h个头注意力输出在最后一维dv进行拼接,通过线性变换获得结果。这样分成k个子空间方便使用不同的方法进行学习。
MultiHead(Q,K,V)=Concat(head1,...,headh)Woheadi=Attention(QWiQ,KWiK,VWiV)
掩码操作
两部分,分别为句长补全掩码和未来信息掩码,前者是在词对齐时产生的无用信息,后者是从左到右进行翻译的顺序决定了后续信息无用。
相关知识
Frobenius范数
常用于衡量矩阵的大小,得到矩阵到原点的距离。
AF=i,j=1∑n∣aij∣2
对ReLU的改善
leakly ReLU、P-ReLU。
Nesterov加速梯度下降法
利用历史梯度信息下降梯度:
wt+1=wt−αvtvt=βvt−1+(1−β)∂(wt−αβvt−1)∂J(wt)
看起来和之前用的基于向量的梯度下降方法很类似,但是该方法使用的梯度不是来自当前参数位置,而是前一个状态的二阶导,算是保留了更多的历史信息。
Future Work