Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

Всем привет! На связи Cloud.ru — провайдер облачных сервисов и AI-технологий. И сегодня мы решили просто и кратко рассказать о математических закономерностях, лежащих в основе красивого кадра, эффектного макета и результативного запроса к нейросети.

Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

Все прекрасное подчиняется строгим математическим законам, будь то компоновка сториз или интерьер. А благодаря text-to-image нейросетям сегодня каждый может попробовать себя в роли цифрового художника, дизайнера или иллюстратора. Мы знаем о нейросетях не понаслышке: у нас есть своя платформа Cloud.ru ML Space, где можно обучать ML-модели и разрабатывать сервисы на основе AI. Ничто прекрасное нам тоже не чуждо. Поэтому сегодня мы расскажем, как с помощью математики можно проверить, хороша ли ваша картинка, если вы:

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

Поскольку разговор будет долгим и охватит путь от Древней Греции до современных компьютеров с CAD, вот вам шпаргалка по разделам:

Это база

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

Правило третей

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

Говорят, впервые это правило зафиксировал английский художник 18 века Джошуа Рейнольдс. И хотя в основе этого метода нет сложных обоснований, в правиле третей появляются соотношения 1:2 и 2:3 — а это первые числа последовательности Фибоначчи. Кстати о ней…

Правило третей на телефоне
Правило третей на телефоне

Золотое сечение и числа Фибоначчи

Вы наверняка встречали загадочные картинки со спиралями в документалках о Леонардо да Винчи и на просторах интернета. Фигурируют они как в контексте золотого сечения, так и чисел Фибоначчи. Однако это все-таки не одно и то же. Как так?

Фибоначчи в природе
Фибоначчи в природе

Золотое сечение — это специфическое иррациональное число (≈1,618). Оно получается, если у нас есть отрезок длины с, который можно поделить на два отрезка a и b так, чтобы большая часть относилась к меньшей так же, как вся длина отрезка к его большей части. Эту пропорцию также можно записать в виде квадратного уравнения x² – x – 1 = 0.

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

Последовательность Фибоначчи знакома очень многим: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 и т.д. У этого числового ряда много интересных свойств. Одно из них в том, что если сложить друг с другом квадраты со сторонами, равными числам Фибоначчи, они образуют спираль.

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

Кому и зачем это использовать

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

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

Это матчасть

Теперь погрузимся глубже в математические закономерности гармонии и затронем вещи, которые лежат в основе современных графических редакторов и систем проектирования. Каждый дизайнер, архитектор, 3D-художник использует в своей практике инструменты, иногда даже не подозревая, какая математика расположена у них «под капотом».

Гладкие функции и поверхности

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

Аргумент — это переменная, которую мы обычно ищем в уравнении. Функция — правило, которое определяет, как значение входной переменной преобразуется во что-то другое, что нас интересует, а именно в значение функции. Производная функции — это показатель того, насколько быстро меняется функция в конкретной точке.

Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

Обычно график функции выглядит как кривая, которая может быть или не быть непрерывной. А чтобы непрерывная функция могла называться гладкой, должно соблюдаться условие, что производную от этой функции можно взять в любой точке графика. Если этот фокус удался один раз — кривую называют гладкой 1-го порядка. Если получилось взять производную от производной k раз (дифференцировать) — это гладкая кривая k-порядка.

Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

Чтобы понять, насколько гладкая ваша кривая, посмотрите на нее: та, что в центре на рисунке — нам не друг. Впрочем, тут всё зависит от того, гармонии или дисгармонии вы хотите добиться.

Кстати про кривизну. Она определяется в каждой конкретной точке и вычисляется как величина, обратная радиусу окружности, касающейся этой кривой — k = 1/R. Это справедливо для плоскости. Если мы говорим про трехмерное пространство, то кривая поверхность будет описываться параметрами сфер, которые она «накрывает» или «продавливает».

Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

А как быть с кривыми и поверхностями, которые настолько сложны, что их невозможно описать одной красивой формулой? Для этого существуют кусочно-определяемые функции: это когда мы берем кусочек (сплайн) от гладкой гиперболы, дольку от элегантной параболы, а в месте их стыка просто обеспечиваем непрерывность. Как если бы пытались собрать фоторобот нашей новой знакомой из кусочков портретов кинозвезд.

Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

Кривые и поверхности Безье

Давным-давно, когда телевизоры еще не были плоскими (в 50-х), математик из компании Citroën Поль де Кастельжо изобрел алгоритм построения кривых, который позволил ему создать обтекаемый корпус, ставшего легендарным, автомобиля Citroën DS. Из-за патентных проволочек алгоритм вошел в историю под именем другого француза — Пьера Безье из конкурирующего Renault. И да — это его кривые сегодня можно встретить почти в каждом графическом редакторе и программе автоматизированного проектирования. Как же они строятся? Придется начать немного издалека…

