Содержание курса 15 / 33

15 / 33 · GAN

StarGAN: один генератор для многих доменов

Многодоменный перевод изображений одной сетью: StarGAN подаёт генератору на вход целевую метку, добавляет к дискриминатору WGAN-GP классификатор доменов, возвращает изображение с исходной меткой для реконструкции и обучается сразу на нескольких наборах данных с помощью вектора-маски; StarGAN v2 заменяет метку кодом стиля из отображающей сети или энкодера стиля, встраиваемым через AdaIN, и даёт много выходов на один вход.

На этой странице 20

Заметка о CycleGAN закончилась двумя ограничениями перевода между двумя доменами. Чтобы охватить kk доменов, нужна отдельная модель для каждой пары, всего k(k−1)k(k-1) генераторов, и каждый из них учится на изображениях только двух доменов. Кроме того, каждый генератор детерминирован: у лошади ровно один вариант в виде зебры. StarGAN (Choi et al., 2018) снимает первое ограничение. Один генератор получает целевой домен на вход, один дискриминатор вдобавок говорит, к какому домену относится изображение, а цикловая функция потерь сохраняется: на обратном пути целевым доменом служит исходный. StarGAN v2 (Choi et al., 2020) снимает второе ограничение. Цель — уже не фиксированная метка, а код стиля (style code), взятый из выученного пространства стилей этого домена, поэтому у одного входного изображения много переводов.

Две модели, одна история. StarGAN отвечает на запрос «переведи в такую комбинацию меток» одним детерминированным генератором; StarGAN v2 — на запрос «переведи в этот домен, в таком стиле» с помощью отображающей сети, энкодера стиля и AdaIN. Обе сохраняют цикл назад к исходному изображению. Тому, кому нужны только метки нескольких доменов, достаточно дочитать до раздела «Один выход на изображение и домен» и перейти к ограничениям; разделы о StarGAN v2 — расширение для разнообразных переводов, управляемых стилем.

Обозначения. Домен (domain) — множество изображений с общим значением атрибута: светлые волосы, мужской пол, радостное выражение лица (Choi et al., 2018, раздел 1). xx — настоящее изображение, c′c' — его исходная метка домена; cc — целевая метка. Метки — векторы из ncn_c элементов: бинарные для атрибутов, которые могут встречаться вместе (цвет волос, пол, возраст), и в виде one-hot-векторов для взаимоисключающих категорий (выражения лица). GG — генератор, DD — дискриминатор. Для StarGAN v2 yy — исходный домен xx, y~\tilde y — целевой домен, z∼N(0,I)z \sim \mathcal N(0, I) — латентный код, ss — код стиля; FF — отображающая сеть (mapping network; это не обратный генератор из CycleGAN), EE — энкодер стиля (style encoder). Как и в заметке о CycleGAN, ∥a−b∥1\|a - b\|_1 — сумма модулей попиксельных разностей, которую реализации усредняют по пикселям.

Почему не один CycleGAN на каждую пару?#

Модель перевода между kk доменами должна обслуживать каждую упорядоченную пару доменов (i,j)(i, j), то есть k(k−1)k(k-1) направлений. CycleGAN обучает оба направления пары вместе, по генератору на каждое, поэтому нужно k(k−1)/2k(k-1)/2 моделей с k(k−1)k(k-1) генераторами и столькими же дискриминаторами. Четырём доменам нужно 12 генераторов, восьми выражениям лица из набора данных RaFD — 56. Новый домен добавляет kk пар, то есть 2k2k генераторов. Число моделей — не единственная цена. Каждый генератор учится на изображениях двух доменов, хотя большая часть того, что ему нужно, — форма лица или текстура кожи — общая для всех доменов (Choi et al., 2018, раздел 1 и рисунок 2).

StarGAN делает цель входом. Его генератор принимает изображение и целевую метку и возвращает перевод G(x,c)G(x, c). При обучении cc выбирается случайно, поэтому одна и та же сеть учит все направления, а при тестировании можно запросить любую метку. Это условный GAN, в котором место шума занимает изображение. Дискриминатор тоже общий: помимо ответа «настоящее или подделка» он предсказывает домен своего входа, D:x↦{Dsrc(x), Dcls(x)}D: x \mapsto \{D_{\mathrm{src}}(x),\, D_{\mathrm{cls}}(x)\}.

Как генератор читает метку#

На CelebA метка состоит из пяти бинарных элементов: чёрные, светлые и каштановые волосы, мужчина, молодой. На RaFD это one-hot-вектор по восьми выражениям лица. Генератор копирует каждый элемент в постоянную карту h×wh \times w и конкатенирует эти карты с тремя цветовыми каналами, так что его первый слой видит тензор h×w×(3+nc)h \times w \times (3 + n_c) (Choi et al., 2018, рисунок 3 и таблица 4).

Остальное — по сути генератор CycleGAN для разрешения 128×128128 \times 128, но с ядрами 4×44 \times 4 при понижении и повышении разрешения: свёртка 7×77 \times 7, две свёртки с шагом (stride) 2, шесть остаточных блоков (residual blocks), две транспонированные свёртки (transposed convolutions) с шагом 2 и свёртка 7×77 \times 7 с tanh⁡\tanh; после каждого слоя, кроме последнего, стоит нормализация по экземпляру (instance normalization). У генератора 8.43 млн параметров. Каждый элемент метки добавляет к первой свёртке 64⋅7⋅7=313664 \cdot 7 \cdot 7 = 3136 весов, и больше ничто в генераторе не зависит от числа доменов.

Дискриминатор: настоящее или подделка и какой домен#

Дискриминатор — это шесть свёрток 4×44 \times 4 с шагом 2 и LeakyReLU (наклон 0.01) без нормализации, а за ними две головы (heads) на одних и тех же признаках (Choi et al., 2018, таблица 5). DsrcD_{\mathrm{src}}, свёртка 3×33 \times 3, оценивает реалистичность; для входа 128×128128 \times 128 она выдаёт карту 2×22 \times 2 на манер PatchGAN, хотя каждое из четырёх значений зависит от всего изображения. DclsD_{\mathrm{cls}} — свёртка, ядро которой покрывает всю карту признаков 2×22 \times 2, — выдаёт по одному логиту на каждый элемент метки. Дискриминатору принадлежат 44.76 млн из 53.19 млн параметров модели.

Вторая голова — вспомогательный классификатор (auxiliary classifier) из AC-GAN (Odena, Olah and Shlens, 2017). Он входит в две функции потерь (Choi et al., 2018, формулы 2–3):

Lclsr=Ex,c′[−log⁡Dcls(c′∣x)],Lclsf=Ex,c[−log⁡Dcls(c∣G(x,c))].\begin{aligned} \mathcal L^{r}_{\mathrm{cls}} &= \mathbb E_{x, c'}\big[-\log D_{\mathrm{cls}}(c' \mid x)\big],\\ \mathcal L^{f}_{\mathrm{cls}} &= \mathbb E_{x, c}\big[-\log D_{\mathrm{cls}}\big(c \mid G(x, c)\big)\big]. \end{aligned}

Первую минимизирует DD: на настоящих изображениях он учится предсказывать их истинные метки. Вторую минимизирует GG: переведённое изображение должно классифицироваться как изображение целевого домена. На подделках классификатор не учится никогда. Он обучается только на настоящих изображениях, поэтому кодирует то, как домены выглядят в данных, и генератор получает награду за то, что воспроизводит именно это.

