【发布时间】:2016-12-20 12:48:09
【问题描述】:
我有一个 8000 帧的视频,我想在每批 200 帧上训练一个 Keras 模型。我有一个帧生成器,它逐帧循环播放视频并将(3 x 480 x 640)帧累积到形状为(200, 3, 480, 640)的numpy矩阵(200, 3, 480, 640)——(批量大小,rgb,帧高度,帧width) -- 并且每 200 帧产生 X 和 Y:
import cv2
...
def _frameGenerator(videoPath, dataPath, batchSize):
"""
Yield X and Y data when the batch is filled.
"""
camera = cv2.VideoCapture(videoPath)
width = camera.get(3)
height = camera.get(4)
frameCount = int(camera.get(7)) # Number of frames in the video file.
truthData = _prepData(dataPath, frameCount)
X = np.zeros((batchSize, 3, height, width))
Y = np.zeros((batchSize, 1))
batch = 0
for frameIdx, truth in enumerate(truthData):
ret, frame = camera.read()
if ret is False: continue
batchIndex = frameIdx%batchSize
X[batchIndex] = frame
Y[batchIndex] = truth
if batchIndex == 0 and frameIdx != 0:
batch += 1
print "now yielding batch", batch
yield X, Y
这是fit_generator()的运行方式:
batchSize = 200
print "Starting training..."
model.fit_generator(
_frameGenerator(videoPath, dataPath, batchSize),
samples_per_epoch=8000,
nb_epoch=10,
verbose=args.verbosity
)
我的理解是当模型看到samples_per_epoch 样本并且samples_per_epoch = 批大小 * 批数 = 200 * 40 时,一个纪元结束。因此,在帧 0-7999 上训练一个纪元后,下一个 epoch 将从第 0 帧开始再次训练。这是正确的吗?
使用此设置我希望每个 epoch 有 40 个批次(每个 200 帧)从生成器传递到 fit_generator;这将是每个 epoch 总共 8000 帧——即samples_per_epoch=8000。然后对于后续的 epoch,fit_generator 将重新初始化生成器,以便我们从视频开始再次开始训练。然而事实并非如此。 在第一个 epoch 完成后(在模型记录批次 0-24 之后),生成器从中断处继续。新纪元不应该从训练数据集的开头重新开始吗?
如果我对fit_generator的理解有误,请解释。我浏览了文档,这个example 和这些related issues。我正在使用带有 TensorFlow 后端的 Keras v1.0.7。这个问题也发布在Keras repo。
【问题讨论】:
-
作为临时修复,我手动迭代各个时期并调用
model.fit(),如下所示:github.com/fchollet/keras/issues/107
标签: python tensorflow generator keras