Полиномы Бернштейна

В 1912 году отечественный математик Сергей Бернштейн изучал полиномы — это те самые многочлены, над которыми мы хихикали в школе, только на солидно-математическом. Конкретно Бернштейна интересовали полиномы, которые выглядят примерно так:

Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

В чем суть? Представим, что у нас есть какая-то особенно хитровыдуманная кривая (поезд), которую нам нужно повторить. Чтобы ее повторить, нам нужно математически описать форму, но нет простой единой формулы, которая позволяет это сделать. Тогда мы разбираем кривую на «запчасти», каждая из которых описывается суммами отдельных многочленов Бернштейна (тележки, колесные пары, рессоры, сцепки, платформы, крепеж). В этом случае мы можем собрать кривую очень или не очень похожую на интересующую нас исходную модель.

Полиномы с математической точки зрения прекрасны: все гладкие и непрерывные. Это значит, если мы зададим в пространстве n опорных точек P₀, P₁, … P𝗇, повторяющих исходную кривую, у нас будет возможность подобрать такую совокупность кривых, которая гармонично будет проходить через все интересующие нас точки. Вот так выглядит набор базовых «запчастей», из которых можно собрать практически любую кривую:

Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

Вернемся к тому, в чем же заключалась инновация Поля де Кастельжо. Он применил давно известные математические методы, в частности полиномы, для решения задач проектирования сложных форм.

Используя такую формулу, можно задать гладкие кривые или поверхности произвольной формы, в том числе и такие поверхности, которые можно будет отштамповать в металле
Используя такую формулу, можно задать гладкие кривые или поверхности произвольной формы, в том числе и такие поверхности, которые можно будет отштамповать в металле
  1. Для начала он задал исходную и конечную точку P₀ и P₁, ведь должна же кривая с чего-то начинаться?
  2. Далее он использовал запись нескольких полиномов в параметрической форме, то есть с использованием третьей переменной.
  3. Далее мы ставим промежуточные опорные точки и последовательно соединяем с первой по последнюю, получая криволинейную форму.
  4. Выберем t из диапазона от 0 до 1.
  5. Каждый из полученных отрезков делим в соотношении t:(1-t) и ставим точку на этой отметке.
  6. Соединяем последовательно эти пары точек отрезками.
  7. С полученными отрезками повторяем шаги 5—7, пока не получим единственную точку.
  8. Повторяем шаги 4—7 для других значений t, получая новые точки.
  9. Соединяем полученные точки и получаем гладкую кривую.

Если описанное выше слишком сложно, просто посмотрите на анимацию. Сегодня именно по этому правилу почти все графические редакторы рисуют кривые:

Что с этим делать

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

Кривая Безье, построенная с помощью двух контрольных точек P₀ и P₃ и двух опорных P₂ и P₁ 
Кривая Безье, построенная с помощью двух контрольных точек P₀ и P₃ и двух опорных P₂ и P₁ 

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

Анатомия нейросетей

Многие уже пробовали генерировать картинки с помощью Midjourney, DALL-E или Kandinsky. Но из-за сложности применяемых методов простой пользователь практически обречен на полное непонимание того, что находится «под капотом» генеративных моделей. Чтобы чуть-чуть приоткрыть завесу, давайте пробежимся по основополагающим понятиям. В дальнейшем это поможет генерировать изображения более осознанно.

Эмбеддинги, метрики, расстояния

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

  • Потому что с их помощью легко отобразить близкие по морфологии или смыслу слова: например,векторы «кошки» и «кота» будут жить где-то по соседству.
  • С ними легко производить математические операции: «нога + мяч = футбол».
  • Мы всегда знаем, где у вектора начало, а где конец — это помогает не перепутать «корт» и «крот», «масть» и «месть».
  • Из-за многомерности пространства становится возможен анализ по разным критериям: например, «маленький синий резиновый кубик» и «маленький желтый резиновый кубик» будут отличаться только в пространстве, определяющем яркость красного и синего цветов в RGB-палитре.

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

Процесс перевода слова в вектор называется эмбеддингом. Практически все современные генеративные модели, такие как Word2Vec, GloVe, BERT, GPT, CLIP работают с эмбеддингами.

Допустим, у нас есть два вектора. Как определить, насколько они отличаются? Очевидно, измерить расстояние между ними. А как измерить расстояние, если дело происходит не в евклидовом, а в n-мерном пространстве? Здесь на арену выходит «манхэттенское расстояние» или «расстояние городских кварталов» — это расстояние между двумя точками, измеренное вдоль осей, расположенных под прямым углом друг к другу (как городские кварталы). Его вычисляют путем нахождения суммы абсолютных разностей соответствующих координат векторов. Так для векторов A = (x1, y1, z1) и B = (x2, y2, z2) манхэттенское расстояние рассчитывается так: |x1 - x2| + |y1 - y2| + |z1 - z2|.

