| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 人工智能 -> Seq2Seq - 序列到序列的学习(RNN循环神经网络) -> 正文阅读 |
|
[人工智能]Seq2Seq - 序列到序列的学习(RNN循环神经网络) |
序列到序列学习(Seq2Seq)正如我们在之前中看到的,机器翻译中的输入序列和输出序列都是长度可变的。为了解决这类问题,我们设计了一个通用的”编码器-解码器“架构。本节,我们将使用两个循环神经网络的编码器和解码器,并将其应用于序列到序列(sequence to sequence,seq2seq) 类的学习任务 遵循编码器-解码器架构的设计原则,循环神经网络编码器使用长度可变的序列作为输入,将其转换为固定形状的隐状态。换言之,输入序列的信息被编码到循环神经网络编码器的隐状态中。为了连续生成输出序列的词元,独立的循环神经网络解码器是基于输入序列的编码信息和输出序列已经看见的或者生成的词元来预测下一个词元。 下图演示了如何在机器翻译中使用两个循环神经网络进行序列到序列学习。 在上图中,特定的 “<eos>” 表示序列结束词元。一旦输出序列生成此词元,模型就会停止预测。在循环神经网络解码器的初始化时间步,有两个特定的设计决定:首先,特定的 “<bos>” 表示序列开始词元,它是解码器的输入序列的第一个词元。其次,使用循环神经网络编码器最终的隐状态来初始化解码器的隐状态。 类似之前的语言模型的训练,可以允许标签成为原始的输出序列,从源序列词元“<bos>”、“Ils”、“regardent”、“.”到新序列词元“Ils”、“regardent”、“.”、“<eos>”来移动预测的位置。 下面,我们动手实现上图的设计,并将基于机器翻译与数据集中介绍的“英-法”数据集来训练这个机器翻译模型。
编码器从技术上讲,编码器将长度可变的输入序列转换成形状固定的上下文变量 c \mathbf{c} c,并且将输入序列的信息在该上下文变量中进行编码。如上图所示,可以使用循环神经网络来设计编码器。 考虑由一个序列组成的样本(批量大小是 1 1 1)。假设输入序列是 x 1 , … , x T x_1, \ldots, x_T x1?,…,xT?,其中 x t x_t xt?是输入文本序列中的第 t t t个词元。在时间步 t t t,循环神经网络将词元 x t x_t xt?的输入特征向量 x t \mathbf{x}_t xt?和 h t ? 1 \mathbf{h} _{t-1} ht?1?(即上一时间步的隐状态)转换为 h t \mathbf{h}_t ht?(即当前步的隐状态)。使用一个函数 f f f来描述循环神经网络的循环层所做的变换: h t = f ( x t , h t ? 1 ) . \mathbf{h}_t = f(\mathbf{x}_t, \mathbf{h}_{t-1}). ht?=f(xt?,ht?1?). 总之,编码器通过选定的函数 q q q,将所有时间步的隐状态转换为上下文变量: c = q ( h 1 , … , h T ) . \mathbf{c} = q(\mathbf{h}_1, \ldots, \mathbf{h}_T). c=q(h1?,…,hT?). 比如,当选择 q ( h 1 , … , h T ) = h T q(\mathbf{h}_1, \ldots, \mathbf{h}_T) = \mathbf{h}_T q(h1?,…,hT?)=hT?时(就像上图中一样),上下文变量仅仅是输入序列在最后时间步的隐状态 h T \mathbf{h}_T hT?。 到目前为止,我们使用的是一个单向循环神经网络来设计编码器,其中隐状态只依赖于输入子序列,这个子序列是由输入序列的开始位置到隐状态所在的时间步的位置(包括隐状态所在的时间步)组成。我们也可以使用双向循环神经网络构造编码器,其中隐状态依赖于两个输入子序列,两个子序列是由隐状态所在的时间步的位置之前的序列和之后的序列(包括隐状态所在的时间步),因此隐状态对整个序列的信息都进行了编码。 现在,让我们实现循环神经网络编码器。注意,我们使用了嵌入层(embedding layer) 来获得输入序列中每个词元的特征向量。嵌入层的权重是一个矩阵,其行数等于输入词表的大小(vocab_size),其列数等于特征向量的维度(embed_size)。对于任意输入词元的索引 i i i,嵌入层获取权重矩阵的第 i i i行(从 0 0 0开始)以返回其特征向量。另外,本文选择了一个多层门控循环单元GRU来实现编码器。 这个编码器Encoder最终返回的是隐状态信息。
下面,我们实例化上述编码器的实现:我们使用一个两层门控循环单元编码器,其隐藏单元数为 16 16 16。给定一小批量的输入序列 X(批量大小为 4 4 4 ,时间步为 7 7 7 )。在完成所有时间步后,最后一层的隐状态的输出是一个张量(output由编码器的循环层返回),其形状为(时间步数,批量大小,隐藏单元数)。
解码器正如上文提到的,编码器输出的上下文变量 c \mathbf{c} c对整个输入序列 x 1 , … , x T x_1, \ldots, x_T x1?,…,xT?进行编码。来自训练数据集的输出序列 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?,…,yt′?1?和上下文变量 c \mathbf{c} c,即 P ( y t ′ ∣ y 1 , … , y t ′ ? 1 , c ) P(y_{t'} \mid y_1, \ldots, y_{t'-1}, \mathbf{c}) P(yt′?∣y1?,…,yt′?1?,c)。 为了在序列上模型化这种条件概率,我们可以使用另一个循环神经网络作为解码器。在输出序列上的任意时间步 t ′ t^\prime t′,循环神经网络将来自上一时间步的输出 y t ′ ? 1 y_{t^\prime-1} yt′?1?和上下文变量 c \mathbf{c} c作为其输入,然后在当前时间步将它们和上一隐状态 s t ′ ? 1 \mathbf{s}_{t^\prime-1} st′?1?转换为隐状态 s t ′ \mathbf{s}_{t^\prime} st′?。因此,可以使用函数 g g g来表示解码器的隐藏层的变换: s t ′ = g ( y t ′ ? 1 , c , s t ′ ? 1 ) . \mathbf{s}_{t^\prime} = g(y_{t^\prime-1}, \mathbf{c}, \mathbf{s}_{t^\prime-1}). st′?=g(yt′?1?,c,st′?1?). 在获得解码器的隐状态之后,我们可以使用输出层和softmax操作来计算在时间步 t ′ t^\prime t′时输出 y t ′ y_{t^\prime} yt′?的条件概率分布 P ( y t ′ ∣ y 1 , … , y t ′ ? 1 , c ) P(y_{t^\prime} \mid y_1, \ldots, y_{t^\prime-1}, \mathbf{c}) P(yt′?∣y1?,…,yt′?1?,c)。 根据上图,当实现解码器时,我们直接使用编码器最后一个时间步的隐状态来初始化解码器的隐状态。这就要求使用循环神经网络实现的编码器和解码器具有相同数量的层和隐藏单元。为了进一步包含经过编码的输入序列的信息,上下文变量在所有的时间步与解码器的输入进行拼接(concatenate)。为了预测输出词元的概率分布,在循环神经网络解码器的最后一层使用全连接层来变换隐状态。
下面,我们用与前面提到的编码器中相同的超参数来实例化解码器。 如我们所见,解码器的输出形状变为(批量大小,时间步数,词表大小), 其中张量的最后一个维度存储预测的词元分布。
总之,上述循环神经网络“编码器-解码器”模型中的各层如下所示。 损失函数在每个时间步,解码器预测了输出词元的概率分布。类似于语言模型,可以使用softmax来获得分布,并通过计算交叉熵损失函数来进行优化。回想一下之前的操作,特定的填充词元被添加到序列的末尾,因此不同长度的序列可以以相同形状的小批量加载。但是,我们应该将填充词元的预测排除在损失函数的计算之外。 为此,我们可以使用下面的 sequence_mask 函数 通过零值化屏蔽不相关的项,以便后面任何不相关预测的计算都是与零的乘积,结果都等于零。例如,如果两个序列的有效长度(不包括填充词元)分别为 1 1 1 和 2 2 2,则第一个序列的第一项和第二个序列的前两项之后的剩余项将被清除为零。
我们还可以使用此函数屏蔽最后几个轴上的所有项。如果愿意,也可以使用指定的非零值来替换这些项。
现在,我们可以通过扩展softmax交叉熵损失函数来遮蔽不相关的预测。 最初,所有预测词元的掩码都设置为 1。 一旦给定了有效长度,与填充词元对应的掩码将被设置为 0。 最后,将所有词元的损失乘以掩码,以过滤掉损失中填充词元产生的不相关预测。
我们可以创建三个相同的序列来进行代码健全性检查, 然后分别指定这些序列的有效长度为 4 、2 和 0。 结果就是,第一个序列的损失应为第二个序列的两倍,而第三个序列的损失应为零。
训练在下面的循环训练过程中,特定的序列开始词元(“<bos>”)和 原始的输出序列(不包括序列结束词元“<eos>”) 拼接在一起作为解码器的输入。 这被称为强制教学(teacher forcing), 因为原始的输出序列(词元的标签)被送入解码器。 或者,将来自上一个时间步的预测得到的词元作为解码器的当前输入。
现在,在机器翻译数据集上,我们可以 创建和训练一个循环神经网络“编码器-解码器”模型用于序列到序列的学习。
预测为了采用一个接着一个词元的方式预测输出序列, 每个解码器当前时间步的输入都将来自于前一时间步的预测词元。 与训练类似,序列开始词元(“<bos>”) 在初始时间步被输入到解码器中。 该预测过程如下图所示, 当输出序列的预测遇到序列结束词元(“<eos>”)时,预测就结束了。
预测序列的评估我们可以通过与真实的标签序列进行比较来评估预测序列。虽然[Papineni.Roukos.Ward.ea.2002]提出的 BLEU(bilingual evaluation understudy) 最先是用于评估机器翻译的结果,但现在它已经被广泛用于测量许多应用的输出序列的质量。原则上说,对于预测序列中的任意 n n n 元语法(n-grams),BLEU的评估都是这个 n n n 元语法是否出现在标签序列中。 我们将BLEU定义为: exp ? ( min ? ( 0 , 1 ? l e n label l e n pred ) ) ∏ n = 1 k p n 1 / 2 n , \exp\left(\min\left(0, 1 - \frac{\mathrm{len}_{\text{label}}}{\mathrm{len}_{\text{pred}}}\right)\right) \prod_{n=1}^k p_n^{1/2^n}, exp(min(0,1?lenpred?lenlabel??))n=1∏k?pn1/2n?, 其中 l e n label \mathrm{len}_{\text{label}} lenlabel? 表示标签序列中的词元数和 l e n pred \mathrm{len}_{\text{pred}} lenpred? 表示预测序列中的词元数, k k k 是用于匹配的最长的 n n n 元语法。另外,用 p n p_n pn? 表示 n n n 元语法的精确度,它是两个数量的比值:第一个是预测序列与标签序列中匹配的 n n n 元语法的数量,第二个是预测序列中 n n n 元语法的数量的比率。具体地说,给定标签序列 A A A、 B B B、 C C C、 D D D、 E E E、 F F F和预测序列 A A A、 B B B、 B B B、 C C C、 D D D,我们有 p 1 = 4 / 5 p_1 = 4/5 p1?=4/5、 p 2 = 3 / 4 p_2 = 3/4 p2?=3/4、 p 3 = 1 / 3 p_3 = 1/3 p3?=1/3 和 p 4 = 0 p_4 = 0 p4?=0。 根据BLEU的定义,当预测序列与标签序列完全相同时,BLEU为 1 1 1。此外,由于 n n n 元语法越长则匹配难度越大,所以BLEU为更长的 n n n 元语法的精确度分配更大的权重。具体来说,当 p n p_n pn? 固定时, p n 1 / 2 n p_n^{1/2^n} pn1/2n? 会随着 n n n 的增长而增加(原始论文使用 p n 1 / n p_n^{1/n} pn1/n? )。而且,由于预测的序列越短获得的 p n p_n pn? 值越高,所以 eq_bleu 中乘法项之前的系数用于惩罚较短的预测序列。例如,当 k = 2 k=2 k=2 时,给定标签序列 A A A、 B B B、 C C C、 D D D、 E E E、 F F F和预测序列 A A A、 B B B,尽管 p 1 = p 2 = 1 p_1 = p_2 = 1 p1?=p2?=1,惩罚因子 exp ? ( 1 ? 6 / 2 ) ≈ 0.14 \exp(1-6/2) \approx 0.14 exp(1?6/2)≈0.14会降低BLEU。 BLEU的代码实现如下。
最后,利用训练好的循环神经网络“编码器-解码器”模型, 将几个英语句子翻译成法语,并计算BLEU的最终结果。
小结1、根据“编码器-解码器”架构的设计, 我们可以使用两个循环神经网络来设计一个序列到序列学习的模型。 2、在实现编码器和解码器时,我们可以使用多层循环神经网络。 3、我们可以使用遮蔽来过滤不相关的计算,例如在计算损失时。 4、在“编码器-解码器”训练中,强制教学方法将原始输出序列(而非预测结果)输入解码器。 5、BLEU是一种常用的评估方法,它通过测量预测序列和标签序列之间的 n n n 元语法的匹配度来评估预测。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 21:47:54- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |