- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 TensorFlow 对时间序列回归问题进行有状态 LSTM 试验。抱歉,我无法共享数据集。下面是我的代码。
train_feature = train_feature.reshape((train_feature.shape[0], 1, train_feature.shape[1]))
val_feature = val_feature.reshape((val_feature.shape[0], 1, val_feature.shape[1]))
batch_size = 64
model = tf.keras.Sequential()
model.add(tf.keras.layers.LSTM(50, batch_input_shape=(batch_size, train_feature.shape[1], train_feature.shape[2]), stateful=True))
model.add(tf.keras.layers.Dense(1))
model.compile(optimizer='adam',
loss='mse',
metrics=[tf.keras.metrics.RootMeanSquaredError()])
model.fit(train_feature, train_label,
epochs=10,
batch_size=batch_size)
当我运行上述代码时,在第一个 epoch 结束后,我会收到如下错误。
InvalidArgumentError: [_Derived_] Invalid input_h shape: [1,64,50] [1,49,50]
[[{{node CudnnRNN}}]]
[[sequential_1/lstm_1/StatefulPartitionedCall]] [Op:__inference_train_function_1152847]
Function call stack:
train_function -> train_function -> train_function
但是,如果我将 batch_size 更改为 1,将模型训练成功,并将模型训练的代码更改为以下代码。
total_epochs = 10
for i in range(total_epochs):
model.fit(train_feature, train_label,
epochs=1,
validation_data=(val_feature, val_label),
batch_size=batch_size,
shuffle=False)
model.reset_states()
尽管如此,对于非常大的数据(100 万行),由于 batch_size 为 1,因此模型训练需要很长时间。
所以,我想知道,如何训练批量大小大于 1(例如 64)的有状态 LSTM,而不会出现无效的 input_h 形状错误?
感谢您的回答。
最佳答案
解决方法是确保批处理大小永远不会在批处理之间发生变化。它们的大小必须相同。
一种方法是使用将您的数据集完美划分为大小相等的批处理的批处理大小。例如,如果数据的总大小为 1500 个示例,则使用 50 或 100 的批量大小或 1500 的其他适当除数。
batch_size = len(data)/proper_divisor
另一种方法是忽略任何小于指定大小的批处理,这可以使用 TensorFlow Dataset API 并将 drop_remainder
设置为 是的
。
batch_size = 64
train_data = tf.data.Dataset.from_tensor_slices((train_feature, train_label))
train_data = train_data.repeat().batch(batch_size, drop_remainder=True)
steps_per_epoch = len(train_feature) // batch_size
model.fit(train_data,
epochs=10, steps_per_epoch = steps_per_epoch)
当使用上述数据集 API 时,您还需要指定多少轮训练计为一个 epoch(本质上是多少批处理计为 1 个 epoch)。 tf.data.Dataset
实例(来自 tf.data.Dataset.from_tensor_slices
的结果)不知道它正在流式传输到模型的数据的大小,因此必须使用 steps_per_epoch
手动指定什么构成一个 epoch。
您的新代码将如下所示:
train_feature = train_feature.reshape((train_feature.shape[0], 1, train_feature.shape[1]))
val_feature = val_feature.reshape((val_feature.shape[0], 1, val_feature.shape[1]))
batch_size = 64
train_data = tf.data.Dataset.from_tensor_slices((train_feature, train_label))
train_data = train_data.repeat().batch(batch_size, drop_remainder=True)
model = tf.keras.Sequential()
model.add(tf.keras.layers.LSTM(50, batch_input_shape=(batch_size, train_feature.shape[1], train_feature.shape[2]), stateful=True))
model.add(tf.keras.layers.Dense(1))
model.compile(optimizer='adam',
loss='mse',
metrics=[tf.keras.metrics.RootMeanSquaredError()])
steps_per_epoch = len(train_feature) // batch_size
model.fit(train_data,
epochs=10, steps_per_epoch = steps_per_epoch)
您也可以包含验证集,如下所示(不显示其他代码):
batch_size = 64
val_data = tf.data.Dataset.from_tensor_slices((val_feature, val_label))
val_data = val_data.repeat().batch(batch_size, drop_remainder=True)
validation_steps = len(val_feature) // batch_size
model.fit(train_data, epochs=10,
steps_per_epoch=steps_per_epoch,
validation_steps=validation_steps)
警告:这意味着模型永远不会看到一些数据点。为了解决这个问题,您可以在每轮训练中打乱数据集,以便每个 epoch 留下的数据点发生变化,让每个人都有机会被模型看到。
buffer_size = 1000 # the bigger the slower but more effective shuffling.
train_data = tf.data.Dataset.from_tensor_slices((train_feature, train_label))
train_data = train_data.shuffle(buffer_size=buffer_size, reshuffle_each_iteration=True)
train_data = train_data.repeat().batch(batch_size, drop_remainder=True)
有状态的 RNN 及其变体(LSTM、GRU 等)需要固定的批量大小。原因很简单,因为有状态是实现截断反向传播的一种方式,通过将批处理的最终隐藏状态作为下一批的初始隐藏状态传递。第一批的最终隐藏状态必须与下一批的初始隐藏状态具有完全相同的形状,这要求批处理大小在各个批处理之间保持相同。
当您将批量大小设置为 64 时,model.fit
将使用 epoch 结束时的剩余数据作为批量,这可能没有多达 64 个数据点。因此,您会收到这样的错误,因为批量大小与有状态 LSTM 所期望的不同。批量大小为 1 没有问题,因为在一个时期结束时任何剩余的数据将始终包含恰好 1 个数据点,因此没有错误。更一般地说,1 始终是任何整数的除数。因此,如果您选择了数据大小的任何其他除数,则不会出现错误。
在您发布的错误消息中,最后一批的大小似乎是 49 而不是 64。附带说明:形状看起来与输入不同的原因是,在引擎盖下,keras 使用time_major(即第一个轴用于序列步骤)。当您传递一个表示 (batch_size, steps_per_sequence, num_features) 的形状为 (10, 15, 2) 的张量时,keras 会将其 reshape 为 (15, 10, 2)。
关于tensorflow - Stateful LSTM Tensorflow Invalid Input_h Shape Error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64159777/
我正在使用 TensorFlow 对时间序列回归问题进行有状态 LSTM 试验。抱歉,我无法共享数据集。下面是我的代码。 train_feature = train_feature.reshape((
我是一名优秀的程序员,十分优秀!