Обнаружение неизвестных меток: обнаружение данных вне домена, т. е. классификация изображений только для тех, для которых они обучены.

Мотивация

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

Исследуйте набор данных

Давайте подойдем к проблеме, используя набор данных PETs. Этот набор данных содержит 37 категорий различных пород домашних животных с почти 200 изображениями для каждого класса. Подробнее об этом наборе данных можно узнать здесь.

Начнем с установки и импорта необходимых библиотек.

Теперь давайте загрузим набор данных PETs,

Поскольку мы загрузили набор данных, давайте создадим объект блока данных и загрузчики данных.

Подготовка данных

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

Теперь, когда объект блока данных готов, давайте более подробно рассмотрим, что он делает.

  • blocks: этот параметр определяет входные и целевые типы данных, которые мы предоставляем модели. В приведенном выше коде ImageBlock представляет тип ввода как изображение, а MultiCategoryBlock представляет тип вывода как массив с горячим кодированием, тогда как обычный CategoryBlock , который используется для классификации изображений, использует порядковое кодирование целей.
  • get_items: этот параметр определяет, как получить входные данные. Мы используем функцию утилиты fastai get_image_files, которая принимает путь к папке в качестве параметра и возвращает пути ко всем изображениям, присутствующим в заданном пути. . Поскольку мы определили входной блок как ImageBlock, блок данных сможет преобразовать пути изображения в изображение PIL.
  • get_y: этот параметр определяет, как получить цели. Мы видели пример пути к изображению, которое мы скачали. Каждое имя файла изображения имеет шаблон, т. е. ‘breed_name’_XXX.jpg where X=0–9. Чтобы получить название породы, мы можем использовать регулярное выражение, чтобы извлечь его из строки пути и преобразовать в список. Мы используем Pipeline API Fastai для создания конвейера функций.
  • splitter: этот параметр определяет, как выполняется разделение поезда и проверки. Мы используем RandomSplitter, чтобы выполнить случайное разбиение набора данных с 20 % для проверки (по умолчанию). Мы устанавливаем случайное начальное число как 42, чтобы гарантировать, что мы получаем один и тот же набор проверки для каждого запуска.
  • item_tfms: этот параметр определяет преобразования, которые будут применяться к каждому элементу. Мы используем преобразование Resize с size=460, которое изменяет размер каждого изображения до размера 460.
  • batch_tfms. Этот параметр определяет преобразования, которые будут применяться к каждому пакету данных. Поскольку это применяется к пакетам данных, операция выполняется на графическом процессоре (если он доступен), чтобы ускорить ее. В приведенном выше коде мы используем функцию увеличения aug_tranforms от fastai, которая применяет увеличение основных данных, таких как отражение, изменение контраста, яркости, изменение размера и т. д.

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

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

Давайте также посмотрим на некоторые из целей,

Мы видим, что цель представляет собой массив с горячим кодированием, содержащий в общей сложности 37 классов. Вы можете проверить все ярлыки по dls.vocab .

Теперь давайте воспользуемся предварительно обученной моделью и настроим ее на наши данные.

Обучение модели

Давайте создадим объект учащегося, используя предварительно обученную модель resnet50. Поскольку мы используем метод классификации с несколькими метками для обнаружения неизвестных меток, нам также необходимо изменить функцию потерь. Поэтому мы должны использовать функцию потерь binary cross-entropy или функцию потерь BCEWithLogitsLossFlat() fastai с пороговым значением по умолчанию. Мы должны использовать accuracy_multi с более высоким порогом в качестве метрики, чтобы гарантировать, что выбрана только метка с наибольшей вероятностью.

Чтобы уменьшить размер модели и время обучения, мы используем метод обучения с половинной точностью, преобразуя все веса в модели в 16-битные числа с плавающей запятой. Для этого используется to_fp16().

Теперь давайте посмотрим на код,

Поскольку мы нашли оптимальную скорость обучения, давайте настроим модель на 3 эпохи.

Мы видим, что в течение 3 эпох обучения наша модель достигла точности 99%… Это довольно впечатляющий результат благодаря предварительно обученной модели resnet50. Давайте также посмотрим на график потерь,

Хорошо, мы видим, что потери при обучении и проверке постепенно уменьшаются, и модель не переоснащается.

Теперь давайте перейдем к выводу модели, где мы можем проверить обнаружение неизвестной метки в действии…

Вывод

Перед выводом давайте обновим порог нашей функции потерь BCEWithLogitsLossFlat() до 0,95. Поскольку используемая нами функция потерь имеет сигмовидную активацию, мы должны увеличить порог, чтобы включить обнаружение меток, в которых модель уверена.

Теперь давайте проверим некоторые результаты,

Из приведенных выше результатов видно, что наша модель хорошо работает на проверочном наборе.

Теперь давайте сделаем вывод модели вручную, т.е. загрузим несколько изображений из Интернета и проверим, совпадают ли результаты...

Чтобы проверить положительный случай, я загрузил изображение «Бомбейского кота» из изображений Google в местоположение ноутбука и создал объект изображения PIL,

Теперь давайте предскажем, что будет предсказывать наша модель,

Ура... Наша модель правильно предсказала, что это класс «Бомбей». Мы также видим, что вероятность для этого класса составляет 0,99… что довольно много.

Теперь давайте попробуем найти прогнозы для некоторых данных вне домена. Я загрузил изображение Эйфелевой башни из изображений Google и использовал его для предсказания…

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

Большой!! мы видим, что наша модель смогла понять, что это изображение не принадлежит ни к одной породе собак или кошек, для которой оно было обучено, т. е. к 37 породам домашних животных, и вернуло False для всех доступных классов.

Заключение

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

Спасибо

Источники:

  1. Глубокое обучение программистов с помощью fastai и PyTorch,книга Howard & Gugger.
  2. Прогулка с фастаем

Вы можете связаться со мной в LinkedIn здесь. Ссылка GitHub на блокнот доступна здесь.