将时序数据馈入有状态LSTM的正确方法?

时间:2019-10-07 19:57:53

标签: python tensorflow machine-learning keras lstm

假设我有一个整数序列:

0,1,2, ..

,并且要根据给定的最后3个整数来预测下一个整数,例如:

[0,1,2]->5[3,4,5]->6

假设我这样设置模型:

batch_size=1
time_steps=3
model = Sequential()
model.add(LSTM(4, batch_input_shape=(batch_size, time_steps, 1), stateful=True))
model.add(Dense(1))

据我了解,该模型具有以下结构(请原谅):

enter image description here

第一个问题:我的理解正确吗?

请注意,我已经画出了先前的状态C_{t-1}, h_{t-1}进入图片,因为指定stateful=True时该图片已暴露。在这个简单的“下一个整数预测”问题中,应通过提供这些额外的信息来提高性能(只要先前的状态是由前三个整数产生的)。

这使我想到了我的主要问题:看来,标准做法(例如,请参见此blog postTimeseriesGenerator keras预处理实用程序)是供交错使用训练过程中对模型的一组输入。

例如:

batch0: [[0, 1, 2]]
batch1: [[1, 2, 3]]
batch2: [[2, 3, 4]]
etc

这让我感到困惑,因为这似乎需要第一个Lstm单元的输出(对应于第一时间步长)。看到这个图:

从tensorflow docs

  

有状态:布尔值(默认为False)。如果为True,则每个状态的最后一个状态   批次中索引i处的样本将用作初始状态   接下来的批次中索引i的样本。

似乎此“内部”状态不可用,并且所有可用状态都是最终状态。看到这个图:

因此,如果我的理解是正确的(显然不是这样),那么使用stateful=True时我们是否应该将不重叠的样本窗口馈送到模型中?例如:

batch0: [[0, 1, 2]]
batch1: [[3, 4, 5]]
batch2: [[6, 7, 8]]
etc

1 个答案:

答案 0 :(得分:6)

答案是:取决于眼前的问题。对于单步预测的情况-是的,可以,但是不必这样做。但是,无论您是否这样做,都会对学习产生重大影响。


批处理与示例机制(“参见AI” =参见“其他信息”部分)

所有模型都将样本视为独立实例;一批32个样品就像一次32个样品(有差异-参见AI)。从模型的角度来看,数据分为批次维度batch_shape[0]和要素维度batch_shape[1:]-两个“不要说话”。两者之间的唯一关系是通过渐变(请参见AI)。


重叠与非重叠批处理

也许理解它的最佳方法是基于信息。我将从时间序列二进制分类开始,然后将其与预测联系起来:假设您有10分钟的EEG记录,每个记录有240000个时间步长。任务:癫痫发作还是非癫痫发作?

  • 由于240k对于RNN来说处理不了,因此我们使用CNN进行降维
  • 我们可以选择使用“滑动窗口”-即一次输入一个细分市场;我们用54k

取10个样本,形状为(240000, 1)。怎么喂?

  1. (10, 54000, 1),包括所有样本,切片为sample[0:54000]; sample[54000:108000] ...
  2. (10, 54000, 1),包括所有样本,切片为sample[0:54000]; sample[1:54001] ...

您选择上述哪两个?如果为(2),则您的神经网络将不会混淆这10个样本的非癫痫发作。但这对其他任何样本也一无所知。也就是说,它会大大过拟合,因为每次迭代所看到的信息几乎没有差异(1/54000 = 0.0019%)-因此,您基本上是在为它提供同一批次连续几次。现在假设(3):

  1. (10, 54000, 1),包括所有样本,切片为sample[0:54000]; sample[24000:81000] ...

更合理;现在我们的窗户有50%的重叠,而不是99.998%。


预测:重叠不好?

如果您要进行一步式预测,现在信息格局将发生变化:

  • 可能是,您的序列长度从240000开始,所以任何类型的重叠都不会受到“相同批次多次”的影响
  • 预测与分类从根本上有所不同,因为您输入的每个子样本的标签(下一时间步)都不同;分类在整个序列中使用一个