Почему нельзя просто измерить расстояние по прямой? Потому что это может привести к непозволительным погрешностям. Представьте, что вы смотрите телевизор в своей квартире: формально расстояние до соседей сверху и через стену незначительно — 3 метра. Только, чтобы дойти до соседа сверху, вам понадобится пройти по коридору, выйти на лестницу, подняться на этаж выше и постучать в дверь. А сосед через стену может оказаться как ближе, так и дальше в зависимости от того, живет он в вашем подъезде или в соседнем. Если наша модель, конечно, вообще предусматривает такое измерение как «подъезд».

Однако, у «манхэттенского расстояния» есть и интересная особенность, которая может неожиданным образом повлиять на результат предсказания. Допустим, у нас есть два близких объекта A и B и расстояние R между ними. Если мы немного увеличим расстояние между этими объектами (на небольшую величину r), то в область между R и R+r попадет большое число не сильно связанных с ними объектов. Это чревато тем, что при генерации изображения или текста могут неожиданно выпадать значения, которые просто оказались рядом в векторном пространстве.

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

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

Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

Как именно используется расстояние Фреше? Допустим, у нас есть нейросеть, задача которой генерировать реалистичные изображения лошадей. У нейросети, обученной рисовать лошадей, внутри есть модуль, который «понимает», как должна выглядеть «идеальная нейросетевая лошадь». Ведь нейросеть обучали именно для этого. В процессе генерации изображения нейросеть создает последовательно сотни и тысячи эскизов. После генерации каждого следующего она оценивает: новый ближе к идеалу, чем предыдущий? И лучший вариант используется для сравнения со следующим новым эскизом.

Оценка близости к идеальной картинке производится с помощью расстояния Frechet Inception Distance (FID, метрики Фреше). Метрика Фреше сравнивает два изображения так, будто пытается совместить две картинки, напечатанные на эластичной прозрачной пленке, всячески их растягивая и сжимая, поворачивая и сдвигая. Выраженное в виде числа расстояние Фреше будет максимальным для участка с максимальной разницей между картинками, и равно нулю для идентичных участков. Расстояние Фреше благодаря «внутренней эластичности» гораздо лучше видит сходство у почти одинаковых картинок, нежели другие методы типа попиксельного сравнения.

GAN против диффузии

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

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

С диффузией же всё сложнее. Как же работают диффузионные модели?

  1. Сначала создается набор картинок, потом на каждую из них случайным образом добавляется немного пятен, результат фиксируется. Этот процесс повторяют до тех пор, пока исходник не станет почти неразличим. Затем машину заставляют воспроизвести действия в обратном порядке так, чтобы пятна последовательно исчезали. Этот процесс удаления шумов называется denoising.
  2. Пары последовательно измененных картинок используются для обучения нейросети, и в результате она учится предсказывать зашумление и отделять искажение от изображения. Поскольку модель не знает, что там в исходнике, она постоянно сверяется со специальными модулями, которые подсказывают «горячо» или «холодно», больше картинка на шаге n+1 похожа на промпт, чем на n, или меньше.
  3. А потом происходит настоящая магия: раз машина может нарисовать обратно то, что есть, то может нарисовать и то, чего нет. И из сгенерированного шума, последовательно стирая разные участки, можно получить то, что и хотел пользователь.

Итак, как же думает реальная генеративная модель? Если мы возьмем данные о Kandinsky, выложенные в открытый доступ, получится следующее:

  1. Kandinsky с помощью нейросети CLIP-ViT-G осуществляет преобразование изображений и текстов в эмбеддинги.
  2. Производятся операции с эмбеддингами-векторами. При этом мы можем их не только складывать, но и вычитать. Это необходимо для исключения каких-либо нежелательных элементов в итоговом изображении, а сам процесс получил название negative prompting или «негативная подсказка».
  3. С помощью модели U-Net производится восстановление изображения, используя механизм диффузии и эмбеддинги как подсказки для кристаллизации.
Как создать красивую картинку, если ты дилетант, дизайнер или… нейросеть

Почему предыдущие два пункта важны

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

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

То, как промпт повлияет на выдачу, зависит от количества параметров (измерений) в модели, того, какие значения окажутся рядом с искомыми в многомерном пространстве, того, что получается при сложении значений и даже от…языка запроса! Ведь некоторые слова могут являться омографами или синонимами в одном языке, и не иметь таких свойств в другом, а, соответственно, их векторное представление для разных языков будет отличаться. Например, по запросу «голубое небо» по состоянию на июль 2024 Kandinsky генерировал небо над морем или полем с линией горизонта, а если сменить запрос на «светло-голубое небо», то уже без моря. Поэтому если вы замечаете, что при тестировании какого-то промпта вам упорно выдают какого-то соседа по векторному пространству, можете его исключить, используя негативный промпт.

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

11
Начать дискуссию