【问题标题】:Understanding Keras LSTMs: Role of Batch-size and Statefulness理解 Keras LSTM:批量大小和状态的作用
【发布时间】:2018-07-07 14:04:27
【问题描述】:

来源

有几个来源解释了有状态/无状态 LSTM 以及我已经阅读过的 batch_size 的作用。我稍后会在我的帖子中提及它们:

[1]https://machinelearningmastery.com/understanding-stateful-lstm-recurrent-neural-networks-python-keras/

[2]https://machinelearningmastery.com/stateful-stateless-lstm-time-series-forecasting-python/

[3]http://philipperemy.github.io/keras-stateful-lstm/

[4]https://machinelearningmastery.com/use-different-batch-sizes-training-predicting-python-keras/

还有其他 SO 线程,例如 Understanding Keras LSTMsKeras - stateful vs stateless LSTMs,但它们并没有完全解释我在寻找什么。


我的问题

我仍然不确定关于状态和确定 batch_size 的任务的正确方法是什么。

我有大约 1000 个独立的时间序列 (samples),每个时间序列的长度约为 600 天 (timesteps)(实际上是可变长度,但我考虑将数据修剪为一个恒定的时间范围),具有 8 个特征(或input_dim) 对于每个时间步长(某些特征与每个样本相同,每个样本都有一些特征)。

Input shape = (1000, 600, 8)

其中一个特征是我想要预测的,而其他的(应该是)支持这个“主要特征”的预测。我将为 1000 个时间序列中的每一个都这样做。对这个问题建模的最佳策略是什么?

Output shape = (1000, 600, 1)


什么是批处理?

来自 [4]:

Keras 使用快速符号数学库作为后端,例如 TensorFlow 和 Theano。

使用这些库的一个缺点是,无论您是在训练网络还是进行预测,都必须预先定义一次数据的形状和大小并保持不变。

[…]

当您希望进行的预测少于批量大小时,这确实会成为一个问题。例如,您可能会通过大批量获得最佳结果,但您需要在时间序列或序列问题等问题上一次对一个观察结果进行预测。

在我看来,这听起来像是一个“批处理”将沿timesteps-维度拆分数据。

但是,[3] 声明:

换句话说,无论何时训练或测试 LSTM,您首先必须构建形状为 nb_samples, timesteps, input_dim 的输入矩阵 X,其中批量大小除以 nb_samples。例如,如果 nb_samples=1024batch_size=64,这意味着您的模型将接收 64 个样本的块,计算每个输出(无论每个样本的时间步数是多少),平均梯度并传播它以更新参数向量.

在深入研究 [1] 和 [4] 的示例时,Jason 总是将他的时间序列拆分为仅包含 1 个时间步长的几个样本(在他的示例中完全确定了序列)。所以我认为这些批次真的是沿着samples-轴分开的。 (但是他的时间序列拆分方法对我来说对长期依赖问题没有意义。)

结论

假设我选择batch_size=10,这意味着在一个时期内,权重更新 1000 / 10 = 100 次,随机选择 10 个,包含 600 x 8 值的完整时间序列,当我稍后想用模型,我总是需要为它提供 10 个完整时间序列的批次(或使用 [4] 中的解决方案 3,将权重复制到具有不同 batch_size 的新模型)。

batch_size 的原则已了解 - 但仍不知道 batch_size 的价值是多少。以及如何确定它


有状态

KERAS documentation 告诉我们

您可以将 RNN 层设置为“有状态”,这意味着为一个批次中的样本计算的状态将被重新用作下一批中的样本的初始状态。

如果我将我的时间序列拆分为几个 samples(如 [1] 和 [4] 的示例中),那么我的依赖项想要跨多个批次建模,或者批次跨度样本彼此相关,我可能需要一个有状态的网络,否则不需要。这是一个正确而完整的结论吗?

所以对于我的问题,我想我不需要有状态的网络。我会将我的训练数据构建为形状为 (samples, timesteps, features) 的 3D 数组,然后调用 model.fit 并使用尚未确定的 batch_size。示例代码可能如下所示:

model = Sequential()
model.add(LSTM(32, input_shape=(600, 8)))   # (timesteps, features)
model.add(LSTM(32))
model.add(LSTM(32))
model.add(LSTM(32))
model.add(Dense(1, activation='linear'))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(X, y, epochs=500, batch_size=batch_size, verbose=2)

