了解Seq2Seq模型

时间:2017-09-22 01:48:33

标签: tensorflow keras lstm

以下是我对LSTM序列的基本序列的理解。假设我们正在处理问答环境。

你有两套LSTM(下面是绿色和蓝色)。每组分别共享权重(即4个绿色单元中的每一个具有相同的权重并且与蓝色单元类似)。第一个是多对一LSTM,它总结了最后隐藏层/单元格内存的问题

第二组(蓝色)是多对多LSTM,其与第一组LSTM具有不同的权重。输入只是答案句子,而输出是相同的句子移一。

问题有两个: 1.我们是否将最后隐藏状态传递给蓝色LSTM作为初始隐藏状态。或者它是最后隐藏状态和单元格内存。 2.有没有办法在Keras或Tensorflow中设置初始隐藏状态和单元格内存?如果是这样的参考?

http://suriyadeepan.github.io/img/seq2seq/seq2seq2.png (图片来自suriyadeepan.github.io)

2 个答案:

答案 0 :(得分:3)

  
      
  1. 我们是否只将最后一个隐藏状态传递给蓝色LSTM作为初始隐藏状态。或者它是最后隐藏的状态和单元格记忆。
  2.   

隐藏状态h和单元格内存c都会传递给解码器。

TensorFlow

seq2seq source code中,您可以在basic_rnn_seq2seq()中找到以下代码:

_, enc_state = rnn.static_rnn(enc_cell, encoder_inputs, dtype=dtype)
return rnn_decoder(decoder_inputs, enc_state, cell)

如果您使用LSTMCell,则编码器返回的enc_state将成为元组(c, h)。如您所见,元组直接传递给解码器。

Keras

在Keras中,为LSTMCell定义的“状态”也是元组(h, c)(请注意,顺序与TF不同)。在LSTMCell.call()中,您可以找到:

    h_tm1 = states[0]
    c_tm1 = states[1]

要获取从LSTM图层返回的状态,您可以指定return_state=True。返回的值是元组(o, h, c)。张量o是此图层的输出,除非您指定h,否则它将等于return_sequences=True

  
      
  1. 有没有办法在Keras或Tensorflow中设置初始隐藏状态和单元格内存?如果是这样参考?
  2.   

TensorFlow

在调用时,只需向LSTMCell提供初始状态即可。例如,在official RNN tutorial

lstm = tf.contrib.rnn.BasicLSTMCell(lstm_size)
...
    output, state = lstm(current_batch_of_words, state)

initial_state等函数还有一个tf.nn.static_rnn参数。如果您使用seq2seq模块,请将状态提供给rnn_decoder,如问题1的代码中所示。

Keras

在LSTM函数调用中使用关键字参数initial_state

out = LSTM(32)(input_tensor, initial_state=(h, c))

您实际上可以在the official documentation上找到此用法:

  

关于指定RNN初始状态的注意事项

     

您可以通过符号方式指定RNN图层的初始状态   使用关键字参数initial_state调用它们。的价值   initial_state应该是张量或张量的张量代表   RNN层的初始状态。

修改

现在,Keras(lstm_seq2seq.py)中有一个示例脚本,展示了如何在Keras中实现基本的seq2seq。此脚本还介绍了如何在训练seq2seq模型后进行预测。

答案 1 :(得分:1)

(编辑:这个答案是不完整的,并没有考虑到国家转移的实际可能性。请参阅接受的答案)。

Keras 的角度来看,该图片只有两层。

  • 绿色组是一个LSTM图层。
  • 蓝色组是另一个LSTM图层。

除了传递输出之外,绿色和蓝色之间没有任何通信。所以,1的答案是:

  
      
  1. 只有思想向量(它是图层的实际输出)才会传递给另一层。
  2.   

内存和状态(不确定这些是否是两个不同的实体)完全包含在单个层中,并且最初不打算与任何其他层一起查看或共享。

该图像中的每个块在keras中完全不可见。它们被视为"时间步骤",只出现在输入数据的形状中。担心它们很少很重要(除非是非常先进的用法)。

在keras中,它是这样的:

enter image description here

很容易,您只能访问外部箭头(包括"思想向量") 但访问每个步骤(图片中的每个绿色块)并不是暴露的事情。所以......

  
      
  1. 在Keras中也不会将状态从一层传递到另一层。你可能不得不破解东西。 (见:https://github.com/fchollet/keras/issues/2995
  2.   

但是考虑到一个足够大的思想向量,你可以说它将学会一种方法来携带重要的东西。

您从步骤中获得的唯一理念是:

  • 您必须输入形状类似(sentences, length, wordIdFeatures)
  • 的内容

考虑到长度维度中的每个切片是每个绿色块的输入,将执行这些步骤。

您可以选择只有一个输出(sentences, cells),您可以完全忘记步骤。还是......

  • 类似(sentences, length, cells)的输出,您可以通过长度维度知道每个块的输出。

一对多或多对多?

现在,第一层是多对一的(但如果你愿意的话,没有什么能阻止它成为多对多)。

但第二个......那很复杂。

  • 如果思想向量是由多对一制成的。您将不得不管理创建一对多的方法。 (这在keras中并不重要,但你可以考虑重复预期长度的思维向量,使其成为所有步骤的输入。或者可能用零或1填充整个序列,仅保留第一个元素作为思想载体)
  • 如果思想向量是由多对多制作的,那么你可以利用这个并保持一个简单的多对多,如果你愿意接受输出的步骤数与输入。

Keras没有针对1到多种情况的现成解决方案。 (从单个输入预测整个序列)。