Создание и обучение модели машинного обучения с учителем для распознавания кошек и собак

Вступление

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

Что ты узнаешь?

Вы узнаете, как создать и настроить сверточную нейронную сеть (CNN). Нейронная сеть - очень мощный метод для решения задач компьютерного зрения и других приложений. Вы попрактикуетесь в настройке и оптимизации CNN в Tensorflow.

Определение проблемы

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

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

Пошаговое решение

Создайте папку проекта

Создайте на своем компьютере папку для проекта под названием «Кошки и собаки».

Начать новую записную книжку

Откройте папку в Терминале / командной строке и запустите Jupyter Notebook, введя следующую команду:

$ jupyter notebook

Нажмите «Создать» в правом верхнем углу и выберите Python 3.

В вашем браузере откроется новый Jupyter Notebook. Переименуйте проект Untitled в название своего проекта, и все готово.

Если на вашем компьютере установлена ​​Anaconda, у вас уже должны быть установлены все библиотеки, необходимые для этого проекта.

Если вы получаете сообщение об отсутствующей библиотеке, вы можете использовать pip3 или conda для установки отсутствующей библиотеки.

Есть два способа установить новую библиотеку Python на свой компьютер - pip3 или conda. Откройте Терминал / командную строку и введите:

pip3 install tensorflow

or

conda install tensorflow

Вы можете использовать эти команды для любых недостающих библиотек. Например, Keras, TensorFlow.

Если вы используете Google Colab, откройте новую записную книжку.

Загрузка библиотек

Импорт Numpy, Matplotlib, Tensorflow 2 и Keras.

В этом проекте мы будем использовать три набора данных (изображения) кошек и собак.

  • Набор данных обучения для обучения и соответствия нашей модели.
  • Набор данных Validation, который мы будем использовать во время обучения модели, чтобы проверить эффективность обучения.
  • Набор данных Test, который мы будем использовать для тестирования нашей модели, чтобы увидеть, как она работает.

Вы можете скачать изображения с этого конкурса Kaggle.

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

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

- test\cats_and_dogs - contains 100 images of cats and 100 images of dogs moved from the "train" folder of the Kaggle competition
- train\cats - contains 10000 images of cats from the "train" folder of the Kaggle competition
- train\dogs - contains 10000 images of dogs from the "train" folder of the Kaggle competition
- validation\cats - contains 2400 images of cats from the "train" folder of the Kaggle competition
- validation\dogs - contains 2400 images of dogs from the "train" folder of the Kaggle competition

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

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

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

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

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

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

Мы определим наш ImageDataGenerator здесь с rescale = 1. / 255, который стандартизирует числовые значения в матрице наших изображений.

Вы также можете попробовать следующие варианты:

  • shear_range = 0,2 - определяет интенсивность сдвига трансформации нашего изображения.
  • zoom_range = 0,2 - определяет диапазон случайного масштабирования, применяемого к нашим изображениям.
  • horizontal_flip = True - произвольно переворачивает изображения по горизонтали.

Не стесняйтесь экспериментировать, используя документацию по функции здесь: https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator

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

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

Вот вариант конфигурации, который мы используем:

  • batch_size - сколько обучающих примеров используется за одну итерацию обучения.
  • каталог - где наши изображения
  • перемешать - следует ли перемешивать изображения
  • target_size - целевой размер нашего изображения, которое функция вернет
  • class_mode - мы используем «двоичный», потому что в нашем примере у нас есть две категории кошек или собак.
Found 20000 images belonging to 2 classes.
Found 4800 images belonging to 2 classes.
Found 200 images belonging to 1 classes.

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

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

Затем мы добавим к нашей модели несколько 2D сверточных слоев.

Вот некоторые из наиболее важных элементов моделей нейронных сетей, которые мы будем создавать:

