Seq2Seq模型实现(Decoder部分)

0、引言:

承接上一篇,现在继续对于seq2seq模型进行讲解,decoder部分是和encoder部分对应的,层数、隐藏层、单元数都要对应。

1、LSTM Seq2Seq Decoder

Decoder只执行一个解码步骤。第一层将从前一个时间步接收隐藏和单元状态,并通过将当前的token 传给LSTM,进一步产生一个新的隐藏和单元状态。
Decoder的初始隐藏和单元状态是我们的上下文向量,它们是来自同一层的Encoder的最终隐藏和单元状态。接下来将隐藏状态传递给Linear层,预测目标序列下一个标记应该是什么。

Encoder输入参数:

  • output_dim将要输入到Decoder的one-hot向量,这个和输出词汇大小一致,就是输出字典长度
  • emb_dim嵌入层的维度,这一层将one-hot向量转为密度向量,256
    词嵌入在 pytorch 中只需要调用 torch.nn.Embedding(m, n) 就可以了,m 表示单词的总数目,n 表示词嵌入的维度,是一种降维,相当于是一个大矩阵,矩阵的每一行表示一个单词。
  • hid_dim隐藏和cell的状态维度,512
  • n_layers RNN层数,这里就是2
  • dropout是要使用的丢失量。这是一个防止过度拟合的正则化参数,0.5

Encoder返回参数:

  • prediction,预测
  • hidden,隐藏状态
  • cell,单元状态
    看一下实现
class Decoder(nn.Module):
    def __init__(self, output_dim, emb_dim, hid_dim, n_layers, dropout):
        super(Decoder,self).__init__()
        
        self.emb_dim=emb_dim
        self.hid_dim=hid_dim
        self.output_dim=output_dim
        self.n_layers=n_layers
        self.dropout=dropout
        
        self.embedding=nn.Embedding(output_dim,emb_dim)
        self.rnn=nn.LSTM(emb_dim,hid_dim,n_layers,dropout=dropout)
        self.out=nn.Linear(hid_dim,output_dim)
        self.dropout=nn.Dropout(dropout)
    def forward(self, input,hidden,cell):
        # torch.unsqueeze()这个函数主要是对数据维度进行扩充。给指定位置加上维数为一的维度,比如原本有个三行的数据(3),在0的位置加了一维就变成一行三列(1,3)
        input=input.unsqueeze(0)
        embedded=self.dropout
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的 Seq2Seq 模型的 TensorFlow 代码实现: ```python import tensorflow as tf class Seq2SeqModel(object): def __init__(self, input_vocab_size, output_vocab_size, hidden_size): # 输入序列的占位符 self.encoder_inputs = tf.placeholder(shape=(None, None), dtype=tf.int32, name='encoder_inputs') # 输出序列的占位符 self.decoder_inputs = tf.placeholder(shape=(None, None), dtype=tf.int32, name='decoder_inputs') # 输出序列的偏移量,用于计算损失 self.decoder_targets = tf.placeholder(shape=(None, None), dtype=tf.int32, name='decoder_targets') # 定义编码器和解码器的 RNN 单元 encoder_cell = tf.nn.rnn_cell.BasicLSTMCell(hidden_size) decoder_cell = tf.nn.rnn_cell.BasicLSTMCell(hidden_size) # 运行编码器 with tf.variable_scope("encoder"): encoder_embeddings = tf.get_variable("encoder_embeddings", [input_vocab_size, hidden_size]) encoder_inputs_embedded = tf.nn.embedding_lookup(encoder_embeddings, self.encoder_inputs) _, encoder_state = tf.nn.dynamic_rnn(encoder_cell, encoder_inputs_embedded, dtype=tf.float32) # 运行解码器 with tf.variable_scope("decoder"): decoder_embeddings = tf.get_variable("decoder_embeddings", [output_vocab_size, hidden_size]) decoder_inputs_embedded = tf.nn.embedding_lookup(decoder_embeddings, self.decoder_inputs) # 定义解码器的输出层 output_layer = tf.layers.Dense(output_vocab_size, activation=None) # 定义训练解码器的 helper train_helper = tf.contrib.seq2seq.TrainingHelper(inputs=decoder_inputs_embedded, sequence_length=tf.ones_like(self.decoder_inputs[0]) * tf.shape(self.decoder_inputs)[1]) # 定义推理解码器的 helper infer_helper = tf.contrib.seq2seq.GreedyEmbeddingHelper(embedding=decoder_embeddings, start_tokens=tf.fill([tf.shape(self.encoder_inputs)[0]], 1), end_token=2) # 定义训练解码器 train_decoder = tf.contrib.seq2seq.BasicDecoder(cell=decoder_cell, helper=train_helper, initial_state=encoder_state, output_layer=output_layer) # 定义推理解码器 infer_decoder = tf.contrib.seq2seq.BasicDecoder(cell=decoder_cell, helper=infer_helper, initial_state=encoder_state, output_layer=output_layer) # 运行训练解码器 train_outputs, _, _ = tf.contrib.seq2seq.dynamic_decode(train_decoder, maximum_iterations=tf.shape(self.decoder_inputs)[1]) # 运行推理解码器 infer_outputs, _, _ = tf.contrib.seq2seq.dynamic_decode(infer_decoder, maximum_iterations=tf.shape(self.encoder_inputs)[1]) # 定义损失函数 self.loss = tf.reduce_mean(tf.contrib.seq2seq.sequence_loss(logits=train_outputs.rnn_output, targets=self.decoder_targets, weights=tf.to_float(tf.sequence_mask(tf.shape(self.decoder_inputs)[1])))) # 定义训练步骤 self.train_op = tf.train.AdamOptimizer().minimize(self.loss) # 定义预测结果 self.predictions = infer_outputs.sample_id ``` 这个模型实现了一个基本的 Seq2Seq 模型,用于将输入序列翻译成输出序列。该模型使用 LSTM 单元,并使用带有注意力机制的解码器,以便模型可以更好地关注输入序列中的重要部分
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值