Классификация изображения с использованием технологии Transfer Learning в PyTorch

МЕНЮ


Искусственный интеллект
Поиск
Регистрация на сайте
Помощь проекту

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости


В этом посте мы расскажем, как классифицировать изображения в PyTorch. Мы будем использовать датасет CalTech256 для классификации 10 различных видов животных. Мы рассмотрим такие этапы как, подготовка данных, увеличение данных и создание классификатора. Мы используем Transfer Learning, чтобы находить низкоуровневые эллементы изображения, такие как края, текстуры и т.д., а затем обучим наш классификатор, чтобы узнать детали более высокого уровня, таких как глаза, ноги и т. д. ResNet50 уже прошел обучение на ImageNet с миллионами изображений.

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

Набор данных CalTech256 содержит 30 607 изображений, разделенных на 256 классов вместе шумами. Обучение всего набора данных займет несколько часов, поэтому мы будем работать с подмножеством набора данных, содержащим 10 животных - медведь, шимпанзе, жираф, горилла, лама, страус, дикобраз, скунс, трицератопс и зебра. Таким образом, мы можем обучаться быстрее. Затем этот код можно использовать для обучения всего набора данных. Количество изображений в этих папках варьируется от 81 (для скунса) до 212 (для гориллы). Мы используем первые 60 изображений в каждой из этих категорий для обучения, следующие 10 изображений для проверки, а остальные для тестирования в наших экспериментов. Итак, наконец, у нас есть 600 тренировочных изображений, 100 проверочных изображений, 409 тестовых изображений и 10 классов животных. Если вы хотите повторить эксперименты, пожалуйста, следуйте инструкциям ниже.

1.Скачайте датасет CalTech256

2. Создайте три каталога с именами train, valid и test.

3. Создайте 10 подкаталогов каждый внутри train, valid и test. Подкаталоги должны быть названы так «медведь», «шимпанзе», «жираф», «горилла», «лама», «страус», «дикобраз», «скунс», «трицератопс» и «зебра». (Обязательно на английском)

4. Переместите первые 60 изображений из папки «медведь» из набора данных Caltech256 в каталог train/bear и повторите это для каждого животного.

5. Переместите следующие 10 изображений с медведем из набора данных Caltech256 в каталог valid / bear и повторите это для каждого животного.

6. Скопируйте оставшиеся изображения медведя (то есть те, которые не включены в train и valid) в каталог test / bear. Повторите это для каждого животного.

Увеличение данных

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

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

Ниже мы видим примеры преобразованных версий образа Трицератопса.

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

Преобразование RandomResizedCrop обрезает входное изображение в случайном месте(в пределах диапазона от 0,8 до 1,0 от исходного размера и случайного соотношения сторон в диапазоне по умолчанию от 0,75 до 1,33). Обрезка затем изменяется до 256 ? 256.

RandomRotation поворачивает изображение на угол, случайно выбранный в диапазоне от -15 до 15 градусов.

RandomHorizontFlip случайным образом переворачивает изображение по горизонтали с вероятностью по умолчанию 50%.

CenterCrop обрезает изображение 224 ? 224 от центра.

ToTensor преобразует изображение PIL, имеющее значения в диапазоне 0-255, в тензор с плавающей запятой и нормализует их в диапазоне 0-1, разделив его на 255.

Нормализация принимает трехканальный тензор и нормализует каждый канал по среднему значению и стандартному отклонению для канала. Средние и среднеквадратичные векторы вводятся как 3-элементные векторы. Каждый канал в тензоре нормируется как T u003d (T - среднее) / (стандартное отклонение)

Все вышеперечисленные преобразования объединены с помощью Compose.

Обратите внимание, что для validation и test мы не выполняем преобразования RandomResizedCrop, RandomRotation и RandomHor HorizontalFlip. Вместо этого мы просто изменяем размеры проверочных изображений до 256 ? 256 и обрезаем центр 224 ? 224, чтобы иметь возможность использовать их с предварительно обученной моделью. Затем изображение преобразуется в тензор и нормализуется по среднему и стандартному отклонению всех изображений в ImageNet.

Загрузка данных

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

Сначала мы создаем набор данных train и validation, а также размер батча. Затем мы загружаем их с помощью DataLoader. Обратите внимание, что преобразования изображений, которые мы обсуждали ранее, применяются к данным при их загрузке с использованием DataLoader. Порядок данных также перетасовывается. Пакет torchvision.transforms и DataLoader являются очень важными функциями PyTorch, которые упрощают процесс увеличения и загрузки данных.

