【问题标题】:In Keras when does LSTM state reset in the call to model.predict?在 Keras 中,LSTM 状态何时在对 model.predict 的调用中重置?
【发布时间】:2017-01-04 22:27:07
【问题描述】:

该模型的第一层是 LSTM。

当调用 model.predict 时说你传入了几个样本:

>sam = np.array([ [[.5, .6, .3]], [[.6, .6, .3]], [[.5, .6, .3]] ])
>model.predict(sam)
array([[ 0.23589483],
       [ 0.2327884 ],
       [ 0.23589483]])

上面我们看到映射:[[.5, .6, .3]] -> 0.23589483 etc(1个元素的序列,即长度为3的向量,映射到一个实数)

模型的 input_length 为 1,input_dim 为 3。请注意,第一个和最后一个是相同的,并且具有相同的输出 (0.23589483)。所以我的假设是,在 Keras 处理一个样本(在本例中为 1 个 3-D 向量的序列)之后,它会重置模型的内存。即每个序列基本上是独立的。这种观点有什么不正确或误导的地方吗?

再举一个 input_length 3 和 input_dim 1 的例子。这一次,在一个序列中切换值并看到不同的结果(比较第二个列表和最后一个列表)。因此,随着 Keras 处理序列,内存正在发生变化,但是在处理完成后,内存会重置(第一个和第二个序列具有相同的结果)。

sam = np.array([ [[.1],[.1],[.9]], [[.1],[.9],[.1]], [[.1],[.1],[.9]]   ])
model.predict(sam)
array([[ 0.69906837],
   [ 0.1454899 ],
   [ 0.69906837]])

在上面我们看到映射 [[.1],[.1],[.9]] -> 0.69906837 等(3 个元素到实数的序列)

【问题讨论】:

    标签: keras lstm


    【解决方案1】:

    我很欣赏这是一个老问题,但希望这个答案可以帮助像我这样的其他 Keras 初学者。

    我在我的机器上运行了这个示例,并观察到 ​​LSTM 的隐藏状态和单元状态确实随着对 model.predict 的调用而发生了变化。

    import numpy as np
    import keras.backend as K
    from keras.models import Model
    from keras.layers import LSTM
    
    batch_size = 1
    timestep_size = 2
    num_features = 4
    
    inputs = Input(batch_shape=(batch_size, timestep_size, num_features)
    x = LSTM(num_features, stateful=True)(inputs)
    
    model = Model(inputs=inputs, outputs=x)
    model.compile(loss="mse",
                  optimizer="rmsprop",
                  metrics=["accuracy"])
    
    x = np.random.randint((10,2,4))
    y = np.ones((10,4))
    model.fit(x,y, epochs=100, batch_size=1)
    
    def get_internal_state(model):
        # get the internal state of the LSTM
        # see https://github.com/fchollet/keras/issues/218
        h, c = [K.get_value(s) for s, _ in model.state_updates]
        return h, c
    
    print "After fitting:", get_internal_state(model)
    
    for i in range(3):
        x = np.random.randint((10,2,4))
        model.predict(x)
        print "After predict:", get_internal_state(model)
    

    以下是训练后对get_internal_state 的调用的输出示例:

    After_fitting: (array([[ 1.,  1.,  1.,  1.]], dtype=float32), array([[  11.33725166,   11.8036108 ,  181.75688171,   25.50110626]], dtype=float32))
    After predict (array([[ 1.        ,  0.99999994,  1.        ,  1.        ]], dtype=float32), array([[   9.26870918,    8.83847237,  179.92633057,   28.89341927]], dtype=float32))
    After predict (array([[ 0.99999571,  0.9992013 ,  1.        ,  0.9915328 ]], dtype=float32), array([[   6.5174489 ,    8.55165958,  171.42166138,   25.49199104]], dtype=float32))
    After predict (array([[ 1.,  1.,  1.,  1.]], dtype=float32), array([[   9.78496075,    9.27927303,  169.95401001,   28.74017715]], dtype=float32))
    

    【讨论】:

      【解决方案2】:

      您正在调用model.predict(),这意味着在处理输入时网络的权重不会改变,因此当您输入[[.1],[.1],[.9]] 时,无论其他输入在两者之间接收什么,它总是会产生相同的结果。请注意,当您训练模型并预测测试数据时,这是首选行为。您不希望您提供的其他测试数据影响您的预测。

      您所期望的效果在 model.fit() 中可见,例如,您可以使用 model.train_on_batch() 对输入进行训练(并更新模型权重),然后调用 model.predict() 以查看输出的变化。

      编辑:如果您要寻找 LSTM 的状态而不是网络的权重,您应该将 stateful=True 传递给层的 init,默认情况下它设置为 False。使用 stateful 时,您也必须传递 batch_input_shape 参数。请参阅here 了解更多信息。请注意,如果您希望每个输入影响下一个预测,您必须将批量大小设置为 1(例如 batch_input_shape=(1,3,1)),因为评估是对批量中的样本并行进行的,它们不会相互影响。

      【讨论】:

      • 好的,我同意权重不会改变。但是 LTSM 的内存/状态呢?这不被认为是“重量”,对吧?我想知道是否真的转储了 LTSM 状态。
      • 好的,我明白了你的意思并编辑了我的答案。我希望它能回答这个问题。
      • @yalis 你能用stateful=True看到你想要的效果吗?如果需要,我可以提供一个工作示例。
      • @S.Mohsensh 一个工作示例将不胜感激。提前致谢。
      猜你喜欢
      • 2017-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 2017-08-31
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      相关资源
      最近更新 更多