我有一个8000帧的视频,我想训练一个Keras模型,每批200帧。我有一个帧生成器,它逐帧循环播放视频,并将(3 x 480 x 640)帧累加成一个numpy矩阵x
(200,3,480,640)-(批量大小,rgb,帧高度,帧宽度)--每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\u generator()
:
batchSize = 200
print "Starting training..."
model.fit_generator(
_frameGenerator(videoPath, dataPath, batchSize),
samples_per_epoch=8000,
nb_epoch=10,
verbose=args.verbosity
)
我的理解是,当模型看到samples\u per\u epoch
样本,并且samples\u per\u epoch
=批次大小*批次数量=200*40时,一个新纪元就结束了。因此,在第0-7999帧上训练一个历元后,下一个历元将从第0帧开始再次训练。这是正确的吗?
通过此设置,我预计每个历元将有40批(每个200帧)从生成器传递到fit_生成器
;这将是每个历元的总帧数为8000,即,samples\u per\u epoch=8000
。然后,对于后续的时代,fit_generator
将重新初始化该生成器,以便我们从视频开始再次开始训练。但事实并非如此。第一个历元完成后(在模型记录批次0-24后),生成器将从其停止的位置开始。新纪元不应该从训练数据集的开始重新开始吗?
如果我对fit_generator
的理解不正确,请解释。我已经阅读了文档、这个示例以及这些相关问题。我用的是KerasV1。0.7与TensorFlow后端。本期债券也发布在Keras回购协议中。
第一个历元完成后(在模型记录批次0-24后),生成器将从其停止的位置开始
这是对所发生情况的准确描述。如果要重置或倒带发电机,必须在内部执行此操作。请注意,keras的行为在许多情况下都非常有用。例如,您可以在看到1/2的数据后结束一个历元,然后在另一半上执行历元,如果生成器状态被重置,这将是不可能的(这有助于更密切地监视验证)。
您可以通过在1:循环中添加来强制生成器重置自身,这就是我的操作方式。因此,生成器可以为每个时代生成批处理数据。
因为生成器是一个完全分离的函数,所以每当再次调用它时,它将继续执行其无限循环。
我无法证明的是,fit\u generator()
将调用生成器,直到它有足够的样本。我找不到变量batch\u size
,但必须有一个条件来设置定义大小的内部变量。
我在打印每个循环序列中的状态时检查了这个:
def generator():
while 1:
for i in range(0,len(x_v)-1):
if (i != predict_batch_nr):
print("\n -> usting Datasett ", i+1 ," of ", len(x_v))
x = x_v[i] #x_v has Batches of different length
y = y_v[i] #y_v has Batches of different length
yield x, y
model.fit_generator(generator(),steps_per_epoch=5000,epochs=20, verbose=1)
示例输出为:
4914/5000 [============================>.] - ETA: 13s - loss: 2442.8587
usting Datasett 77 of 92
4915/5000 [============================>.] - ETA: 12s - loss: 2442.3785
-> usting Datasett 78 of 92
-> usting Datasett 79 of 92
-> usting Datasett 80 of 92
4918/5000 [============================>.] - ETA: 12s - loss: 2442.2111
-> usting Datasett 81 of 92
-> usting Datasett 82 of 92