【问题标题】:Using output from one LSTM as input into another LSTM in TensorFlow [closed]在TensorFlow中使用一个LSTM的输出作为另一个LSTM的输入[关闭]
【发布时间】:2020-05-27 02:25:05
【问题描述】:

我想构建一个基于 LSTM 的神经网络,它接受两种输入并预测两种输出。大致结构见下图。

Output 2 依赖于Output 1,正如在回答类似问题here 中所述,我试图通过从 LSTM 1 的隐藏状态设置 LSTM 2 的初始状态来实现这一点。我已经实现这使用 TensorFlow 使用以下代码。

import tensorflow as tf

from tensorflow.keras.layers import Input
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import Dense
import numpy as np

np.set_printoptions(suppress=True) # to suppress scientific notation while printing arrays

def reset_graph(seed=2):
    tf.compat.v1.reset_default_graph()
    tf.random.set_seed(seed)  # tf.set_random_seed(seed)
    np.random.seed(seed)

tf.__version__

seq_len = 10
in_features1 = 3
in_features2 = 5
batch_size = 2
units = 5

# define input data
data1 = np.random.normal(0,1, size=(batch_size, seq_len, in_features1))
print('input 1 shape is', data1.shape)

data2 = np.random.normal(0,1, size=(batch_size, seq_len, in_features2))
print('input 2 shape is', data2.shape)

reset_graph()

# define model
inputs1 = Input(shape=(seq_len, in_features1))
inputs2 = Input(shape=(seq_len, in_features2))
lstm1 = LSTM(units, return_state=True)
lstm1_out, lstm_h, lstm_c = lstm1(inputs1, initial_state=None)
dense1 = Dense(1)
dense1_out = dense1(lstm1_out)

lstm2 = LSTM(units)
lstm2_out = lstm2(inputs2, initial_state=[lstm_h, lstm_c])

dense2 = Dense(1)
dense2_out = dense2(lstm2_out)

两个 LSTM 的输入并不完全相同,因为有些 Input 2Output 1 无关,但 Output 2 肯定受到 Output 1 的影响。比如Output 1是水流,Output 2是水质,所以水质受水流的影响。

这段代码运行良好,但我不确定这段代码是否符合我的预期,即LSTM 2 的工作受到LSTM 1 输出的影响。

请验证执行和推理是否正确?

【问题讨论】:

  • inputs1 等于 inputs2?我只看到一个输入,对吗?
  • @MarcoCerliani 它们是不同的,但并不完全不同。但是,我已经编辑了问题以使它们有所不同。
  • 谢谢……这样一来,就有了2个“分支”。两者通信的方式是共享 lstms 状态,对吗?我这样说是因为在图像中箭头似乎将dense1与lstm2连接起来
  • @MarcoCerliani 箭头显示了网络的初衷,即利用 lstm1 输出作为 lstm2 的输入(连同输入 2)。但是,对类似问题(也有问题的链接)的答案表明,可以(或应该)通过设置 LSTM 的初始状态来完成相同的操作。所以我的问题是,像我所做的那样设置初始状态是否正确?它是否达到目的,即我希望 LSTM2 受到 LSTM1 输出的影响。
  • 好的,所以如果您不想将 lstm1 的输出与 input2 连接起来(如您引用的解决方案中所述),您需要共享状态。否则,如果您有一个输入(如编辑前报告的那样),您可以堆叠两个 lstm 单元并在不同级别产生 2 个输出(我可以报告第二种情况的解决方案)

标签: python tensorflow keras deep-learning lstm


【解决方案1】:

这段代码运行良好,但我不确定这段代码是否符合我的意图 它要做,即 LSTM 2 的工作受到输出的影响 LSTM 1.

请验证执行和推理是否正确?

是的,实现和推理都是对的。将 LSTM1 的最终状态作为 LSTM2 的初始状态传递会创建您正在寻找的依赖项。但是,我并不完全相信这种解决方案。为了让 LSTM2 能够考虑输出 1,将输出 1 连接到输入 2 并让 LSTM2 学习从 [输入 2,输出 1] 中抽象特征更为自然。但无论如何,这两种解决方案都会在您描述的 input2 和 input1 之间创建依赖关系。

将LSTM1的输出连接到输入2的解决方案可以这样描述:

由于 LSTM1 返回一个序列 (return_sequence=True),您只需将 LSTM1 的输出 (seq_len, num_units) 连接到 imput2 (seq_len, in_features2) 得到 (seq_len, num_units + in_features2)

# define model
inputs1 = Input(shape=(seq_len, in_features1))
inputs2 = Input(shape=(seq_len, in_features2))

lstm1 = LSTM(units, return_sequences=True)
lstm1_out = lstm1(inputs1)

lstm2_input = tf.keras.layers.concatenate([inputs2, lstm1_out])
lstm2 = LSTM(units)
lstm2_out = lstm2(lstm2_input)

dense1 = Dense(1)
dense1_out = dense1(lstm1_out)

dense2 = Dense(1)
dense2_out = dense2(lstm2_out)

希望对您有所帮助! :)

【讨论】:

  • 您能否详细说明与我尝试实施并已被描述为here 的“初始状态共享”方法相比,这种方法的优势和/或可能的劣势?
  • 我认为没有特定的优势。两种解决方案都会在 input2 和 input1 之间创建依赖关系。我编辑了答案,试图更清楚一点。
  • 您不应该在代码中使用return_sequences 而不是return_state 吗?由于我们想将 LSTM1 的输出作为 LSTM2 的输入,所以最好使用单个 Dense 层来执行此操作,但首先将其应用于 LSTM1 的最终输出,然后将其应用于所有输出LSTM1可以与inputs2连接吗?
  • 是的,应该是return_sequences,抱歉我的失误。
  • 我认为最好直接使用 LSTM1 的输出(没有密集层),因为当你应用密集层时,你正在删除我认为可能有趣的输入的“序列”性质LSTM2。但是,这取决于您的数据,因此我建议您尝试这些不同的方法并检查哪种方法更适合您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-22
  • 2021-08-31
  • 1970-01-01
相关资源
最近更新 更多