Наборы данных и их аннотации часто хранятся в очень разных форматах. FiftyOne позволяет легко загружать и визуализировать любой набор данных изображений и меток.

DataFrames - это стандартный способ хранения табличных данных с помощью различных инструментов, которые существуют для визуализации данных различными способами. С другой стороны, наборы данных изображений и видео не имеют стандартного формата для хранения данных и аннотаций. Почти каждый разрабатываемый набор данных создает новую схему для хранения необработанных данных, ограничивающих рамок, меток уровня выборки и т. Д.

Я работал над инструментом машинного обучения с открытым исходным кодом под названием FiftyOne, который может помочь облегчить боль от необходимости писать собственные сценарии загрузки, визуализации и преобразования всякий раз, когда вы используете новый набор данных. FiftyOne поддерживает сразу несколько форматов наборов данных, включая MS-COCO, YOLO, Pascal VOC и другие. Однако, если у вас есть формат набора данных, который не предоставляется по умолчанию, вы все равно можете легко загрузить его в FiftyOne вручную.

Зачем вам нужны ваши данные в FiftyOne? FiftyOne предоставляет высокофункциональное приложение и API, которые позволят вам быстро визуализировать свой набор данных, генерировать интересные запросы, находить аннотации ошибок, конвертируйте его в другие форматы, загружайте в зоопарк моделей и многое другое.

В этом сообщении блога вы узнаете, как загрузить классификации на уровне изображений, обнаружение объектов, сегментацию и визуальные отношения в FiftyOne, визуализировать их и преобразовать в другие форматы. Я буду использовать Open Images V6, выпущенный в феврале 2020 года, в качестве основы для этого поста, поскольку он содержит все эти типы данных. Если вас интересует только загрузка Open Images V6, вы можете проверить это в FiftyOne Dataset Zoo и загрузить в одну строку кода! Если у вас есть собственный набор данных, который вы хотите загрузить, настройте код в этом сообщении, чтобы проанализировать формат, в котором хранятся ваши данные.

Открыть изображения V6

Open Images - это набор данных, выпущенный Google, содержащий более 9 миллионов изображений с метками, охватывающими различные задачи:

  • Метки уровня изображения *
  • Ограничительные рамки объекта *
  • Визуальные отношения *
  • Маски сегментации экземпляров *
  • Локализованные повествования

* Загружено в этом сообщении

Эти аннотации были созданы с помощью комбинации алгоритмов машинного обучения с последующей проверкой человеком теста, валидацией и подмножествами обучающих разделов. Версии этого набора данных также используются в Задачах открытых изображений на Kaggle.

Open Images V6 представил локализованные повествования, которые представляют собой новую форму мультимодальных аннотаций, состоящих из закадрового комментария и следа мыши аннотатора, описывающего изображение. Поддержка локализованных повествований FiftyOne в настоящее время находится в разработке.

Новый способ загрузки и оценки открытых изображений!

[Обновлено 12 мая 2021 г.] После публикации этого сообщения мы сотрудничали с Google для поддержки Открытых изображений V6 напрямую через FiftyOne Dataset Zoo. Теперь так просто загрузить открытые изображения, данные, аннотации и все остальное:

С помощью этой реализации в FiftyOne вы также можете указать любое подмножество открытых изображений с такими параметрами, как classes, split, max_samples и другими:

Кроме того, если вы обучаете модель на открытых изображениях, FiftyOne теперь поддерживает оценку стиля открытых изображений, позволяющую создавать те же метрики mAP, которые используются в задачах открытых изображений. Преимущество использования FiftyOne для этого заключается в том, что он также хранит истинно положительные, ложноположительные и ложноотрицательные результаты на уровне экземпляра, что позволяет вам не полагаться только на совокупные показатели всего набора данных, но фактически получить практические результаты своей модели и узнать как лучше всего повысить производительность.

Для получения дополнительной информации ознакомьтесь с этим постом или этим руководством!

Открытые форматы ярлыков изображений

В предыдущем разделе показан лучший способ загрузки набора данных Open Images. Однако FiftyOne также позволяет легко загружать пользовательские наборы данных. В следующих нескольких разделах показано, как загрузить набор данных в FiftyOne с нуля. Мы используем Open Images в качестве примера набора данных для этого, поскольку он содержит большое количество типов меток.

Примечание. Код в следующих разделах предназначен для адаптации к вашим собственным наборам данных, его не нужно использовать для загрузки открытых изображений. Используйте приведенные выше примеры, если вас интересует только загрузка набора данных Open Images.