Что означает Dcls(c∣x)D_{\mathrm{cls}}(c \mid x), зависит от метки. Для метки в виде one-hot-вектора это вероятность целевого класса после softmax, и −log⁡-\log от неё — кросс-энтропия. Элементы бинарного вектора атрибутов могут встречаться вместе, поэтому DclsD_{\mathrm{cls}} даёт каждому атрибуту собственную сигмоиду и считает атрибуты независимыми при данном изображении. Тогда Dcls(c∣x)=∏iσ(ℓi)ci(1−σ(ℓi))1−ciD_{\mathrm{cls}}(c \mid x) = \prod_i \sigma(\ell_i)^{c_i}\big(1 - \sigma(\ell_i)\big)^{1 - c_i} для логитов ℓi\ell_i, а −log⁡Dcls(c∣x)-\log D_{\mathrm{cls}}(c \mid x) — сумма бинарных кросс-энтропий (binary cross-entropy); именно её вычисляет для CelebA реализация авторов (Choi, 2018).

Разобранный пример: классификация подделки#

Возьмём игрушечные логиты, которые DclsD_{\mathrm{cls}} мог бы выдать для переведённого лица с целью c=(0,1,0,1,1)c = (0, 1, 0, 1, 1): светлые волосы, мужчина, молодой. Каждый атрибут вносит слагаемое −[cilog⁡σ(ℓi)+(1−ci)log⁡(1−σ(ℓi))]-\big[c_i \log \sigma(\ell_i) + (1 - c_i)\log\big(1 - \sigma(\ell_i)\big)\big]:

чёрныесветлыекаштановыемужчинамолодой
цель cic_i01011
логит ℓi\ell_i−2.01.5−1.00.52.0
σ(ℓi)\sigma(\ell_i)0.1190.8180.2690.6220.881
слагаемое функции потерь0.1270.2010.3130.4740.127

Сумма равна 1.243=−log⁡0.2891.243 = -\log 0.289: классификатор приписывает полной целевой метке вероятность 0.289. Наибольшее слагаемое — пол, в котором классификатор уверен меньше всего. Если бы генератор проигнорировал элементы метки, отвечающие за волосы, и оставил волосы чёрными, логиты чёрных и светлых волос могли бы поменяться местами и стать 1.51.5 и −2.0-2.0, и функция потерь выросла бы до 4.7434.743. Градиент Lclsf\mathcal L^{f}_{\mathrm{cls}} проходит через классификатор в GG и подталкивает волосы к светлому цвету.

Состязательная функция потерь и обратный путь#

Состязательную функцию потерь сначала записывают как стандартную функцию ценности (value function) GAN, Exlog⁡Dsrc(x)+Ex,clog⁡(1−Dsrc(G(x,c)))\mathbb E_x \log D_{\mathrm{src}}(x) + \mathbb E_{x, c} \log\big(1 - D_{\mathrm{src}}(G(x, c))\big), а затем для устойчивости обучения заменяют целевой функцией WGAN-GP (Choi et al., 2018, формула 8):

Ladv=Ex[Dsrc(x)]−Ex,c[Dsrc(G(x,c))]−λgp Ex^[(∥∇x^Dsrc(x^)∥2−1)2],\begin{aligned} \mathcal L_{\mathrm{adv}} = {}& \mathbb E_x\big[D_{\mathrm{src}}(x)\big] - \mathbb E_{x, c}\big[D_{\mathrm{src}}(G(x, c))\big]\\ &- \lambda_{\mathrm{gp}}\, \mathbb E_{\hat x}\Big[\big(\|\nabla_{\hat x} D_{\mathrm{src}}(\hat x)\|_2 - 1\big)^2\Big], \end{aligned}

где x^\hat x берётся на отрезках между настоящими и переведёнными изображениями, а λgp=10\lambda_{\mathrm{gp}} = 10. DsrcD_{\mathrm{src}} — критик с вещественным выходом. Дискриминатор максимизирует Ladv\mathcal L_{\mathrm{adv}}, а генератор минимизирует, но в функцию потерь генератора входит только второе слагаемое: штраф вычисляется в интерполированных точках, зависящих от G(x,c)G(x, c), и по нему обучается только дискриминатор.

Ни Ladv\mathcal L_{\mathrm{adv}}, ни Lclsf\mathcal L^{f}_{\mathrm{cls}} не упоминают вход: обеим удовлетворяет любое реалистичное изображение домена cc, каким бы ни был xx. С этой проблемой CycleGAN столкнулся при одной лишь состязательной функции потерь, и StarGAN применяет то же средство — функцию потерь цикловой согласованности (cycle-consistency loss; Choi et al., 2018, формула 4):

Lrec=Ex,c,c′ ∥x−G(G(x,c), c′)∥1.\mathcal L_{\mathrm{rec}} = \mathbb E_{x, c, c'}\, \big\|x - G\big(G(x, c),\, c'\big)\big\|_1 .

Обратный путь — тот же генератор с исходной меткой c′c'. Второй сети, которая отменяла бы действие первой, нет: обратить перевод — значит просто выполнить ещё один перевод. Функции потерь тождественного отображения у StarGAN нет.

Полная целевая функция#

Два игрока минимизируют разные целевые функции (Choi et al., 2018, формулы 5–6):

LD=−Ladv+λcls Lclsr,LG=Ladv+λcls Lclsf+λrec Lrec,\begin{aligned} \mathcal L_D &= -\mathcal L_{\mathrm{adv}} + \lambda_{\mathrm{cls}}\, \mathcal L^{r}_{\mathrm{cls}},\\ \mathcal L_G &= \mathcal L_{\mathrm{adv}} + \lambda_{\mathrm{cls}}\, \mathcal L^{f}_{\mathrm{cls}} + \lambda_{\mathrm{rec}}\, \mathcal L_{\mathrm{rec}}, \end{aligned}

с λcls=1\lambda_{\mathrm{cls}} = 1 и λrec=10\lambda_{\mathrm{rec}} = 10 во всех экспериментах. Это не одна минимаксная функция: у каждого игрока своё слагаемое классификации, и каждый его минимизирует. Обучение использует Adam с шагом обучения (learning rate) 10−410^{-4} и betas (0.5,0.999)(0.5, 0.999), пять обновлений критика на одно обновление генератора, как в WGAN-GP, размер батча 16 и случайные горизонтальные отражения. На CelebA (202 599 лиц с 40 бинарными атрибутами, обрезанных с 178×218178 \times 218 до 178×178178 \times 178 и уменьшенных до 128×128128 \times 128; 2000 отложены для теста) шаг обучения постоянен первые 10 эпох и линейно убывает до нуля за следующие 10 (разделы 5.2–5.3). Реализация авторов выбирает целевые метки, перемешивая метки батча, так что каждая запрошенная метка — комбинация, которая встречается в данных (Choi, 2018).

Рисунок

Один шаг обучения StarGAN: перевести, обмануть D, вернуться

