【问题标题】:Does Keras's LSTM really take into account the cell state and previous output?Keras 的 LSTM 真的考虑了细胞状态和之前的输出吗?
【发布时间】:2023-12-16 11:05:02
【问题描述】:

我在过去一天了解了LSTM,然后我决定看一个使用Keras 创建它的教程。我看了几个教程,它们都有

model = Sequential()
model.add(LSTM(10, input_shape=(1,1)))
model.add(Dense(1, activation='linear'))
model.compile(loss='mse', optimizer='adam')
X,y = get_train()
model.fit(X, y, epochs=300, shuffle=False, verbose=0)

然后他们预测使用

 model.predict(X, verbose=0)

我的问题是:为了使用 LSTM 预测下一个结果,您是否必须提供先前的预测以及输入和单元状态? 另外,model.add(LSTM(10, input_shape(1,1)) 中的 10 代表什么?

【问题讨论】:

    标签: python tensorflow keras lstm


    【解决方案1】:

    您必须将先前的预测赋予 LSTM 状态。如果你调用 predict ,LSTM 每次都会被初始化,它不会记住之前预测的状态。

    通常(例如,如果您使用 lstm 生成文本)您有一个循环,您可以在其中执行以下操作:

    # pick a random seed
    start = numpy.random.randint(0, len(dataX)-1)
    pattern = dataX[start]
    print "Seed:"
    print "\"", ''.join([int_to_char[value] for value in pattern]), "\""
    # generate characters
    for i in range(1000):
        x = numpy.reshape(pattern, (1, len(pattern), 1))
        x = x / float(n_vocab)
        prediction = model.predict(x, verbose=0)
        index = numpy.argmax(prediction)
        result = int_to_char[index]
        seq_in = [int_to_char[value] for value in pattern]
        sys.stdout.write(result)
        pattern.append(index)
        pattern = pattern[1:len(pattern)]
    print "\nDone."
    

    (从machinelearningmastery.com复制的示例)

    重要的是这几行:

    pattern.append(index)
    pattern = pattern[1:len(pattern)]
    

    在这里,他们将下一个字符附加到模式中,然后删除第一个字符以具有与 lstm 的期望相匹配的输入长度。然后将其带到一个 numpy 数组 (x = np.reshape(...)) 并使用生成的输出从模型中进行预测。因此,要回答您的第一个问题,您需要再次输入输出。

    对于第二个问题,10 对应于您在一个层中拥有的 lstm 单元的数量。如果您不使用“return_sequences=True”,则它对应于该层的输出大小。

    【讨论】:

      【解决方案2】:

      让我们把它分解成碎片,然后用图形看

      LSTM(10, input_shape=(3,1))):定义一个序列长度为 3 的 LSTM,即 LSTM 将展开 3 个时间步长。在每个时间步,LSTM 将采用大小为 1 的输入。输出(以及隐藏状态和所有其他 LSTM 门的大小)为 10(向量或大小为 10)

      您不必手动展开(将当前隐藏状态传递到下一个状态),它由 keras/tensorflow LSTM 层负责。您所要做的就是以 (batch_size X time_steps X input_size) 格式传入数据。

      Dense(1, activation='linear'):这是一个具有线性激活的密集层,将前一层的输出作为输入(即 LSTM 的输出,它将是最后一次展开的大小为 10 的向量)。它将返回一个大小为 1 的向量。

      同样可以使用model.summary()进行检查

      【讨论】:

      • 你说它会在展开之间处理单元格状态,但是当我调用 .predict 两次时它会保留状态吗?
      • @ArjunBemarkar Unrolling 将当前状态带到每个输入的下一个状态。
      【解决方案3】:

      你的第一个问题:

      您是否必须提供先前的预测以及输入和单元状态才能使用 LSTM 预测下一个结果?

      不,您不必这样做。据我了解,它存储在 LSTM 单元中,这就是 LSTM 使用这么多 RAM 的原因

      如果您的数据形状如下:

      (100,1000)
      

      如果将其插入 fit 函数,每个 epoch 将在 100 个列表上运行。当 LSTM 移动到下一个列表时,它会在刷新之前记住 1000 个数据图。

      第二个:

      另外,model.add(LSTM(10, input_shape(1,1))中的10代表什么?

      是输入后第一层的形状,所以你的模型目前的形状是:

      1,1 10 1

      希望对你有帮助:)

      【讨论】:

      • 那么单元状态和最后的预测是否存储在 LSTM 单元中?
      最近更新 更多