了解 Seq2Seq 模型
Posted
技术标签:
【中文标题】了解 Seq2Seq 模型【英文标题】:Understanding Seq2Seq model 【发布时间】:2018-03-03 11:57:08 【问题描述】:这是我对基本序列到序列 LSTM 的理解。假设我们正在处理问答设置。
你有两组 LSTM(下面的绿色和蓝色)。每组分别共享权重(即 4 个绿色单元格中的每一个都具有相同的权重,并且与蓝色单元格相似)。第一个是多对一LSTM,总结了在最后一个隐藏层/cell memory的问题。
第二组(蓝色)是多对多 LSTM,其权重与第一组 LSTM 不同。输入只是答案句子,而输出是同一个句子移位了。
问题有两个方面: 1. 我们是否将最后一个隐藏状态仅作为初始隐藏状态传递给蓝色 LSTM。或者它是最后一个隐藏状态和细胞记忆。 2. 有没有办法在 Keras 或 Tensorflow 中设置初始隐藏状态和单元内存?如果有参考?
(图片取自 suriyadeepan.github.io)
【问题讨论】:
我对你的问题有很多疑问...... 1 - “每组分别共享权重”是什么意思? -- 2- 你对细胞记忆和细胞状态的理解是什么? -- 3 -- 如果图片说它以“思想向量”作为输入,为什么蓝色是多对多的? -- 4 -- 为什么蓝色得到答案并输出一个偏移的答案?疑问句从何而来? ---- 我可以说的一件事是:只有“输出”从一层传递到另一层。 1.在上面的括号中回答。 2. 我想我的意思是细胞状态(根据 colah 的博客,基本上是从 LSTM 传递出来的两件事之一)。 3.我不理解思想向量(这是整个问题的意义所在),但没有它,它是多对多的。看看输出如何循环回输入。 4.这只是训练时间,在测试期间你只需要最高概率的输出(或光束搜索) 【参考方案1】:我们是否仅将最后一个隐藏状态作为初始隐藏状态传递给蓝色 LSTM。或者它是最后的隐藏状态和单元记忆。
隐藏状态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
是该层的输出,除非您指定return_sequences=True
,否则它将等于h
。
有没有办法在 Keras 或 Tensorflow 中设置初始隐藏状态和单元内存?如果有参考?
TensorFlow
调用时只需将初始状态提供给LSTMCell
。比如在official RNN tutorial:
lstm = tf.contrib.rnn.BasicLSTMCell(lstm_size)
...
output, state = lstm(current_batch_of_words, state)
对于诸如tf.nn.static_rnn
之类的函数,还有一个initial_state
参数。如果您使用 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 模型后进行预测。
【讨论】:
你能把链接放到你在 tensorflow 上找到 seq2seqenc_state
信息的部分吗?只是有一种感觉,你正在通过它的外观看源头。非常感谢,写得很好!
是的,我查看了它的源代码。我已经添加了代码的链接。这些行来自basic_rnn_seq2seq()
函数(这是官方教程中使用的函数)。如果执行rnn.static_rnn()
行,返回的enc_state
将是LSTMStateTuple(c=..., h=...)
。【参考方案2】:
(编辑:此答案不完整,未考虑状态转移的实际可能性。请参阅已接受的答案)。
从 Keras 的角度来看,该图片只有两层。
绿色组是一个 LSTM 层。 蓝色组是另一个 LSTM 层。除了传递输出之外,绿色和蓝色之间没有任何通信。所以,1 的答案是:
只有思想向量(该层的实际输出)被传递到另一层。
内存和状态(不确定它们是否是两个不同的实体)完全包含在单个层中,并且最初不打算与任何其他层看到或共享。
该图像中的每个单独块在 keras 中完全不可见。它们被认为是“时间步长”,仅以输入数据的形式出现。很少担心它们(除非非常高级的用法)。
在keras中是这样的:
很容易,您只能访问外部箭头(包括“思想向量”)。 但是可以访问每个步骤(图片中的每个单独的绿色块)并不是一件暴露的事情。所以...
在 Keras 中也不希望将状态从一层传递到另一层。你可能不得不破解一些东西。 (见:https://github.com/fchollet/keras/issues/2995)
但是考虑到一个足够大的思想向量,你可以说它会学会一种携带本身重要的东西的方法。
您从这些步骤中得到的唯一概念是:
你必须输入形状像(sentences, length, wordIdFeatures)
的东西
考虑到长度维度中的每个切片是每个绿色块的输入,将执行这些步骤。
您可以选择使用单个输出(sentences, cells)
,这样您就完全忘记了步骤。或者……
(sentences, length, cells)
这样的输出,您可以从中通过长度维度了解每个块的输出。
一对多还是多对多?
现在,第一层是多对一的(但如果您愿意,也没有什么能阻止它成为多对多)。
但是第二个......这很复杂。
如果思想向量是由多对一构成的。您将不得不管理一种创建一对多的方式。 (这在 keras 中并非微不足道,但您可以考虑重复预期长度的思想向量,使其成为所有步骤的输入。或者用零或一填充整个序列,仅保留第一个元素作为思想向量) 如果思想向量是由多对多构成的,则可以利用这一点并保持简单的多对多,前提是您愿意接受输出与输入具有完全相同的步数。Keras 没有针对 1 到多个案例的现成解决方案。 (从单个输入预测整个序列)。
【讨论】:
but nothing prevents it from being many to many too if you want
。这实际上是错误的。您可能正在考虑尝试预测下一个单词,这不是我在这里尝试做的。我想总结最后一个单元状态/隐藏层中的问题,然后将其传递给答案 LSTM。这严格来说是多对多。我认为你应该在回答这个问题之前先看看 tensorflow seq2seq 文档。
哇,你至少不能对丹尼尔没有礼貌,他花了一些时间给你写了一个很好的答案。据我所知,您可以使用many to many
或one to many
。这取决于您是否希望将绿色 LSTM 层中每个时间步的结果馈送到蓝色 LSTM 层
我真的很抱歉这么直率,并不是故意听起来粗鲁。不是我对最初的 +1 投了反对票。我真的很感谢您为做出这个答案所付出的时间和精力。再次,对不起,我是个混蛋。
嗯,看来我的回答根本不值得。查看已接受的答案,我的答案是完全错误的。以上是关于了解 Seq2Seq 模型的主要内容,如果未能解决你的问题,请参考以下文章