COCO category_id: почему номер класса не равен позиции в массиве
Датасет в формате COCO содержит два класса. Разработчик видит category_id=3 в аннотации и пытается взять classes[3]. Список имеет длину два, поэтому импорт падает. Иногда ошибка хуже: индекс существует, но соответствует другому имени, и модель учится на неверной метке. Источник проблемы — смешение идентификатора категории в файле с позицией в массиве классов модели.
Храните явную карту, а не догадку о порядке
В COCO аннотация ссылается на категорию через category_id, а массив categories содержит объекты с их id и именами. Эти ID могут иметь пропуски и не обязаны начинаться с нуля. Модель же часто требует плотные индексы от 0 до N−1. При импорте создайте два отображения: ID файла → индекс модели и индекс модели → ID файла. Второе нужно при экспорте предсказаний обратно.
data = {
"categories": [{"id": 1, "name": "человек"}, {"id": 3, "name": "автомобиль"}],
"annotations": [{"image_id": 7, "category_id": 3, "bbox": [10, 20, 30, 40]}],
}
names = {item["id"]: item["name"] for item in data["categories"]}
ann = data["annotations"][0]
print("category_id:", ann["category_id"])
print("класс:", names[ann["category_id"]])
print("индексы модели:", {category_id: i for i, category_id in enumerate(sorted(names))})
assert names[3] == "автомобиль"
assert len(names) == 2В примере ID 1 и 3 отвечают двум классам. Аннотация с ID 3 — автомобиль; плотный индекс модели для него равен 1. Код не использует позицию элемента COCO-массива как смысл ID. Запишите эту карту вместе с весами модели, иначе при следующем запуске перестановка списка категорий может поменять имена предсказаний без изменения чисел.
Что проверить при импорте
Каждый category_id из аннотаций должен находиться в словаре категорий. Пустые или неизвестные ID нужно разобрать до обучения, а не молча отправлять в «фон». После конвертации посчитайте число аннотаций по каждому исходному ID и по каждому индексу модели: суммы должны совпадать. Для нескольких изображений нарисуйте рамки и имена классов из обеих карт. Так можно обнаружить перепутанные подписи до дорогого обучения.
Не смешивайте здесь проблему формата рамки. COCO bbox часто хранится как [x, y, width, height], а детектор может ждать углы xyxy. Это отдельное преобразование; проверка координат после letterbox понадобится ещё позже. Карта классов и карта координат должны проходить независимые тесты, потому что верная геометрия не исправляет неверное имя объекта.
Если объединяете несколько COCO-выгрузок, одинаковые числовые ID могут обозначать разные категории. Сопоставляйте по согласованному словарю проекта и фиксируйте версии разметки. После переименования категории решите, изменилась ли её семантика или только отображаемое название: в первом случае старую и новую разметку нельзя бездумно смешивать.
Не считайте автоматически, что индекс ноль всегда означает фон. Одни фреймворки резервируют его, другие ожидают плотные индексы классов с нуля без отдельного фона. Проверьте контракт выбранного обучающего кода и сохраните точную карту для экспорта результатов. Если модель вернула индекс 1 из нашего примера, в исходный COCO-формат нужно записать category_id=3, а не 1. Иначе обучение может пройти успешно, но проверяющая система оценит все автомобили как другую категорию.
Курс «Computer Vision Engineer: от детекции и Doc-AI до продакшна» включает подготовку и проверку датасетов, обучение детекторов и анализ качества. Явная карта классов превращает импорт аннотаций в воспроизводимый этап этого пути. Откройте программу курса.
Продолжить на практике
- Computer Vision Engineer: от детекции и Doc-AI до продакшна ↗
Практический курс по Computer Vision. Соберёте продакшн-сервис: датасет → обучение (YOLO/RT-DETR, SAM), трекинг, OCR/Doc-AI, веб-приложение (UI+API) и мониторинг. Экспорт в ONNX/TensorRT/OpenVINO, батчинг/квантование под CPU/GPU. Плюс профессиональные блоки: mAP/IoU/Dice и калибровка доверия, QA разметки и аугментации, p95/стоимость, дрейф данных и алерты, guardrails (NMS/правила), A/B-тесты, Triton/gRPC/FastAPI.
