9.7 序列到序列学习

序列到序列学习详解

正如我们在9.5节中看到的,机器翻译中的输入序列和输出序列都是长度可变的,为了解决这类问题,我们在9.6节中设计了一个通用的编码器-解码器架构,在本节中,我们将使用两个循环神经完了编码器解码器并将其应用于序列序列学习任务

遵循编码器-解码器架构设计原则循环神经网络编码器使用长度可变序列作为输入将其转换固定形状状态换言之输入序列信息编码循环神经网络编码器状态为了连续生成输出序列词元独立循环神经网络解码器输入序列编码信息输出序列可见或者生成词元预测下一个词元9-12展示了如何机器翻译中使用两个循环神经网络进行序列序列学习

编码器

They are watching eos

解码器

bos lts regardent

9-12 使用循环神经网络编码器循环神经网络解码器序列序列学习

特定eos 表示序列结束词元一旦输出序列生成词元模型就会停止预测在循环神经网络解码器初始化时间步两个特定设计首先特定表示序列开始词元解码器输入序列第一个词元其次使用循环神经网络编码器最终状态初始化解码器状态例如参考文献设计中基于这种设计输入序列的编码信息送入输入解码器生成输出序列在其他一些设计中如图9-12所示编码器最终状态每个时间步都作为解码器输入序列一部分类似8.3语言模型训练可以允许标签作为原始输出序列序列词元序列词元移动预测位置

我们动手构建9-12设计并将基于9.5节中介绍英语-法语数据集训练这个机器翻译模型

import collections

import math

import torch

from torch import nn

from d2l import torch as d2l

9.7.1 编码器

编码器长度可变输入序列转换形状固定上下文变量并且输入序列信息上下文变量进行编码如图9-12所示可以使用循环神经网络设计编码器

考虑一个序列组成样本假设输入序列x1,,,,xt其中Xt输入文本序列i词元在时间步t循环神经网络词元xt输入特征向量XtHt-1 转换为ht使用一个函数f描述循环神经网络循环所做转换

Ht = f(Xt,Ht-1)

编码器通过选定函数q, 将所有时间步状态转换为上下文变量

c = q(h1,,ht)

选择q(h1,,,ht)上下文变量仅仅输入序列最后时间步状态Ht

到目前为止我们使用是一个循环神经网络设计编码器其中状态只依赖输入子序列这个子序列输入序列开始位置状态所在时间步设置我们也可以使用双向循环神经网络构建编码器其中状态依赖两个输入子徐磊这两个字序列分别是状态所在时间步位置之前序列之后序列因此状态整个序列的信息进行编码

我们实现循环神经网络编码器注意我们使用嵌入层来获得输入序列中每个词元特征向量嵌入权重是一个矩阵其行数等于输入词表大小其列等于特征向量维度对于任意输入词元索引 嵌入层获取权重矩阵i1️⃣返回特征向量这里选择一个多层循环单元实现编码器

class Seq2seqEncdoer(d2l.Encoder):

用于序列序列学习循环神经网络编码器

def __init__(self, vocab_size, embed_size, num_hiddens, num_layers, dropout=0, **kwargs):

super(Seq2seqEncoder, self).__init__(**kwargs)

嵌入层

self.embedding = nn.Embedding(vocab_size, embed_size)

slef.rnn = nn.GRU(embed_size, num_hiddens, num_layers, dropout=dropout)

def forward(self, X, *args):

输入X形状(batch_size, num_steps, embed_size)

X = self.embedding(X)

循环神经网络模型第一个对应时间步

X =X.permute(1, 0, 2)

如果未提及状态则默认为0

output, state = self.rnn(X)

output形状(num_steps, batch_size, num_hiddens)

#state[0]形状(num_layers, batch_szie, num_hiddens)

return output, state

循环返回变量说明参见8.6

我们实例化上述编码器实现使用一个两层循环单元编码器隐藏单元16给定一个小批量输入序列X在完成所有时间最后一层状态输出是一个张量形状为 时间批量大小隐藏单元

encoder = Seq2SeqEncoder(vocab_size=10, embed_size=8, num_hiddens=16, num_layers = 2)

encoder.eval()

X=torch.zeros(4, 7), dtype = torch.long

output, state = encoder(X)

output.shape

torch.Size([7, 4, 16])

这里使用的是门控循环单元最后一个时间步的多层状态形状如果使用长短期记忆网络state还将包含记忆信息

state.shape

torch.Size([2, 4, 16])

9.7.2 解码器

编码器输出上下文变量c整个输入序列x1,,,Xt进行编码来自训练数据输出序列Y1,Y2,,,Yt,对于每个时间步t 解码器输出Yt概率取决于之前输出子序列Y1,,,,Yt上下文变量cP(Y1|Y2,,,Yt-1, x)

序列模型这种条件概率我们可以使用另一个循环神经网络作为解码器在输出序列任意时间步t循环神经网络将来自上一个时间步输出Yt-1上下文变量c作为输入然后当前时间步它们上一个状态St-1转换为状态St可以使用函数g表示解码器隐藏变换

St = g(Yt-1,c,St-1)

在获得将其状态之后可以使用输出层softmax操作来计算在时间步t输出yt条件概率分布P(Yt|Y1,,,Yt-1, c)

根据9-12 实现解码器直接使用编码器最后一个时间步状态初始化解码器状态这就要求使用循环神经网络实现编码器解码器具有相同数量隐藏单元为了进一步包含经过编码输入序列信息上下文变量所有时间步解码器输入进行连接为了预测输出词元概率分布在循环神经网络解码器最后一层使用连接变换状态

class Seq2SeqDecoder(d2l.Decoder):

用于序列序列学习循环神经网络解码器

def __init__(self, vocab_size, embed_size, num_hiddens, num_layers, dropout=0, **kwargs):

super(Seq2SeqDecoder, self).__init__(**kwargs)

self.embedding = nn.Embedding(vocab_size, embed_size)

self.rnn = nn.GRU(embed_size + num_hiddens, num_hiddens, num_layers, dropout=dropout)

self.dense = nn.Linear(num_hiddens, vocab_size)

def init_state(self, enc_outputs, *args):

return enc_outputs[1]

def forward(self, X, state):

输出X形状(batch_size, num_steps, embed_size)

X = self.embedding(X).permute(1, 0, 2)

广播context, 使其具有X相同num_steps

context = state[-1].repeat(X.shape[0], 1, 1)

X_and_context = torch.cat((X, context), 2)

output, state = self.rnn(X_and_context, state)

output = self.dense(output).permute(1,0,2)

output形状(batch_size, num_steps, vocab_size)

state[0]形状num_layers, batch_size, num_hiddens

return output, state

下面我们前面提到编码器中相同超参数实例化解码器解码器输出形状变为批量大小时间步词表大小其中张量最后一个维度存储预测词元分布

decoder = Seq2SeqDecoder(vocab_size=10, embed_size=8, num_hiddens=16,num_layers=2)

decoder.eval()

state = decoder.init_state(encoder(X))

output, state = decoder(X, state)

output.shape, state.shape

torch.Size([4,7,10]), torch.Size([2,4,16])

上述循环神经网络编码器解码器模型各层如图9-13所示

编码器

循环层

嵌入层

解码器

全连接层

循环层

嵌入层

目标

9-13 循环神经网络编码器-解码器模型各层

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值