Python Keras fit_generator()-时间序列的批处理是如何工作的?
上下文: 我目前正在使用Keras和Tensorflow后端进行时间序列预测,因此研究了提供的教程 在本教程之后,我谈到了Python Keras fit_generator()-时间序列的批处理是如何工作的?,python,tensorflow,keras,generator,recurrent-neural-network,Python,Tensorflow,Keras,Generator,Recurrent Neural Network,上下文: 我目前正在使用Keras和Tensorflow后端进行时间序列预测,因此研究了提供的教程 在本教程之后,我谈到了fit\u generator()方法的生成器。 此生成器生成的输出如下(左示例,右目标): 在本教程中使用了TimeSeriesGenerator,但对于我的问题,如果使用自定义生成器或此类,则是次要的。 关于数据,我们每个历元有8个步骤和一个形状样本(8,1,2,2)。 该发生器被馈送到由LSTM实现的递归神经网络 我的问题 fit_generator()只允许每个批次有
fit\u generator()
方法的生成器。
此生成器生成的输出如下(左示例,右目标):
在本教程中使用了TimeSeriesGenerator
,但对于我的问题,如果使用自定义生成器或此类,则是次要的。
关于数据,我们每个历元有8个步骤和一个形状样本(8,1,2,2)。
该发生器被馈送到由LSTM实现的递归神经网络
我的问题
fit_generator()
只允许每个批次有一个目标,由TimeSeriesGenerator
输出。
当我第一次读到fit()的batches选项时,我认为我可以有多个样本和相应数量的目标(按批处理,即逐行处理)。但是fit_generator()
不允许这样做,因此显然是错误的。
例如,这看起来像:
[[[10. 15. 20. 25.]]] => [[30. 35.]]
[[[20. 25. 30. 35.]]] => [[40. 45.]]
|-> Batch no. 1: 2 Samples | 2 Targets
---------------------------------------------
[[[30. 35. 40. 45.]]] => [[50. 55.]]
[[[40. 45. 50. 55.]]] => [[60. 65.]]
|-> Batch no. 2: 2 Samples | 2 Targets
---------------------------------------------
...
其次,我认为,例如,[10,15]和[20,25]被连续用作目标[30,35]的RNN输入,这意味着这与输入[10,15,20,25]类似。由于使用第二种方法时RNN的输出不同(我对其进行了测试),因此这也必然是一个错误的结论
因此,我的问题是:
[[40]这样的输入,
45],[50,55]]]=>
[[40,45,50,55]]=>[[60,65]]
根据今天的答案进行编辑
由于对我对样本和目标的定义存在一些误解,我遵循Keras试图告诉我的理解: ValueError:输入数组的采样数应与目标数组的采样数相同。找到1个输入样本和2个目标样本 例如,当我创建一个如下所示的批时,会发生此错误:
#This is just a single batch - Multiple batches would be fed to fit_generator()
(array([[[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]]]),
array([[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]]))
这应该是一个包含两个长度为5的时间序列(5个连续数据点/时间步)的单个批次,其目标也是两个相应的序列<代码>[5,6,7,8,9]是[0,1,2,3,4]
的目标,[10,11,12,13,14]
是[5,6,7,8,9]
的相应目标其中的样本形状将是
形状(批次数量、每批次元素数量、序列大小)
和目标形状形状(每批次元素数量、序列大小)
Keras看到2个目标样本(在ValueError中),因为我有两个提供3D样本作为输入,2D目标作为输出(可能我不知道如何提供3D目标…)
无论如何,根据@todays answer/comments,Keras将其解释为两个时间步和五个功能。关于我的第一个问题(在这个编辑示例中,我仍然将序列视为我的序列的目标),我寻求如何/如果我可以实现这一点,以及这样一个批次的外观如何(就像我试图在问题中可视化的那样)。简短回答: 为什么每批只允许一个目标(我知道有一些解决办法,但一定有原因) 事实并非如此。批次中目标样品的数量没有限制。唯一的要求是,每个批次中的输入和目标样本数量应相同。阅读较长的答案以进一步澄清 我如何理解一批的计算?意思是,像
[[40]这样的输入,
45],[50,55]]=>[[60,65]]
已处理,为什么它不是类似于[[40,45,50,55]]]=>[[60,65]
第一个是多变量时间序列(即每个时间步有多个功能),第二个是单变量时间序列(即每个时间步有一个功能)。因此,它们并不等同。阅读较长的答案以进一步澄清
长答案:
我将给出我在评论部分中提到的答案,并尝试使用示例对此进行详细说明:
我认为您正在混合样本、时间步、功能和目标。让我描述一下我是如何理解它的:在您提供的第一个示例中,每个输入示例似乎由两个时间步组成,例如[10,15]
和[20,25]
,其中每个时间步由两个特性组成,例如10和15或20和25。此外,相应的目标由一个时间步组成,例如[30,35]
,该时间步还具有两个特征。换句话说,批中的每个输入样本必须具有相应的目标。然而,每个输入样本及其对应目标的形状可能不一定相同
例如,考虑一个模型,它的输入和输出都是时间序列。如果我们将每个输入样本的形状表示为(input\u num\u timesteps,input\u num\u features)
,将每个目标(即输出)数组的形状表示为(output\u num\u timesteps,output\u num\u features)
,我们将出现以下情况:
1) 输入和输出时间步数相同(即,input\u num\u timesteps==output\u num\u timesteps
)。例如,以下模型可以实现这一点:
from keras import layers
from keras import models
inp = layers.Input(shape=(input_num_timesteps, input_num_features))
# a stack of RNN layers on top of each other (this is optional)
x = layers.LSTM(..., return_sequences=True)(inp)
# ...
x = layers.LSTM(..., return_sequences=True)(x)
# a final RNN layer that has `output_num_features` unit
out = layers.LSTM(output_num_features, return_sequneces=True)(x)
model = models.Model(inp, out)
from keras import layers
from keras import models
inp = layers.Input(shape=(input_num_timesteps, input_num_features))
# a stack of RNN layers on top of each other (this is optional)
x = layers.LSTM(..., return_sequences=True)(inp)
# ...
x = layers.LSTM(...)(x) # The last layer ONLY returns the last output of RNN (i.e. return_sequences=False)
# repeat `x` as needed (i.e. as the number of timesteps in output timseries)
x = layers.RepeatVector(output_num_timesteps)(x)
# a stack of RNN layers on top of each other (this is optional)
x = layers.LSTM(..., return_sequences=True)(x)
# ...
out = layers.LSTM(output_num_features, return_sequneces=True)(x)
model = models.Model(inp, out)
2) 输入和输出时间步数不同(即,input\u num\u timesteps~=output\u num\u timesteps
)。这通常是通过首先使用一个或多个LSTM层的堆栈将输入时间序列编码为向量,然后重复该向量output_num_time来实现的
from keras import layers
from keras import models
inp = layers.Input(shape=(input_num_timesteps, input_num_features))
# a stack of RNN layers on top of each other (this is optional)
x = layers.LSTM(..., return_sequences=True)(inp)
# ...
x = layers.LSTM(...)(x) # The last layer ONLY returns the last output of RNN (i.e. return_sequences=False)
# repeat `x` as needed (i.e. as the number of timesteps in output timseries)
x = layers.RepeatVector(output_num_timesteps)(x)
# a stack of RNN layers on top of each other (this is optional)
x = layers.LSTM(..., return_sequences=True)(x)
# ...
out = layers.LSTM(output_num_features, return_sequneces=True)(x)
model = models.Model(inp, out)
inp = layers.Input(shape=(input_num_timesteps, input_num_features))
# a stack of RNN layers on top of each other (this is optional)
x = layers.LSTM(..., return_sequences=True)(inp)
# ...
x = layers.LSTM(...)(x) # The last layer ONLY returns the last output of RNN (i.e. return_sequences=False)
out = layers.Dense(output_num_features, activation=...)(x)
model = models.Model(inp, out)
>>> np.array([[[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]]]).shape
(1,2,5)
# step 1: I want a numpy array
s1 = np.array([])
# step 2: I want it to have two samples
s2 = np.array([
[],
[]
])
# step 3: I want each sample to have 5 timesteps of length 1 in them
s3 = np.array([
[
[0], [1], [2], [3], [4]
],
[
[5], [6], [7], [8], [9]
]
])
>>> s3.shape
(2, 5, 1)
>>> np.array([[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]]).shape
(2,5)
>>> t = np.array([[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> t = np.expand_dims(t, axis=-1)
>>> t.shape
(2, 5, 1)