В этом разделе «Форматы меток открытых изображений» мы описываем формат, используемый Google для хранения аннотаций открытых изображений на диске. Мы будем использовать эту информацию для написания парсеров для загрузки этого набора данных в FiftyOne в следующем разделе «Загрузка пользовательских наборов данных в FiftyOne».

Локальная загрузка данных

Ссылки для загрузки AWS для обучающей группы (513 ГБ), проверки (12 ГБ) и тестирования (36 ГБ) можно найти в репозитории Open Images на GitHub. Аннотации к интересующим вас задачам можно скачать прямо с сайта Open Images.

В этом примере мы будем использовать образцы из тестового сплита. Вы можете скачать весь тестовый сплит (36 Гб!) Следующими командами:

pip install awscli
aws s3 --no-sign-request sync s3://open-images-dataset/test ./open-images/test/

В качестве альтернативы я буду загружать только несколько изображений из тестовой части ниже в этом сообщении.

Нам также необходимо будет загрузить соответствующие файлы аннотаций для каждой задачи, которые находятся здесь: https://storage.googleapis.com/openimages/web/download.html

Ярлыки на уровне изображения

Каждое изображение в Open Images может содержать несколько меток уровня изображения для сотен классов. Эти ярлыки делятся на два типа: положительные и отрицательные. Положительные метки - это классы, присутствие которых на изображении было подтверждено, а отрицательные метки - это классы, которые проверены на отсутствие на изображении. Отрицательные метки полезны, потому что они обычно указываются для классов, которые, как вы можете ожидать, появятся в сцене, но не появятся. Например, если на поле находится группа людей в костюмах, вы можете ожидать, что там будет ball. Если его нет, это будет хороший отрицательный ярлык.

wget -P labels https://storage.googleapis.com/openimages/v5/test-annotations-human-imagelabels-boxable.csv

Ниже приведен образец содержимого этого файла:

ImageID,Source,LabelName,Confidence
000026e7ee790996,verification,/m/0cgh4,0
000026e7ee790996,verification,/m/04hgtk,0
...

Нам нужен список классов как для меток, так и для детекторов:

wget -P labels https://storage.googleapis.com/openimages/v5/class-descriptions-boxable.csv

Ниже приведен образец содержимого этого файла:

/m/011k07,Tortoise
/m/011q46kg,Container
...

Обнаружения

Объекты локализованы и помечены теми же классами, что и метки уровня изображения. Кроме того, каждое обнаружение содержит логические атрибуты, указывающие, является ли объект закрытым, усеченным, представляющим группу других объектов внутри другого объекта или изображение объекта (например, мультфильм).

wget -P detections https://storage.googleapis.com/openimages/v5/test-annotations-bbox.csv

Ниже представлен образец содержимого этого файла:

ImageID,Source,LabelName,Confidence,XMin,XMax,YMin,YMax,IsOccluded,IsTruncated,IsGroupOf,IsDepiction,IsInside
000026e7ee790996,xclick,/m/07j7r,1,0.071875,0.1453125,0.20625,0.39166668,0,1,1,0,0
000026e7ee790996,xclick,/m/07j7r,1,0.4390625,0.571875,0.26458332,0.43541667,0,1,1,0,0
...

Визуальные отношения

Отношения помечаются между двумя обнаружениями объектов. Примеры: если один объект носит другой. Наиболее распространенная связь - is, указывающая, is объект имеет какой-то атрибут (например, кожаная сумка is). Аннотации для этих отношений включают ограничивающие рамки и метки обоих объектов, а также метку для отношения.

wget -P relationships https://storage.googleapis.com/openimages/v6/oidv6-test-annotations-vrd.csv
wget -P relationships https://storage.googleapis.com/openimages/v6/oidv6-attributes-description.csv

Ниже приведен образец содержимого файла отношений:

ImageID,LabelName1,LabelName2,XMin1,XMax1,YMin1,YMax1,XMin2,XMax2,YMin2,YMax2,RelationshipLabel
9553b9608577b74b,/m/04yx4,/m/017ftj,0.023404,0.985106,0.038344,0.981595,0.238298,0.759574,0.349693,0.529141,wears
819903f6353b60b5,/m/03m3pdh,/m/0dnr7,0.096875,1.000000,0.095833,1.000000,0.096875,1.000000,0.095833,1.000000,is
...

