从文档中,我们可以看到所有 Keras 循环层所期望的输入形状是:
(None, TimeSteps, DataDimension)
在 Keras 形状中,None
是您拥有的示例数量。
因此,在第一种简单的方法中,您必须将训练数据定型为:
(NumberOfVideos, NumberOfFrames, height * width * channels)
你的第一层(如果第一层是 LSTM)应该使用:
LSTM(AnyNumberOfCells, input_shape=(NumberOfFrames, height * width * channels))
创建模型时从不考虑批量大小(示例数),它只出现在您的训练数据中,这就是 KerasNone
在消息中显示该维度的原因。
现在,这是一种非常简单直观的开始方式,但实际上,没有义务像这样塑造你的训练数据,你可以尝试各种方式,只要你保持 LSTM 层的数据形状为(BatchSize,TimeSteps,DataDimension)
. 一个很好的方法(在我看来)是在将数据输入 LSTM 之前先进行一些卷积以减小数据大小。维度“高度 * 宽度 * 通道”可能太多了,无法在 LSTM 层中一次处理所有内容,并且可能会导致内存问题。
如果你有记忆问题。您可以研究“生成器”或Keras 序列。这些将与fit_generator()方法一起使用。Keras 将首先使用生成器读取有限数量的数据,并仅使用该数据进行训练。不过,您必须让这些生成器以相同的格式输出内容(ASmallerNumberOfVideos, NumberOfFrames, height * width * channels)
。
现在,即使这样你仍然有内存问题,你将不得不开始使用stateful=True
层。
在这种情况下,“TimeSteps”可能被分隔在不同的数组中。当你训练时,你的 LSTM 层不会认为“好的,这个例子已经完成”。您喂食的下一批将被视为“继续上一个序列”。
数据的形状会像(NumberOfVideos,ReducedNumberOfFrames, h*w)
.
在这种情况下,每次在训练足够的“ReducedNumberOfFrames”后完成一个序列时,您都必须使用.reset_states()手动重置网络的状态。
你也可以通过类似的训练来结合这两个想法(ReducedNumberOfVideos,ReducedNumberOfFrames,h*w)
,只要你能很好地控制你的训练并且.reset_states()
在正确的点上。