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

Сегодня мы собираемся создать идентификатор изображения, используя python вместе с библиотекой Keras. Keras — это библиотека-оболочка, которая используется для построения и обучения моделей с использованием Tensorflow для выполнения матричных вычислений. Мы вернемся к ним через секунду.

Предпосылки

Прежде чем вы сможете начать, вам необходимо установить Python версии 3.8 (64-разрядная версия). Tensorflow совместим только с Python 3.8, поэтому, к сожалению, мы не можем использовать последнюю версию Python. Для Tensorflow также требуется 64-битная версия Python, поэтому убедитесь, что вы не используете 32-битную версию. Я также рекомендую использовать виртуальную среду для этого проекта, так как она сохраняет старую версию Python и библиотеку Tensorflow отдельно от других ваших проектов. Если вы новичок в создании виртуальных сред, вы можете прочитать краткое руководство здесь. Перейдите в корневой каталог вашего проекта или виртуальной среды и выполните следующую команду в терминале или командной строке, чтобы установить tensorflow.

pip install tensorflow

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

import sys
print(sys.version)

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

После установки tensorflow запустите файл Python со следующими инструкциями:

import tensorflow as tf
from tensorflow import keras
import numpy as np
print("success")

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

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

Нейронная сеть

Сердце каждого алгоритма глубокого обучения: нейронная сеть состоит из нескольких слоев. Наша нейронная сеть будет состоять из 3 слоев: входного слоя, скрытого слоя и выходного слоя. Вы можете думать о проходящих данных как о шариках разного размера. Пути, соединяющие скрытый слой с выходным слоем, служат фильтрами, направляя только шарики одинаковой формы к определенным выходным узлам. Узел с наибольшим распределением бусин (данные пикселей в нашем случае) — это одежда, соответствующая изображению. Однако, чтобы это работало, наша модель должна знать, какого размера бусинки должны идти к какому выходному узлу. Мы вернемся к этому, когда будем обучать нашу модель. А пока давайте подробнее рассмотрим сами слои.

Мое объяснение нейронной сети немного упрощено, вот более подробный взгляд на нейронные сети, если вам интересно.

Входной слой

Мы будем использовать изображения в градациях серого 28x28 из тестового набора данных Keras. Каждое изображение в наборе данных помечено одним из десяти возможных предметов одежды. Вот несколько примеров изображений, которые мы будем использовать:

Из изображений мы будем сохранять интенсивность каждого пикселя (0–255) в массив. Затем мы передадим эти данные через нашу нейронную сеть. Таким образом, наш входной слой будет представлять собой массив из 784 символов данных интенсивности пикселей для каждого изображения.

Скрытый слой

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

Выходной слой

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

Построение нейронной сети

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

Функция load_data() возвращает данные о пикселях и метки для 70 тыс. изображений. Из них мы разделяем 60 тысяч на training_images и training_labels. Мы сохраняем оставшиеся 10 КБ в test_images и test_labels для тестирования нашей модели после завершения обучения.

Здесь мы используем последовательный метод Keras для создания архитектуры нашей нейронной сети. Последовательный просто означает, что данные должны проходить через каждый слой нейронной сети по порядку.

Шаг 1: Входной слой. Мы создаем входной слой с помощью Flatten, который преобразует наш массив 28 x 28 в массив 784 x 1.

Шаг 2: Выходной слой. Мы создаем наш выходной слой, используя метод Dense, который указывает, что каждый узел должен быть подключен к каждому другому узлу в соседних слоях. Мы также указываем 10 единиц (или узлов) и нашу функцию активации как softmax. Softmax просто направляет входящие данные к ближайшему значению из выходных узлов, а 10 выходных узлов означают 10 возможных результатов.

Шаг 3: Скрытый слой. Как и в случае с выходным слоем, мы используем функцию плотности, но на этот раз мы указываем 128 единиц и используем Relu в качестве функции активации. Relu удаляет все отрицательные числа, проходящие через сеть, и заменяет их на 0.

И с этим мы создали нашу собственную нейронную сеть!

Компиляция нашей модели

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

Функции потерь

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

Функции оптимизатора

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

Обучение

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

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

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

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

Тестирование

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

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

Результаты

После запуска нашего кода мы получаем потрясающую точность ~80 процентов!

Вывод

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

Следите за новыми проектами в будущем! Между тем, вот полный код, если вы что-то пропустили: