Нейроссия: как я научил нейросеть рисовать русскую хтонь

Вступление

В России модно грустить. Популярная культура под разными соусами толкает нам депресняк: всякие майки «Россия для грустных», фестивали «боль», подборки «Russian doomer music» на ютубе и так далее. Рунет завален однотипными постпанком, панельками и серостью, которые тем не менее довольно много людей видят чем-то родным и уютным, ощущают частью своего культурного кода. Мне стало интересно, сможет ли ИИ если не победить то хотя бы возглавить эту моду и затронуть струны душ рашн думеров. Ведь что может быть более бессмысленно и тоскливо чем нейросеть, рисующая гипертрофированно-хтоническую Россию? Так появился проект нейроссия.

Собираем данные

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

Примеры скачанных фотографий
Примеры скачанных фотографий

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

Качаем картинки из последнего поста на стене группы
import os import vk_api import urllib.request  def captcha_handler(captcha):     print (f"url: {captcha.get_url()}\n")     key = input("Enter captcha code: ")     return captcha.try_again(key)  def auth_handler():     code = input("Enter 2FA code: ")     return (code, True)  def save_post_pictures(post, imgfolder, imres):     pictures = []          if not os.path.exists(imgfolder):         os.makedirs(imgfolder)          for attachment in post['attachments']:         if attachment['type'] == 'photo':             photo = attachment['photo']             for size in photo['sizes']:                 if size['type'] == imres:                     url = size['url']                     filename = ('_'.join(url.split('/')[-2:])).split('?')[0]                     urllib.request.urlretrieve(url, os.path.join(imgfolder, filename))                     pictures.append(filename)                          return pictures  phone = input("phone ") password = input("password ") domain = 'plattenbauten' # vk.com/plattenbauten  sess = vk_api.VkApi(phone, password, captcha_handler=captcha_handler, auth_handler=auth_handler) sess.auth() api = sess.get_api()  posts = api.wall.get(domain=domain, count=1)['items'] save_post_pictures(posts[0], domain, 'z') # https://vk.com/dev/photo_sizes - z максимальный размер

Так я накачал чуть больше чем 100к фоточек из нескольких пабликов. Дальше встал вопрос, как их отфильтровать. Для фильтрации я использовал детектор EfficientDet (чтобы выкинуть из датасета фотки с людьми, машинами, котиками и.т.д, оставив только пейзажи), а также совсем чуть-чуть NLP в лице NLTK чтобы обработать подписи к фотографиям — сделать стемминг слов и найти по тегам то что не нашёл детектор. В итоге осталось около 10к фотографий.

Обучаем стайлган

Я использовал архитектуру Stylegan2 с аугментациями дискриминатора. Аугментации (повороты, отзеркаливания, кропы) позволяют получать чуть лучшие результаты на маленьких датасетах. Вот в этом репозитории оригинальный код, а вот здесь — моя наколеночная модификация для запуска в Google Colab и генерации видео по ключевым кадрам (об этом дальше).

У этой реализации стайлгана есть одна особенность — на вход ему нужны данные в формате .tfrecord (как их получить из картинок описано в readme). А особенность заключается в том, что картинки записываются в tfrecord-ы без сжатия, что в условиях работы на Colab может быть критично. Так, например, датасет из 10 тысяч картинок разрешения 1024х1024, будучи сконвертированным в .tfrecord забьёт диск Колаба под завязку. Говорят, что есть модификация stylegan2 которая использует сжатие в .tfrecord-ах, но я её пока не проверял.

Отчего так в России берёзы шумят?
Отчего так в России берёзы шумят?

Обучение на Google Colab в бесплатной версии идёт со скоростью примерно полчаса на эпоху для разрешения 1024х1024. Когда уже на первых эпохах на генерируемых сеткой картинках проступила родная цветовая гамма, вспомнился мем про «отчего так в России берёзы шумят».

Несколько эпох спустя
Несколько эпох спустя

Генерируем видео

В какой-то момент проект из гиковских прикольчиков превратился в прикольчики творческие. Возникла идея привлечь к этому друзей-музыкантов и сделать генеративное видео с генеративной музыкой (впоследствие трансформировавшаяся в вариативный стрим на платформе mubert). Хотелось чтобы переходы в видео были хоть немного осмысленными и согласующимися с музыкой.

Латентный вектор это промежуточное сильно сжатое представление картинки, в котором скрыты все выученные нейросетью свойства. Наверное, можно было заморочиться и найти в латентном векторе (размерности 512) компоненты отвечающие за тот или иной параметр картинки (чтобы например плавно менять освещение, сохраняя структуру картинки), но я решил что проще сгенерировать видео по ключевым кадрам. Если плавно переходить от вектора соответствующего одной картинке (ключевому кадру) к вектору соответствующему другой, то картинки также будут плавно перетекать одна в другую. Для этого я поменял несколько строк в скрипте generate.py так, чтобы на вход он принимал папку с латентными векторами выбранных картинок, и список, в котором эти картинки должны появляться в видео.

В заключение

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

Ещё картиночки
Ещё картиночки

Ссылки

https://vk.com/neurussia — нейроссия в ВК

https://github.com/NVlabs/stylegan2-ada — нейросеть Stylegan2-ada

https://github.com/python273/vk_api — python-обёртка api вконтакте

ссылка на оригинал статьи https://habr.com/ru/post/535854/

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

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