Как я упоминал в моем комментарии , если все данные обучения не помещаются в памяти, вам нужно написать собственный генератор (или использовать встроенный ImageDataGenerator
, но в вашем конкретном сценарии) это бесполезно или, по крайней мере, немного сложно заставить его работать).
Вот пользовательский генератор, который я написал (необходимо заполнить необходимые части):
import numpy as np
from keras.preprocessing import image
def generator(csv_path, batch_size, img_height, img_width, channels, augment=False):
########################################################################
# The code for parsing the CSV (or loading the data files) should goes here
# We assume there should be two arrays after this:
# img_path --> contains the path of images
# annotations ---> contains the parsed annotaions
########################################################################
n_samples = len(img_path)
batch_img = np.zeros((batch_size, img_width, img_height, channels))
idx = 0
while True:
batch_img_path = img_path[idx:idx+batch_size]
for i, p in zip(range(batch_size), batch_img_path):
img = image.load_img(p, target_size=(img_height, img_width))
img = image.img_to_array(img)
batch_img[i] = img
if augment:
############################################################
# Here you can feed the batch_img to an instance of
# ImageDataGenerator if you would like to augment the images.
# Note that you need to generate images using that instance as well
############################################################
# Here we assume that the each column in annotations array
# corresponds to one of the outputs of our neural net
# i.e. annotations[:,0] to output1, annotations[:,1] to output2, etc.
target = annotations[idx:idx+batch_size]
batch_target = []
for i in range(annotations.shape[1]):
batch_target.append(target[:,i])
idx += batch_size
if idx > n_samples - batch_size:
idx = 0
yield batch_img, batch_target
train_gen = generator(train_csv_path, train_batch_size, 256, 256, 3)
val_gen = generator(val_csv_path, val_batch_size, 256, 256, 3)
test_gen = generator(test_csv_path, test_batch_size, 256, 256, 3)
model.fit_generator(train_gen,
steps_per_epoch= , # should be set to num_train_samples / train_batch_size
epochs= , # your desired number of epochs,
validation_data= val_gen,
validation_steps= # should be set to num_val_samples / val_batch_size)
Поскольку я точно не знаю формат и типы аннотаций, возможно, вам придется внести изменения в этот код, чтобы он работал на вас. Кроме того, учитывая текущий способ обновления idx
, если n_sample
не делится на batch_size
, некоторые из семплов в конце могут вообще не использоваться. Так что это можно сделать намного лучше. Одним из быстрых решений будет:
idx += batch_size
if idx == n_samples:
idx = 0
else if idx > n_samples - batch_size:
idx = n_samples - batch_size
Однако, независимо от того, как вы обновляете idx
, если вы используете fit_generator
и учитывая, что n_samples
не делится на batch_size
, то в каждую эпоху либо некоторые из выборок могут не генерироваться, либо некоторые из образцов может быть сгенерировано более одного раза в зависимости от значения аргумента steps_per_epoch
(что, я думаю, не является существенной проблемой).