Поток данных StarGANВерхний ряд: x, генератор G с целевой меткой c снизу, подделка G(x, c), снова G с исходной меткой c′, реконструкция и пунктирная стрелка восстановления к x. Внизу два дискриминатора D: под x для настоящего изображения и под подделкой.xнастоящее, c′G01011целевая c(размножена, конкатенирована)G(x, c)подделка, домен cDDsrc: значение ↑ (для G)Dcls → cG10001исходная c′G(G(x, c), c′)реконструкциявосстановление: ‖x − G(G(x, c), c′)‖₁DDsrc: x ↑, подделка ↓, + GPDcls(x) → c′1234Поток данных StarGANСверху вниз: x, генератор G с целевой меткой c, подделка G(x, c), снова G с исходной меткой c′ и реконструкция; пунктирная стрелка ведёт от реконструкции к x. Справа дискриминатор D для x и для подделки.xнастоящее, c′G01011целевая cG(x, c)подделка, cDDsrc: значение ↑Dcls → cG10001исходная c′G(G(x, c), c′)реконструкциявосст.: ‖x − G(G(x, c), c′)‖₁DDsrc: x ↑, подделка ↓Dcls(x) → c′1234
Зелёные — входы (настоящее изображение и метки), красные — сгенерированные изображения, жёлтый — дискриминатор. Метки CelebA из пяти элементов (чёрные, светлые, каштановые волосы, мужчина, молодой): на входе молодая женщина с чёрными волосами, c′ = (1, 0, 0, 0, 1), цель — светлые волосы, мужчина, молодой, c = (0, 1, 0, 1, 1). Генератор видит изображение и размноженную метку как один тензор 128 × 128 × 8 (1). Критик D_src оценивает подделку, а классификатор D_cls должен найти в ней целевую метку (2). Тот же генератор с меткой c′ должен вернуть вход; эту потерю взвешивает λ_rec = 10 (3). В своём шаге дискриминатор ставит настоящие изображения выше подделок со штрафом на градиент (λ_gp = 10) и учится классифицировать настоящие изображения (4); λ_cls = 1.
  1. Перевести. Генератор получает настоящее изображение xx и случайную целевую метку cc, размноженную в постоянные карты и конкатенированную с цветовыми каналами, и выдаёт G(x,c)G(x, c).
  2. Обмануть дискриминатор. Критик DsrcD_{\mathrm{src}} оценивает подделку, и генератор стремится к высокому значению. Классификатор DclsD_{\mathrm{cls}} должен отнести подделку к cc — это Lclsf\mathcal L^{f}_{\mathrm{cls}}.
  3. Вернуться. Тот же генератор переводит подделку обратно с исходной меткой c′c', и Lrec=∥x−G(G(x,c),c′)∥1\mathcal L_{\mathrm{rec}} = \|x - G(G(x, c), c')\|_1 требует получить вход.
  4. Обучить дискриминатор. На настоящих изображениях и подделках критик учится ставить настоящим изображениям значения выше, чем подделкам, со штрафом на градиент (gradient penalty); только на настоящих изображениях классификатор учит исходную метку c′c' — это Lclsr\mathcal L^{r}_{\mathrm{cls}}.

Обучение на нескольких наборах данных: вектор-маска#

В CelebA размечены цвет волос, пол и возраст; в RaFD (4824 изображения 67 человек, каждый из которых показывает восемь выражений) — выражения лица. Модель, обученная на обоих наборах, могла бы придавать лицам из CelebA выражения, выученные на RaFD. Препятствие — функция потерь реконструкции: ей нужна полная исходная метка c′c', а каждый набор данных знает только свою её часть (Choi et al., 2018, раздел 3.2).

StarGAN дописывает к метке вектор-маску (mask vector) mm — one-hot-вектор по nn наборам данных, который указывает, какая часть метки известна, — и обнуляет неизвестные части (формула 7):

c~=[ c1,…,cn,m ].\tilde c = [\,c_1, \dots, c_n, m\,].

Для CelebA и RaFD объединённая метка состоит из 5+8+2=155 + 8 + 2 = 15 элементов. Молодая блондинка из CelebA — это (0,1,0,0,1∣0,…,0∣1,0)(0, 1, 0, 0, 1 \mid 0, \dots, 0 \mid 1, 0); запрос «сделай её радостной» — (0,0,0,0,0∣(0, 0, 0, 0, 0 \mid one-hot-вектор радости ∣0,1)\mid 0, 1). Генератор не меняется, кроме ширины входа. Классификатор предсказывает все 5+8=135 + 8 = 13 меток, но на батче из одного набора данных в Lclsr\mathcal L^{r}_{\mathrm{cls}} и Lclsf\mathcal L^{f}_{\mathrm{cls}} входят только выходы для меток этого набора, а обучение чередует наборы данных.

Совместно обученная модель придаёт лицам из CelebA более чёткие выражения, чем модель, обученная только на RaFD, которая не видит ни одного изображения CelebA (раздел 5.6, рисунок 6). Маска используется так, как задумано. Если подать метку выражения с неверной маской [1,0][1, 0], модель игнорирует выражение, читает нулевую часть CelebA как «не молодой» и старит лицо (рисунок 7).

Что даёт один генератор#

  • Качество. В опросе пользователей на CelebA, где StarGAN сравнивали с DIAT, CycleGAN и IcGAN, StarGAN получил 66.2% голосов за лучший перевод цвета волос, 39.1% — за лучший перевод пола и 70.6% — возраста (Choi et al., 2018, таблица 1).
  • Верные домены. На RaFD при переводе нейтральных лиц в семь других выражений классификатор выражений ResNet-18, который ошибается на 0.45% настоящих тестовых изображений, ошибается на 2.12% переводов StarGAN против 5.99% у CycleGAN, 4.10% у DIAT и 8.07% у IcGAN (таблица 3).
  • Размер. Те же семь переводов требуют 53.2 млн параметров у StarGAN и 52.6M×1452.6\text{M} \times 14 у CycleGAN, примерно в 14 раз больше (таблица 3). Таблицы архитектуры дают 8.43 млн для генератора и 44.76 млн для дискриминатора, всего 53.19 млн.

Авторы объясняют качество многозадачным обучением (multi-task learning): модель, обученная на двух выражениях RaFD, видит около 1000 изображений, StarGAN — около 4000, и выученные им признаки служат всем направлениям (раздел 5.5).

Один выход на изображение и домен#

G(x,c)G(x, c) — функция: одно и то же изображение с одной и той же меткой всегда даёт один и тот же перевод. А домен вмещает много вариантов внешности. «Женщина» — это любая причёска и любой макияж, и StarGAN выбирает для каждого входа один из них. Авторы прямо говорят об этом в следующей статье: генератор получает фиксированную метку и поэтому «при данном исходном изображении неизбежно выдаёт один и тот же выход для каждого домена» (Choi et al., 2020, раздел 1). На CelebA-HQ StarGAN меняет пол лица лишь локально, нанося макияж (раздел 3.1, рисунок 3a).

Очевидное решение — дать генератору ещё и шум. Авторы StarGAN v2 попробовали это: подать в GG латентный код zz вместе с доменом и потребовать, чтобы энкодер восстанавливал его, ∥z−E(G(x,z,y))∥1\|z - E(G(x, z, y))\|_1. Выходы стали разнообразными, но коды никак не были привязаны к доменам, поэтому выучили вариации, общие для всех доменов, например цвет, а не присущие отдельному домену, например причёску (раздел 3.1). Сработало другое решение: сначала отобразить шум в стиль конкретного домена.

StarGAN v2: код стиля вместо метки#

Четыре сети#

В StarGAN v2 четыре сети (Choi et al., 2020, раздел 2.1 и приложение E):

  • генератор G(x,s)G(x, s) переводит xx в изображение, отражающее код стиля s∈R64s \in \mathbb R^{64}. Метку домена он не получает: код стиля уже принадлежит домену;
  • отображающая сеть FF превращает латентный код z∈R16z \in \mathbb R^{16}, z∼N(0,I)z \sim \mathcal N(0, I), в код стиля выбранного домена, s=Fy(z)s = F_y(z). Это MLP с четырьмя общими линейными слоями ширины 512 и, для каждого из kk доменов, ветвью ещё из четырёх слоёв;
  • энкодер стиля EE извлекает код стиля изображения домена yy, s=Ey(x)s = E_y(x): шесть общих остаточных блоков и по одной линейной выходной голове на домен;
  • дискриминатор DD устроен так же — та же общая часть и по одному выходу на домен. Dy(x)D_y(x) говорит, является ли xx настоящим изображением домена yy.

Два источника стиля дают два способа перевода. По латентному коду (latent-guided): сэмплируем zz и берём s=Fy~(z)s = F_{\tilde y}(z); каждый zz даёт другой выход. По образцу (reference-guided): берём настоящее изображение xrefx_{\mathrm{ref}} целевого домена и используем s=Ey~(xref)s = E_{\tilde y}(x_{\mathrm{ref}}); выход перенимает стиль образца. Новый домен стоит одной ветви FF (0.82 млн параметров), линейной головы EE (32 832) и головы DD (513).

Как входит стиль: AdaIN#

Для канала ii карты признаков hh пусть μi\mu_i и σi2\sigma_i^2 — его среднее и дисперсия по пространственным позициям одного изображения, а ϵ\epsilon — малая константа (10−510^{-5} в InstanceNorm2d из PyTorch), которая не даёт делению обратиться в бесконечность для постоянного канала. Адаптивная нормализация по экземпляру (adaptive instance normalization, AdaIN) заменяет их значениями, вычисленными по стилю:

AdaIN(h,s)i=γi(s) hi−μiσi2+ϵ+βi(s),\mathrm{AdaIN}(h, s)_i = \gamma_i(s)\, \frac{h_i - \mu_i}{\sqrt{\sigma_i^2 + \epsilon}} + \beta_i(s),

где γ(s)\gamma(s) и β(s)\beta(s) — выученные аффинные функции ss, свои в каждом слое AdaIN. Масштаб γi(s)\gamma_i(s) — выученное число, а не стандартное отклонение: ничто не держит его положительным, и отрицательное значение переворачивает канал, давая на выходе стандартное отклонение ∣γi∣\lvert\gamma_i\rvert. Все их смещения инициализируются нулём, кроме смещения масштаба γ\gamma, которое начинается с единицы (Choi et al., 2020, приложения B и E); официальный код записывает масштаб как 1+γ(s)1 + \gamma(s) с нулевым смещением, что равносильно (Clova AI Research, 2020). AdaIN пришла из переноса стиля, где γ\gamma и β\beta были стандартным отклонением и средним признаков изображения-стиля (Huang and Belongie, 2017, формула 8); StyleGAN стал вычислять их по выученному вектору стиля (Karras, Laine and Aila, 2019). В генераторе StarGAN v2 блоки понижения разрешения и первые два блока узкого места (bottleneck) используют обычную нормализацию по экземпляру; последние два блока узкого места и все блоки повышения разрешения используют AdaIN, и код стиля входит в каждый из них.

Разобранный пример (игрушечные числа). Канал содержит h=(1,2,3,6)h = (1, 2, 3, 6) в четырёх позициях. Его среднее равно 33, стандартное отклонение — 3.5≈1.871\sqrt{3.5} \approx 1.871, поэтому нормированные значения равны (−1.069,−0.535,0,1.604)(-1.069, -0.535, 0, 1.604); ϵ=10−5\epsilon = 10^{-5} меняет их лишь в шестом знаке после точки. Стиль, дающий γ=0.5\gamma = 0.5 и β=2\beta = 2, превращает их в (1.465,1.733,2.000,2.802)(1.465, 1.733, 2.000, 2.802), среднее которых ровно 22, а стандартное отклонение ровно 0.50.5. Вход 10h−710h - 7 дал бы те же нормированные значения: AdaIN отбрасывает входящие среднее и масштаб каждого канала и навязывает те, что выбрал стиль. Стиль действует после нормализации, поэтому, в отличие от конкатенированной метки StarGAN, нормализация не может его стереть.

Одна голова дискриминатора на домен#

Дискриминатор StarGAN отвечал двумя головами на два вопроса: настоящее ли изображение и к какому домену оно относится. Дискриминатор StarGAN v2 задаёт по одному вопросу на домен: настоящее ли это изображение домена yy? Каждая голова DyD_y — бинарный классификатор «настоящее или подделка», и функции потерь классификации нет. Такой многозадачный дискриминатор (multi-task discriminator; Mescheder, Geiger and Nowozin, 2018; Liu et al., 2019) позволяет генератору менять глобальную структуру изображения, а не только локальные детали (Choi et al., 2020, раздел 3.1).

Функции потерь#

Пусть xx — настоящее изображение домена yy; выберем целевой домен y~\tilde y и латентный код zz, а целевой стиль положим равным s=Fy~(z)s = F_{\tilde y}(z) (Choi et al., 2020, раздел 2.2). Статья обозначает целевые величины тильдой, s~\tilde s; мы оставляем тильду только у домена.

Состязательная функция потерь. Перевод оценивает голова целевого домена (формула 1):

Ladv=Ex,y[log⁡Dy(x)]+Ex,y~,z[log⁡(1−Dy~(G(x,s)))],\mathcal L_{\mathrm{adv}} = \mathbb E_{x, y}\big[\log D_y(x)\big] + \mathbb E_{x, \tilde y, z}\big[\log\big(1 - D_{\tilde y}(G(x, s))\big)\big],

где DyD_y здесь обозначает вероятность — сигмоиду от логита головы. На практике генератор использует ненасыщающуюся функцию потерь (non-saturating loss) −log⁡Dy~(G(x,s))-\log D_{\tilde y}(G(x, s)) (приложение B).

Восстановление стиля (style reconstruction). Генератор должен использовать код стиля, поэтому энкодер стиля должен уметь прочитать его обратно по выходу (формула 2):

Lsty=Ex,y~,z ∥s−Ey~(G(x,s))∥1.\mathcal L_{\mathrm{sty}} = \mathbb E_{x, \tilde y, z}\, \big\|s - E_{\tilde y}\big(G(x, s)\big)\big\|_1 .

Диверсификация стилей (style diversification). Второй латентный код z2z_2 даёт второй код стиля s2=Fy~(z2)s_2 = F_{\tilde y}(z_2), и генератор получает награду за то, что два выхода различаются (формула 3):

Lds=Ex,y~,z,z2 ∥G(x,s)−G(x,s2)∥1.\mathcal L_{\mathrm{ds}} = \mathbb E_{x, \tilde y, z, z_2}\, \big\|G(x, s) - G(x, s_2)\big\|_1 .

Это слагаемое максимизируется. В более ранних работах его делили на расстояние между латентными кодами, ∥z−z2∥1\|z - z_2\|_1; когда два кода близки, отношение становится большим, а его градиенты — неустойчивыми, поэтому StarGAN v2 убирает знаменатель (раздел 2.2). Сверху слагаемое не ограничено, и его вес в ходе обучения линейно уменьшают до нуля (приложение B).

Цикловая согласованность. Выход должен вести обратно ко входу, если дать генератору собственный стиль входа (формула 4):

Lcyc=Ex,y,y~,z ∥x−G(G(x,s), s^)∥1,s^=Ey(x).\mathcal L_{\mathrm{cyc}} = \mathbb E_{x, y, \tilde y, z}\, \big\|x - G\big(G(x, s),\, \hat s\big)\big\|_1, \qquad \hat s = E_y(x).

В StarGAN обратный путь использовал исходную метку c′c', которая говорит только о том, в какой домен вернуться. Здесь он использует оценённый стиль s^\hat s самого xx, поэтому возврат должен восстановить конкретную внешность входа.

Полная целевая функция. Генератор, отображающая сеть и энкодер стиля играют против дискриминатора (формула 5):

min⁡G,F,E  max⁡D  Ladv+λsty Lsty−λds Lds+λcyc Lcyc,\min_{G, F, E}\; \max_D\; \mathcal L_{\mathrm{adv}} + \lambda_{\mathrm{sty}}\, \mathcal L_{\mathrm{sty}} - \lambda_{\mathrm{ds}}\, \mathcal L_{\mathrm{ds}} + \lambda_{\mathrm{cyc}}\, \mathcal L_{\mathrm{cyc}},

с λsty=λcyc=1\lambda_{\mathrm{sty}} = \lambda_{\mathrm{cyc}} = 1 и λds=1\lambda_{\mathrm{ds}} = 1 на CelebA-HQ, 22 на AFHQ (приложение B). Та же целевая функция обучается и со стилями по образцу, s=Ey~(xref)s = E_{\tilde y}(x_{\mathrm{ref}}), вместо Fy~(z)F_{\tilde y}(z).

Рисунок

Один шаг обучения StarGAN v2: стиль, перевод и три проверки

