Что ж, одним из решений является модификация кода ImageDataGenerator
и включение в него механизма обработки ошибок (т. Е. Try / Кроме).
Однако, одна альтернатива - заключить генератор в другой генератор и использовать try/ кроме там.Недостатком этого решения является то, что оно отбрасывает весь сгенерированный пакет, даже если в этом пакете повреждено одно изображение (это может означать, что некоторые образцы могут вообще не использоваться для обучения):
data_gen = ImageDataGenerator(...)
train_gen = data_gen.flow_from_directory(...)
def my_gen(gen):
while True:
try:
data, labels = next(gen)
yield data, labels
except:
pass
# ... define your model and compile it
# fit the model
model.fit_generator(my_gen(train_gen), ...)
Еще один недостаток этого решения заключается в том, что, поскольку вам необходимо указать количество шагов генератора (т. Е. steps_per_epoch
), а также учесть, что партия может быть выброшена за шаг, и вместо нее выбирается новая партия водин и тот же шаг, вы можете закончить обучение на некоторых из образцов более чем один раз в эпоху.Это может иметь или не иметь существенных эффектов в зависимости от того, сколько пакетов содержит поврежденные изображения (т. Е. Если их несколько, то не о чем беспокоиться).
Наконец, обратите внимание, что вы можете захотетьиспользуйте более новый генератор данных Keras, то есть класс Sequence
, чтобы считывать изображения по одному в методе __getitem__
в каждой партии и отбрасывать поврежденные.Однако проблема предыдущего подхода, то есть обучения некоторых изображений более одного раза, все еще присутствует в этом подходе, поскольку вам также необходимо реализовать метод __len__
, и он по существу эквивалентен аргументу steps_per_epoch
.Хотя, на мой взгляд, этот подход (т.е. создание подкласса Sequence
class) превосходит вышеуказанный подход (конечно, если вы отбросите тот факт, что вам может потребоваться написать больше кода) и имеет меньше побочных эффектов (поскольку вы можетеудалить одно изображение, а не всю партию).