我有一个8000帧的视频,我想训练一个每批200帧的Keras模型。我有一个帧生成器,它逐帧循环通过视频帧,并将(3 x 480 x 640)帧累积成形状为(200, 3, 480, 640)
(批量大小、rgb、帧高度、帧宽度)的numpy矩阵,并且每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
以下是运行^{
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之后,下一个epoch将从第0帧再次开始训练。是这样吗?
通过此设置,我希望每个epoch有40个批(每个批200帧)从生成器传递到fit_generator
;这将是每个epoch总共8000帧。然后,对于随后的阶段,fit_generator
将重新初始化生成器,以便我们从视频开始时再次开始训练。但事实并非如此。在第一个历元完成后(在模型记录批次0-24之后),生成器将从它停止的地方提取。新纪元不应该从训练数据集的开头重新开始吗?
如果我对fit_generator
的理解有误,请解释。我已经看过了文档,这个example,还有这些relatedissues。我在TensorFlow后端使用Kerasv1.0.7。这个问题也发表在Keras repo上。
您可以通过添加一个
while 1:
循环来强制生成器重置自身,这就是我继续的方式。因此,生成器可以为每个时间段生成批处理数据。因为生成器是一个完全分离的函数,所以每当再次调用它时,它都将继续无限循环。
我不能证明的是
fit_generator()
将调用生成器,直到它有足够的样本。我找不到变量batch_size
,但必须有一个条件来设置定义大小的内部变量。我在打印每个循环序列中的状态时检查了这个:
示例输出为:
这是对所发生事情的准确描述。如果要重置或回放生成器,则必须在内部执行此操作。注意,keras的行为在很多情况下都非常有用。例如,您可以在看到1/2的数据后结束一个epoch,然后在另一半上执行epoch,如果生成器状态被重置,这将是不可能的(这对于更密切地监视验证非常有用)。
相关问题 更多 >
编程相关推荐