ОПИСАНИЕ ИДЕИ
В рамках данного проекта я обучила генеративную нейросеть создавать произведения искусства в стиле сюрреалиста Сальвадора Дали. Мой выбор этого художника обусловлен глубокой любовью к сюрреализму, который исследует сложные структуры человеческого разума и тонкую грань между восприятием реальности и абсурдом подсознания.
Я также считаю неэтичным использовать работы современных художников, так как это обесценивает их вклад в искусство. Вместо этого я выбрала Дали, чьи произведения уже стали частью культурного наследия, и его уникальная эстетика позволяет мне создавать новые работы без нарушения прав авторов.
При создании текстовых подсказок для генерации изображений я использовала героев классического фэнтези. Это сочетание должно создать комический эффект, основанный на взаимодействии известных архетипов и абсурда. Кроме того, своеобразная недосказанность нейросетевых артефактов только играет на руку сюрреалистическому стилю.
ИСХОДНАЯ СЕРИЯ ИЗОБРАЖЕНИЙ
Для тренировки нейросети было использовано 29 работ Сальвадора Дали и его учеников.
ПРОЦЕСС СОЗДАНИЯ НЕЙРОСЕТИ
Сначала нужно было собрать и изменить разные изображения в формат 1:1. Это важно, потому что квадратные изображения упрощают работу нейросети и обеспечивают одинаковый размер данных для пакетной обработки. Квадратные форматы также помогают избежать искажений при изменении размера.
Дальше я работала в Google Colab, используя Stable Diffusion XL, метод DreamBooth и технологию LoRA. Сначала выполнила все подготовительные шаги, включая загрузку исходных изображений.
Код ч.1
В этом коде я сначала импортирую библиотеку PIL для работы с изображениями и определяю функцию image_grid, которая создаёт сетку из изображений. Эта функция принимает список изображений, количество строк и столбцов, а также размер для изменения. Если указан размер, изображения изменяются, а затем вставляются в новую пустую картинку.
Далее с помощью библиотеки glob я собираю все .jpg изображения из папки ./Juk/ и открываю их с помощью PIL. Затем создаю сетку из первых пяти изображений для предварительного просмотра, чтобы быстро оценить их и убедиться, что они отображаются правильно.
Код ч.2
Затем я импортирую нужные библиотеки для обработки изображений и генерации описаний. Определяю, будет ли использоваться GPU или CPU, и загружаю модель BLIP из Hugging Face. Эта модель нужна для создания текстовых описаний к изображениям.
Функция caption_images принимает изображение, обрабатывает его и генерирует описание с помощью модели BLIP. Описание возвращается в виде строки. После этого я снова собираю все изображения из папки ./Juk/ и создаю список с путями к изображениям и самими изображениями. В файл metadata.jsonl записываются метаданные для каждого изображения: имя файла и сгенерированное описание, начинающееся с "painting in the style of surrealism".
Код ч.3
После записи метаданных я открываю файл metadata.jsonl, чтобы проверить созданные данные. Это помогает убедиться, что все описания сгенерированы правильно. Затем я снова создаю сетку из первых пяти изображений для предварительного просмотра, чтобы оценить результаты своей работы.
Код ч.4
В конце я освобождаю ресурсы: удаляю загруженные процессор и модель BLIP, вызываю сборщик мусора для очистки памяти GPU и устанавливаю кодировку UTF-8. Затем настраиваю ускорение вычислений и вхожу в Hugging Face Hub для дальнейшей работы с данными. Также устанавливаю библиотеку datasets для работы с наборами данных в будущем.
Код ч.5
В этом коде я запускаю обучение модели DreamBooth с использованием LoRA командой !accelerate launch. Указываю путь к предобученной модели "stabilityai/stable-diffusion-xl-base-1.0" и VAE модели "madebyollin/sdxl-vae-fp16-fix". Набор данных называется "Juk", а результаты обучения сохраняются в папке "Juk_LoRA". Столбец с описаниями изображений называется "prompt", чтобы модель могла понимать текстовые подсказки.
Я настраиваю параметры обучения: разрешение изображений 512x512 пикселей, размер батча 2 и количество шагов накопления градиента 3 для экономии памяти GPU. Включаю контрольное сохранение градиента, чтобы снизить потребление памяти. Скорость обучения установлена на 1e-4, значение SNR gamma — 5.0. Выбираю постоянный планировщик скорости обучения с нулевым количеством шагов разогрева и активирую 8-битный оптимизатор Adam для экономии памяти. Максимальное количество шагов тренировки — 500, контрольные точки сохраняются каждые 250 шагов, а начальное значение генератора случайных чисел установлено на "0" для воспроизводимости.
Код ч.6
Я подготавливаюсь к загрузке модели на Hugging Face. Сначала выполняю команду !ls Juk_LoRA, чтобы увидеть содержимое папки с результатами обучения. Затем импортирую функцию whoami из библиотеки huggingface_hub, чтобы получить информацию о себе. Определяю переменную output_dir для директории с результатами и формирую идентификатор репозитория repo_id, который включает моё имя пользователя.
Далее создаю репозиторий на Hugging Face с помощью функции create_repo. Затем вызываю save_model_card, чтобы сохранить метаданные модели, включая базовую модель и текстовые подсказки, при этом указывая, что текстовый энкодер не будет обучаться.
Во втором фрагменте я загружаю обученную модель в созданный репозиторий. Функция upload_folder загружает содержимое папки "Juk_LoRA" с сообщением о завершении обучения, игнорируя промежуточные файлы.
Код ч.7
После загрузки я вывожу сообщение о завершении обучения с ссылкой на модель на Hugging Face для быстрого доступа.
В конце кода я загружаю необходимые компоненты для работы с моделью. Импортирую класс AutoencoderKL и создаю объект VAE, загружая предобученную модель. Затем создаю объект DiffusionPipeline, который загружает основную модель и настраивает параметры для работы с 16-битной плавающей точкой. Наконец, загружаю веса LoRA в пайплайн и перевожу его на GPU для ускорения генерации изображений.
Код ч.8
И, наконец, я приступаю к генерации изображений при помощи следующего кода, изменяя сам текст промта.
Код ч.9
РЕЗУЛЬТИРУЮЩАЯ СЕРИЯ ИЗОБРАЖЕНИЙ
На основе полученных изображений можно сделать следующие выводы об обученной модели:
С переменным успехом обученная модель создаёт портретные изображения. Далее видно, как успешный пример Короля с лицом из овощей, так и менее успешный Друид в кукурузе (да, он там правда есть, присмотритесь).
«painting in the style of surrealism, Portrait of a king made of vegetables»
«painting in the style of surrealism, Druid in the Corn»
Проблемы начинаются и в момент, когда нейросети требуется нарисовать персонажа, не являющегося человеком. Черты, безусловно, угадываются, но трудности восприятия присутствуют. Впрочем, недостатки изображения полностью компенсируются тонкостями сюрреализма.
«painting in the style of surrealism, Cat-wife and a bowl of rice»
«painting in the style of surrealism, rabbit archer»


