Поток данных StarGAN v2Ряд 1: z, отображающая сеть F, код стиля s и голова дискриминатора D_ỹ. Ряд 2: x, генератор G, выход G(x, s), энкодер стиля E и восстановленный стиль. Ряд 3: стиль входа ŝ = E_y(x), снова G и реконструкция. Ряд 4: второй код s₂, G и второй выход, пунктирная двусторонняя стрелка к первому выходу.xдомен yновое: код стиля вместо меткиzFветвь ỹs = Fỹ(z)AdaINGG(x, s)Dỹнастоящееиз домена ỹ?EEỹ(G(x, s))стиль: ‖s − Eỹ(G(x, s))‖₁Eŝ = Ey(x)GG(G(x, s), ŝ)цикл: ‖x − G(G(x, s), ŝ)‖₁s₂ = Fỹ(z₂)xGG(x, s₂)разнообразие ↑: ‖G(x, s) − G(x, s₂)‖₁12345Поток данных StarGAN v2Сверху вниз: z, F и код стиля s; x, G, выход G(x, s) и голова D_ỹ; энкодер стиля E и восстановленный стиль; стиль входа ŝ, G и реконструкция; второй код s₂, G и второй выход.xдомен yновоеzFветвь ỹs = Fỹ(z)AdaINGG(x, s)Dỹнастоящее для ỹ?EEỹ(G(x, s))стиль: ‖s − Eỹ(G(x, s))‖₁ŝ = Ey(x)G(x, s)GG(G(x, s), ŝ)цикл: ‖x − G(G(x, s), ŝ)‖₁s₂ = Fỹ(z₂)xGG(x, s₂)G(x, s)разнообразие ↑: ‖G(x, s) − G(x, s₂)‖₁12345
Зелёные — входы (изображение x и латентные коды), синие — коды стиля, красные — сгенерированные изображения, жёлтый — дискриминатор. Жёлтая пунктирная рамка отмечает то, что заменило метку StarGAN: код стиля s из 64 чисел, который отображающая сеть строит из z (16 чисел) для целевого домена ỹ (1). G встраивает стиль через AdaIN, а голова дискриминатора домена ỹ судит результат (2). Энкодер стиля должен прочитать s по выходу (3). Со стилем самого входа ŝ = E_y(x) генератор должен вернуться к x (4). Второй код s₂ даёт второй выход, и генератор получает награду за расстояние между ними (5). Веса: λ_sty = λ_cyc = 1, λ_ds = 1 на CelebA-HQ.
  1. Стиль. Отображающая сеть превращает zz в код стиля s=Fy~(z)s = F_{\tilde y}(z) для случайного целевого домена y~\tilde y; в шагах по образцу его вместо этого считывает с изображения-образца энкодер стиля.
  2. Перевод и проверка. Генератор встраивает ss через AdaIN и выдаёт G(x,s)G(x, s); голова Dy~D_{\tilde y} решает, настоящее ли это изображение домена y~\tilde y.
  3. Восстановление стиля. Энкодер стиля должен восстановить ss по выходу: Lsty\mathcal L_{\mathrm{sty}}.
  4. Цикл. Со стилем самого входа s^=Ey(x)\hat s = E_y(x) генератор должен перевести выход обратно в xx: Lcyc\mathcal L_{\mathrm{cyc}}.
  5. Разнообразие. Второй код s2s_2 даёт второй выход, и Lds\mathcal L_{\mathrm{ds}} поощряет расстояние между двумя выходами.

R1: штраф только на настоящих изображениях#

StarGAN использовал WGAN-GP. StarGAN v2 использует ненасыщающуюся функцию потерь и добавляет к функции потерь дискриминатора штраф R1 (R1 penalty; Mescheder, Geiger and Nowozin, 2018, раздел 4.1, формула 9; Choi et al., 2020, приложение B):

R1=γ2 Ex∼P ∥∇xD(x)∥22,γ=1,R_1 = \frac{\gamma}{2}\, \mathbb E_{x \sim P}\, \big\|\nabla_x D(x)\big\|_2^2, \qquad \gamma = 1,

где D(x)D(x) — логит дискриминатора (для StarGAN v2 — логит головы DyD_y для настоящего изображения домена yy). Штраф действует только на настоящих изображениях и тянет градиент к нулю, а не к норме 1 на интерполированных точках, как в WGAN-GP. Обоснование касается конца обучения. Когда генератор воспроизводит данные, а дискриминатор на них постоянен, дискриминатор с ненулевым градиентом поперёк данных всё ещё мог бы столкнуть генератор с данных; R1 делает такой градиент дорогим. Mescheder et al. доказывают, что обучение GAN со штрафами такого вида с центром в нуле (zero-centered) локально сходится там, где обучение без регуляризации может не сходиться.

Разобранный пример. У дискриминатора с линейным логитом D(x)=w⊤x+bD(x) = w^\top x + b и w=(0.6,−0.8,0)w = (0.6, -0.8, 0) градиент равен ∇xD=w\nabla_x D = w, а ∥w∥2=1\|w\|_2 = 1. Штраф WGAN-GP (∥w∥2−1)2(\|w\|_2 - 1)^2 равен 00: наклон в точности такой, какого требует WGAN-GP. R1 с γ=1\gamma = 1 равен 12∥w∥22=0.5\tfrac12 \|w\|_2^2 = 0.5: он требует, чтобы дискриминатор был плоским на данных.

Обучение. Размер батча 8, 100 000 итераций (около трёх суток на одной V100), изображения 256×256256 \times 256. Adam с betas (0,0.99)(0, 0.99); шаг обучения 10−410^{-4} для GG, DD и EE и 10−610^{-6} для FF. λds\lambda_{\mathrm{ds}} линейно убывает до нуля за 100 000 итераций. При оценке качества используется экспоненциальное скользящее среднее (EMA) весов каждой сети, кроме DD (Choi et al., 2020, приложение B).

Что даёт каждая часть#

StarGAN v2 строили, добавляя к StarGAN по одному изменению и измеряя каждый шаг на CelebA-HQ, разбитом на домены «мужчины» и «женщины» (Choi et al., 2020, таблица 1). FID измеряет, насколько переводы далеки от настоящих изображений целевого домена (чем ниже, тем лучше); LPIPS здесь — среднее расстояние между выходами, сгенерированными для одного и того же входа (чем выше, тем разнообразнее).

КонфигурацияFIDLPIPS
A. StarGAN: WGAN-GP, вспомогательный классификатор, конкатенированная метка98.4–
B. + многозадачный дискриминатор91.4–
C. + штраф R1, AdaIN вместо конкатенации80.5–
D. + латентный код на входе GG, восстановление латентного кода32.30.312
E. + отображающая сеть и код стиля, восстановление стиля17.10.405
F. + диверсификация стилей: StarGAN v213.70.452

Конфигурации A–C дают один выход на вход, поэтому значения метрики разнообразия у них нет. Падение от C к D — не признак лучшей модели: D выдаёт десять выходов на вход там, где C выдаёт один, FID по большему числу сгенерированных изображений ниже, и авторы объясняют весь разрыв между C и D числом сэмплов (раздел 3.1). Это смещение FID из-за размера выборки на практике. Среди конфигураций с одинаковым числом выходов и код стиля (от D к E), и слагаемое разнообразия (от E к F) снижают FID и повышают LPIPS. Для сравнения: FID между обучающими и тестовыми изображениями CelebA-HQ равен 14.8. Это не нижняя граница: тестовая выборка мала, и значение StarGAN v2, 13.7, лежит ниже (таблица 2).

По сравнению с моделями для двух доменов, которые уже давали разнообразные выходы, — MUNIT, DRIT и MSGAN, каждая из которых обучается отдельно для каждой пары доменов, — у StarGAN v2 самый низкий FID при переводе по латентному коду: 13.7 против 31.4–52.1 на CelebA-HQ и 16.2 против 41.5–95.6 на AFHQ, наборе из 15 000 морд кошек, собак и диких животных (таблица 2). Его LPIPS — наивысший на CelebA-HQ (0.452), но на AFHQ у MUNIT (0.511) и MSGAN (0.517) значения выше, чем у StarGAN v2 (0.450). Авторы объясняют это паразитными артефактами в выходах этих моделей: артефакты делают выходы разными, и метрика разнообразия засчитывает их как разнообразие.

