d2l解码编码器与seq2seq

本文详细介绍了Seq2Seq模型的组成部分,包括基于GRU的编码器和解码器的实现,以及如何处理输入输出。还讨论了训练过程、预测方法、损失计算,特别是针对填充词元的处理和BLEU评估指标。

seq2seq难死了,卡了好久,好不容易有些头绪了。。。

目录

1.编码器与解码器

1.1原理

1.2实现

2.seq2seq

2.1构造编码器

2.2构造解码器

repeat与cat探索

总结nn.rnn\GRU\LSTM输入输出

看一下解码器的输出

2.3损失计算

2.4训练

2.5预测

2.6预测评估BLEU

2.7预测结果


1.编码器与解码器

1.1原理

编码器(encoder ):它接受⼀个⻓度可变的序列作为输⼊,并将其转换为具有固定形状的编码状态。第⼆个组件是解码器(decoder ):它将固定形状的编码状态映射到⻓度可变的序列。

1.2实现

#@save
class EncoderDecoder(nn.Module):
    """编码器-解码器架构的基类"""
    def __init__(self, encoder, decoder, **kwargs):
        super(EncoderDecoder, self).__init__(**kwargs)
        self.encoder = encoder
        self.decoder = decoder
        
    def forward(self, enc_X, dec_X, *args):
        enc_outputs = self.encoder(enc_X, *args)
        dec_state = self.decoder.init_state(enc_outputs, *args)
        return self.decoder(dec_X, dec_state)

其中,dec_X为解码器输入,dec_state为解码器的初始状态,enc_outputs为编码器输出(p269),传入decoder中的init_state函数。

2.seq2seq

2.1构造编码器

Embedding当作每个词嵌入one-hot。onehot是最简单的一种embedding

#@save
class Seq2SeqEncoder(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)
        self.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的形状:(num_layers,batch_size,num_hiddens)
        return output, state

  编码器最终的output输出为(T,bs,hiddens),state的输出为(n_layers,bs,hiddens)
  如果是Lstm的话,state是一个包含两个tensor的tuple,为Ht与Ct

  下面这个例子bs=4,T=7,生成最终的output与state符合上述结论

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, state.shape

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

2.2构造解码器

  encoder(X)得到的有output与state,这里init_state只拿[1],即只拿state。
  再在forward中,拿到state[-1]最后一个时刻的最后一层的hidden,使用repeat广播到与X相同的维数(repeat探索下文)
  目标tgt的输入X与src中的最后一层最后一个时刻广播后的state进行concat,一起送到目标层中的gru中进行输出,得到(T,bs,hidden),再通过dense的Linear层并转换维数permute,得到最终的输出(bs,T,len(v)).
  state形状见(V,为(n_layer,bs,h),表示最后一个时刻每个layer的Ht

  定义GRU时,假设Encoder与Decoder中的hiddens是一致的,作用是将Encoder的state与decoder的input进行concat起来,使得满足训练图:每个input都与最后的state进行cat。

  &nb

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值