Собака против кошки - это стандартная проблема в машинном обучении и компьютерном зрении, цель которой - построить модель, которая может предсказать, содержит ли изображение собаку или кошку. Благодаря развитию нейронных сетей и фреймворков, таких как Tensorflow и PyTorch, в последние несколько лет эта проблема была эффективно решена. В этой статье мы построим классификатор собак и кошек с использованием трансферного обучения, чтобы разработать модель, которая может предсказать, будет ли изображение кошкой или собакой с заметной точностью. Для разработки этой модели мы будем использовать Oxford-IIIT Pet Dataset и Keras и изучим множество новых концепций, таких как моделирование данных, предварительная обработка и то, как мы можем повысить точность нашей базовой модели с помощью предварительно обученных моделей с помощью трансферного обучения. .

Что такое трансферное обучение?

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

Идея Transfer Learning возникла в AlexNet еще в 2012 году, когда он выиграл конкурс ImageNet Large Scale Visual распознавания. После AlexNet появилось много других предварительно обученных моделей, которые превзошли AlexNet с точки зрения точности набора данных ImageNet. Исследователи придумали идею использования этих предварительно обученных моделей для обучения и разработки новых классификаторов для набора данных, с которыми предварительно обученная модель никогда раньше не сталкивалась. Этот метод использовался для переноса обучения предыдущей модели в новый набор данных.

И, что удивительно, трансферное обучение позволяет исследователям и разработчикам машинного обучения довольно легко обучать модели на новых наборах данных, просто изменяя и модифицируя последний слой в соответствии с их потребностями. Набор данных ImageNet имеет 1000 выходных классов. Fashion MNIST, с другой стороны, имеет только 10, в то время как наш классификатор Dog-Cat имеет только 2. Мы можем добиться этого, изменив последний слой модели и заморозив предварительно обученную модель, установив переменные как необучаемые.

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

Чтобы начать работу с кодом, рекомендуется запустить его в Google Colab или Azure Notebooks, так как это ускорит время разработки и моделирования данных, и вам не нужно беспокоиться об установке пакетов. Теперь мы начнем с загрузки нашего набора данных и подготовки его для моделирования данных.

Скачивание набора данных

Как упоминалось ранее, мы будем использовать набор данных домашних животных Oxford-IIIT для нашей цели и намерения здесь разработать классификатор собак и кошек. Здесь мы будем использовать библиотеку urllib для загрузки набора данных, который представляет собой библиотеку Python для открытия и чтения URL-адресов. Мы также сначала импортируем необходимые пакеты, чтобы упростить процесс разработки. Давайте сначала загрузим наш набор данных из онлайн-хранилища:

В приведенном выше блоке кода мы сделали две вещи:

  • Заявлены необходимые нам пакеты для работы с данными.
  • Скачивание набора данных, который включает изображения и аннотации.

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

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

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

Если вы используете Colab, вы можете включить графический процессор, перейдя в Runtime и нажав Change Runtime. Вы можете включить опцию графического процессора, щелкнув «Аппаратный ускоритель» и нажав «Графический процессор».

Теперь, когда мы загрузили наш набор данных и выполнили необходимые проверки, мы можем продолжить решение проблемы. Поскольку это проблема двоичной классификации, мы будем использовать аннотации, чтобы указать на наши образцы в наборе данных. Наш набор данных был загружен в каталог данных, поэтому теперь мы будем писать код для правильного добавления комментариев к изображениям собак и кошек. Если вы посмотрите на свой набор данных, вы обнаружите, что там есть аннотации и изображения. В аннотациях вы можете увидеть список, который представляет собой ваш список файлов, а также trainval и test, которые содержат наш набор данных для обучения и тестирования. Они содержат имена изображений, которые мы будем использовать для аннотирования нашего набора данных.

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

По сути, «Класс для индексации» и «Индекс для класса» означает, что изображения, помеченные как 0, принадлежат кошке, а изображения, помеченные как 1, принадлежат собаке. Теперь, когда мы извлекли аннотации, перейдем к изображениям.

Теперь мы напишем код для получения случайной партии из наших изображений. Здесь мы будем предварительно обрабатывать наш набор данных с помощью Keras. Основная цель Random Batch - взять словарь аннотаций и вернуть несколько случайно выбранных примеров из нашего набора данных.

