【问题标题】:LSTM autoencoder noisy reconstructionLSTM 自动编码器噪声重建
【发布时间】:2021-06-24 13:50:28
【问题描述】:

我正在尝试构建一个用于时间序列压缩的 LSTM 自动编码器(目前只有一维,但也可能是多维的)。

先说一点上下文:

我正在使用DeepNote 开发模型,根据终端安装的TensorFlow 版本是2.4.1,Keras 版本是2.4.3 (Linux)

对于训练数据,我使用来自Intel Berkeley Research Lab Dataset 的特定传感器的大约 400.000 个数据点作为训练数据,另外 40.000 个作为测试数据。所有数据点都是传感器收集的温度。 数据被分成小序列(通常每个序列有 20 个数据点),因此重构数据的结果形状为(num_examples, sequence_length, dims),可能看起来像(19456, 20, 1)。 该模型将一次对这 20 个长度的序列之一进行预测。

这是模型最简单形式的代码

n_dims = data.shape[2]
sample_size = data.shape[1]

inputs = Input(shape=(data.shape[1],n_dims), batch_size=batch_size)

# encoder
x = LSTM(n_dims, activation='relu', return_sequences=False, stateful=True, kernel_regularizer=regularizers.l2(regularization))(inputs)
    
# decoder
# Because sequences are not returned by encoder for (better) compression, have to be spread
# for decoder
x = RepeatVector(sample_size)(x)

decoding = LSTM(n_dims, activation='relu', return_sequences=True, stateful=True, kernel_regularizer=regularizers.l2(regularization))(x)


model = Model(inputs=inputs, outputs=decoding)
model.compile(optimizer=optimizer, loss=loss)

模型总结:

Model: "model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(1, 20, 1)]              0         
_________________________________________________________________
lstm (LSTM)                  (1, 1)                    12        
_________________________________________________________________
repeat_vector (RepeatVector) (1, 20, 1)                0         
_________________________________________________________________
lstm_1 (LSTM)                (1, 20, 1)                12        
=================================================================
Total params: 24
Trainable params: 24
Non-trainable params: 0

这是训练模型的代码:

model.fit(
    x_train, x_train,    # learns an identity function, thus x_train is label and input at the same time
    epochs=num_epochs, batch_size=batch_size,
    shuffle=False,
    validation_data=(x_test, x_test),
    verbose=verbosity
)

我的问题:

该模型或多或少能够重建数据遵循的趋势,但是如果放大,就会出现这种奇怪的周期性行为。 以下是模型输出的图像。在显示输出时,我将每个序列连接在一起,以便我得到数据的原始形状。第一张图片显示重建放大on 5000 data points和第二张on 100 data points

令人费解的是句号的长度总是等于sequence length(例如上面代码中的20)。如果我将其更改为 40,这些颠簸将每 50 个数据点发生一次。我的理论是,这是由于 LSTM 单元在每个训练示例之后都会重置其状态,因此无法将任何状态或上下文“转移”到新的状态或上下文中。通过互联网阅读,我将stateful 参数设置为true,因为这会阻止模型按照我的理解重置状态。另外为了训练,我设置了shuffle=False,使得序列的顺序正确。

【问题讨论】:

  • 我忘了提什么,但我不知道这是否重要:我使用的batch_size 通常是 128(也试过 1,但也没有用),@ 987654336@ 始终为 0,num_epochs 为 100(但在 10-15 个 epoch 之后它并没有学到更多)
  • 嗨@nerobbel,这仍然相关吗?您能否与我分享您的 Deepnote 项目,以便我能以更快的方式提供帮助?虽然没有承诺。
  • 嘿,感谢您对此进行调查 :) 我设法解决了,如果您对更多细节感兴趣,请随时询问!

标签: python tensorflow keras lstm autoencoder


【解决方案1】:

我想我解决了这个问题 - 或者说找到了解决方法。

问题确实是与stateful 相关的组件。默认情况下,LSTM 层将在处理完一批数据后重置其状态。在这种情况下重置意味着它的所有状态再次设置为零。您还可以在重构序列中看到,在每批开始时,重构值太小。

stateful 参数设置为true 将告诉图层保持其状态。然而,如果批量大小大于 1,序列的多个部分将并行计算,因此无法共享有关状态的信息。因此,通过将批量大小设置为 1,问题不会再次出现,但现在训练需要更长的时间。

【讨论】: