当脚本在较大的数据集上运行时,LSTM Autoencoder 没有进展

Posted

技术标签:

【中文标题】当脚本在较大的数据集上运行时,LSTM Autoencoder 没有进展【英文标题】:LSTM Autoencoder no progress when script is running on larger dataset 【发布时间】:2018-01-30 03:54:44 【问题描述】:

this LSTM Autoencoder 中"test.py" 中p_input 的形状为(128,8,1);表示 128 组 8 位数字。我正在尝试将此模型调整为具有 4 组 25,000 个时间步长(基本上是 0 秒到 25,000 秒)的基于时间序列的数据。我尝试将此数据集输入到 p_input 中,形状为 (4,25000,1) 并且没有发生错误。然而,当我运行脚本时,我没有得到iter 1: 0.01727, iter 2: 0.00983, ... 的任何打印反馈,所以我认为脚本有问题。我还尝试将 batch_num 更改为 4 并将 step_num 更改为 25,000 直接到未经编辑的“test.py”文件中,并且没有出现打印反馈的相同结果。

我的想法是,在“test.py”中,p_inputs 计算 tf.splittf.squeeze 操作的时间太长了。另一个想法是我可能需要增加 hidden_num 中隐藏 LSTM 单元的数量和/或增加 epoch 数量(iteration)。此外,batch_num 可能必须大于step_num。我用 step_num = 4batch_num = 25000 用“test.py”尝试了这个,脚本运行正常并打印了反馈。

让我知道您对阻止脚本运行可能存在的问题的看法。

【问题讨论】:

【参考方案1】:

输入的第二个维度是网络通过BPTT 算法展开计算梯度的次数。

这个想法是通过将每个时间步“展开”为网络的新层,将循环网络(如 LSTM)转换为前馈网络。

当您一起提供整个时间序列(即 25000 个时间步)时,您将网络展开 25000 次,即您将获得一个具有 25000 层的展开前馈网络!!

因此,即使我不知道您为什么没有收到任何错误,但问题可能与内存不足问题有关。您无法将 25000 层的变量放入内存中。

当您必须处理较长的时间序列时,您需要将数据拆分成块(假设为 20 个时间步长)。您每次运行提供一个块。然后,在接下来的每次运行中,您需要将网络的初始状态恢复为上一次运行的最后状态。

我可以给你举个例子。您现在拥有的(出于实际原因,我忽略了第三维)是一个 4x25000 的向量,其形状如下:

--------------------- 25000----------------------
|
|
4
|
|
--------------------------------------------------

您现在必须将其拆分为如下块:

----20-----  ----20-----  ----20-----
|         |  |         |  |         |
|         |  |         |  |         |
4         |  4         |  4         |  [...]
|         |  |         |  |         |
|         |  |         |  |         |
-----------  -----------  ----------- 

您每次提供一个 4x20 的单块。然后,每次卡盘后 LSTM 的最终状态必须作为下一个卡盘的输入提供。

所以你的feed_dict 必须是这样的:

feed_dict =x: input_4_20, 
            state.c = previous_state.c, 
            state.h=previous_state.h

请参阅 Tensorflow 的 LM tutorial,了解如何将 LSTM 的状态提供给下一次运行的示例。

Tensorflow 提供了一些自动执行此操作的功能。查看 RNN API 上的Tensorflow DevSummit Tutorial 了解更多信息。我链接了解释所需功能的确切第二个。函数是tf.contrib.training.batch_sequences_with_states(...)

作为最后的建议,我建议您重新考虑您的任务。事实上,25000 的时间序列是一个非常长的序列,我担心即使是 LSTM 也无法管理如此久远的依赖关系。我的意思是,当您处理该系列的第 24000 个元素时,LSTM 状态可能已经忘记了关于第一个元素的所有内容。在这些情况下,请尝试查看您的数据以了解您的现象的规模。如果您不需要一秒的粒度(即,您的系列高度冗余,因为功能不会及时快速变化),请缩小您的系列以管理更短的序列。

【讨论】:

感谢您的回复。 25,000 个时间步来自插值和点数的选择。我总是可以改变它。最大时间步数应该是多少?即使在阅读了所有链接之后,我也不太明白您是如何进行分块的。 我编辑了答案。告诉我是否更清楚。对于最大时间步数,这取决于您的需求。 LSTM 能够学习过去相当远的依赖关系,但根据我的经验,超过 100 个时间步长并不好。所以作为单个输入,不要超过时间维度太长的chunk(保持20-50更好)

以上是关于当脚本在较大的数据集上运行时,LSTM Autoencoder 没有进展的主要内容,如果未能解决你的问题,请参考以下文章

Python Pyspark 脚本在整个数据集上失败,但适用于单个文件

图像分类基于PyTorch搭建LSTM实现MNIST手写数字体识别(单向LSTM,附完整代码和数据集)

张量流 LSTM 模型中的 NaN 损失

PyTorch基于 LSTM 的手写数字识别(MNIST)

当使用多个不同长度和多个特征的时间序列时,如何为 LSTM 准备数据?

Keras vs PyTorch LSTM 不同的结果