这会极大地改变您的损失函数,以及将损失函数减至最小的“好的做法”:

  • 预测器必须对其初始样本具有鲁棒性,尤其是对于LSTM-因此,我们通过滑动显示的序列来训练每个这样的“开始”
  • 由于标签的时间步长不同,所以损失函数随时间步长变化很大,因此过拟合的风险要小得多

我该怎么办?

首先,请确保您了解整篇文章,因为这里没有什么是真正的“可选”。然后,这是关于重叠与不重叠的关键,每批

  1. 转移了一个样本:模型可以更好地预测每个起始步骤的下一步-这意味着:(1)LSTM对初始细胞状态的鲁棒性; (2)LSTM预测,只要落后X步,前进的步伐就很好
  2. 许多样本,在以后批次中进行了移位:模型不太可能“记忆”训练组和过度拟合

您的目标:平衡两者; 1在2之上的主要优势是:

  • 2可以使模型忘记看到的样本
  • 1允许模型通过检查多个起点和终点(标签)上的样本并相应地平均梯度来提取更好的质量特征

我应该在预测中使用(2)吗?

  • 如果您的序列长度非常长,并且您有能力负担“滑动窗口” w /〜其长度的50%,但这取决于数据的性质:信号(EEG)?是。股票,天气?怀疑它。
  • 多对多预测;比较常见的是(2),每个序列较长。

LSTM有状态:实际上可能对您的问题完全没有用。

当LSTM不能一次处理整个序列时使用有状态,因此它是“分裂的”-或当反向传播需要不同的梯度时。对于前者,想法是-LSTM在评估后者时会考虑前者的顺序:

  • t0=seq[0:50]; t1=seq[50:100]很有道理; t0在逻辑上指向t1
  • seq[0:50] --> seq[1:51]没有任何意义; t1不是因t0的因果关系

换句话说:在有状态的批次中不要重叠。相同的批次是可以的,再次是独立的-样本之间没有“状态”。

何时使用有状态:何时LSTM在评估下一个批次时受益于前一个批次。该可以包括单步预测,但前提是您不能一次输入整个序列:

    所需:100个时间步。可以做:50。所以我们像上面的第一个项目符号一样设置了t0, t1
  • 问题:难以以编程方式实现。您需要找到一种在不应用渐变的情况下馈入LSTM的方法-例如冻结权重或设置lr = 0

LSTM何时以及如何在有状态的情况下“通过状态”?

  • 何时:仅批到批;样本是完全独立的
  • 方法:在Keras中,只有批样本到批样本stateful=True 需要指定{{1 }}而不是batch_shape-因为Keras在编译时会建立LSTM的input_shape个独立状态

在上面,您不能执行此操作:

batch_size

这意味着# sampleNM = sample N at timestep(s) M batch1 = [sample10, sample20, sample30, sample40] batch2 = [sample21, sample41, sample11, sample31] 因果遵循21-会破坏培训。而是:

10

批次与示例:其他信息

“批次”是一组样本-1个或更多(假定对于此答案,始终为后者) 。三种遍历数据的方法:批量梯度下降(一次整个数据集),随机GD(一次一个样本)和Minibatch GD(in-between)。 (但是,在实践中,我们也称最后一个SGD,并且只区分vs BGD-对此答案假设是这样。)差异:

  • SGD从未真正优化列车的损失函数-仅对其“近似值”进行了优化;每个批次都是整个数据集的子集,计算得出的梯度仅与最小化该批次的损失 有关。批次大小越大,其损失函数就越类似于火车组。
  • 以上可以扩展为适合批次与样本:样本是批次的近似值,或者数据集的近似性较差
  • 首先拟合16个样本,然后再拟合16个样本,一次不同-因为权重在中间进行更新,因此后半部分的模型输出会改变
  • 选择BGD而不是BGD的主要原因实际上不是计算上的局限性-而是大多数情况下它是优越的。简单地解释:通过BGD可以很容易地过拟合,而SGD可以通过探索更多样化的损失空间来收敛到更好的测试数据解决方案。

奖金图表