Как измеряют модели перевода#

Сравнения выше следуют фиксированному протоколу (Choi et al., 2020, приложение C):

  • FID для реалистичности. Каждое тестовое изображение исходного домена переводится в целевой домен с 10 случайными латентными кодами, и вычисляется FID между этими переводами и обучающими изображениями целевого домена. Это повторяется для каждой пары доменов, и результаты усредняются. При синтезе по образцу вместо латентных кодов берутся 10 случайных изображений-образцов целевого домена.
  • LPIPS для разнообразия. Каждое тестовое изображение получает 10 выходов от 10 случайных латентных кодов. Расстояния LPIPS по всем (102)=45\binom{10}{2} = 45 парам выходов усредняются, и результат усредняется по тестовым изображениям.

Каждое число отвечает на один вопрос и упускает другие. FID никогда не смотрит на вход, поэтому генератор, который игнорирует xx и выдаёт хорошие лица, получает хорошее значение. Метрика разнообразия поощряет различия любого рода, включая артефакты. Две дополнительные проверки покрывают то, что эти метрики упускают. Первая — домен: узнаёт ли классификатор, обученный на настоящих изображениях, целевой домен в выходе, как в эксперименте StarGAN на RaFD? Вторая — верность входу (faithfulness): сохраняет ли выход то, что не должно меняться, например позу и личность человека на входе? Расстояние между выходом и его собственным входом, такое как LPIPS, измеряет, насколько перевод изменил изображение, а это не реалистичность и не разнообразие. Тождественное отображение получает 0 — идеальное значение, — ничего не переводя. Честный отчёт приводит реалистичность, разнообразие, долю правильно определённых доменов (domain accuracy) и верность входу вместе.

Что считать доменом#

StarGAN и StarGAN v2 понимают метки по-разному. StarGAN принимает вектор атрибутов и может запросить любую их комбинацию, например светлые волосы, мужской пол и пожилой возраст одновременно. StarGAN v2 требует, чтобы каждое изображение принадлежало ровно одному домену: обучающие пары — это (x,y)(x, y) с единственным yy, а FyF_y, EyE_y и DyD_y — головы, индексированные им. Поэтому пересекающиеся атрибуты не являются доменами. В CelebA одно и то же лицо может быть одновременно мужским, молодым и улыбающимся, так что 40 атрибутов не могут служить 40 доменами StarGAN v2. Пригодное разбиение берёт один бинарный атрибут (мужчины и женщины, как для CelebA-HQ в статье), взаимоисключающие значения одного атрибута (чёрные, светлые и каштановые волосы, после удаления изображений, у которых нет ни одного из этих значений или их несколько) или произведения нескольких атрибутов (мужчина или женщина, молодой или пожилой — четыре домена).

Исследование пространства стилей#

Отображающая сеть, вслед за StyleGAN, делает пространство стилей каждого домена выученным преобразованием гауссовского распределения, а не самим гауссовским распределением, и авторы видят в этом одну из причин разнообразия выходов (Choi et al., 2020, раздел 4). Это пространство можно исследовать напрямую. Интерполяция между двумя кодами стиля Fy(z1)F_y(z_1) и Fy(z2)F_y(z_2) или между кодами двух изображений-образцов, с переводом одного и того же входа с каждым промежуточным кодом, показывает, плавно ли меняются выходы и какие атрибуты меняются; авторы показывают такие интерполяции в видео (приложение D). Интерполяция по zz и по ss даёт разные пути, потому что FF нелинейна. Коды стиля, извлечённые из многих настоящих изображений, можно спроецировать на плоскость, например методом главных компонент (PCA), и посмотреть, разделяются ли домены и соответствуют ли направления видимым атрибутам. Замена образцов внутри домена отделяет то, чем управляет код стиля (причёска, макияж, борода, возраст на CelebA-HQ), от того, что сохраняет вход (поза, личность).

Что изменилось#

CycleGANStarGANStarGAN v2
Сети для kk доменовk(k−1)k(k-1) генераторов и k(k−1)k(k-1) дискриминатороводин GG, один DDпо одной сети GG, FF, EE, DD
Условиенет: одно направление на генераторцелевая метка, размноженная и конкатенированнаякод стиля через AdaIN, из Fy~(z)F_{\tilde y}(z) или Ey~(xref)E_{\tilde y}(x_{\mathrm{ref}})
Дискриминаторпо одному на домен, PatchGAN 70×7070 \times 70общий: критик DsrcD_{\mathrm{src}} и классификатор DclsD_{\mathrm{cls}}по одной голове «настоящее/подделка» DyD_y на домен
Состязательная функция потерьнаименьшие квадратыWGAN-GP, λgp=10\lambda_{\mathrm{gp}} = 10ненасыщающаяся, R1 с γ=1\gamma = 1
Связь со входомдва цикла и функция потерь тождественного отображенияодин цикл с исходной меткой c′c', λrec=10\lambda_{\mathrm{rec}} = 10цикл со стилем входа Ey(x)E_y(x), λcyc=1\lambda_{\mathrm{cyc}} = 1
Выходов на вход и цельодинодинмного
Меткинет: две неразмеченные коллекциилюбая комбинация атрибутов; несколько наборов данных через вектор-маскуодин домен на изображение

Ограничения#

  • StarGAN детерминирован. Один выход на изображение и метку; к тому же метка, входящая через конкатенацию, склонна давать локальные правки, а не изменения структуры.
  • StarGAN v2 нужно разбиение. Каждое изображение должно принадлежать одному домену, а комбинации атрибутов приходится перечислять как отдельные домены. У вектора-маски StarGAN, объединяющего наборы данных с разными наборами меток, аналога нет.
  • Цикл проверяет восстановимость, а не смысл. Как и в CycleGAN, перевод может быть обратимым и всё же неверным или прятать то, что нужно для возврата, в сигналах, невидимых человеку.
  • Разнообразием приходится управлять. Слагаемое разнообразия не ограничено сверху и постепенно отключается в ходе обучения. Метрики разнообразия к тому же поощряют артефакты, как показывают результаты на AFHQ.
  • Стиль и содержание разделяют функции потерь, а не определение. Что попадёт в код стиля, зависит от данных: порода и шерсть на AFHQ; причёска, макияж, борода и даже возраст на CelebA-HQ.
  • Числа зависят от протокола. FID зависит от числа сгенерированных изображений, а расстояние до входа поощряет бездействие; сравнения честны только при одинаковом протоколе.

