30 / 33 · Диффузионные модели
Редактирование изображений по точкам: DragGAN и DragDiffusion
Перемещение точки изображения к цели оптимизацией латентного кода генеративной модели: пространство W+ генератора StyleGAN2 и обращение GAN, motion supervision и отслеживание точек в DragGAN, а также дообучение LoRA, обращение DDIM, оптимизация латента и reference-latent-control в DragDiffusion с оценкой на DragBench.
Генеративно-состязательные сети · Латентная диффузия и Stable Diffusion · LPIPS · LoRA
На этой странице 12
Заметка о латентной диффузии закончилась четырьмя способами редактировать изображение обученной моделью: image-to-image, инпейнтинг, LoRA и textual inversion. Все четыре управляют тем, что показывает изображение, — через промпт, маску или новое понятие. Ни один из них не говорит, где что должно находиться. Многие правки геометрические: открыть рот, повернуть голову, поднять ухо, сделать машину выше. Пользователь может задать такую правку двумя щелчками: управляющей точкой (handle point) на объекте и целевой точкой (target point), куда она должна попасть. Редактирование по точкам (point-based editing) превращает щелчки в оптимизацию по латентному коду генеративной модели, так что каждый промежуточный результат — изображение, которое модель способна породить. DragGAN (Pan et al., 2023) делает это в StyleGAN2. DragDiffusion (Shi et al., 2024) переносит тот же цикл в Stable Diffusion — модель, которая может представить почти любую фотографию.
Обозначения. Управляющие точки и их цели — позиции пикселей; мы пишем (goal, цель) там, где DragGAN пишет , потому что — шаг диффузии. — начальное положение управляющей точки, — её положение после итераций. — необязательная бинарная маска, равная 1 там, где изображение может меняться. — единичный вектор от точки к её цели. — вектор признаков в позиции карты признаков, вычисленной по оптимизируемой переменной ; в нецелой позиции он билинейно интерполируется по четырём соседним позициям. — stop-gradient (остановка градиента): значение проходит вперёд, а градиент равен нулю. — круг позиций вокруг , а — квадрат. — сумма модулей. Обозначения диффузии , , , , и — те же, что в заметке о латентной диффузии.
Чего требует перетаскивание#
DragGAN называет три свойства идеального инструмента для такого управления (Pan et al., 2023, раздел 1). Он должен быть гибким: менять можно положение, позу, форму, выражение и компоновку. Он должен быть точным: управляющая точка оказывается в цели, а не рядом с ней. Он должен быть общим: не привязанным к одной категории объектов. Прежние подходы не выполняют хотя бы одно из этих требований. Методы, построенные на 3D-моделях или обученные на ручной разметке, например условный GAN, управляемый ключевыми точками или картами сегментации, дают только те средства управления, для которых обучены, и не переносятся на новые категории. Текст — общее средство, но он не может сказать «сдвинь это на 40 пикселей».
Четвёртое свойство даёт сам выбор инструмента. Если правка делается изменением латентного кода предобученного генератора, каждый промежуточный результат — выход этого генератора, так что генератор служит априорным знанием, тянущим к реалистичным изображениям. Содержимое, которое открывается при движении, придумывает модель: DragGAN открывает пасть льва, и внутри появляются зубы. Деформация пикселей так не умеет. Реалистичность, однако, не гарантирована. Быть выходом генератора, то есть лежать в его математическом образе, — не то же самое, что лежать там, где сосредоточены его обучающие данные, и оптимизированный код в или зашумлённый латент диффузии может уйти из этой области; ограничения перечисляют артефакты и смену идентичности, к которым это приводит. Реалистичность и сохранение идентичности нужно проверять на каждом результате. Остаётся дифференцируемым образом сказать «эта точка должна сдвинуться на один шаг вон туда» и знать, где точка находится после каждого шага.
Генератор StyleGAN2 вкратце#
До сих пор курс использовал генераторы GAN как чёрные ящики, переводящие шум в изображения (заметка о GAN). DragGAN опирается на четыре свойства одного конкретного генератора — StyleGAN2 (Karras et al., 2020), обученного обычной состязательной игрой.
-
Отображающая сеть (mapping network). Вектор шума , , сначала проходит через 8-слойный MLP , который даёт промежуточный код (Karras, Laine and Aila, 2019, раздел 2). не обязано быть гауссовским, и статья о StyleGAN утверждает, что оно менее запутано (entangled), чем пространство : движение вдоль направления в , как правило, меняет меньше атрибутов одновременно.
-
Модуляция стилем (style modulation). Синтезирующая сеть начинает с обучаемой константы и блок за блоком удваивает разрешение до . Каждая свёртка получает стиль (style) — обучаемую аффинную функцию от с одним масштабом на входной канал. StyleGAN2 применяет стиль к весам. Если — вес от входного канала к выходному каналу в позиции ядра , то
где второй шаг, демодуляция (demodulation), делит каждый выходной канал на норму его весов, так что входы с единичной дисперсией снова дают выходы с единичной дисперсией (Karras et al., 2020, раздел 2.2). Попиксельные карты шума добавляют случайные детали, например расположение волос.
-
Расширенное пространство . Ничто не заставляет все слои получать одно и то же . Если каждому входу стиля подать собственный код, получится — пространство (Xia et al., 2022, раздел IV-A). Генератор с выходом имеет входов стиля: 14 при , 16 при и 18 при . Первые коды действуют на грубых разрешениях. В экспериментах StyleGAN со смешиванием стилей (style mixing) коды слоёв от до несут позу, форму лица и общую причёску, коды и — более мелкие черты лица, а самые тонкие слои — цвет и микроструктуру (Karras, Laine and Aila, 2019, раздел 3.1). Первые шесть кодов управляют слоями примерно до .
-
Промежуточные признаки. Каждый блок синтеза выдаёт карту признаков своего разрешения. DragGAN использует карту после шестого блока, билинейно приведённую к размеру изображения. Из проверенных блоков этот дал самые точные правки: более ранние слишком грубы, более поздние дают менее различающие признаки (Pan et al., 2023, разделы 3.2 и 4.2). Если считать от блока , шестой блок выдаёт карту , и именно её использует официальный код. В статье указано (раздел 3.3) — разрешение седьмого блока.
Редактирование реального фото: обращение GAN#
У сгенерированного изображения есть латентный код. У фотографии его нет, поэтому сначала выполняется обращение GAN (GAN inversion) — поиск кода, изображение которого её воспроизводит:
где — расстояние в пространстве пикселей или признаков (Xia et al., 2022, раздел II). Обзор делит методы на три семейства (раздел IV-B).
- Методы на основе оптимизации решают задачу напрямую для каждого изображения градиентным спуском. Собственный проектор (projector) StyleGAN2 оптимизирует и карты шума в течение 1000 итераций Adam по расстоянию LPIPS, вычисленному на обоих изображениях, уменьшенных до (Karras et al., 2020, раздел 5 и приложение D). Точно, но медленно.
- Методы на основе энкодера один раз обучают сеть на множестве изображений. Тогда обращение — один прямой проход, ценой менее точной реконструкции.
- Гибридные методы начинают с кода, выданного энкодером, и уточняют его оптимизацией.
Выбор пространства важен. У в раз больше степеней свободы, чем у , и оно точнее воспроизводит фотографии, но код, найденный далеко от кодов, которые порождает отображающая сеть, плохо редактируется: обзор называет это компромиссом между искажением и редактируемостью (distortion–editability trade-off; раздел IV-A). Pivotal tuning inversion (PTI, обращение с донастройкой генератора вокруг опорного кода; Roich et al., 2022) обходит этот компромисс, меняя вместо кода генератор. Сначала фото обращается в , что даёт опорный код (pivot) (450 шагов оптимизации по LPIPS с регуляризатором шума). Затем веса генератора дообучаются 350 шагов, чтобы совпадало с фото по LPIPS плюс квадратичной ошибке, с регуляризатором, который оставляет генератор неизменным вдали от . Вся процедура занимает меньше трёх минут на изображение на одной RTX 2080. Именно так DragGAN редактирует реальные фото: сначала PTI, затем цикл перетаскивания на полученном коде (Pan et al., 2023, раздел 4.1).
Обращение ограничивает возможности редактора на основе GAN. Модель лиц может обратить портрет, но не человека в полный рост, модель кошек не может обратить машину, а то, что лежит вне многообразия изображений генератора, нельзя достичь движением по нему.
DragGAN: motion supervision и отслеживание точек#
DragGAN начинает с кода , его признаков и начальных управляющих точек . Каждая итерация состоит из двух подшагов (Pan et al., 2023, раздел 3.1). Motion supervision (контроль движения) сдвигает каждую точку на небольшой шаг к цели одним градиентным шагом по . Отслеживание точек (point tracking) затем находит, куда сместилась каждая точка. Подшаги повторяются, пока все точки не достигнут своих целей. Ничего не обучается: генератор заморожен, и единственная переменная — код редактируемого изображения.
Одна итерация DragGAN: motion supervision и отслеживание точки
- Генератор переводит в изображение и, после шестого блока, в карту признаков .
- Motion supervision сравнивает признаки в участке вокруг каждой точки с тем же участком, сдвинутым на один пиксель вдоль .
- Градиент функции потерь распространяется назад до первых шести кодов , и Adam делает один шаг.
- Генератор снова запускается с новым кодом ; в его признаках содержимое вокруг каждой точки немного сдвинулось.
- Отслеживание точек находит новые положения точек поиском ближайшего соседа в . Цикл возвращается к шагу 2, пока каждая точка не окажется достаточно близко к своей цели.
Motion supervision#
Функция потерь одной итерации —
Первое слагаемое сравнивает участок признаков вокруг каждой точки с тем же участком, сдвинутым на один пиксель к цели. Эталон заморожен, поэтому уменьшить слагаемое можно лишь одним способом: менять признаки в сдвинутых позициях , пока они не станут похожи на текущие признаки в , — содержимое вокруг копируется на один шаг вдоль . Позиции нецелые, поэтому читается билинейной интерполяцией. Именно интерполяция позволяет единичному шагу указывать в любом направлении, а не только вдоль сетки, и сохраняет сдвинутые признаки дифференцируемой функцией карты признаков. Если точка уже стоит в цели, полагают равным 0; тогда её слагаемое тождественно равно нулю и больше на эту точку не действует. Второе слагаемое, которое используется, когда нарисована маска, сохраняет признаки вне подвижной области равными признакам исходного изображения.
Оптимизируемая переменная лежит в , и обновляются только первые шесть её кодов. Статья отмечает, что пространственные атрибуты задаются в основном этими кодами, а более поздние отвечают за внешний вид; если поздние коды зафиксировать, содержимое сдвигается без перерисовки — то же разделение, что и при смешивании стилей (Pan et al., 2023, раздел 3.2). вместо оставляет место для правок, редких в обучающих данных; пример из статьи — закрыть кошке один глаз, что в не удаётся (рисунок 16).
Почему эталон заморожен#
Без stop-gradient обе части каждой разности зависят от , и градиент становится разностью двух почти равных градиентов. Он больше не предпочитает направление : функцию потерь можно уменьшить так же хорошо, сдвигая содержимое назад, чтобы стал похож на , или сглаживая признаки в участке, пока все позиции не станут одинаковыми.
Разобранный пример. Одномерный игрушечный генератор рисует горб, положение которого задаёт латент , и читает два канала признаков в позиции :
Второй канал отличает левый склон горба от правого. Возьмём , управляющую точку , цель , так что , и участок из одной позиции, . Эталон — , сдвинутый признак — , поэтому функция потерь равна ; первая разность отрицательна, вторая положительна.
Со stop-gradient меняется только . Его производные — , поэтому
Градиентный спуск увеличивает и двигает горб к цели. При замороженном эталоне функция потерь как функция равна при , при и при : её минимум — ровно сдвиг содержимого на .
Без stop-gradient двигается и эталон, с , и
Знак меняется: теперь градиентный спуск уводит горб от цели.
Отслеживание точек#
После шага содержимое сдвинулось, но на величину, которую функция потерь не задаёт. Один градиентный шаг может сдвинуть его меньше чем на пиксель или больше — в зависимости от шага обучения и от объекта. Если бы следующий шаг контролировал старое положение, он толкал бы не то содержимое. Поэтому DragGAN заново находит каждую точку поиском ближайшего соседа в пространстве признаков (Pan et al., 2023, раздел 3.3):
где — обновлённый код, а — признак точки в исходном изображении. Эталоном всегда служит исходный признак, а не признак с предыдущей итерации, поэтому малые ошибки отслеживания не накапливаются в дрейф. В разобранном примере, после того как горб сдвинулся в , при кандидаты находятся на расстояниях от : точка найдена в . По одному первому каналу оказалось бы наравне с ; для отслеживания нужны признаки, различающие позиции.
Почему не специальный трекер? Признаки генератора уже вычислены в прямом проходе и достаточно хорошо различают позиции. Замена поиска ближайшего соседа сетью оптического потока (RAFT) или трекером точек (PIPs) в тестах статьи дала бо́льшие итоговые ошибки и более медленные правки (таблица ниже). Motion supervision и отслеживание разделены, потому что отвечают на разные вопросы: функции потерь нужно текущее положение точки, чтобы разместить участок, а где это положение теперь, может сказать только поиск после шага.
Цикл и его параметры#
- Оптимизатор — Adam по шести кодам с шагом обучения для FFHQ, AFHQ-Cat и LSUN Car и для остальных наборов данных.
- , и для изображения : 3 и 12 пикселей при , 6 и 24 при .
- Цикл останавливается, когда каждая точка находится не дальше 1 пикселя от своей цели или не дальше 2 пикселей, если точек больше пяти (Pan et al., 2023, раздел 3.4).
- Правка обычно занимает от 30 до 200 итераций, несколько секунд на одной RTX 3090 (разделы 1 и 3.1). Пользователь может остановиться в любой момент, передвинуть цели, добавить точки и продолжить.
Игрушечная модель ниже прогоняет весь цикл в двух измерениях; латентом служит положение пятна.
Игрушечный DragGAN: одна точка, сдвиг пятна как латент
Две особенности игрушки переносятся на настоящий метод. Функция потерь не убывает от итерации к итерации: всё время она остаётся между 7.4 и 8.5, потому что каждая итерация задаёт новый участок в новом положении точки. Прогресс измеряется расстоянием до цели, а не функцией потерь. Кроме того, отслеживание возвращает позиции сетки, а содержимое движется непрерывно: в конце содержимое сдвинулось на , а отслеженная точка находится в 0.11 пикселя от того места, где на самом деле оказалось её содержимое.
Результаты#
Основной количественный тест — перемещение ключевых точек лица (face landmark manipulation; Pan et al., 2023, раздел 4.2). Моделью StyleGAN2, обученной на FFHQ при , генерируются два случайных лица; ключевые точки первого лица, найденные детектором dlib, служат управляющими точками, а точки второго лица — целями. Среднее расстояние (mean distance, MD) между ключевыми точками, найденными на отредактированном изображении, и целями усредняется по 1000 тестам, не более 300 итераций на правку. FID между отредактированными и исходными изображениями проверяет, что правки остаются реалистичными.
| Метод | MD, 1 точка | MD, 5 точек | MD, 68 точек | FID | Время, с |
|---|---|---|---|---|---|
| Без правки | 12.93 | 11.66 | 16.02 | – | – |
| UserControllableLT | 11.64 | 10.41 | 10.15 | 25.32 | 0.03 |
| DragGAN с отслеживанием RAFT | 13.43 | 13.59 | 15.92 | 51.37 | 15.4 |
| DragGAN с отслеживанием PIPs | 2.98 | 4.83 | 5.30 | 31.87 | 6.6 |
| DragGAN | 2.44 | 3.18 | 4.73 | 9.28 | 2.0 |
FID и время приведены для задачи с одной точкой. UserControllableLT, более ранний метод редактирования по точкам, быстр, но почти не сдвигает ключевые точки. Вблизи выбранного блока признаков выбор блока мало что меняет: блок 6 даёт MD 2.44, блоки 5 и 7 дают 2.50 и 2.51 для motion supervision и 2.55 и 2.58 для отслеживания, а блок 4 — 2.73 и 3.61 (таблица 3). Радиус влияет ещё меньше: MD от 2.44 до 2.51 при от 1 до 5 (таблица 4). Во втором тесте изображение, порождённое возмущённым кодом, нужно восстановить по исходному изображению и 32 перетаскиваниям, взятым из оптического потока между ними; у DragGAN наименьшие квадратичная ошибка и LPIPS во всех четырёх категориях (таблица 2).
DragDiffusion: тот же цикл в латенте диффузии#
DragGAN редактирует только то, что может сгенерировать его GAN, а реальные фото — лишь настолько хорошо, насколько удаётся обращение. Диффузионная модель «текст в изображение» покрывает гораздо больше изображений, чем любой GAN одной категории, но у неё нет единого кода вроде : изображение — конец цепочки шагов очистки от шума (денойзинга). DragDiffusion сохраняет оба подшага DragGAN и меняет то, что оптимизируется: один зашумлённый латент Stable Diffusion 1.5 на одном промежуточном шаге (Shi et al., 2024). Два дополнения сохраняют верность отредактированного изображения оригиналу: дообучение U-Net с LoRA на входном изображении перед редактированием и изменение self-attention при финальной очистке от шума.
DragDiffusion: четыре этапа
- Дообучение с сохранением идентичности обучает веса LoRA в U-Net только на входном изображении.
- Обращение DDIM переводит латент изображения в зашумлённый латент , отстоящий от изображения на 35 шагов 50-шагового расписания.
- Оптимизация латента сдвигает точки с помощью motion supervision и отслеживания точек на признаках U-Net; меняется только .
- Очистка от шума с reference-latent-control возвращает отредактированный латент в изображение, заимствуя ключи и значения из очистки исходного латента.
Дообучение с сохранением идентичности#
Обращение DDIM с последующей очисткой от шума не возвращает в точности входное фото, а после правки латента расхождение растёт: лица меняют идентичность, меняются текстуры. Поэтому перед редактированием DragDiffusion дообучает (fine-tuning) U-Net на одном изображении обновлениями LoRA в проекциях запросов, ключей и значений всех слоёв внимания. Функция потерь — целевая функция DDPM из заметки о латентной диффузии, ограниченная одним латентом :
где заморожены, — веса LoRA, а — короткий промпт, описывающий изображение. Статья записывает зашумлённый латент как ; это то же самое при и . Параметры: ранг 16, AdamW с шагом обучения , размер батча 4 и 80 шагов, около 25 секунд на A100 (Shi et al., 2024, раздел 4.1 и приложение D). После дообучения модель точно восстанавливает это изображение, и результат правки остаётся узнаваемо той же картинкой. Без дообучения среднее расстояние резко растёт, а верность изображению (image fidelity) падает; обе величины быстро улучшаются с ростом числа шагов и выходят на плато, а меньше 80 шагов оставляют артефакты вроде искажённых лиц (разделы 4.4 и 4.6, приложение G).
Обращение DDIM до одного шага#
Сэмплирование с DDIM детерминировано. Пусть 50 шагов сэмплера пронумерованы через , а взяты в соответствующих шагах обучения; тогда один шаг —
предсказать чистый латент, затем снова зашумить его до следующего уровня вдоль предсказанного шума (Song, Meng and Ermon, 2021, формула 12 при ). Обращение DDIM (DDIM inversion) выполняет то же обновление вверх, от к , подставляя шум, предсказанный в , вместо шума в неизвестном . При малых шагах подстановка мало что меняет, и очистка обращённого латента возвращает изображение, близкое к исходному (раздел 4.3 статьи о DDIM рассматривает обновление как дискретизацию ОДУ, которое можно решать в любом направлении).
DragDiffusion обращает фото на 35 из 50 шагов и редактирует ; отсчитывается от изображения, так что — фото, а — чистый шум. Для реальных фото classifier-free guidance выключен и при обращении, и при очистке от шума, потому что он усиливает ошибку обращения (Shi et al., 2024, раздел 4.1).
Почему достаточно одного латента? Перетаскивание меняет компоновку, а компоновка диффузионного сэмпла устанавливается рано в цепочке, при сильном шуме; поздние шаги добавляют детали. Статья показывает, что признаки U-Net при уже содержат форму и позу объекта (рисунок 2), так что оптимизация этого одного латента может сдвинуть объект. Тогда каждая итерация стоит одного прямого и одного обратного прохода через U-Net, а не обратного прохода через всю цепочку шагов очистки. Выбор шага — компромисс (раздел 4.5). Верность изображению монотонно убывает с ростом , потому что более зашумлённый латент свободнее меняется. Среднее расстояние минимально при от 30 до 40: при меньших латент слишком скован, чтобы совершить перемещение, а при больших редактирование становится неустойчивым и идентичность теряется.
Оптимизация латента на признаках U-Net#
Motion supervision из DragGAN переносится с латентом вместо и признаками U-Net вместо признаков генератора. Пусть — латент после обновлений, ; тогда
и каждое обновление — градиентный шаг по латенту, , на практике выполняемый с Adam (Shi et al., 2024, раздел 3.3). От DragGAN отличаются три вещи.
- Признаки. — выход одного блока декодера U-Net, когда U-Net очищает от шума на шаге . Из четырёх блоков повышения разрешения третий даёт наименьшее среднее расстояние при относительно высокой верности. Первые блоки слишком грубы для точного управления, а последний несёт текстуру, а не геометрию, и почти ничего не сдвигает (раздел 4.7). Официальный код билинейно приводит эту карту к половине разрешения изображения, для изображения , и соответственно масштабирует точки; читается билинейной интерполяцией, как в DragGAN.
- Участки. — квадрат с полушириной : позиции для motion supervision () и для отслеживания () на этой карте.
- Слагаемое маски. Оно действует на латенты, а не на признаки. — один шаг очистки DDIM от текущего латента, а — тот же шаг от неизменённого латента, так что вне маски следующий, чуть более чистый латент не должен меняться. По умолчанию ; пользователь может увеличить это значение, если область вне маски всё же сдвигается.
Отслеживание — как в DragGAN, но на признаках U-Net:
Признаки U-Net играют ту же роль, что признаки генератора в DragGAN. Они всё равно вычисляются в прямом проходе, дифференцируемо зависят от оптимизируемого латента и несут соответствия между изображениями (Tang et al., 2023). Сети оптического потока понадобилось бы декодированное изображение на каждой итерации, тогда как для motion supervision и так нужны признаки, дифференцируемо зависящие от латента. Adam работает с шагом обучения 0.01 не более 80 шагов, от 10 до 30 секунд на A100 в зависимости от размера перетаскивания (раздел 4.1 и приложение D).
Reference-latent-control#
После оптимизации очищается от шума за оставшиеся шагов и декодируется. Обычная очистка может уйти от оригинала по идентичности и текстуре. Reference-latent-control (управление через опорный латент) параллельно выполняет очистку исходного и на каждом шаге в слоях self-attention блоков повышения разрешения U-Net заменяет ключи и значения отредактированной ветви ключами и значениями исходной:
где и — вытянутые в вектор признаки отредактированной и исходной ветвей, а — размерность ключа (Shi et al., 2024, разделы 3.4 и 4.1). Механизм повторяет взаимный self-attention (mutual self-attention) из MasaCtrl (Cao et al., 2023). Каждая позиция отредактированного изображения находит позиции оригинала, ключи которых подходят к её запросу, и копирует их значения, так что кошка со сдвинутым ухом всё равно получает шерсть исходной кошки. В перекрёстном внимании из заметки о латентной диффузии ключи и значения берутся из промпта; здесь они берутся из исходного изображения. Удаление этого шага в основном снижает верность изображению (раздел 4.4). Финальная очистка от шума занимает 1–2 секунды.
Оценка на DragBench#
DragBench создан специально для этой задачи (Shi et al., 2024, раздел 4.2 и приложение A). В нём 205 изображений с 349 парами управляющих и целевых точек в десяти категориях: животные, произведения искусства, здания (виды города и сельской местности), люди — голова, по пояс и в полный рост, — дизайн интерьера, пейзажи и прочие объекты. Изображения людей сгенерированы Midjourney; остальные — фотографии с Unsplash, Pexels и Pixabay. Сообщаются две меры.
- Верность изображению , усреднённая по изображениям: сколько осталось от оригинала; 1 для неизменённого изображения (LPIPS).
- Среднее расстояние MD: положение, в которое попало содержимое управляющей точки, находится на отредактированном изображении с помощью DIFT — метода поиска соответствий на признаках диффузии (Tang et al., 2023), — и его расстояние до цели усредняется по всем парам; 0 для идеального перетаскивания.
Две меры тянут в противоположные стороны. Бездействие даёт идеальную верность и начальное расстояние; радикальное изменение может достичь целей и потерять изображение. Их нужно читать вместе, и статья откладывает одну против другой (рисунок 8). Для DragGAN каждое изображение редактируется моделью StyleGAN, обученной на наборе одного класса — того, который по сходству CLIP лучше всего соответствует описанию изображения (раздел 4.4).
| Категория | MD, DragGAN | MD, DragDiffusion | IF, DragGAN | IF, DragDiffusion |
|---|---|---|---|---|
| произведения искусства | 59.51 | 30.74 | 0.71 | 0.88 |
| пейзаж | 47.60 | 36.55 | 0.84 | 0.88 |
| город | 41.94 | 26.18 | 0.74 | 0.89 |
| сельская местность | 46.96 | 43.21 | 0.79 | 0.88 |
| животные | 60.12 | 39.22 | 0.72 | 0.87 |
| голова | 65.14 | 36.43 | 0.91 | 0.85 |
| по пояс | 82.98 | 39.75 | 0.33 | 0.89 |
| в полный рост | 37.01 | 20.56 | 0.31 | 0.95 |
| дизайн интерьера | 75.65 | 24.83 | 0.57 | 0.90 |
| прочие объекты | 58.25 | 39.52 | 0.71 | 0.87 |
Значения взяты из таблиц 1 и 2 статьи; MD измеряется в пикселях, и чем оно меньше, тем лучше, а IF — чем больше, тем лучше. DragDiffusion оставляет точки ближе к целям во всех десяти категориях и сохраняет больше изображения в девяти. Исключение — категория «голова», где DragGAN сохраняет больше (0.91 против 0.85), но оставляет точки гораздо дальше от целей (65.14 против 36.43). В категориях «по пояс» и «в полный рост» верность DragGAN падает до 0.33 и 0.31: обращённые изображения теряют бо́льшую часть оригинала.
Что изменилось#
| Image-to-image и инпейнтинг | DragGAN | DragDiffusion | |
|---|---|---|---|
| Пользователь задаёт | промпт, маску | точки, цели, необязательную маску | точки, цели, необязательную маску, промпт |
| Модель | Stable Diffusion | StyleGAN2 одной категории | Stable Diffusion 1.5 |
| Что оптимизируется | ничего во время правки | первые 6 кодов , чисел | один латент , числа |
| Признаки | нет | генератора, после блока 6 | декодера U-Net, третий блок повышения разрешения |
| Сохранение остального | маска | на признаках вне маски | на следующем латенте, LoRA, reference-latent-control |
| Реальные фото | да | после обращения PTI | после LoRA и обращения DDIM |
| Время на правку | один запуск сэмплирования | несколько секунд | около 25 + 10–30 + 1–2 с |
Ограничения#
- Возможности модели ограничивают правку. DragGAN не может выйти за пределы области своего GAN, а позы вне распределения дают артефакты (Pan et al., 2023, раздел 4.3). У DragDiffusion диапазон гораздо шире, но каждая правка фото проходит через приближённое обращение.
- Отслеживание может сбиться. Поиск ближайшего соседа по признакам дрейфует в областях без текстуры, где многие позиции выглядят одинаково, и на симметричных объектах, как показывает одноканальный случай разобранного примера. DragGAN рекомендует ставить точки на участках с богатой текстурой.
- Не каждая точка доходит до цели. DragDiffusion иногда оставляет точки, не дошедшие до целей (приложение E); на DragBench её среднее расстояние всё ещё составляет от 20.56 до 43.21 пикселя в зависимости от категории.
- Перетаскивание неоднозначно. Несколько точек не определяют изображение. Без маски DragGAN склонен выбирать решение, ближайшее к выученному многообразию, например двигать всю собаку, когда перетаскивали только её голову (раздел 4.3).
- Стоимость на изображение. PTI для DragGAN на фото и дообучение LoRA для DragDiffusion добавляют запуск обучения перед каждым новым изображением.
- Оценка — пара чисел. Верность поощряет бездействие, а среднее расстояние — достижение цели любой ценой.
- Злоупотребления. Оба инструмента позволяют легко изменить позу, выражение лица или фигуру реального человека на фото (раздел 4.3).
Итоги#
- Перетаскивание — это оптимизация латента генератора: каждый промежуточный результат — выход модели, которая служит априорным знанием о реалистичности и позволяет придумывать открывшееся содержимое. Реалистичность и идентичность всё равно нужно проверять, потому что оптимизированный код может уйти из области, которую поддерживают обучающие данные.
- StyleGAN2 переводит в , модулирует каждую свёртку стилем из и в берёт отдельный код для каждого слоя; первые коды задают компоновку, поздние — внешний вид. Реальные фото попадают в модель через обращение GAN, для DragGAN — через PTI.
- DragGAN чередует motion supervision — функцию потерь L1, которая копирует участок признаков на один пиксель к цели при эталоне, замороженном stop-gradient, — и отслеживание точек поиском ближайшего соседа к исходному признаку точки. Обновляются только первые шесть кодов .
- DragDiffusion запускает тот же цикл в Stable Diffusion: дообучение LoRA на входном изображении, обращение DDIM до из 50, оптимизация этого одного латента на признаках декодера U-Net и очистка от шума с ключами и значениями, заимствованными у оригинала.
- DragGAN быстр и точен на изображениях, которые может породить его GAN. DragDiffusion работает с реальными фото любого рода и на DragBench подходит к целям ближе в каждой категории и сохраняет больше изображения во всех категориях, кроме одной.
Ноутбук#
Ноутбук о DragGAN из репозитория HSE-LAMBDA Deep Generative Models охватывает оба метода: краткие изложения в текстовых ячейках, два приложения Gradio (неофициальную реализацию DragGAN от сообщества и официальный интерфейс DragDiffusion) и две короткие реализации, написанные с нуля (ячейки нумеруются с 1, считая все ячейки подряд, включая текстовые). Сохранённых выходов ячеек в нём нет, поэтому он документирует процедуры, и заметка не приводит из него результатов. Изложение выше от этого раздела не зависит: он фиксирует, что делают ячейки и где они отступают от двух методов, для тех, кто запускает ноутбук.
- Ячейка 1: значок «Open in Colab», указывающий на копию на Google Drive, которая может отличаться от версии в репозитории.
- Ячейки 2–4: DragGAN. План, мотивация (ячейка 3) и метод (ячейка 4): конвейер, обе функции потерь, что обучается (ничего, кроме латента), параметры (Adam, шаг обучения или , , с масштабированием по размеру изображения, , остановка в пределах 1–2 пикселей или по лимиту итераций, например 300), стоимость (секунды на RTX 3090) и обращение GAN для реальных фото. Ячейка 4 говорит, что исходное изображение получено от «a pre-trained StarGANv2»; на самом деле это StyleGAN2. Она говорит, что градиент течёт «through the target locations, not the original handle points»; в функции потерь градиент течёт через сдвинутые признаки участка, а не через эталон , а сама цель входит только через . Сумма в motion supervision идёт от до , как в статье; для точек это .
- Ячейки 5–10: приложение Gradio для DragGAN. Ячейка 6 клонирует
Zeqiang-Lai/DragGAN, который теперь перенаправляет наOpenGVLab/DragGAN, — неофициальную реализацию (официальная —XingangPan/DragGAN); ячейка 7 устанавливает её зависимости, которые фиксируют Gradio 3.34.0; ячейки 8 и 10 импортируютgradio_app.mainи запускают его сqueue(concurrency_count=1, max_size=20)— аргументом, который существует только в Gradio 3. Приложению нужен GPU с CUDA (device = 'cuda'жёстко прописан в коде), а по умолчанию оно использует модель AFHQ-Cat при . Егоdrag_ganследует методу: оптимизирует первые шесть кодов с Adam при , берёт признаки седьмого блока синтеза, , билинейно приведённые к размеру изображения (официальный код берёт шестой, ), использует круг с и квадрат с , отсоединяет (detach) эталонный участок и останавливается в пределах 2 пикселей. Для пользователя важны два отклонения: слагаемое маски закомментировано, так что нарисованная в интерфейсе маска ни на что не влияет, а шаг отслеживания использует признаки, вычисленные до шага Adam, так что отслеживание и показанное изображение отстают от кода на одну итерацию. Проверка остановки,torch.allclose(handle_points, target_points, atol=2), проверяет каждую координату отдельно, а не расстояние. - Ячейки 11–20: DragGAN «с нуля». Конфигурация, модель и конвейер в стиле классов Hugging Face оборачивают генератор StyleGAN2-ADA AFHQ-Cat (
ada/afhqcat.pklизZeqiangLai/StyleGAN2-pkl); ячейка 17 клонируетstylegan2-ada-pytorch, а ячейка 14 загружает pickle из пути Colab/content/stylegan2-ada-pytorch. Ячейка 18 перетаскивает две точки, заданные как , из и в и с Adam при шаге обучения 0.01 за 20 шагов, а ячейки 19–20 показывают изображения до и после. Это не DragGAN. Перед генератором стоит необученный слойLinear+LeakyReLU, а собственная отображающая сеть генератора применяется к его выходу, так что переменной служит вектор шума, а не первые шесть кодов . Функция потерь,F.l1_loss(handle_feats, target_feats), сравнивает значения RGB выходного изображения в пикселе точки и в пикселе цели, удалённых друг от друга на 283 и 320 пикселей. Нет ни сдвинутого участка, ни stop-gradient, ни отслеживания, ни маски: функцию потерь можно уменьшить, меняя пиксель цели так же, как пиксель точки, и она требует, чтобы два пикселя совпали по цвету, а не чтобы содержимое сдвинулось. Корректная версия регистрирует хук на шестом блоке синтеза (G.synthesis.b128, , как в официальном коде), получаетws = G.mapping(z, None), оптимизируетws[:, :6], вычисляет функцию потерь сдвинутого участка сgrid_sampleотносительно отсоединённого эталона и после каждого шага выполняет отслеживание; приложение из ячеек 6–10 делает то же самое на седьмом блоке. - Ячейки 21–22: DragDiffusion. Мотивация, три этапа, функция потерь дообучения и её параметры (LoRA в модулях внимания, AdamW, , батч 4, 80 шагов, ранг 16, около 25 с на A100), обращение DDIM до , функция потерь motion supervision с её обозначениями, отслеживание, параметры оптимизации (Adam, 0.01, не более 80 шагов, , , ), reference-latent-control, кратко изложенный конвейер инференса, DragBench с IF и MD, время работы и ограничения. Текст говорит, что GAN ограничивают правки «to synthetic images»; DragGAN редактирует реальные фото через обращение, а предел задаёт ёмкость GAN. «DDIM inversion steps: typically 35» означает 35 шагов из 50-шагового расписания. «Less precise on synthetic data» — не результат ни одной из статей, а «slower than DragGAN» верно для сэмплов GAN; на реальном фото DragGAN сначала требуется PTI, который занимает минуты.
- Ячейки 23–28: приложение Gradio для DragDiffusion. Ячейка 24 клонирует
Yujun-Shi/DragDiffusion; ячейка 25 фиксирует Gradio 3.41.1, Diffusers 0.24.0, Transformers 4.27.0, Accelerate 0.17.0, PEFT 0.4.0,huggingface_hub0.20.3 и PyTorch Lightning 1.5.0; ячейка 27 описывает два сценария работы с интерфейсом (реальное изображение: ввести промпт, обучить LoRA, нарисовать маску, отметить точки и цели, запустить; сгенерированное изображение: сгенерировать, затем перетаскивать); ячейка 28 запускаетdrag_ui.py. Официальный код берёт признаки третьего блока повышения разрешения, приведённые к половине разрешения изображения, с и на этой карте; его README требует около 14 ГБ видеопамяти. - Ячейки 29–37: DragDiffusion «с нуля», без LoRA.
DragDiffusionPipeline(ячейка 30) кодирует промпт, сэмплирует латент из шума с classifier-free guidance с масштабом 7.5, при необходимости выполняетdrag_stepи декодирует.drag_stepделает 5 простых градиентных шагов размера 0.1 по итоговому чистому латенту с функцией потерьF.mse_loss(latents[0,:,sy,sx], latents[0,:,ty,tx]). Ячейка 31 загружает Stable Diffusion 1.5 сLMSDiscreteScheduler; ячейки 33–34 генерируют «A photograph of a cute cat in a hat» при за 20 шагов без перетаскивания; ячейки 36–37 генерируют «A cartoon cat on the table» при с перетаскиванием из в . Проблемы:- Цикл сэмплирования не умножает начальный шум на
scheduler.init_noise_sigma(около 14.6 для этого расписания) и не пропускает вход U-Net черезscheduler.scale_model_input;LMSDiscreteSchedulerнужно и то и другое, поэтому сэмплы неверны. СDDIMSchedulerобе операции тождественны. - Перетаскивание — не DragDiffusion: оно действует на чистый латент после сэмплирования, а не на обращённый ; сравнивает сырые каналы латента в двух позициях вместо признаков U-Net в сдвинутом участке; и в нём нет stop-gradient, отслеживания, маски, LoRA, обращения реального изображения и reference-latent-control. Вызов U-Net внутри
drag_stepна случайном шаге вычисляется и отбрасывается: функция потерь от него не зависит. - Точки — координаты на сетке латента, обрезанные по её границам. При латент имеет размер , поэтому и , и становятся : источник и цель совпадают, функция потерь тождественно равна нулю, и перетаскивание ничего не меняет.
- Два запуска используют разные промпты, размеры и шум без фиксированного начального значения генератора (seed), так что это не пара «до и после», а Stable Diffusion 1.5 при работает намного ниже своего разрешения обучения.
runwayml/stable-diffusion-v1-5удалён с Hugging Face Hub; те же веса опубликованы какstable-diffusion-v1-5/stable-diffusion-v1-5.
- Цикл сэмплирования не умножает начальный шум на
- Ячейка 38: заключение и одиннадцать вопросов. Заключение противопоставляет DragGAN, точный на изображениях, которые генерирует его GAN, и DragDiffusion, распространяющий перетаскивание на реальные изображения. Ответы на вопросы есть в этой заметке: как два метода контролируют движение и что оптимизируют их целевые функции (вопросы 1 и 10) — в разделах Оптимизация латента на признаках U-Net и Что изменилось; зачем нужно отслеживание, почему оно использует признаки, а не оптический поток, и почему оно отделено от motion supervision (2, 5, 8) — в разделе Отслеживание точек и после формулы отслеживания DragDiffusion; чего не умеют GAN (3) — в разделе Обращение GAN; почему достаточно одного шага диффузии и как результат зависит от этого шага (4, 11) — в разделе Обращение DDIM до одного шага; роль LoRA (6) — в разделе Дообучение с сохранением идентичности; какие слои оптимизируются (7) и зачем нужна билинейная интерполяция (9) — в разделе Motion supervision.
- Ячейка 39 пуста.
README папки также ссылается на статью о выделении фона (background matting) как на «Sengupta et al., 2020, arXiv:2011.02225»; этот идентификатор принадлежит не связанной с ней статье по материаловедению, статья о выделении фона — Lin et al. (2021), arXiv:2012.07810, а в ноутбуке выделение фона нигде не используется.
Код#
Разобранный пример на PyTorch, с detach() в роли stop-gradient. Он выполняется примерно за секунду на CPU.
import torch
sigma = 2.0
def features(x, s):
"""Toy generator: a bump at position s, read at positions x; two channels."""
u = x - s
phi = torch.exp(-u**2 / (2 * sigma**2))
return torch.stack([phi, u / sigma * phi])
p, g = 1.0, 4.0
d = 1.0 if g > p else -1.0 # единичный шаг от точки к цели
for stop_grad in (True, False):
s = torch.tensor(0.0, requires_grad=True) # латент: положение горба
ref = features(torch.tensor(p), s)
if stop_grad:
ref = ref.detach() # sg[F_p(s)]
loss = (features(torch.tensor(p + d), s) - ref).abs().sum()
loss.backward()
print(stop_grad, round(loss.item(), 4), round(s.grad.item(), 4))
# True 0.4412 -0.3033
# False 0.4412 0.2483
# Отслеживание точки после того, как содержимое сдвинулось на d (s = 1):
f = features(torch.tensor(p), torch.tensor(0.0)) # исходный признак точки
xs = torch.arange(-1.0, 4.0) # Omega_2 вокруг p = 1 при r2 = 3
dist = (features(xs, torch.tensor(1.0)) - f[:, None]).abs().sum(0)
print(xs[dist.argmin()].item(), [round(v, 3) for v in dist.tolist()])
# 2.0 [1.324, 0.882, 0.559, 0.0, 0.441]
Дальше#
Оба метода двигают изображение по многообразию модели, которая порождает всё изображение сразу — из латентного кода или многократной очисткой от шума всей картинки, — и ни один не даёт вероятности результата. Последнее семейство курса строит изображение по частям: авторегрессионные модели раскладывают плотность изображения в произведение условных распределений, предсказывают по одному пикселю или токену за раз и точно вычисляют правдоподобие.
Литература#
- X. Pan, A. Tewari, T. Leimkühler, L. Liu, A. Meka, C. Theobalt. Drag Your GAN: Interactive Point-based Manipulation on the Generative Image Manifold. SIGGRAPH 2023 Conference Proceedings, 2023. Разделы 3.1–3.4 (метод и параметры), 4.1–4.3 (PTI для реальных изображений, таблицы 1–4, обсуждение и ограничения), рисунок 16 ( против ).
- Y. Shi, C. Xue, J. H. Liew, J. Pan, H. Yan, W. Zhang, V. Y. F. Tan, S. Bai. DragDiffusion: Harnessing Diffusion Models for Interactive Point-based Image Editing. CVPR, 2024. Номера разделов относятся к версии 6 на arXiv: разделы 3.2–3.4 (метод), 4.1 (параметры), 4.2 и приложение A (DragBench), 4.4–4.7 (результаты и абляции), приложения D (время работы) и E (ограничения), таблицы 1–2.
- T. Karras, S. Laine, M. Aittala, J. Hellsten, J. Lehtinen, T. Aila. Analyzing and Improving the Image Quality of StyleGAN. CVPR, 2020. Раздел 2.2 (модуляция и демодуляция), раздел 5 и приложение D (проекция).
- T. Karras, S. Laine, T. Aila. A Style-Based Generator Architecture for Generative Adversarial Networks. CVPR, 2019. Раздел 2 (отображающая сеть), раздел 3.1 (смешивание стилей).
- W. Xia, Y. Zhang, Y. Yang, J.-H. Xue, B. Zhou, M.-H. Yang. GAN Inversion: A Survey. IEEE Transactions on Pattern Analysis and Machine Intelligence, 45, 3121–3138, 2023 (онлайн-публикация в 2022). Разделы II и IV.
- D. Roich, R. Mokady, A. H. Bermano, D. Cohen-Or. Pivotal Tuning for Latent-based Editing of Real Images. ACM Transactions on Graphics, 2022.
- E. J. Hu, Y. Shen, P. Wallis, Z. Allen-Zhu, Y. Li, S. Wang, L. Wang, W. Chen. LoRA: Low-Rank Adaptation of Large Language Models. ICLR, 2022.
- J. Song, C. Meng, S. Ermon. Denoising Diffusion Implicit Models. ICLR, 2021. Формула 12 (обновление) и раздел 4.3 (взгляд через ОДУ и кодирование).
- M. Cao, X. Wang, Z. Qi, Y. Shan, X. Qie, Y. Zheng. MasaCtrl: Tuning-Free Mutual Self-Attention Control for Consistent Image Synthesis and Editing. ICCV, 2023.
- L. Tang, M. Jia, Q. Wang, C. P. Phoo, B. Hariharan. Emergent Correspondence from Image Diffusion. NeurIPS, 2023. DIFT.
- HSE-LAMBDA, репозиторий курса Deep Generative Models:
draggan.ipynb.