Transfer Learning

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

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

ResNet50 - один из тех, у кого есть хороший компромисс между точностью и временем вывода. Когда модель загружается в PyTorch, все ее параметры имеют поле «require_grad», установленное по умолчанию «true». Это означает, что каждое и каждое изменение значений параметров будет сохранено для использования в графе обратного распространения, используемом для обучения. Это увеличивает требования к памяти. Итак, так как большинство параметров в нашей предварительно обученной модели уже обучены, мы возвращаем в поле require_grad значение false.

Затем мы заменяем последний слой модели ResNet50 небольшим набором последовательных слоев. Входы на последний полностью подключенный уровень ResNet50 поступают на линейный уровень, который имеет 256 выходов, которые затем подаются на уровни ReLU и Dropout. Затем следует линейный слой 256 ? 10, который имеет 10 выходов, соответствующих 10 классам в нашем подмножестве CalTech.

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

Далее мы определяем функцию потерь и оптимизации, которая будет использоваться для обучения. PyTorch предоставляет много видов функций потерь. Мы используем функцию loss, так как она может использоваться для классификации нескольких классов. PyTorch также поддерживает несколько оптимизаторов. Мы используем оптимизатор Adam. Адам является одним из самых популярных оптимизаторов, потому что он может адаптировать скорость обучения для каждого параметра в отдельности.

Обучение

Весь код находится в Notebook Python, но здесь мы покажем лишь концепцию. Обучение проводится для фиксированного набора эпох, обрабатывая каждое изображение один раз в одну эпоху. Загрузчик данных загружает данные пакетами. В нашем случае мы установили размер пакета 32, что означает, что каждая партия может иметь максимум 32 изображения.

Для каждой партии входные изображения передаются через модель (прямой переход), чтобы получить выходные данные. Затем предоставленная функция loss_criterion или cost используется для вычисления потерь. Градиенты потерь по отношению к обучаемым параметрам вычисляются с использованием обратной функции. Обратите внимание, что при обучении переносу нам нужно вычислять градиенты только для небольшого набора параметров, которые принадлежат нескольким вновь добавленным слоям ближе к концу модели. Сводный вызов функции для модели может выявить фактическое количество параметров и количество обучаемых параметров. Как мы видим ниже, теперь нам нужно тренироваться только на десятой части от общего количества параметров модели.

Вычисление градиента выполняется с использованием autograd и back propagation, дифференцируясь в графе с использованием правила цепочки. PyTorch накапливает все градиенты в обратном проходе. Поэтому важно обнулить их в начале цикла обучения. Это достигается с помощью функции оптимизатора zero_grad. Наконец, после вычисления градиентов в обратном проходе параметры обновляются с помощью функции шага оптимизатора.

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

Validation

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

Для каждого батча проверки входные данные и метки передаются в GPU (если доступна cuda, иначе - процессор). Входные данные проходят прямой проход, за которым следуют вычисления потерь и точности для партии и в конце цикла для всей эпохи.

Как мы можем видеть на графиках выше, и потери на валидацию и обучение довольно быстро распределяются для этого набора данных. Точность также увеличивается до диапазона 0,9 очень быстро. По мере увеличения количества эпох потери на обучение продолжают уменьшаться, что приводит к переобучению, но результаты проверки не улучшаются значительно. Поэтому мы выбрали модель той эпохи, которая имела более высокую точность и меньшие потери. Также лучше, если мы остановимся рано, чтобы не допустить переобучения тренировочных данных. В нашем случае мы выбрали эпоху # 8, которая имела точность проверки 96%.

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

Вывод данных

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

Сначала входное изображение подвергается всем преобразованиям, используемым для проверки / проверки данных. Полученный тензор затем преобразуется в 4-мерный и проходит через модель, которая выводит логарифмические вероятности для разных классов. Экспонента выходных данных модели предоставляет нам вероятности класса, а затем мы выбираем класс с наибольшей вероятностью в качестве нашего выходного класса.

Выберите класс с наибольшей вероятностью в качестве нашего выходного класса.

Точность 92,4% была достигнута на тестовом наборе с 409 изображениями.

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

Мы только что увидели, как использовать предварительно обученную модель, которая была обучена для 1000 классов ImageNet, чтобы очень эффективно классифицировать изображения, принадлежащие к 10 различным классам, которые нас интересуют.

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


Источник: m.vk.com

Комментарии: