Оригинальная версия этого поста доступна здесь на dl.asmaamir.com ✨
🌱 Введение
- ✨ Tensorflow API обнаружения объектов - это мощный инструмент, который позволяет нам создавать собственные детекторы объектов в зависимости от предварительно обученных, точно настроенных моделей, даже если у нас нет сильного фона AI или сильного TensorFlow знания.
- 💁♀️ Построение моделей на основе предварительно обученных моделей экономит нам много времени и усилий, поскольку мы используем модели, которые, возможно, обучались неделями на очень мощных машинах, этот принцип называется Трансферное обучение.
- 🗃️ В качестве набора данных я покажу вам, как использовать набор данных OpenImages и преобразовать его данные в формат, удобный для TensorFlow.
🚩 Разработка
- 👩💻 Подготовка окружающей среды
- 🖼️ Получение изображения
- 🤹♀️ Организация изображений
- 🤖 Выбор модели
- 👩🔧 Конфигурация модели
- 👶 Обучение
- 👮♀️ Оценка
- 👒 Экспорт модели
- 📱 Преобразование в tflite
- 🤕 Пока вы применяете инструкции, если вы получаете ошибки, вы можете проверить раздел «Общие проблемы» в конце статьи.
- 🤯 Если ваша модель не обучается должным образом, ознакомьтесь с примечаниями по отладке модели здесь (бета 🧪)
👩💻 Подготовка окружающей среды
🔸 Информация об окружающей среде
- 🐍 Версия Python: 3.7
- 🔥 Версия TensorFlow: 1.15
🥦 Настройка среды Conda
🔮 Создать новый env
- 🥦 Установите Anaconda
- 💻 Откройте cmd и запустите:
# conda create -n <ENV_NAME> python=<REQUIRED_VERSION> conda create -n tf1 python=3.7
⚡ Активируйте новый env
# conda activate <ENV_NAME> conda activate tf1
🔽 Установить пакеты
💥 GPU против вычислений CPU
🚀 Установка TensorFlow
# for gpu conda install tensorflow-gpu=1.15 # for cpu conda install tensorflow=1.15
📦 Установка других пакетов
conda install pillow Cython lxml jupyter matplotlib conda install -c anaconda protobuf
🤖 Скачивание репозитория моделей
🤸♀️ Клонирование с GitHub
- Репозиторий, содержащий необходимые утилиты для обучения и оценки.
- Откройте CMD, запустите
E
диск и запустите:
# note that every time you open CMD you have # to activate your env again by running: # under E:\> conda activate tf1 git clone https://github.com/tensorflow/models.git cd models/research
🧐 Я предполагаю, что вы выполняете свои команды под
E
диском.
🔃 Компиляция Protobufs
💻 Окна
# under (tf1) E:\models\research> for /f %i in ('dir /b object_detection\protos\*.proto') ^do protoc object_detection\protos\%i --python_out=.
🐧 Linux
# under /models/research $ protoc object_detection/protos/*.proto --python_out=.
📦 Компиляция пакетов
#under (tf1) E:\models\research> python setup.py build python setup.py install
🚩 Временная установка пути Python
💻 Окна
#under (tf1) E:\models\research> set PYTHONPATH=E:\models\research;E:\models\research\slim
🐧 Linux
# under /models/research $ export PYTHONPATH=`pwd`:`pwd`/slim
👮♀️ Каждый раз, когда вы открываете CMD, вам нужно снова установить
PYTHONPATH
👩🔬 Тест установки
🧐 Убедитесь, что все сделано
💻 Команда
# under (tf1) E:\models\research> python python object_detection/builders/model_builder_tf1_test.py
🎉 Ожидаемый результат
Ran 17 tests in 0.833s OK (skipped=1)
🖼️ Получение изображений
👮♀️ Структура каталогов
- 🏗️ Я полагаю, что вы создали такую структуру, как:
|___ models |___ demo |___ annotations |___ eval |___ images |___ inference |___ OIDv4_ToolKit |___ OpenImagesTool |___ pre_trainded_model |___ scripts |___ training
🤖 model
: репо здесь
📄 annotations
: будет содержать сгенерированные файлы .csv
и .record
👮♀️ eval
: будет содержать результаты оценки
🖼️ images
: будет содержать набор данных изображения
▶ ️ inference
: будет содержать экспортированные модели после обучения
🔽 OIDv4_ToolKit
: репо здесь (OpenImages Downloader)
👩🔧 OpenImagesTool
: репо здесь (OpenImages Organizer)
👩🏫pre_trained_model
: будет содержать файлы модели TensorFlow, которые мы будем переобучать
👩💻 scripts
: будет содержать скрипты, которые мы будем использовать для процессов предварительной обработки и обучения
🚴♀️ training
: будет содержать сгенерированные контрольные точки во время тренировки
🚀 Набор данных OpenImages
- 🕵️♀️ Вы можете получать изображения различными способами
- 👩🏫 Я покажу процесс организации набора данных OpenImages
- 🗃️ OpenImages - это огромный набор данных, содержащий аннотированные изображения 600 объектов
- 🔍 Вы можете просматривать изображения по категориям здесь
🎨 Загрузка по категориям
OIDv4_Toolkit - это инструмент, который мы можем использовать для загрузки набора данных OpenImages по категориям и по набору (тест, обучение, проверка)
💻 Чтобы клонировать и собрать проект, откройте CMD и запустите:
(tf1) E:\demo>git clone https://github.com/EscVM/OIDv4_ToolKit.git (tf1) E:\demo>cd OIDv4_ToolKit (tf1) E:\demo\OIDv4_ToolKit>pip install -r requirements.txt
⏬ Чтобы начать скачивание по категориям:
# python main.py downloader --classes <OBJECT_LIST> --type_csv <TYPE> # TYPE: all | test | train | validation (tf1) E:\demo\OIDv4_ToolKit>python main.py downloader --classes Apple Orange --type_csv validation
👮♀️ Если имя объекта состоит из 2 частей, запишите его с помощью
'_', e.g.
Bell_pepper
🤹♀️ Организация изображений
🔮 OpenImagesTool
- 👩💻 OpenImagesTool - это инструмент для преобразования изображений и аннотаций OpenImages в структуру, удобную для TensorFlow.
- 🙄 OpenImages предоставляет аннотации и
.txt
файлы в таком формате, как:<OBJECT_NAME> <XMIN> <YMIN> <XMAX> <YMAX>
, который несовместим с TensorFlow, требующим формата аннотаций VOC - 💫 Для этой синхронизации мы можем сделать следующее
💻 Чтобы клонировать и построить проект, откройте CMD и запустите:
(tf1) E:\demo>git clone https://github.com/asmaamirkhan/OpenImagesTool.git (tf1) E:\demo>cd OpenImagesTool/src
💻 Применение организации
🚀 Теперь мы преобразуем изображения и аннотации, которые мы загрузили, и сохраним их в папку images
.
# under (tf1) E:\demo\OpenImagesTool\src> # python script.py -i <INPUT_PATH> -o <OUTPUT_PATH> python script.py -i E:\pre_trainded_model\OIDv4_ToolKit\OID\Dataset -o E:\pre_trainded_model\images
👩🔬 OpenImagesTool по умолчанию добавляет проверочные изображения в обучающий набор. Если вы хотите отключить это поведение, вы можете добавить к команде флаг
-v
.
🏷️ Создание карты меток
- ⛓️
label_map.pbtxt
- это файл, который сопоставляет имена объектов с соответствующими идентификаторами. - ➕ Создайте
label_map.pbtxt
file в папке аннотаций и откройте его в текстовом редакторе - 🖊️ Напишите имена и идентификаторы ваших объектов в следующем формате
item { id: 1 name: 'Hamster' } item { id: 2 name: 'Apple' }
👮♀️ id:0
зарезервирован для фона, поэтому не используйте его
🐞 Связанная ошибка:
ValueError: Label map id 0 is reserved for the background label
🏭 Создание файлов CSV
- 🔄 Теперь нам нужно преобразовать
.xml
файлов в файл csv. - 🔻 Загрузите скрипт xml_to_csv.py и сохраните его в папке
scripts
. - 💻 Откройте CMD и запустите:
👩🔬 Создание CSV-файла поезда
# under (tf1) E:\demo\scripts> python xml_to_csv.py -i E:\demo\images\train -o E:\demo\annotations\train_labels.csv
👩🔬 Создание тестового CSV-файла
# under (tf1) E:\demo\scripts> python xml_to_csv.py -i E:\demo\images\test -o E:\demo\annotations\test_labels.csv
👩🏭 Создание записей TF
- 🙇♀️ Теперь мы сгенерируем tfrecords, которые будут использоваться в прецессе обучения
- 🔻 Загрузите скрипт generate_tfrecords.py и сохраните его в папке
scripts
.
👩🔬 Генерация поездов tfrecord
# under (tf1) E:\demo\scripts> # python generate_tfrecords.py --label_map=<PATH_TO_LABEL_MAP> # --csv_input=<PATH_TO_CSV_FILE> --img_path=<PATH_TO_IMAGE_FOLDER> # --output_path=<PATH_TO_OUTPUT_FILE> python generate_tfrecords.py --label_map=E:\demo\annotations\label_map.pbtxt --csv_input=E:\demo\annotations\train_labels.csv --img_path= E:\demo\images\train --output_path=E:\demo\annotations\train.record
👩🔬 Создание тестовой записи tfrecord
# under (tf1) E:\demo\scripts> python generate_tfrecords.py --label_map=E:\demo\annotations\label_map.pbtxt --csv_input=E:\demo\annotations\test_labels.csv --img_path= E:\demo\images\test --output_path=E:\demo\annotations\test.record
🤖 Выбор модели
- 🎉 TensorFLow Object Detection Zoo предоставляет множество предварительно обученных моделей.
- 🕵️♀️ Модели различаются по точности и скорости, вы можете выбрать подходящую модель в соответствии с вашими приоритетами
- 💾 Выберите модель, извлеките ее и сохраните в папке
pre_trained_model
. - 👀 Прочтите мои заметки здесь, чтобы узнать о различиях между популярными моделями.
👩🔧 Конфигурация модели
⏬ Загрузка файла конфигурации
- 😎 Мы загрузили модели (предварительно обученные веса), но теперь нам нужно загрузить файл конфигурации, который содержит параметры и настройки обучения.
- 👮♀️ Каждая модель в TensorFlow Object Detection Zoo имеет файл конфигурации, представленный здесь
- 💾 Загрузите файл конфигурации, соответствующий выбранным моделям, и сохраните его в папке
training
.
👩🔬 Обновление файла конфигурации
Вам необходимо обновить следующие строки:
// number of classes num_classes: 1 // set it to total number of classes you have // path of pre-trained checkpoint fine_tune_checkpoint: "E:/demo/pre_trained_model/ssd_mobilenet_v1_quantized_300x300_coco14_sync_2018_07_18/model.ckpt" // path to train tfrecord tf_record_input_reader { input_path: "E:/demo/annotations/train.record" } // number of images that will be used in evaluation process eval_config: { metrics_set: "coco_detection_metrics" use_moving_averages: false // I suggest setting it to total number of testing set to get accurate results num_examples: 11193 } eval_input_reader: { tf_record_input_reader { // path to test tfrecord input_path: "E:/demo/annotations/test.record" } // path to label map label_map_path: "E:/demo/annotations/label_map.pbtxt" // set it to true if you want to shuffle test set at each evaluation shuffle: false num_readers: 1 }
🤹♀️ Если вы отдадите весь набор тестов на оценку, тогда функция перемешивания не повлияет на результаты, а только предоставит вам разные примеры на TensorBoard
👶 Обучение
- 🎉 Теперь мы сделали все приготовления
- 🚀 Пусть компьютер начнет учиться
- 💻 Откройте CMD и запустите:
# under (tf1) E:\models\research\object_detection\legacy> # python train.py --train_dir=<DIRECTORY_TO_SAVE_CHECKPOINTS> # --pipline_config_path=<PATH_TO_CONFIG_FILE> python train.py --train_dir=E:/demo/training --pipeline_config_path=E:/demo/training/ssd_mobilenet_v1_quantized_300x300_coco14_sync.config
- 🕐 Этот процесс займет много времени (Вы можете вздремнуть 🤭, но вздремнуть долго 🙄)
- 🕵️♀️ Пока модель обучается, вы увидите значения потерь на CMD.
- ✋ Вы можете остановить процесс, когда значение убытка достигнет хорошего значения (менее 1)
👮♀️ Оценка
🎳 Сценарий оценки
- 🤭 После того, как процесс обучения будет завершен, давайте проведем экзамен, чтобы узнать, насколько хорошо (или плохо 🙄) наша модель справляется.
- 🎩 Следующая команда будет использовать модель для всего набора тестов и после этого распечатать результаты, чтобы мы могли провести анализ ошибок.
- 💻 Итак, откройте CMD и запустите:
# under (tf1) E:\models\research\object_detection\legacy> # python eval.py --logtostderr --pipline_config_path=<PATH_TO_CONFIG_FILE> # --checkpoint_dir=<DIRECTORY_OF_CHECKPOINTS> --eval_dir=<DIRECTORY_TO_SAVE_EVAL_RESULTS> python eval.py --pipeline_config_path=E:/demo/training/ssd_mobilenet_v1_quantized_300x300_coco14_sync.config --checkpoint_dir=--pipeline_config_path=E:/demo/training --eval_dir=--pipeline_config_path=E:/demo/eval
👀 Визуализация результатов
- ✨ Чтобы увидеть результаты на графиках и изображениях, мы можем использовать TensorBoard для лучшего анализа
- 💻 Откройте CMD и:
👩🏫 Визуализация тренировочных ценностей
- 🧐 Здесь вы можете увидеть графики потерь, скорости обучения и других значений
- 🤓 И многое другое (вы можете изучить вкладки вверху)
- 😋 Можно использовать на тренировках (и увлекательно 🤩)
# under (tf1) E:\> tensorboard --logdir=E:/demo/tarining
👮♀️ Визуализация оценочных значений
- 👀 Здесь вы можете увидеть изображения из вашего тестового набора с соответствующими прогнозами.
- 🤓 И многое другое (вы можете просмотреть вкладки вверху)
- ❗ Вы должны использовать это после запуска оценочного скрипта
# under (tf1) E:\> tensorboard --logdir=E:/demo/eval
- 🔍 Посмотрите визуализированные результаты на localhost: 6006 и
- 🧐 Вы можете просмотреть числовые значения из отчета на терминале, пример результата:
Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.708 Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.984 Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.868 Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.289 Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.623 Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.767 Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 1 ] = 0.779 Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets= 10 ] = 0.781 Average Recall (AR) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.781 Average Recall (AR) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.300 Average Recall (AR) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.703 Average Recall (AR) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.824
- 🎨 Если вы хотите получить отчет по метрикам для каждого класса, вам необходимо изменить протокол оценки на паскаль метрики, настроив
metrics_set
в.config
файле:
eval_config: { ... metrics_set: "weighted_pascal_voc_detection_metrics" ... }
👒 Экспорт модели
- 🔧 После завершения процессов обучения и оценки мы должны сделать модель в таком формате, чтобы мы могли ее использовать.
- 🦺 На данный момент у нас есть только контрольные точки, поэтому нам нужно экспортировать
.pb
файл - 💻 Итак, открываем CMD и запускаем:
# under (tf1) E:\models\research\object_detection> # python export_inference_graph.py --input_type image_tensor # --pipeline_config_path <PATH_TO_CONFIG_FILE> # --trained_checkpoing_prefix <PATH_TO_LAST_CHECKPOINT> # --output_directory <PATH_TO_SAVE_EXPORTED_MODEL> python export_inference_graph.py --input_type image_tensor --pipeline_config_path=E:/demo/training/ssd_mobilenet_v1_quantized_300x300_coco14_sync.config --trained_checkpoing_prefix E:/demo/training/model.ckpt-16438 --output_directory E:/demo/inference/ssd_v1_quant
- Если вы используете SSD и планируете позже преобразовать его в tflite, вам нужно запустить
# under (tf1) E:\models\research\object_detection> # python export_tflite_ssd_graph.py --input_type image_tensor # --pipeline_config_path <PATH_TO_CONFIG_FILE> # --trained_checkpoing_prefix <PATH_TO_LAST_CHECKPOINT> # --output_directory <PATH_TO_SAVE_EXPORTED_MODEL> python export_tflite_ssd_graph.py --input_type image_tensor --pipeline_config_path=E:/demo/training/ssd_mobilenet_v1_quantized_300x300_coco14_sync.config --trained_checkpoing_prefix E:/demo/training/model.ckpt-16438 --output_directory E:/demo/inference/ssd_v1_quant
📱 Преобразование в tflite
- 💁♀️ Если вы хотите использовать модель в мобильных приложениях или встроенных устройствах с поддержкой tflite, вам необходимо преобразовать
.pb
файл в.tflite
файл.
📙 О TFLite
- 📱 TensorFlow Lite - легкое решение TensorFlow для мобильных и встроенных устройств.
- 🧐 Он обеспечивает логический вывод машинного обучения на устройстве с малой задержкой и небольшим двоичным размером.
- 😎 В TensorFlow Lite для этого используются многие методы, такие как квантованные ядра, которые позволяют создавать более мелкие и быстрые (математические модели с фиксированной точкой).
- 📍 Официальный сайт
🍫 Команда преобразования
- 💻 Чтобы применить преобразование, откройте CMD и запустите:
# under (tf1) E:\> # toco --graph_def_file=<PATH_TO_PB_FILE> # --output_file=<PATH_TO_SAVE> --input_shapes=<INPUT_SHAPES> # --input_arrays=<INPUT_ARRAYS> --output_arrays=<OUTPUT_ARRAYS> # --inference_type=<QUATIZED_UINT8|FLOAT> --change_concat_input_ranges=<true|false> # --alow_custom_ops # args for QUATIZED_UINT8 inference # --mean_values=<MEAN_VALUES> std_dev_values=<STD_DEV_VALUES> toco --graph_def_file=E:\demo\inference\ssd_v1_quant\tflite_graph.pb --output_file=E:\demo\tflite\ssd_mobilenet.tflite --input_shapes=1,300,300,3 --input_arrays=normalized_input_image_tensor --output_arrays=TFLite_Detection_PostProcess,TFLite_Detection_PostProcess:1,TFLite_Detection_PostProcess:2,TFLite_Detection_PostProcess:3 --inference_type=QUATIZED_UINT8 --mean_values=128 --std_dev_values=128 --change_concat_input_ranges=false --allow_custom_ops
🐞 Общие проблемы
🥅 проблема с сетевым модулем
ModuleNotFoundError: No module named 'nets'
Это означает, что возникла проблема с настройкой PYTHONPATH
, попробуйте запустить:
# under (tf1) E:\models\research> set PYTHONPATH=E:\models\research;E:\models\research\slim
🗃️ проблема с модулем tf_slim
ModuleNotFoundError: No module named 'tf_slim'
Это означает, что модуль tf_slim не установлен, попробуйте запустить:
# under (tf1) E:\models\research> pip install tf_slim
🗃️ Ошибка распределения
2020-08-11 17:44:00.357710: I tensorflow/core/common_runtime/bfc_allocator.cc:929] Stats: Limit: 10661327 InUse: 10656704 MaxInUse: 10657688 NumAllocs: 2959 MaxAllocSize: 3045064
Для меня это исправлено путем минимизации batch_size в .config
файле, это связано с вашими вычислительными ресурсами.
train_config: { .... batch_size: 128 .... }
❗ нет такой ошибки файла или каталога
train.py tensorflow.python.framework.errors_impl.notfounderror no such file or directory
- 🙄 Для меня это была опечатка в команде train.py
- 📍 Связанное обсуждение 1
- 📍 Связанное обсуждение 2
🤯 LossTensor - это информационная проблема
LossTensor is inf or nan. : Tensor had NaN values
- 👀 Связанное обсуждение ведется здесь, обычно это проблема с аннотациями
- 🙄 Возможно, есть какие-то ограничивающие рамки за пределами изображения
- 🤯 Решением для меня было уменьшение размера пакета в
.config
файле
🙄 Проблема с достоверностью информации
The following classes have no ground truth examples
- 👀 Связанное обсуждение находится здесь
- 👩🔧 Для меня это была ошибка в файле
label_map
, - 🙄 Обратите внимание на строчные и заглавные буквы
🏷️ проблема с картой этикеток
ValueError: Label map id 0 is reserved for the background label
- 👮♀️ id: 0 зарезервирован для фона, мы не можем использовать его для объектов
- 🆔 начальные идентификаторы с 1
🔦 Нет переменной для сохранения
Value Error: No Variable to Save
- 👀 Связанное решение: здесь
- 👩🔧 Добавление следующей строки в файл
.config
решило проблему
train_config: { ... fine_tune_checkpoint_type: "detection" ... }
🧪 проблема с модулем pycocotools
ModuleNotFoundError: No module named 'pycocotools'
- 👀 Связанное обсуждение находится здесь
- 👩🔧 Применение инструкций по загрузке, предоставленных здесь, решило проблему для меня (в Windows 10)
🥴 проблема с ошибкой типа pycocotools
pycocotools typeerror: object of type cannot be safely interpreted as an integer.
- 👩🔧 Я решил проблему, отредактировав следующие строки в скрипте cocoeval.py из пакета pycocotools (добавив приведение)
- 👮♀️ Убедитесь, что вы редактируете пакет в своем env, а не в другом env.
self.iouThrs = np.linspace(.5, 0.95, int(np.round((0.95 - .5) / .05)) + 1, endpoint=True) self.recThrs = np.linspace(.0, 1.00, int(np.round((1.00 - .0) / .01)) + 1, endpoint=True)
💣 Потеря взрыва
INFO:tensorflow:global step 440: loss = 2106942657570782838784.0000 (0.405 sec/step) INFO:tensorflow:global step 440: loss = 2106942657570782838784.0000 (0.405 sec/step) INFO:tensorflow:global step 441: loss = 7774169971762292326400.0000 (0.401 sec/step) INFO:tensorflow:global step 441: loss = 7774169971762292326400.0000 (0.401 sec/step) INFO:tensorflow:global step 442: loss = 25262924095336287830016.0000 (0.404 sec/step) INFO:tensorflow:global step 442: loss = 25262924095336287830016.0000 (0.404 sec/step)
🙄 У меня было 2 проблемы:
Первое:
- Некоторые аннотации были неправильными и выходили за пределы изображения (например, xmax ›width)
- Я мог проверить это, проверив файл
.csv
- Пример:
Второй:
- Скорость обучения в
.config
файле слишком велика (значение по умолчанию было большим 🙄) - Следующие значения действительны и протестированы на
mobilenet_ssd_v1_quantized
(Не очень хорошо 🙄)
learning_rate: { cosine_decay_learning_rate { learning_rate_base: .01 total_steps: 50000 warmup_learning_rate: 0.005 warmup_steps: 2000 } }
🥴 Ошибка получения свертки
Error : Failed to get convolution algorithm. This is probably because cuDNN failed to initialize, so try looking to see if a warning log message was printed above.
- Это может быть проблема несовместимости версий Cuda.
- Для меня это была проблема с памятью, и я решил ее, добавив следующую строку в скрипт
train.py
os.environ['TF_FORCE_GPU_ALLOW_GROWTH'] = 'true'
📦 Ошибка неверных данных коробки
raise ValueError('Invalid box data. data must be a numpy array of ' ValueError: Invalid box data. data must be a numpy array of N*[y_min, x_min, y_max, x_max]
- 🙄 Для меня это была логическая ошибка, в
test_labels.csv
были недопустимые значения, например:file123.jpg,134,63,3,0,0,-1029,-615
- 🔖 Итак, это была проблема с маркировкой, исправление этих строк решило проблему
- 👀 Связанное обсуждение
🔄 Изображение с добавленным идентификатором
raise ValueError('Image with id {} already added.'.format(image_id)) ValueError: Image with id 123.png already added.
- ☝ Это проблема в
.config
, вызванная присвоениемnum_example
значения, превышающего общее количество тестовых изображений в тестовом каталоге.
eval_config: { metrics_set: "coco_detection_metrics" use_moving_averages: false num_examples: 1265 // <--- this value was greater than total test images }