机器翻译及实践 初级版:含注意力机制的编码器—解码器模型


前言

本博客为笔者NLP实验课内容。
行文逻辑如下:
1.介绍2个重要的前置知识:Seq2Seq和注意力机制
至于更基础的词嵌入、RNN等前置知识可看前一篇博客或自行学习
2.实践:法英翻译(使用含注意力机制的编码器—解码器)


一、什么是机器翻译?

其实就是我们所说的翻译,也就是把一句话由一种语言翻译成另一种语言。

按理来说最容易理解的方法是构造一个映射关系或字典,把一个语言中的每个词与另一种语言一一对应起来。但实际实行起来难度很大

一是词太多;
二是对于词组,短语这种含多个词,每个词分开分别有各自的意思,合起来又是另一种意思这种情况很难处理;
还有,输入输出的序列长度不一致,例如输入3个词,输出可能4个词。

以上这些难点都需要我们去考虑,故基于此,我们开始我们本次的实验。

二、所需要的前置知识

延续前一篇博客的传统,本部分还是按照what—why—how的逻辑进行介绍。
how部分主要讲解实现原理,具体代码实现会放在第三节即实践部分进行讲解。

(一).Seq2Seq

1.什么是Seq2Seq

简单的描述其功能就是:利用编码器把a变为b,再利用解码器把b变成c。

输入序列->Seq2Seq->输出序列

在我看来,任何的Seq2Seq都是在做”翻译“,只不过翻译出的“语言”不一样。
比如,输入1,1,1,输出2,2。这也是一种翻译啊!

下面是一个简单的基于Seq2Seq的翻译模型。
在这里插入图片描述
可以看到,一个Seq2Seq模型由两部分组成,编码器和解码器。
输入语句通过编码器生成C(背景变量),需要注意的是,这个C是定长的。然后解码器用C生成翻译。
是不是很想知道他们到底内部的运行机理?别急,咱按规矩,what后得将why,哈哈。

2.机器翻译为什么要用Seq2Seq

1.最直观的理由是他能处理变长数据:在翻译时,输入语言的长度和输出语言的长度是不一样的。
可是简单的RNN也能处理变长数据,为什么不用它?
2.因为Seq2Seq模型相较于RNN在翻译任务中有自己的优势
(1)处理变长序列:Seq2Seq模型专门设计用于解决序列到序列的转换问题,自然地处理变长输入和输出。编码器将输入序列压缩成一个上下文向量,而解码器则从这个向量生成可变长度的输出序列。
(2)捕捉依赖关系:在自然语言中,单词间存在复杂的依赖关系,这些关系对正确翻译至关重要。Seq2Seq模型通过循环神经网络(RNN)或更先进的长短时记忆网络(LSTM)来捕捉长距离的依赖关系。这些网络结构能够存储和访问前文信息,有助于生成准确和连贯的翻译。
(3)端到端的学习:Seq2Seq模型采用端到端的训练方式,直接从输入和输出对中学习翻译函数。这种方法简化了模型的设计和训练过程,因为不需要人工设计特征或规则。通过大量的训练数据,Seq2Seq模型可以自动学习词汇、语法和语义层面的复杂映射关系。

3.如何使用Seq2Seq

还是结合此图进行讲解:
在这里插入图片描述

3.1编码器的实现

我们的目的是让编码器生成一个定长的背景变量 c \boldsymbol{c} c

我们可以看到,如果我们让编码器每个步骤都有一个输出,类似这样:在这里插入图片描述

是不是跟RNN一模一样了!!!那他具体的参数更新等等是不是都明白了?
或者你把他换成双向循环神经网络,LSTM,GRU都行(在我的眼中他们是属于加强版的RNN,本质上没啥大的区别)。

虽然说到这基本上可以结束了,但咱们还是得用数学公式把他描述的严谨点。

假设我们使用的是循环神经网络

输入序列是 x 1 , … , x T x_1,\ldots,x_T x1,,xT,批量大小为1,例如 x i x_i xi是输入句子中的第 i i i个词。在时间步 t t t,循环神经网络将输入 x t x_t xt的特征向量 x t \boldsymbol{x}_t xt和上个时间步的隐藏状态 h t − 1 \boldsymbol{h}_{t-1} ht1变换为当前时间步的隐藏状态 h t \boldsymbol{h}_t ht。我们可以用函数 f f f表达循环神经网络隐藏层的变换:

h t = f ( x t , h t − 1 ) . \boldsymbol{h}_t = f(\boldsymbol{x}_t, \boldsymbol{h}_{t-1}). ht=f(xt,ht1).

接下来,编码器通过自定义函数 q q q将各个时间步的隐藏状态变换为背景变量

c = q ( h 1 , … , h T ) . \boldsymbol{c} = q(\boldsymbol{h}_1, \ldots, \boldsymbol{h}_T). c=q(h1,,hT).

3.2解码器的实现

还是来看这张图:在这里插入图片描述

我们现在已经得到了编码器输出的背景变量 c \boldsymbol{c} c.
其实我们观察解码器,是不是本质上还是一个RNN模型,只不过把输入改成了前一个状态的输出和背景变量 c \boldsymbol{c} c,那么参数的更新啥的,也是一样的。

还是跟上面一样,为了严谨,结合数学公式讲解:

给定训练样本中的输出序列 y 1 , y 2 , … , y T ′ y_1, y_2, \ldots, y_{T'} y1,y2,,yT,对每个时间步 t ′ t' t(符号与输入序列或编码器的时间步 t t t有区别),解码器输出 y t ′ y_{t'} yt的条件概率将基于之前的输出序列 y 1 , … , y t ′ − 1 y_1,\ldots,y_{t'-1} y1,,yt1和背景变量 c \boldsymbol{c} c,即 P ( y t ′ ∣ y 1 , … , y t ′ − 1 , c ) P(y_{t'} \mid y_1, \ldots, y_{t'-1}, \boldsymbol{c}) P(yty1,,yt1,c)

这个P其实就是当前词预测正确的概率,我们要最大化这个P。

为此,我们可以使用另一个循环神经网络作为解码器。在输出序列的时间步 t ′ t^\prime t,解码器将上一时间步的输出 y t ′ − 1 y_{t^\prime-1} yt1以及背景变量 c \boldsymbol{c} c作为输入,并将它们与上一时间步的隐藏状态 s t ′ − 1 \boldsymbol{s}_{t^\prime-1} st1变换为当前时间步的隐藏状态 s t ′ \boldsymbol{s}_{t^\prime} st。因此,我们可以用函数 g g g表达解码器隐藏层的变换:

s t ′ = g ( y t ′ − 1 , c , s t ′ − 1 ) . \boldsymbol{s}_{t^\prime} = g(y_{t^\prime-1}, \boldsymbol{c}, \boldsymbol{s}_{t^\prime-1}). st=g(yt1,c,st1).
(其实我们就是要更新这个 g ,从而使得 P 变大) (其实我们就是要更新这个g,从而使得P变大) (其实我们就是要更新这个g,从而使得P变大)
有了解码器的隐藏状态后,我们可以使用自定义的输出层和softmax运算来计算 P ( y t ′ ∣ y 1 , … , y t ′ − 1 , c ) P(y_{t^\prime} \mid y_1, \ldots, y_{t^\prime-1}, \boldsymbol{c}) P(yty1,,yt1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值