Создаём нейросеть на Python

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

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

Структура каталогов для датасета

Для начала создадим проект на python со следующей структурой каталогов:

, где папки:

  • predict (1) — сюда положим фотографии, по которым нейросеть будет давать ответ, лето там или зима
  • tarin (2) — с двумя подпапками summer и winter, в которые разместим фотографии лета и осени для обучения нейросети. На скриншоте их всего 4, но этого конечно очень мало. Как минимум нужно пару тысяч для хорошего предсказания.
  • validation (3) — валидационный набор фотографий — нужен для оценки качества обученной нейросети.

Необходимые для работы модули

Далее необходимо установить необходимые модули для Python для работы с нейросетью:

Рыба главного файла main.py

Создадим файл main,py со следующим содержимым:

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

Подготовка данных и установка параметров модели нейросети

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

  • rescale=1./255 — преобразует тензор (матрицу) изображений из интервалов значений 0..255 до 0..1 Зачем и какой механизм? У меня четкого понимания. Пока просто принимаю как данность, что необходимо при работе с изображениями.
  • horizontal_flip=True — добавляет в тензор еще одно изображение, но отраженное по горизонтали
  • rotation_range=xx — поворачивает изображение на xx градусов
  • zoom_range=хх — увеличивает изображение

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

Спойлер

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

  • Прочитать изображения с диска
  • Декодировать содержимое изображений и преобразовать в нужный формат с учетом RGB-профиля
  • Преобразовать к тензорам со значениями с плавающей запятой
  • Произвести нормализацию значений тензора из интервала от 0 до 255 к интервалу от 0 до 1, так как нейронные сети лучше работают с маленькими входными значениями.

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

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

При желании можно посмотреть, что у нас получилось:

Добавим в модель слои

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

Что такое активатор relu

Выпрямленная линейная функция активации или сокращенно ReLU (rectified linear activation unit) — это кусочно-линейная функция, которая выводит входные данные без изменений, если они положительные, и ноль, если входные данные отрицательные. Она стала функцией активации по умолчанию для многих типов нейронных сетей, потому что модель, использующую ее, легче обучать, и она часто достигает лучших результатов
Подробнее можно почитать например здесь

Рассмотрим подробнее что означает каждая строчка:

  • input_shape=(IMG_SHAPE, IMG_SHAPE, 3) — на входе изображение с размерами IMG_SHAPE х IMG_SHAPE, с 3 размерностью цветов (RGB)
  • 32 — количество фильтров (каналов), фактически в моём понимании это количество признаков по которым могут отличаться изображения друг от друга
  • (3,3) — размер ядра (окна внутри матрицы) в каждом фильтре. Выбираем исходя из того, насколько чувствительную модель мы хотим получить

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

Команда tf.keras.layers.MaxPooling2D(2, 2), говорит о том, что далее мы укрупняем масштаб полученых признаков. (2.2) — размер окна в котором выбирается максимальное значение

Команда tf.keras.layers.Dense(150, activation=’relu’), говорит что в работе будет задействовано 150 нейронов (по размеру матрицы)

Команда tf.keras.layers.Dense(2, activation=’softmax’), сообщает нейросети, что результат мы хотим получить в виде двух классов 0 — лето, 1 — зима (ну на входе для обучения у нас два вида картинок)

Какие бывают слои

В пакете Keras можно найти слои:
Conv1D, Conv2D, Conv3D
так как на практике используют свертки для анализа одномерного, двумерного и трехмерного сигналов. Например, для:

  • аудио – 1D (одномерный сигнал);
  • изображения – 2D (двумерный сигнал);
  • видео – 3D (трехмерный сигнал).

Компиляция модели

После того как данные по модели подготовили, её нужно «скомпилировать», указав алгоритм будущего обучения, и прочие параметры:

Мы воспользуемся оптимизатором adam. В качестве функции потерь воспользуемся sparse_categorical_crossentropy. Так же мы хотим на каждой обучающей итерации следить за точностью модели, поэтому передаём значение accuracy в параметр metrics.

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

Функция потерь — это мера того, насколько хорошо ваша модель прогнозирования предсказывает ожидаемый результат (или значение). Функция потерь также называется функцией затрат.
Что такое оптимизатор

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

Помимо adam, есть еще ряд оптимизаторов: RMSprop, SGD и прочее. Чуть подробнее можно прочитать тут. Обычно таки для обработки изобращений используют adam.

Adam — один из самых эффективных алгоритмов оптимизации в обучении нейронных сетей. Он сочетает в себе идеи RMSProp и оптимизатора импульса. Вместо того чтобы адаптировать скорость обучения параметров на основе среднего первого момента (среднего значения), как в RMSProp, Adam также использует среднее значение вторых моментов градиентов. В частности, алгоритм вычисляет экспоненциальное скользящее среднее градиента и квадратичный градиент, а параметры beta1 и beta2 управляют скоростью затухания этих скользящих средних

Зачем этот оптимизатор?

Его преимущества:

  • Простая реализация.
  • Вычислительная эффективность.
  • Небольшие требования к памяти.
  • Инвариант к диагональному масштабированию градиентов.
  • Хорошо подходит для больших с точки зрения данных и параметров задач.
  • Подходит для нестационарных целей.
  • Подходит для задач с очень шумными или разреженными градиентами.
  • Гиперпараметры имеют наглядную интерпретацию и обычно требуют небольшой настройки.

Тренируем модель

Для тренировки модели необходимо выполнить код:

EPOCHS — это количество циклов обучения модели. Чем больше — тем лучше результат обучения. Подбирается экспериментальным путём.

Результат тренировки можно посмотреть в виде графиков:

Проверка обученой модели

На этом шаге мы получили обученную модель. Теперь можно попробовать её попросить распознать, что же за изображение на картинке: Зима или лето? :

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

Результат будет или 0 или 1, в зависимости от того что на картинке — лето или зима. Т.е. в зависисмости от количества классов.

Исходный код нейросети можно скачать здесь

Один комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

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