Сегментация экземпляра

Маски сегментации загружаются через 16 zip-файлов, каждый из которых содержит маски, относящиеся к изображениям, начинающимся с 0–9 или A-F. В этом примере мы будем использовать только изображения, начинающиеся с 0. Следующая команда загружает только эти маски, замените 0 на 1-9 или a-f, чтобы загрузить маски для других изображений.

Эти аннотации сегментации хранятся в отдельном изображении для каждого объекта, а также включают координаты ограничивающей рамки вокруг сегментации и метку сегментации.

wget -P segmentations https://storage.googleapis.com/openimages/v5/test-masks/test-masks-0.zip
unzip -d segmentations/masks segmentations/test-masks-0.zip
wget -P segmentations https://storage.googleapis.com/openimages/v5/test-annotations-object-segmentation.csv

Ниже приведен образец содержимого файла сегментации:

MaskPath,ImageID,LabelName,BoxID,BoxXMin,BoxXMax,BoxYMin,BoxYMax,PredictedIoU,Clicks
d0ed76e0533a914d_m01xyhv_cffd8afa.png,d0ed76e0533a914d,/m/01xyhv,cffd8afa,0.122966,0.958409,0.389892,0.998195,0.00000,
fba940ee0203b368_m08pbxl_13094a08.png,fba940ee0203b368,/m/08pbxl,13094a08,0.460938,0.551562,0.387500,0.572917,0.00000,
...

Предварительная обработка

Мы собираемся использовать только небольшую часть набора данных в этом примере, чтобы упростить отслеживание. Кроме того, поскольку мы хотим загрузить много разных типов аннотаций, нам нужно найти несколько примеров, совместимых со всеми нашими этикетками.

Давайте загрузим аннотации из csv файлов, которые мы загрузили, и проанализируем их, чтобы найти подмножество изображений, которые мы хотим использовать.

Теперь у нас есть список valid_ids, который содержит все аннотации, на которые мы хотим обратить внимание. Давайте выберем подмножество из 100 из них и загрузим соответствующие изображения, следуя тому, что делается в официальном скрипте загрузки Open Images.

pip install boto3

Последнее, что нам нужно, - это сопоставление идентификаторов классов и атрибутов с их фактическими именами.

Загрузка пользовательских наборов данных в FiftyOne

Сначала вам нужно установить FiftyOne с помощью простой команды pip. Рекомендуется работать с FiftyOne в интерактивных сессиях Python, так что давайте установим и его.

pip install fiftyone
pip install ipython

После запуска ipython первым шагом будет создание FiftyOne Dataset.

Если вы хотите, чтобы этот набор данных существовал после выхода из сеанса Python, установите для атрибута persistent значение True. Это позволяет нам быстро загружать набор данных в будущем.

Затем нам нужно создать FiftyOne Samples для каждого изображения, которое содержит путь к файлу с изображениями, а также всю информацию меток, которую мы хотим импортировать. Для каждого типа метки мы создадим соответствующий объект в FiftyOne и добавим его как field в наши образцы.

Добавление классификационных меток уровня изображения будет использовать класс fo.Classifications. Обнаружения, сегментации и отношения могут использовать класс fo.Detections, поскольку он поддерживает ограничивающие рамки, маски, а также настраиваемые атрибуты, назначаемые каждому обнаружению. Эти настраиваемые атрибуты могут использоваться для таких вещей, как IsOccluded в обнаружениях или для двух меток, между которыми существует связь.

В разделах ниже описывается, как создавать ярлыки FiftyOne из данных открытых изображений, которые мы уже загрузили, а затем как добавлять их в ваш набор данных FiftyOne.

Классификационные этикетки

В классификационных этикетках используется класс fo.Classification. Поскольку это классификации с несколькими метками, мы будем использовать класс fo.Classifications для хранения нескольких меток классификации.

Кроме того, мы хотим разделить положительные и отрицательные метки (уверенность 1 и 0 соответственно) в разные поля классификации, чтобы мы могли просматривать их отдельно в приложении.

Обнаружение объектов

Подобно классификациям, класс fo.Detections позволяет хранить несколько fo.Detection объектов в списке. Мы создаем обнаружение, определяя координаты ограничивающего прямоугольника и метку класса объекта. Затем мы можем добавить любые дополнительные атрибуты, которые захотим, например IsOccluded и IsTruncated.

Визуальные отношения

