Выполнение генеративного искусства с помощью Tensorflow и GAN. Полный исходный код:https://github.com/antigones/py-truchet-gan

«Генеративное искусство» — это термин, относящийся к процессу создания искусства с помощью автоматизации и обычно выполняемый с помощью алгоритмов.

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

Плитки Truchet

Жан Трюше впервые представил плитку Трюше в 1704 году. Эти плитки разделены по диагонали на пару треугольников черного и белого цветов.

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

Создание плиток Трюше

Чтобы сгенерировать мозаичное изображение Трюше, мы можем начать генерировать одно изображение:

Здесь «create_base_tile» создает базовую плитку Truchet с определенным цветом переднего плана, цветом фона и размером, создавая следующее изображение:

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

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

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

Разработка GAN для создания новых плиток Трюше

GAN (Generative Adversarial Network) — это архитектура, состоящая из двух нейронных сетей, обучающихся «в тандеме».

Первая сеть называется «генератором»: роль «генератора» состоит в том, чтобы создавать изображения, выглядящие реальными; последний вместо этого называется «дискриминатором»: это CNN, используемая для различения реальных образцов (из обучающего набора) от поддельных («сгенерированных»).

Генератор

Генератор начинает со случайного изображения выборки, увеличенного до размера входных выборок. Масштабирование здесь выполняется с помощью слоев Conv2DTranspose, где шаг используется для удвоения размера изображения в два раза для целевого размера ввода (в следующем фрагменте кода мы масштабируем с 7 * 7 до 28 * 28):

Дискриминатор

Дискриминатор представляет собой классификатор CNN:

Потери

Мы вычисляем две потери: одну для генератора и одну для дискриминатора.

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

Чем более похожи два распределения, тем меньше перекрестная энтропия.

Потери дискриминатора учитывают как реальные_потери, так и ложные_потери. Реальные потери — это перекрестная энтропия распределения реальных выборок и выборок, предсказанных дискриминатором, в то время как fake_loss вычисляется как перекрестная энтропия между вектором со всеми нулями и fake_output, предсказанным дискриминатором (0 = фальшивый).

Обучение GAN

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

Затем градиенты генератора и дискриминатора вычисляются с помощью функции «градиент», используя информацию в контексте, сохраненном GradientTape(); в самом конце шага обучения оптимизатор применит градиенты к переменным, используя «apply_gradients». Фактически роль оптимизатора заключается в обновлении параметров модели в соответствии с информацией, полученной с помощью функции потерь.

Здесь мы используем оптимизаторы Adam со скоростью обучения 1e-4:

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

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

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

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

Следующий GIF показывает процесс обучения GAN:

Результаты

Результаты после 300 EPOCHS с BATCH_SIZE=128 кажутся неплохими:

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