model.add (Conv2D (32, (3, 3), Activation = ’relu’, input_shape = (150, 150, 3)))

  • 32 означает количество выходных фильтров в свертке.
  • (3, 3) - размер ядра слоя, который определяет высоту и ширину окна двумерной свертки. Обычно это зависит от размера изображения.
  • Activation = ’relu’ - определяет функцию активации на выходе узлов слоя. ReLU - наиболее часто используемая функция активации в нейронных сетях. Вы можете поэкспериментировать и узнать больше о различных функциях активации в документации Keras (https://keras.io/api/layers/activations/).
  • input_shape = (150, 150, 3): размер изображения 150x150 с тремя цветами RGB.

model.add (MaxPooling2D (pool_size = (2, 2)))

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

model.add (Flatten ())

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

model.add (Dense (256, activate = ’relu’))

  • Обычный плотносвязный слой. Плотно связанный означает, что каждый нейрон в слое получает входные данные от всех нейронов в предыдущем слое.

model.add (Dropout (0,5))

  • Слой Dropout случайным образом устанавливает для входных единиц значение 0 с частотой на каждом шаге во время обучения. Это помогает предотвратить переоснащение.

model.add (Dense (1, activate = ’sigmoid’))

  • Это последний слой в сети, который вернет вероятность появления кошки или собаки в виде числа от 0-кошка до 1-собака.

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

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

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d (Conv2D)              (None, 148, 148, 32)      896       
_________________________________________________________________
activation (Activation)      (None, 148, 148, 32)      0         
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 74, 74, 32)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 72, 72, 64)        18496     
_________________________________________________________________
activation_1 (Activation)    (None, 72, 72, 64)        0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 36, 36, 64)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 34, 34, 128)       73856     
_________________________________________________________________
activation_2 (Activation)    (None, 34, 34, 128)       0         
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 17, 17, 128)       0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 15, 15, 128)       147584    
_________________________________________________________________
activation_3 (Activation)    (None, 15, 15, 128)       0         
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 7, 7, 128)         0         
_________________________________________________________________
flatten (Flatten)            (None, 6272)              0         
_________________________________________________________________
dense (Dense)                (None, 256)               1605888   
_________________________________________________________________
dropout (Dropout)            (None, 256)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 257       
=================================================================
Total params: 1,846,977
Trainable params: 1,846,977
Non-trainable params: 0
_________________________________________________________________

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

Epoch 1/5
626/626 [==============================] - 1210s 2s/step - loss: 0.6438 - accuracy: 0.6274 - val_loss: 0.5164 - val_accuracy: 0.7470
Epoch 2/5
626/626 [==============================] - 1159s 2s/step - loss: 0.4909 - accuracy: 0.7664 - val_loss: 0.4545 - val_accuracy: 0.7892
Epoch 3/5
626/626 [==============================] - 1130s 2s/step - loss: 0.4025 - accuracy: 0.8225 - val_loss: 0.3625 - val_accuracy: 0.8354
Epoch 4/5
626/626 [==============================] - 1131s 2s/step - loss: 0.3429 - accuracy: 0.8529 - val_loss: 0.3830 - val_accuracy: 0.8226
Epoch 5/5
626/626 [==============================] - 1138s 2s/step - loss: 0.3076 - accuracy: 0.8726 - val_loss: 0.3221 - val_accuracy: 0.8686

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

[0.6274461, 0.7664237, 0.82253397, 0.8529353, 0.87260383]

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

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

7/6 [=================================] - 3s 421ms/step
Accuracy on the test data: 90.0%

Мы видим, что с помощью относительно простой настройки и конфигурации модели нейронной сети мы смогли достичь довольно хорошей точности в 90%. С оптимизацией функции ImageDataGenerator и самой нейронной сети мы, вероятно, могли бы приблизиться к 96–98%. Я рекомендую вам поэкспериментировать с этим примером и попытаться достичь большей точности с различными параметрами функции ImageDataGenerator и нейронной сети.

Если вы хотите узнать больше и поэкспериментировать с Python и Data Science, вы можете прочитать еще одну из моих статей Анализ данных о продажах фармацевтических препаратов на Python, Введение в компьютерное зрение с MNIST », Распознавание лиц на изображениях в Python , Прогнозирование выживших после титаника с помощью науки о данных и машинного обучения и Анализ настроений в Twitter на Python .

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

Полный код Python в Jupyter Notebook доступен на GitHub:
https://github.com/pjonline/Basic-Data-Science-Projects/tree/ master / 9-Кошки и Собаки

Удачного кодирования!

Еще не подписаны на Medium? Рассмотрите возможность регистрации, чтобы стать участником Medium. Это всего 5 долларов в месяц, и вы получите неограниченный доступ ко всем историям на Medium. Подписка на Medium поддерживает меня и других авторов на Medium.