当前位置: 首页 > 面试题库 >

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

漆雕成弘
2023-03-14
问题内容

假设我有一个整数序列:

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))

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

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

这使我想到了一个主要问题:似乎标准做法(例如,参见此博客文章和
TimeseriesGenerator keras预处理实用程序)是在训练过程中向模型提供一组交错的输入。

For example:

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

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

从tensorflow
docs:

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

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

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

问题答案:

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

批处理与示例机制(“参见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)LSTM对初始细胞状态的鲁棒性;(2)在落后X步的情况下,LSTM可以很好地预测前进
许多样本在以后的批次中转移:模型不太可能“记住”火车设置和过拟合
您的目标:平衡两者;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 需要你指定batch_shape,而不是input_shape-因为,Keras建立batch_size了LSTM的独立的国家在编制
    根据以上情况,您不能执行以下操作:

    batch1 = [sample10, sample20, sample30, sample40]
    batch2 = [sample21, sample41, sample11, sample31]

This implies 21 causally follows 10 - and will wreck training. Instead
do:

batch1 = [sample10, sample20, sample30, sample40]
batch2 = [sample11, sample21, sample31, sample41]

批次与样本:其他信息

“批”是一组样本-1个或更大(此
答案总是假定为后者)。三种迭代数据的方法:批量梯度下降
(一次整个数据集),随机GD(一次一个样本)和Minibatch
GD(中间)。(
但是,在实践中,我们也称最后一个SGD,仅区分vs BGD-
对此答案假设如此。)差异:

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


 类似资料:
  • 问题内容: 我似乎在将数据推入状态数组时遇到问题。我正在尝试以这种方式实现它: 但是我相信这是不正确的方式,并导致可变性问题? 问题答案: 返回扩展数组的长度,而不是数组本身。Array.prototype.push()。 我猜您希望返回的值是数组。 不变性 似乎这是React的行为: 切勿直接更改this.state,因为此后调用setState()可能会替换您所做的更改。将此this.stat

  • 问题内容: 给定训练有素的LSTM模型,我想对单个时间步执行推断,即在下面的示例中。在每个时间步之后,需要记住下一个“批”的内部LSTM状态(内存和隐藏状态)。对于推论的最开始,在给定输入的情况下计算内部LSTM状态。然后将它们存储在传递给LSTM的对象中。在训练期间,此状态会在每个时间步更新。但是,为了进行推断,我希望在批处理之间保存初始状态,即,仅需在最开始时计算初始状态,然后在每次“批处理”

  • 问题内容: 我正在尝试为我要适应的模型找出正确的语法。这是一个时间序列预测问题,在将其输入LSTM之前,我想使用一些密集层来改善时间序列的表示形式。 这是我正在使用的虚拟系列: 首先,我将安装没有密集层的LSTM。这要求我重塑数据: 这个对吗? 这些教程使单个时间序列在第一个维度上应该具有1,然后是时间步数(1000),然后是协变量数(3)。但是,当我这样做时,模型无法编译。 在这里,我编译并训练

  • 我已经开始学习ReactJS,有一个关于无状态和有状态组件的问题。一般来说,我遵循组件和容器的分离,如下所示。有状态函数在组件文件夹中,其他逻辑操作在容器文件夹下。文件夹结构 让我们思考材料UI下拉列表。 为了打开和关闭下拉菜单和方法更改打开状态,这意味着它是有状态组件。但没有其他变化(省略年龄设置)。它似乎是可重用的组件,但包括状态与非常简单的操作,如打开和关闭。我应该放入哪个文件夹?容器还是组

  • 我在UI中有一个按钮,在OnClick事件处理程序中,我必须运行一个设置间隔计时器。在设置间隔计时器中,我检查一个条件,如果条件满足,我将更新状态,但它不能正常工作。 00); 在倒计时功能中有一个console.log,它总是打印“0 false”,但UI中的组件网正在更新为正确的数字。 你能告诉我为什么吗 控制台中的计数始终为“0”。log 代码沙盒链接:https://codesandbox

  • 问题内容: 我做了一个小实验:http : //codepen.io/hawkphil/pen/NqMomm?editors=101 这是我的状态流(单击按钮): 在每个状态变化,我在出了 但是,你可以在看线,奇怪的事情发生了。我从“后退”按钮获得的“思维”,它显示为先前的状态()。这是不对的,对吧?它应该显示为以前的状态,因为我必须通过单击按钮来 手动*状态。我还显示了(line )中的值,以防