Вопрос или проблема
Я пытался использовать MaskRCNN с основной моделью Resnet на DeepFashion2 датасете для сегментации объектов. Настройки кастомизации следующие:
class ClothDataset(utils.Dataset):
# функция load_dataset используется для загрузки обучающего и тестового наборов данных
def load_dataset(self, dataset_dir):
print("Загрузка набора данных")
categories = ["футболка с коротким рукавом", "футболка с длинным рукавом", "верхняя одежда с коротким рукавом", "верхняя одежда с длинным рукавом", "жилет", "сарафан",
"шорты", "брюки", "юбка", "платье с коротким рукавом", "платье с длинным рукавом", "платье-жилет", "платье-сарафан"]
for index, category in enumerate(categories):
self.add_class("fashion", index+1, category.lower())
images_dir = dataset_dir + '/image/'
annotations_dir = dataset_dir + '/annos/'
for filename in listdir(images_dir):
image_id = filename[:-4]
# переменные img_path и ann_path определены
img_path = images_dir + filename
ann_path = annotations_dir + image_id + '.json'
# используя функцию add_image, мы передаем image_id, image_path и ann_path, чтобы текущее
# изображение было добавлено в набор данных для обучения
self.add_image('fashion', image_id=image_id, path=img_path, annotation=ann_path)
# функция, используемая для извлечения ограничительных рамок из аннотированных файлов
def extract_boxes(self, filename):
print("Извлечение ограничительных рамок")
boxes = list()
# Реализация для аннотаций JSON
annotation_file = json.load(open(filename))
for item in annotation_file.keys():
if item != "source" and item != "pair_id":
name = annotation_file[item]['category_name'].lower()
coors = annotation_file[item]['bounding_box']
coors.append(name)
boxes.append(coors)
# Извлечение ширины и высоты изображения
image_path = filename.replace("annos", "image").replace("json", "jpg")
image = skimage.io.imread(image_path)
height, width = image.shape[:2]
return boxes, width, height
# возвращает булеву маску с размерами ширина * высота * экземпляры
def load_mask(self, image_id):
print("Загрузка маски")
info = self.image_info[image_id]
path = info['annotation']
boxes, w, h = self.extract_boxes(path)
masks = np.zeros([h, w, len(boxes)], dtype="uint8")
class_ids = list()
for i in range(len(boxes)):
box = boxes[i]
masks[box[1]:box[3], box[0]:box[2], i] = self.class_names.index(box[4])
class_ids.append(self.class_names.index(boxes[i][4]))
return masks, np.asarray(class_ids, dtype="int32")
# эта функция берет image_id и возвращает путь к изображению
def image_reference(self, image_id):
info = self.image_info[image_id]
return info['path']
class ClothConfig(Config):
# название конфигурации
NAME = "fashion_config"
GPU_COUNT = 1
IMAGES_PER_GPU = 4
STEPS_PER_EPOCH = 20
# Количество классов
NUM_CLASSES = 1 + 13
# Размеры изображения
IMAGE_MIN_DIM = HEIGHT_TARGET
IMAGE_MAX_DIM = WIDTH_TARGET
IMAGE_SHAPE = [HEIGHT_TARGET, WIDTH_TARGET, 3]
IMAGE_RESIZE_MODE = 'square'
BACKBONE = 'resnet50'
TRAIN_BN = True
# Темп обучения
LEARNING_RATE = 0.004
WEIGHT_DECAY = 0.0
LR_SCHEDULE = True
# Размер очереди загрузчика данных (было установлено на 100, но привело к ошибке OOM)
MAX_QUEUE_SIZE = 10
# Кэширование элементов
CACHE = True
# Режим отладки отключает контрольные точки модели
DEBUG = False
# Не используйте многопоточность, так как это замедляет загрузчик данных!
WORKERS = 0
# Убытки
LOSS_WEIGHTS = {
'rpn_class_loss': 1.0, # правильный ли класс бокса? / Убыток классификатора якорей RPN (Фон/Передний план)
'rpn_bbox_loss': 1.0, # правильный ли размер бокса? / график потерь бокса RPN (бокс общего объекта)
'mrcnn_class_loss': 1.0, # потеря для классификатора Mask R-CNN (Фон / конкретный класс)
'mrcnn_bbox_loss': 1.0, # правильный ли размер ограничивающей рамки? / потеря для уточнения ограничивающей рамки Mask R-CNN
'mrcnn_mask_loss': 1.0, # правильный ли класс? правильно ли пиксель отнесен к классу? / потеря бинарной кросс-энтропии для масок
}
# Структура обучения
FPN_CLASSIF_FC_LAYERS_SIZE = 1024
RPN_ANCHOR_SCALES = (32, 64, 128, 256, 512)
Тем не менее, я получаю ошибку ‘индекс списка вне диапазона’ при вызове model.train(..), и из стека ошибок я не могу понять, в чем именно проблема. Прилагаю журналы ошибок ниже,
Буду признателен за любую помощь. Спасибо!
Обновление
Я narrowed down the issue to a possible Tensorflow version incompatibility. Хотя у меня нет всех деталей, кажется, что проблема может быть связана с этим.
Чтобы дать больше контекста, я работал с Kaggle ядрами для запуска модели. Изначально я изменял существующий ноутбук в попытке переиспользовать оригинальную среду. Именно тогда я столкнулся с вышеупомянутыми журналами ошибок. В качестве альтернативы я попытался использовать другой ноутбук с другой, более актуальной закрепленной средой, и, что интересно, та же модель сработала (снимок прикреплён).
Ответ или решение
Ошибка «list index out of range», возникающая при вызове MaskRCNN.train
, может быть вызвана несколькими причинами. Давайте рассмотрим возможные источники этой проблемы, а также потенциальные подходы к её устранению, с акцентом на необходимые детали вашей реализации.
Возможные Причины Ошибки
-
Неправильные Или Отсутствующие Аннотации:
Ошибка «list index out of range» может возникнуть, если аннотации для изображений содержат ошибки. Убедитесь, что файл JSON аннотации для каждого изображения правильно структурирован и что все аннотации соответствуют ожидаемому формату. Например, все категории и координаты ограничивающих рамок должны быть корректно указаны. -
Проблемы с Изображениями:
Если в директории изображений есть файлы, которые не соответствуют ожидаемым форматам, или если некоторые изображения повреждены, это может привести к ошибкам при попытке загрузки данных. Проверьте, что все изображения доступны и имеют правильные форматы. -
Неверные Индексы Классов:
Убедитесь, что функции, загружающие классы и маски, корректно используют индексы классов. В методеload_mask
необходимо убедиться, что индексclass_names.index(box[4])
действительно существует вclass_names
. Если категорий в наборах данных больше, чем указано в классеClothConfig
, это может привести к ошибке. -
Несоответствие Версий Tensorflow:
Так как вы упомянули о возможной несовместимости версий TensorFlow, это тоже важно учитывать. Некоторые функции могут работать некорректно из-за изменений в библиотеке. Определите, какие версии TensorFlow и Keras использовались в работающих примерах на Kaggle и постарайтесь сопоставить с вашей средой.
Рекомендации по Устранению Ошибок
-
Логгирование Аннотаций и Изображений:
Добавьте дополнительные проверки и логгирование вload_dataset
иload_mask
. Выводите информацию о каждом загружаемом изображении и его аннотации. Это поможет обнаружить конкретные изображения или аннотации, вызывающие проблемы.print(f"Loading image ID {image_id} with annotation {path}")
-
Проверка Доступности Изображений:
Убедитесь, что все изображения, на которые ссылаются аннотации, действительно существуют. Для этого можно реализовать проверку файла перед его использованием. -
Используйте Try-Except Блоки:
Чтобы лучше локализовать проблему, используйте блоки исключений, чтобы перехватывать ошибку и выводить более детальную информацию о месте её возникновения.try: # Ваш код except IndexError as e: print(f"IndexError: {str(e)} at image_id {image_id}")
-
Убедитесь в Совместимости Версий:
Установите совместимую версию TensorFlow, которая использовалась в работающем примере. Проверьте требования к версиям зависимостей в документации проекта Mask R-CNN или репозитории DeepFashion2.
Заключение
Ошибки «list index out of range» могут быть сложными для диагностики, и часто возникают из-за несовпадений между ожиданиями модели и форматом ваших данных. Проверяя данные на каждом этапе анализа, вы сможете локализовать проблему и найти соответствующее решение. Если ошибка все еще не найдена, рассмотрите возможность создания минимального воспроизводимого примера, который поможет другим понять контекст вашей проблемы и предложить более точные решения.