【问题讨论】:

    标签: python keras lstm recurrent-neural-network


    【解决方案1】:

    让我通过一个例子来解释一下:

    假设您有以下系列:1,2,3,4,5,6,...,100。你必须决定你的 lstm 将学习多少个时间步长,并重新塑造你的数据。如下:

    如果您决定 time_steps = 5,则必须以这种方式将时间序列重塑为样本矩阵:

    1,2,3,4,5 -> 样本1

    2,3,4,5,6 -> 样本2

    3,4,5,6,7 -> 样本3

    等等……

    通过这样做,您将得到一个形状矩阵(96 个样本 x 5 个时间步)

    这个矩阵应该被重塑为 (96 x 5 x 1),表明 Keras 你只有 1 个时间序列。如果您有更多并行时间序列(如您的情况),则对每个时间序列执行相同的操作,因此您将以每个形状(96 个样本 x 5 个时间步长)的 n 个矩阵(每个时间序列一个)结束。

    为了争论,假设你是 3 个时间序列。您应该将所有三个矩阵连接成一个形状的张量(96 个样本 x 5 timeSteps x 3 timeSeries)。对于这个例子,你的 lstm 的第一层是:

        model = Sequential()
        model.add(LSTM(32, input_shape=(5, 3)))
    

    32 作为第一个参数完全取决于您。这意味着在每个时间点,您的 3 个时间序列将成为 32 个不同的变量作为输出空间。更容易将每个时间步视为具有 3 个输入和 32 个输出的完全连接层,但计算量与 FC 层不同。

    如果您要堆叠多个 lstm 层,请使用 return_sequences=True 参数,因此该层将输出整个预测序列,而不仅仅是最后一个值。

    您的目标应该是您要预测的系列中的下一个值。

    综上所述,假设您有以下时间序列:

    时间序列 1(主):1,2,3,4,5,6,..., 100

    时间序列 2(支持):2、4、6、8、10、12、...、200

    时间序列 3(支持):3、6、9、12、15、18、...、300

    创建输入和目标张量

    x     -> y
    

    1,2,3,4,5 -> 6

    2,3,4,5,6 -> 7

    3,4,5,6,7 -> 8

    重新格式化其余时间序列,但忘记目标,因为您不想预测这些序列

    创建你的模型

        model = Sequential()
        model.add(LSTM(32, input_shape=(5, 3), return_sequences=True)) # Input is shape (5 timesteps x 3 timeseries), output is shape (5 timesteps x 32 variables) because return_sequences  = True
        model.add(LSTM(8))  # output is shape (1 timesteps x 8 variables) because return_sequences = False
        model.add(Dense(1, activation='linear')) # output is (1 timestep x 1 output unit on dense layer). It is compare to target variable.
    

    编译并训练。一个好的批量大小是 32。批量大小是为了更快的计算而拆分样本矩阵的大小。只是不要使用有状态的

    【讨论】:

    • 所以你有 1000 个独立的序列,每个序列有 600 步长,你将基于 101 个时间步训练你的 lstm。所以,最后你会得到(500 samples x 101 length each x 1000 series)
    • 好吧,也许我们在这里谈论的不是同一个词。假设我有 3 个系列:最高温度、最低温度和纽约 360 天的污染量。我想研究这三个系列之间的关系,以预测污染。您的 lstm 将学习过去 30 天。所以你的尺寸是(330 samples x 30 time steps each x 3 series)。希望对你有帮助
    • 好的,我想我明白了。现在假设我不仅对 NY,而且对总共 1000 个城市都有相同的模型,并且想要拟合一个对 所有 城市有效的模型。当然,实际上我需要的不仅仅是这 3 个系列,但为简单起见,我们假设其中包含所有相关信息以进行预测。所以在这种情况下,我最终会得到(1000 x 330 samples x 30 time steps each x 3 series)。请确认我的假设。
    • 好的!我现在明白了。是的,对于您的情况,您最终会得到这样的维度。我不明白你在很多情况下都有相同的系列。这里的术语很复杂哈哈。问候
    • 很好的答案。为我澄清了术语,但仍然存在一个问题。为什么不建议使用有状态?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 1970-01-01
    • 2018-10-07
    • 1970-01-01
    • 2019-12-23
    • 2017-09-27
    • 2018-04-23
    相关资源
    最近更新 更多