我正在尝试建立一个用于时间序列压缩的LSTM自动编码器(目前只有一维,但也可以用于多维)。
先了解一下上下文:
我正在使用DeepNote开发模型,根据终端,安装的TensorFlow版本是带有Keras version 2.4.3 (Linux)的2.4.1。
对于训练数据,我使用来自Intel Berkeley Research Lab Dataset的大约400.000个特定传感器的数据点作为训练数据,另外40.000个作为测试数据。所有数据点都是传感器收集的温度。数据被分成小序列(通常每个序列20个数据点),因此重塑后的数据的结果形状是看起来像(19456, 20, 1)的(num_examples, sequence_length, dims)。该模型将一次对这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,这样序列的顺序是正确的。
发布于 2021-08-01 15:34:18
我想我已经解决了这个问题--或者更确切地说,我找到了一个解决方法。
问题确实出在stateful-related组件上。默认情况下,LSTM层将在处理完一批数据后重置其状态。在这种情况下的重置意味着它的所有状态再次设置为零。您还可以在重构的序列中看到,在每个批次的开始,重构的值太小。
将stateful参数设置为true将告知层保持其状态。但是,如果批处理大小大于1,则将并行计算序列的多个部分,因此无法共享有关状态的信息。因此,通过将批处理大小设置为1,该问题不会再次出现,但是现在训练所需的时间更长。
https://stackoverflow.com/questions/68117080
复制相似问题