Пошаговое руководство по созданию вашей первой нейронной сети

Компьютерное зрение — одна из самых горячих тем на сегодняшний день. Он обеспечивает надежные решения различных проблем, связанных с изображениями. В этой статье мы создадим сверточную нейронную сеть (CNN) с нуля, используя Tensorflow. Затем мы будем использовать его для классификации изображений кошек и собак, одного из самых популярных наборов данных для классификации изображений.

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

Что такое классификация?

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

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

Для более подробного объяснения, что такое классификация и самые популярные алгоритмы, настоятельно рекомендую прочитать следующую статью:



Сверточные нейронные сети (CNN)

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

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

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



Создание нашей сети

(Вы можете найти весь код в этом репозитории)

Пришло время приступить к работе и построить наш классификатор. Как мы уже говорили ранее, мы создадим классификатор кошек/собак, используя простую архитектуру CNN с использованием Tensorflow и Keras.

Загрузить набор данных

Мы будем использовать Oxford-IIIT Pet Dataset, содержащий более 7000 изображений кошек и собак. Этот набор данных имеет лицензию CC-BY-SA 4.0, что означает, что мы можем делиться и адаптировать данные для любых целей.

Прежде всего, нам понадобятся следующие библиотеки.

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

Когда у нас будет набор данных, он будет содержать одну папку с именем images со всеми изображениями питомцев внутри.

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

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

Посмотрим, сколько у нас данных.

There are 7390 images in the dataset

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

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

There are 2400 images of cats
There are 4990 images of dogs

В наборе данных 2400 кошек и 4990 собак.

Раздел данных

Для нашей сети мы хотим использовать три разных набора:

  • train: изображения для обучения модели.
  • проверка: изображения для проверки модели в процессе обучения.
  • test: изображения для проверки модели после завершения обучения.

Мы будем использовать 70% изображений для обучения, 10% для проверки и оставшиеся 20% для тестирования.

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

Сначала мы перемешиваем данные и делим их на три набора с соответствующим распределением данных 70/10/20.

Далее нам нужно создать фреймы данных с помощью pandas.

У них будет только два столбца, один с названием изображения, а другой с меткой «кошка» или «собака».

Наконец, мы можем объединить фреймы данных.

There are 5173 images for training
There are 739 images for validation
There are 1478 images for testing
There are 7000 images for training
There are 1000 images for validation
There are 2000 images for testing

Идеальный! Мы создали три раздела из нашего набора данных.

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

Следующим шагом является предварительная обработка всех изображений. Мы хотим, чтобы они имели одинаковые размеры (потому что CNN потребуются все входные данные с одинаковым размером), а их пиксели были нормализованы. Это делается для того, чтобы быстрее обучить нашу модель нейронной сети.

Мы собираемся использовать класс ImageDataGenerator от Keras.

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

Визуализация

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

Batch shape:  (32, 224, 224, 3)
Label shape:  (32,)

У нас есть 32 изображения с соответствующими ярлыками. Также мы можем построить эти изображения (например, четвертое).

Label:  1.0

Метки 1 для собак и 0 для кошек.

Модель

Теперь, когда у нас есть все данные, пришло время построить модель.

Model: "sequential" _________________________________________________________________  Layer (type)                    Output Shape            Param #    =================================================================  conv2d (Conv2D)                 (None, 222, 222, 64)    1792                                                                          max_pooling2d (MaxPooling2D)    (None, 111, 111, 64)    0                                                                                                                                             conv2d_1 (Conv2D)               (None, 109, 109, 128)   73856                                                                         max_pooling2d_1 (MaxPooling2D)  (None, 54, 54, 128)     0                                                                                                                                          conv2d_2 (Conv2D)               (None, 52, 52, 256)     295168                                                                        max_pooling2d_2 (MaxPooling2D)  (None, 26, 26, 256)     0                                                                                                                                        conv2d_3 (Conv2D)               (None, 24, 24, 512)     1180160                                                                       global_average_pooling2d (G     (None, 512)             0           lobalAveragePooling2D)                                                                                                              dense (Dense)                   (None, 1)               513
=================================================================
Total params: 1,551,489
Trainable params: 1,551,489
Non-trainable params: 0 _________________________________________________________________

Это простая модель CNN с четырьмя сверточными слоями и выходным слоем, состоящим из плотного слоя с 1 выходным нейроном.

Перейдем к этапу обучения. Нам нужно скомпилировать и подогнать модель. Мы будем использовать двоичную кросс-энтропию для функции потерь, так как мы работаем с классами с целочисленными метками (0 для кошки и 1 для собаки). Оптимизатором будет алгоритм adam, и мы будем использовать точность в качестве показателя процесса.

Мы собираемся обучить сеть на 15 эпох.

Теперь мы обучили нашу первую CNN! Мы можем посмотреть значения сети точность и потери в процессе обучения.

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

47/47 [==============================] - 10s 204ms/step - loss: 0.4277 - accuracy: 0.8051
Loss: 0.4276582598686218
Accuracy: 0.8051421046257019

Модель имеет Точность 80%.

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

Предсказания

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

В нашем случае мы предскажем класс для следующего изображения.

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

array([[0.08732735]], dtype=float32)

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

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

Вы можете увидеть полный код в этом репозитории.

Следующие шаги

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

  • Измените архитектуру сети. Вы можете попробовать новые слои, отредактировать существующие или изменить функции активации. Чем больше вы будете пытаться, тем больше знаний вы приобретете в CNN.
  • Добавьте слои Dropout и Batch Normalization. Есть очень полезные, особенно в больших моделях. Эти слои также помогут избежать переобучения в модели.
  • Попробуйте новые оптимизаторы для тренировочного процесса. Существует множество различных оптимизаторов, которые можно использовать для обучения сети. Вы можете изменить их и посмотреть, есть ли улучшения или нет.
  • Сделайте увеличение изображения, метод, используемый для создания новых изображений из тех, которые у нас уже есть. Вы можете попробовать масштабировать, вращать или обрезать части изображений, чтобы получить больше данных.

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

Я надеюсь, что вы нашли учебник полезным. Если у вас есть какие-либо вопросы, не стесняйтесь оставлять комментарии! 👋🏻​