当脚本在较大数据集上 运行 时,LSTM 自动编码器没有进展

LSTM Autoencoder no progress when script is running on larger dataset

this LSTM Autoencoder for "test.py"p_input的形状为(128,8,1);意思是 128 组 8 位数字。我正在尝试使用 4 组 25,000 个时间步长(基本上是 0 秒到 25,000 秒)使该模型适应基于时间序列的数据。我尝试将此数据集输入到形状为 (4,25000,1) 的 p_input 中,但没有发生任何错误。然而,当我 运行 脚本时,我没有得到 iter 1: 0.01727, iter 2: 0.00983, ... 而不是从脚本中得到任何打印的反馈,所以我假设有什么东西阻碍了脚本。我还尝试将 batch_num 更改为 4 并将 step_num 更改为 25,000 直接到未经编辑的 "test.py" 文件中,结果相同,没有打印反馈。

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

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

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

这个想法是将循环网络(如 LSTM)通过 "unrolling" 每个时间步转换为前馈网络作为网络的新层。

当您一起提供整个时间序列(即 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}

有关如何将 LSTM 的状态提供给下一个 运行 的示例,请参见 Tensorflow 的 LM tutorial

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

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