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

Классификация художественных стилей с помощью сверточных нейронных сетей

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

Около года назад (2021) я начал серьезно относиться к цифровому искусству. С тех пор я нарисовал всего 73 готовых арта, среди скетчей и прочего.

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

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

Мое искусство: данные

Данные содержат 139 изображений png/jpg. 66 изображений принадлежат SamDoesArts, а остальные 73 принадлежат мне. К счастью, SamDoesArts загружает zip-файлы своих ежемесячных работ на патреон, так что я мог легко скомпилировать некоторые из его работ.

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

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

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

Локальная загрузка наборов данных изображений в TensorFlow

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

data = keras.utils.image_dataset_from_directory
(directory=DATASET_PATH,
labels="inferred",
label_mode="binary", # 0 and 1
color_mode="rgb",
batch_size=None,
image_size=(RESIZE_HEIGHT, RESIZE_WIDTH),
shuffle=False
)

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

Используя гиперпараметр labels="inferred", Tensorflow автоматически создаст метки для вашего набора данных на основе папки, в которой находятся ваши изображения.

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

Передача обучения с использованием модели Xception

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

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

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

Трансферное обучение — это когда обучение одной модели (которая обычно обучается) используется в другой модели для решения другой задачи. Это полезно во многих ситуациях:

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

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

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

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

Как проводить трансферное обучение

Я не буду говорить о специфике Tensorflow (так как мой блокнот включен в статью), но вот общие шаги трансферного обучения:

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

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

Полученные результаты

Вот результаты первой модели:

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

Точность обучения первой модели составила 99,3%, что означает, что модель сильно переобучена. Он неправильно угадал большинство моих работ (нижний ряд). Недавно я экспериментировал со сложным фоном, поэтому я предположил, что, поскольку модель представляет собой такую ​​глубокую сеть, а выходной нейрон модели имеет так много связей, возможно, модель классифицировала изображения на основе того, насколько «сложными» они выглядят ( с простыми изображениями, классифицированными как мои, и сложными изображениями, классифицированными как Сэм).

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

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

Таким образом, я обучил вторую модель

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

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

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

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

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

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

Небольшая попытка регуляризации модели

Я не хочу тратить много времени на эту модель, поэтому

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

Я хочу уменьшить размер данных, идущих к последнему нейрону, поэтому я добавлю несколько полносвязных слоев размером 512 и 128. Надеюсь, что использование слоев все меньшего и меньшего размера заставит сеть представлять свои данные в более низком измерении, чтобы, надеюсь, лучше обобщить новые экземпляры.

Тем не менее, сеть может выполнять некоторые тривиальные вычисления и все же в конечном итоге получить переоснащение (например, если она просто использует один нейрон на слой и передает свой предыдущий сигнал вверх). Таким образом, я решил использовать Dropout с относительно высоким коэффициентом 0,5. У каждого нейрона в слое есть шанс «выпасть», когда его выходы будут установлены на ноль во время обучения. Это не позволяет сети полагаться на конкретные нейроны и, надеюсь, заставляет ее действительно обобщать.

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

В целом точность модели не сильно улучшилась. Недостаток данных усложняет эту задачу.

Теперь модель может правильно классифицировать эти изображения.

Это также сделало лучшие прогнозы здесь.

Однако это может быть просто чистой удачей.

Заключение

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

Блокнот здесь. (В настоящее время не обновляется, чтобы включить выпадающие слои и т. д.)