Что мы здесь делали?

  • Мы взяли аргументы в нашей функции как словарь аннотаций и размер пакета. Ключи аннотации преобразуются в список, и длина сохраняется.
  • Мы использовали случайную функцию Numpy, чтобы вернуть несколько случайно выбранных примеров из нашего набора данных.
  • Изображения сохраняются в массиве x, где мы передаем размер пакета в качестве параметра и принимаем 128x128x3 в качестве размера изображения. Причина, по которой мы используем это, заключается в том, что мы будем использовать MobileNet в качестве нашей базовой модели, и это один из доступных нам вариантов изображения, который является наименьшим размером, для которого доступно изображение.
  • Мы сохраним выходные данные класса в массиве y, где мы сохраним либо 1, либо 0, которые будут нашим выходом класса.
  • Теперь мы запустим цикл, чтобы вернуть примеры изображений, а не только метки и аннотации. Мы извлечем изображение из каталога изображений и передадим ключевой индекс изображения.
  • Мы можем использовать вспомогательную функцию предварительной обработки, определенную в Keras, вызывая tf.keras.preprocessing.image, а затем передавая путь к изображению и размер канала, равный 128x128x3.
  • Мы будем использовать другую функцию Keras для преобразования изображения в массив Numpy, и для этой операции мы будем использовать tf.keras.preprocessing.image.img_to_array только потому, что наша модель ожидает данные в многомерном формате.
  • Мы можем дополнительно обработать наш входной набор данных с помощью другой функции Keras tf.keras.applications.mobilenet_v2.preprocess_input. В первую очередь это делается для изменения среднего стандартного отклонения нашего набора данных, чтобы было легко достичь глобальных минимумов.
  • Наконец, мы можем написать код для расширения наших измерений, чтобы вернуть размер пакета в соответствии с размером, который мы передали в функции. Наконец, мы передадим массив в x, а ключи - в y. Затем мы можем вернуть как x, так и y и завершить функциональный блок.

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

Это покажет наш результат как:

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

Моделирование данных

В рамках данной статьи мы будем использовать MobileNet v2 в качестве базовой модели для выполнения трансферного обучения. MobileNet - это популярная предварительно обученная модель, которая была обучена на наборе данных ImageNet. Обучение модели, подобной MobileNet, которая имеет миллионы параметров, требует больших вычислительных ресурсов и требует много времени, и чтобы сэкономить время и повысить точность во много раз, мы будем полагаться на Transfer Learning для нашей цели.

Давайте загрузим MobileNet v2 из Keras, и мы также должны указать несколько параметров. Напишем этот простой блок кода:

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

Здесь мы кратко изложим всю архитектуру MobileNet и не возьмем на себя никаких проблем, если вы не очень разбираетесь в ней. Мы будем использовать эту архитектуру для разработки нашей собственной модели. У нас здесь более двух миллионов обучаемых параметров, и теперь мы будем создавать нашу собственную модель поверх них. Итак, давайте начнем с кода:

Здесь мы инициализировали нашу модель, поэтому давайте подробно обсудим, что мы здесь сделали:

  • Мы будем использовать последовательную модель от Keras. Это определит, как модель будет размещена в слоях стека.
  • Мы установим архитектуру MobileNet, которую мы скачали, в качестве нашего первого слоя, а затем мы установим для Dropout Layer значение 0,5 в качестве коэффициента отсева.
  • Наш последний слой будет плотным слоем, и здесь мы будем использовать сигмоид в качестве нашей функции активации.
  • Затем мы установим для обучаемых слоев значение False, чтобы не обучать их со своей стороны, а затем передадим функцию model.compile () с двоичной кроссентропией в качестве нашей функции потерь и оптимизатора Адама.
  • Затем мы перейдем к созданию модели и печати сводки по модели.

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

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

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

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

Мы используем волшебную функцию %% time для измерения времени ячейки кода. Для настройки и обучения может потребоваться несколько секунд или минут, и мы видим, что точность проверки составила 94,35%.

Прогнозы

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

Получим такой результат:

Заключение

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

  • Что такое трансферное обучение?
  • Как можно использовать переносное обучение с новыми наборами данных?
  • Предварительная обработка набора данных.
  • Моделирование данных с переносом обучения и предварительно обученными весами.
  • Визуализация результатов.

Что дальше? Вы можете использовать необходимые выводы из этой статьи и использовать трансферное обучение для некоторых новых наборов данных. Вы также можете начать изучение некоторых новых предварительно обученных моделей, таких как VGG16, которые я использовал для создания классификатора COVID-19 здесь, маски R-CNN и YOLOv2. Удачи в ваших будущих начинаниях!

Вы можете просмотреть код здесь!