J'ai une vidéo de 8000 images et j'aimerais former un modèle Keras sur des lots de 200 images chacun. J'ai un générateur d'images qui parcourt la vidéo image par image et accumule les images (3 x 480 x 640) dans une matrice numpy X
de forme (200, 3, 480, 640)
taille de lot, rgb, frame frame, frame width) - et donne X
et Y
chaque 200ème frame:
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
Voici comment exécuter --- (fit_generator()
:
batchSize = 200
print "Starting training..."
model.fit_generator(
_frameGenerator(videoPath, dataPath, batchSize),
samples_per_Epoch=8000,
nb_Epoch=10,
verbose=args.verbosity
)
Ma compréhension est qu'une époque se termine lorsque samples_per_Epoch
Échantillons ont été vus par le modèle, et samples_per_Epoch
= Taille du lot * nombre de lots = 200 * 40. Donc, après la formation pour une époque sur les images 0- 7999, la prochaine Epoque recommencera l'entraînement à partir de l'image 0. Est-ce correct?
Avec cette configuration je m'attends à ce que 40 lots (de 200 images chacun) soient passés du générateur à fit_generator
, Par époque; ce serait 8000 images au total par époque - c'est-à-dire samples_per_Epoch=8000
. Ensuite, pour les époques suivantes, fit_generator
Réinitialiserait le générateur de telle sorte que nous recommençons l'entraînement depuis le début de la vidéo. Pourtant, ce n'est pas le cas. Une fois la première époque terminée (une fois que le modèle enregistre les lots 0-24), le générateur reprend là où il s'était arrêté. La nouvelle Epoch ne devrait-elle pas recommencer depuis le début du jeu de données d'entraînement?
S'il y a quelque chose de incorrect dans ma compréhension de fit_generator
, Veuillez expliquer. J'ai parcouru la documentation, ceci exemple , et ces liésproblèmes . J'utilise Keras v1.0.7 avec le backend TensorFlow. Ce problème est également publié dans le Keras repo .
Une fois la première époque terminée (une fois que le modèle enregistre les lots 0-24), le générateur reprend là où il s'était arrêté
Il s'agit d'une description précise de ce qui se passe. Si vous souhaitez réinitialiser ou rembobiner le générateur, vous devrez le faire en interne. Notez que le comportement des keras est très utile dans de nombreuses situations. Par exemple, vous pouvez mettre fin à une époque après avoir vu la moitié des données puis effectuer une époque sur l'autre moitié, ce qui serait impossible si l'état du générateur était réinitialisé (ce qui peut être utile pour surveiller la validation de plus près).
Vous pouvez forcer votre générateur à se réinitialiser en ajoutant un while 1:
boucle, c'est comme ça que je procède. Ainsi, votre générateur peut fournir des données par lots pour chaque époque.
Parce que le générateur est une fonction complètement séparée, il continuera sa boucle infinie chaque fois qu'il sera rappelé.
Ce que je ne peux pas justifier, c'est que fit_generator()
appellera le générateur jusqu'à ce qu'il ait suffisamment d'échantillons. Je ne trouve pas la variable batch_size
, mais il doit y avoir un critère qui définit une variable interne qui définit la taille.
J'ai vérifié cela lors de l'impression d'un état dans chaque séquence de boucle:
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)
Exemple de sortie:
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