Отношения лучше всего представлены в FiftyOne - fo.Detections, поскольку отношение содержит ограничивающую рамку, метку отношения и метки объекта, которые могут быть сохранены в обнаружении. Мы собираемся сделать так, чтобы ограничивающая рамка отношения охватывала ограничивающие рамки обоих объектов, к которым она относится. Мы добавляем метки каждого объекта в качестве дополнительных настраиваемых полей для обнаружения.

Следует отметить, что вы также можете легко добавить два объекта, которые составляют отношения, как отдельные обнаружения, а не делать этого было просто выбором дизайна для этого сообщения.

Сегментации

Мы снова можем использовать fo.Detections для хранения сегментов, поскольку обнаружение содержит необязательный аргумент mask, который принимает массив NumPy и масштабирует его до области ограничивающего прямоугольника. Сегменты в открытых изображениях также содержат ограничивающую рамку вокруг маски, а также метку экземпляра, которые добавляются к объектам обнаружения.

Создание образцов FiftyOne

Теперь, когда мы определили функции, которые будут принимать данные Open Images и возвращать метки FiftyOne, мы можем создавать образцы и добавлять к ним эти метки.

Образцам требуется только filepath для создания экземпляров, и мы можем добавить к образцу любые метки FiftyOne. После создания образца мы можем добавить его в набор данных и продолжить, пока все наши данные не будут загружены.

Визуализация и исследование

Как только наши данные загружены в набор данных FiftyOne, мы можем запустить Приложение и начать исследование.

В Приложении мы можем выбрать, какое из полей меток мы хотим просмотреть, просмотреть отдельные образцы в развернутом виде, а также просмотреть распределения меток.

Открытие образца в расширенном представлении позволяет визуализировать добавленные нами атрибуты, такие как метки отношений. Например, мы можем видеть, что на изображении ниже есть два Ride отношения между Man и Horse.

Возможность легко визуализировать наш набор данных позволяет нам быстро проверять данные. Например, кажется, что метка Mammal имеет противоречивое значение между разными образцами. Ниже приведены два изображения, на которых изображены люди, на одном Mammal в качестве negative_label, а на другом Mammal в качестве positive_label.

Запросы

Одна из передовых функций FiftyOne - это возможность тесно взаимодействовать с вашим набором данных в коде и в приложении. Это позволяет вам писать сложные запросы, которые в противном случае потребовали бы большого количества сценариев.

Например, предположим, что мы хотим создать подмножество открытых изображений, содержащее изображения лиц крупным планом. Мы можем создать представление в наборе данных, которое позволит нам получать все обнаружения, содержащие Human face с областью ограничивающей рамки больше 0,2.

Обновление объекта session автоматически обновляет то, что мы видим в приложении. Выглядит неплохо, но есть пара изображений с большими Human face рамками только потому, что на них изображена толпа людей. Мы можем дополнительно отфильтровать представление, убедившись, что поля не содержат атрибут IsGroupOf при обнаружении.

Преобразование форматов

Когда ваши данные находятся в FiftyOne, вы можете экспортировать их в любой из форматов, поддерживаемых FiftyOne, с помощью всего лишь пары строк кода.

Например, если мы хотим экспортировать detections, который мы добавили в формат MS-COCO, чтобы мы могли использовать на нем оценку pycocotools, мы можем сделать это в одной строке кода на Python.

Общая формула загрузки наборов данных

Самый простой способ загрузить ваши данные - это следовать стандартному формату для ваших аннотаций. Например, если вы только что закончили комментировать в инструменте с открытым исходным кодом CVAT, вы можете загрузить его в FiftyOne так же легко, как:

Даже если ваши данные находятся в настраиваемом формате, легко вручную создать набор данных FiftyOne.

После загрузки данных вы можете использовать FiftyOne App для визуализации и изучения набора данных, использовать FiftyOne Model Zoo для создания прогнозов на основе ваших данных, экспортировать их в различные форматы и многое другое!

О Voxel51

Высококачественные, специально подобранные данные имеют решающее значение для обучения отличным моделям компьютерного зрения. В Voxel51 мы обладаем более чем 25-летним опытом CV / ML и глубоко заботимся о том, чтобы дать возможность сообществу воплотить свои решения AI в жизнь. Вот почему мы разработали FiftyOne, инструмент с открытым исходным кодом, который помогает инженерам и ученым создавать высококачественные наборы данных и модели.

Хотите узнать больше? Посетите нас на https://fiftyone.ai.