Итоги#

  • Один генератор G(x,c)G(x, c), получающий на вход целевую метку, заменяет k(k−1)k(k-1) генераторов попарных моделей и учится на изображениях всех доменов.
  • Дискриминатор StarGAN состоит из критика WGAN-GP DsrcD_{\mathrm{src}} и вспомогательного классификатора доменов DclsD_{\mathrm{cls}}. Классификатор обучается на настоящих изображениях (Lclsr\mathcal L^{r}_{\mathrm{cls}}), а генератор должен создавать подделки, которые классификатор относит к цели (Lclsf\mathcal L^{f}_{\mathrm{cls}}). Реконструкция с исходной меткой, ∥x−G(G(x,c),c′)∥1\|x - G(G(x, c), c')\|_1, привязывает выход ко входу; λcls=1\lambda_{\mathrm{cls}} = 1, λrec=10\lambda_{\mathrm{rec}} = 10, λgp=10\lambda_{\mathrm{gp}} = 10.
  • Вектор-маска отмечает, метки какого набора данных известны, так что одна модель обучается на CelebA и RaFD вместе.
  • StarGAN детерминирован. StarGAN v2 заменяет метку кодом стиля из отображающей сети (z→Fy(z)z \to F_y(z)) или энкодера стиля (Ey(xref)E_y(x_{\mathrm{ref}})), встраивает его через AdaIN, судит выходы дискриминатором с одной головой на домен и обучается с восстановлением стиля, диверсификацией стилей, циклом со стилем самого входа и штрафом R1.
  • Модели перевода измеряют FID для реалистичности и попарным LPIPS между выходами для разнообразия; доля правильно определённых доменов и верность входу требуют собственных проверок.

Ноутбук#

Этой заметке соответствуют два ноутбука из репозитория HSE-LAMBDA Deep Generative Models: ноутбук о StarGAN, излагающий теорию обеих версий, и ноутбук с заданием 02_hw_StarGAN.ipynb, который предлагает читателю реализовать, обучить и оценить StarGAN на CelebA (ячейки нумеруются с 1, считая все ячейки подряд, включая текстовые). README папки перечисляет статьи о StarGAN и StarGAN v2 рядом с материалами о CycleGAN.

Ноутбук о StarGAN не содержит кода; его единственная ячейка кода (ячейка 6) пуста.

  • Ячейки 1–2: введение. Pix2Pix и CycleGAN переводят между двумя доменами; StarGAN обобщает это на много доменов, а StarGAN v2 добавляет разнообразные выходы.
  • Ячейка 3: StarGAN. Подсчёт K(K−1)K(K-1), G(x,c)G(x, c), дискриминатор с двумя головами, Lclsr\mathcal L^{r}_{\mathrm{cls}}, Lclsf\mathcal L^{f}_{\mathrm{cls}} и Lrec\mathcal L_{\mathrm{rec}}, объединённая целевая функция, то, как StarGAN обобщает CycleGAN, и ограничение: один выход на вход и метку. Встроены рисунки 2 и 3 из статьи о StarGAN.
  • Ячейка 4: StarGAN v2. GG, FF, EE и DD; стили по латентному коду и по образцу; функции потерь — состязательная, восстановления стиля, разнообразия и цикловая — и полная целевая функция; улучшения по сравнению со StarGAN. Встроен рисунок 2 из статьи о StarGAN v2.
  • Ячейка 5: заключение.

Проблемы ноутбука о StarGAN:

  • Как входит метка. Ячейка 3 говорит, что метка подаётся «via channel-wise concatenation or AdaIN-like normalization in some variations». StarGAN размножает метку по пространству и конкатенирует её с входным изображением; AdaIN — механизм StarGAN v2.
  • Состязательная функция потерь и веса. Ячейка 3 называет состязательную функцию потерь «WGAN-GP or similar» и не приводит весов. StarGAN использует WGAN-GP с λgp=10\lambda_{\mathrm{gp}} = 10, а также λcls=1\lambda_{\mathrm{cls}} = 1, λrec=10\lambda_{\mathrm{rec}} = 10.
  • Одна целевая функция вместо двух. Ячейка 3 записывает min⁡Gmax⁡DLadv+λcls[Lclsr+Lclsf]+λrecLrec\min_G \max_D \mathcal L_{\mathrm{adv}} + \lambda_{\mathrm{cls}}[\mathcal L^{r}_{\mathrm{cls}} + \mathcal L^{f}_{\mathrm{cls}}] + \lambda_{\mathrm{rec}}\mathcal L_{\mathrm{rec}}. Дискриминатор минимизирует Lclsr\mathcal L^{r}_{\mathrm{cls}}, а не максимизирует, поэтому статья записывает две целевые функции, LD\mathcal L_D и LG\mathcal L_G, как в разделе «Полная целевая функция».
  • Дискриминатор StarGAN v2. Ячейка 4 описывает его как классифицирующий «real vs. fake and the domain label». У него по одному бинарному выходу «настоящее/подделка» на домен и нет функции потерь классификации; замена вспомогательного классификатора — конфигурация B абляционного исследования.
  • Состязательная функция потерь StarGAN v2. Ячейка 4 вводит «the non-saturating GAN loss», но записывает минимаксную функцию ценности и использует yy и для домена настоящего изображения, и для цели. В статье слагаемое для настоящих изображений использует исходный домен yy, а слагаемое для подделок — целевой y~\tilde y; ненасыщающаяся версия меняет только слагаемое генератора, на −log⁡Dy~(G(x,s))-\log D_{\tilde y}(G(x, s)).
  • Функция потерь разнообразия. Ячейка 4 говорит, что она «possibly normalized by ∥z1−z2∥\|z_1 - z_2\|». StarGAN v2 убирает этот знаменатель ради устойчивости и линейно уменьшает λds\lambda_{\mathrm{ds}} до нуля.
  • Цикловая функция потерь. Ячейка 4 использует стиль «Eorig(x)E_{\text{orig}}(x)». Это тот же энкодер стиля, считанный на голове исходного домена: s^=Ey(x)\hat s = E_y(x).
  • Недостающие части. В ячейке 4 нет штрафа R1 и весов функций потерь (λsty=λcyc=1\lambda_{\mathrm{sty}} = \lambda_{\mathrm{cyc}} = 1, λds=1\lambda_{\mathrm{ds}} = 1 или 22).

Ноутбук с заданием состоит из трёх этапов: данные, модель и обучение, оценка и анализ. Он загружает CelebA через CelebADataset из файла репозитория seminars/utils/datasets/celeba.py.

  • Ячейки 1–2: заголовок и цель — генерация лиц с заданными атрибутами из CelebA.
  • Ячейка 3: подготовка. Устанавливает lpips, добавляет ../../seminars/utils/ в sys.path, импортирует torch, LPIPS, преобразования torchvision, Munch, trange, matplotlib, numpy и CelebADataset и выбирает устройство (CUDA, Apple MPS или CPU).
  • Ячейка 4: данные. args.img_size = 256; изображения масштабируются так, чтобы короткая сторона стала равной 256, обрезаются по центру до 256×256256 \times 256 и нормализуются средним и стандартным отклонением ImageNet. Корень набора данных — ../../seminars/data/celeba; если данных нет, вспомогательный модуль заполняет его, скачивая CelebA и файл атрибутов с Google Drive. Размер батча 32, с перемешиванием; num_workers равен 0 на CUDA и 2 в остальных случаях, pin_memory включён только на CUDA.
  • Ячейка 5: args.num_domains = len(dataset.header) — число названий атрибутов в файле аннотаций, 40.
  • Ячейки 6–7: сетка 3×33 \times 3 случайных изображений, каждое из которых для показа отмасштабировано по своим минимуму и максимуму.
  • Ячейки 8–10: модель. Читатель выбирает StarGAN или StarGAN v2. Ячейка 10 готовит контейнер Munch с закомментированными полями generator, mapping_network, style_encoder и discriminator — четырьмя сетями StarGAN v2 под именами из реализации авторов.
  • Ячейки 11–12: обучение — пустая ячейка для кода читателя.
  • Ячейки 13–16: оценка. LPIPS() с базовой сетью (backbone) AlexNet по умолчанию. Ячейка 16 выполняет 100 итераций; на каждой она берёт три свежих батча x_real, x_ref, x_ref2 и равномерно случайные y_trg и y_org из num_domains, оставляет перевод x_fake читателю (заглушка с NotImplementedError), добавляет в список LPIPS между x_fake и x_real, печатает среднее и проверяет через assert, что оно меньше 1.3.
  • Ячейки 17–18: один выход. Под no_grad выполняется перевод по латентному коду: z∼N(0,I)z \sim \mathcal N(0, I) размера args.latent_dim, s_trg = mapping_network(z_trg, y_trg), x_fake = generator(x_real, s_trg) (вариант по образцу, style_encoder(x_ref2, y_trg), закомментирован), и выводится изображение второго элемента батча.
  • Ячейка 19: анализ. Читателю предлагается проанализировать латентное пространство и написать обзор возможных улучшений; разделы «Исследование пространства стилей» и «Ограничения» покрывают и то и другое.

Ни у одного из ноутбуков нет сохранённых выходов, поэтому они документируют процедуры, а не результаты; у ячеек 4 и 12 ноутбука с заданием есть счётчики выполнения, но нет выходов.

Проблемы ноутбука с заданием и его вспомогательного модуля:

  • Пути. Ноутбук лежит в homeworks/, на один уровень ниже корня репозитория, но ячейки 3 и 4 поднимаются на два уровня, к ../../seminars/utils/ и ../../seminars/data/celeba. Из homeworks/ правильные пути — ../seminars/utils/ и ../seminars/data/celeba.
  • Импорты. sys.path.append ставит папку вспомогательного модуля в конец списка, поэтому установленный пакет Hugging Face datasets затеняет папку datasets вспомогательного модуля, и from datasets.celeba import CelebADataset завершается ошибкой; sys.path.insert(0, ...) этого избегает. Вспомогательному модулю нужен ещё gdown, а ячейка 3 не устанавливает ни его, ни munch.
  • 40 атрибутов — не 40 доменов. Атрибуты CelebA пересекаются, поэтому они не могут быть доменами StarGAN v2, которому нужен один домен на изображение (см. «Что считать доменом»); StarGAN вместо этого использовал бы бинарный вектор из нескольких атрибутов. Вспомогательный модуль возвращает для каждого изображения словарь, элемент attributes которого содержит все 40 значений в виде ±1\pm 1 — в кодировке list_attr_celeba.txt; перед обучением метки нужно перевести в {0,1}\{0, 1\} или в индекс домена. Ячейка 16 их отбрасывает (x_real, _ = ...) и выбирает y_org случайно, так что «исходный домен» — не домен x_real.
  • Диапазон пикселей. Нормализация ImageNet переводит пиксели примерно в [−2.12,2.64][-2.12, 2.64], а не в [−1,1][-1, 1]. LPIPS ожидает входы в [−1,1][-1, 1]; генератор StarGAN заканчивается tanh⁡\tanh и не может выдать нормализованный диапазон; а ячейка 18 рисует выход генератора, не отменив нормализацию, поэтому imshow его обрезает. Normalize([0.5] * 3, [0.5] * 3) даёт [−1,1][-1, 1].
  • Разрешение. Выровненные изображения CelebA имеют размер 178×218178 \times 218, поэтому масштабирование короткой стороны до 256 увеличивает их примерно в 1.44 раза. StarGAN использовал обрезки 178×178178 \times 178, уменьшенные до 128×128128 \times 128; StarGAN v2 обучается на CelebA-HQ при разрешении 256×256256 \times 256.
  • Строка с LPIPS падает. lpips(x_fake, x_real) возвращает по одному значению на изображение, форма (B,1,1,1)(B, 1, 1, 1); .squeeze().item() вызывает ошибку при размере батча 32. Нужно .mean().item(). Кроме того, цикл выполняется без torch.no_grad() и eval().
  • Что измеряет метрика. LPIPS между переводом и его собственным входом измеряет, насколько перевод изменил изображение, а не реалистичность и не разнообразие; если вернуть вход без изменений, получится 0, и проверка будет пройдена. LPIPS в StarGAN v2 — среднее по парам выходов для одного и того же входа (см. «Как измеряют модели перевода»).
  • Ячейка 18 зависит от ячейки 16. Она использует batch_size, y_trg и x_real из последней итерации ячейки 16 и args.latent_dim, который не задаёт ни одна ячейка (в StarGAN v2 это 16).
  • Загрузка данных. next(iter(dataloader)) создаёт новый итератор трижды за шаг оценки, что медленно при работе с процессами-воркерами, а выбор 0 воркеров на CUDA и 2 в остальных случаях выглядит перепутанным.

Дальше#

StarGAN v2 даёт много стилей во многих доменах одним генератором, но это лишь один путь из нескольких. Следующая заметка проходит остальные: разделение каждого изображения на содержание и стиль (MUNIT), отказ от цикла в пользу контрастной функции потерь между фрагментами (CUT), генерация фотографии по карте меток (pix2pixHD, SPADE) и добавление правдоподобных деталей к маленькому изображению (SRGAN, ESRGAN).

Где посмотреть изображения#

Эти модели лучше всего судить по их сэмплам. В каждой строке указано, где их найти; номера рисунков относятся к указанной версии arXiv.

  • StarGAN (Choi et al., 2018; arXiv v3): лица CelebA, которым один генератор придаёт выражения из RaFD, — на рисунке 1; перенос одного и нескольких атрибутов на CelebA — на рисунке 4, ещё примеры — на рисунках 9 и 10; выражения RaFD — на рисунках 5 и 11; репозиторий.
  • StarGAN v2 (Choi et al., 2020; arXiv v2): разнообразные выходы на CelebA-HQ и AFHQ — на рисунке 1; синтез по образцу — на рисунке 4, ещё примеры — на рисунках 9 и 10; сравнения с базовыми моделями — на рисунках 5 и 6; видеоролик и репозиторий.

Литература#

  • Y. Choi, M. Choi, M. Kim, J.-W. Ha, S. Kim, J. Choo. StarGAN: Unified generative adversarial networks for multi-domain image-to-image translation. CVPR, 2018. Номера разделов относятся к arXiv v3: функции потерь — в разделе 3.1 (формулы 1–6), вектор-маска — в разделе 3.2 (формула 7), WGAN-GP и сети — в разделе 4 (формула 8) и приложении 7.2 (таблицы 4–5), наборы данных и обучение — в разделах 5.2–5.3, результаты — в таблицах 1–3 и на рисунках 6–7.
  • Y. Choi, Y. Uh, J. Yoo, J.-W. Ha. StarGAN v2: Diverse image synthesis for multiple domains. CVPR, 2020. Номера разделов относятся к arXiv v2: сети и функции потерь — в разделе 2 (формулы 1–5), абляционное исследование — в разделе 3.1 и таблице 1, сравнения — в таблицах 2–3, детали обучения — в приложении B, протокол оценки — в приложении C, архитектуры — в приложении E.
  • A. Odena, C. Olah, J. Shlens. Conditional image synthesis with auxiliary classifier GANs. ICML, 2017. Вспомогательный классификатор.
  • I. Gulrajani, F. Ahmed, M. Arjovsky, V. Dumoulin, A. Courville. Improved training of Wasserstein GANs. NeurIPS, 2017.
  • L. Mescheder, A. Geiger, S. Nowozin. Which training methods for GANs do actually converge?. ICML, 2018. Штраф R1 — в разделе 4.1, формула 9; реализация авторов также стала источником многозадачного дискриминатора, который использует StarGAN v2.
  • M.-Y. Liu, X. Huang, A. Mallya, T. Karras, T. Aila, J. Lehtinen, J. Kautz. Few-shot unsupervised image-to-image translation. ICCV, 2019. FUNIT; многозадачный состязательный дискриминатор — в разделе 3.2.
  • X. Huang, S. Belongie. Arbitrary style transfer in real-time with adaptive instance normalization. ICCV, 2017. AdaIN, формула 8.
  • T. Karras, S. Laine, T. Aila. A style-based generator architecture for generative adversarial networks. CVPR, 2019.
  • J.-Y. Zhu, T. Park, P. Isola, A. A. Efros. Unpaired image-to-image translation using cycle-consistent adversarial networks. ICCV, 2017.
  • Y. Choi. StarGAN, официальная реализация на PyTorch, 2018. model.py: размножение метки и замечание о дополнении и нормализации по экземпляру; solver.py: бинарная кросс-энтропия для меток CelebA, выбор целевых меток перемешиванием батча, вектор-маска.
  • Clova AI Research. StarGAN v2, официальная реализация на PyTorch, 2020. core/model.py: AdaIN с масштабом 1+γ(s)1 + \gamma(s), отображающая сеть; core/solver.py: функции потерь и штраф R1.
  • HSE-LAMBDA, репозиторий курса Deep Generative Models: StarGAN.ipynb, 02_hw_StarGAN.ipynb и вспомогательный модуль набора данных celeba.py.