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

14 / 33 · GAN

CycleGAN: перевод изображений без пар

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

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

Предыдущая заметка добавила к GAN энкодер, чтобы изображение можно было отобразить в код и обратно. Многие практические задачи начинаются не с шума, а с изображения: превратить фотографию в картину, летний пейзаж в зимний, карту в аэрофотоснимок, лошадь в зебру. Это перевод изображения в изображение (image-to-image translation). Когда обучающие данные состоят из пар, условный GAN учится такому переводу напрямую. Для большинства подобных задач пар не существует: ни у кого нет фотографии той же лошади в виде зебры. CycleGAN (Zhu et al., 2017) обучается на двух непарных коллекциях, по одной на домен. Поверх GAN ему нужна одна идея: перевод изображения в другой домен и обратно должен возвращать оригинал.

Обозначения. Два домена XX и YY (лошади и зебры) с распределениями данных PXP_X и PYP_Y; изображения x∼PXx \sim P_X, y∼PYy \sim P_Y. Два генератора, G:X→YG: X \to Y и F:Y→XF: Y \to X, и два дискриминатора: DYD_Y отличает настоящие yy от переведённых G(x)G(x), DXD_X отличает настоящие xx от F(y)F(y). ∥a−b∥1\|a - b\|_1 — сумма модулей попиксельных разностей; реализации усредняют её по пикселям, что лишь меняет масштаб весов слагаемых.

Перевод по парам: pix2pix#

Если есть выровненные пары (x,y)(x, y), например карта границ и фотография, по которой её получили, перевод становится обучением с учителем, и вопрос только в том, какую функцию потерь взять. Одна лишь попиксельная функция потерь, E ∥y−G(x)∥1\mathbb E\,\|y - G(x)\|_1, даёт размытость: там, где правдоподобны несколько выходов, минимизатор функции потерь L1L_1 — их попиксельная медиана, а функции потерь L2L_2 — их среднее, и ни то ни другое не похоже ни на один из них. pix2pix (Isola et al., 2017) добавляет условную состязательную функцию потерь, в которой дискриминатор видит пару (x,y)(x, y) или (x,G(x))(x, G(x)) и должен сказать, настоящая ли это фотография для этого входа:

G∗=arg⁡min⁡Gmax⁡D  LcGAN(G,D)+λ Ex,y ∥y−G(x)∥1,λ=100.G^* = \arg\min_G \max_D\; \mathcal L_{\text{cGAN}}(G, D) + \lambda\, \mathbb E_{x, y}\, \|y - G(x)\|_1 , \qquad \lambda = 100 .

Состязательное слагаемое делает выход чётким, а слагаемое L1L_1 держит его близко к настоящему целевому изображению. Генератор — U-Net, энкодер–декодер с обходными связями (skip connections) между зеркальными слоями, а дискриминатор — дискриминатор по фрагментам (PatchGAN): вместо одного вердикта на изображение он выдаёт сетку вердиктов, по одному на каждый перекрывающийся фрагмент 70×7070 \times 70, а функция потерь их усредняет. PatchGAN переходит в CycleGAN без изменений, а U-Net заменяется остаточным генератором (ниже).

Без пар состязательной функции потерь недостаточно#

Без пар для данного xx нет цели yy. Остаётся только состязательный сигнал: G(x)G(x) должно выглядеть как сэмпл из YY. Эта функция потерь зависит от GG только через распределение его выходов, поэтому оптимален любой GG, который переносит PXP_X в PYP_Y, что бы он ни делал с отдельным изображением. При достаточной ёмкости сеть может отобразить множество фотографий лошадей в любую перестановку фотографий зебр. На практике одна лишь состязательная функция потерь к тому же склонна к коллапсу мод (mode collapse): все входы переходят в одни и те же несколько выходов (Zhu et al., 2017, раздел 1).

Одномерная модель делает проблему конкретной. Пусть «лошади» — это x∼N(0,1)x \sim \mathcal N(0, 1), а «зебры» — y∼N(3,0.52)y \sim \mathcal N(3, 0.5^2). Три отображения выдают выходы в точности с распределением зебр: два детерминированных генератора и, для сравнения, стохастический сэмплер G(x,ε)=3+0.5 εG(x, \varepsilon) = 3 + 0.5\,\varepsilon со свежим шумом ε∼N(0,1)\varepsilon \sim \mathcal N(0, 1), не зависящим от xx:

Рисунок

Что исключает цикловая функция потерь, а что нет

Три отображения лошадей в зебрВозрастающая прямая, убывающая прямая и облако без зависимости от x (стохастический сэмплер); цикловые ошибки 0, 0 и 0.80.(а) G(x) = 3 + 0.5xцикловая ошибка 0.00x (лошадь)5G(x)1(б) G(x) = 3 − 0.5xцикловая ошибка 0.00x (лошадь)5G(x)1(в) G(x, ε) = 3 + 0.5εцикловая ошибка 0.80x (лошадь)5G(x)1Три отображения лошадей в зебрВозрастающая прямая, убывающая прямая и облако без зависимости от x (стохастический сэмплер); цикловые ошибки 0, 0 и 0.80.(а) G(x) = 3 + 0.5xцикловая ошибка 0.00x (лошадь)5G(x)1(б) G(x) = 3 − 0.5xцикловая ошибка 0.00x (лошадь)5G(x)1(в) G(x, ε) = 3 + 0.5εцикловая ошибка 0.80x (лошадь)5G(x)1
Одномерная модель задачи: «лошади» x ~ N(0, 1), «зебры» y ~ N(3, 0.5²). Во всех трёх случаях G(x) имеет в точности распределение зебр, поэтому дискриминатор их не различает. Отображение (в) стохастическое и не зависит от входа: оно берёт свежий шум ε ~ N(0, 1), поэтому лежит вне класса детерминированных генераторов, а детерминированная константа не дала бы распределения зебр. Лучшая обратная функция F может вернуть только медиану x: цикловая ошибка E|F(G(x)) − x| = √(2/π) ≈ 0.80. Отображения (а) и (б) обратимы, их цикловая ошибка равна нулю, хотя (б) переворачивает порядок: цикл требует сохранить информацию о входе, но не выбирает, какое из обратимых соответствий правильное.

Дискриминатор не может отличить (а), (б) и (в) друг от друга. Только (а) — нужный нам перевод; (в) отбросил всё, что относилось к входу. Отображение (в) лежит вне класса детерминированных генераторов CycleGAN G:X→YG: X \to Y: детерминированный генератор, игнорирующий xx, был бы константой, а константа не может совпасть с невырожденным распределением. Внутри этого класса отбросить информацию об xx значит взять отображение «многие в одно», и цикловая функция потерь ниже наказывает его точно так же.

Цикловая согласованность#

Если GG и FF переводят в противоположных направлениях, каждый должен отменять действие другого: x→G(x)→F(G(x))≈xx \to G(x) \to F(G(x)) \approx x (прямой цикл, forward cycle) и y→F(y)→G(F(y))≈yy \to F(y) \to G(F(y)) \approx y (обратный цикл, backward cycle). Функция потерь цикловой согласованности (cycle-consistency loss) измеряет оба:

Lcyc(G,F)=  Ex∼PX ∥F(G(x))−x∥1+  Ey∼PY ∥G(F(y))−y∥1.\begin{aligned} \mathcal L_{\text{cyc}}(G, F) = \;&\mathbb E_{x \sim P_X}\, \|F(G(x)) - x\|_1 \\ +\;&\mathbb E_{y \sim P_Y}\, \|G(F(y)) - y\|_1 . \end{aligned}

Что она исключает. Нулевое значение функции потерь прямого цикла означает, что F(G(x))=xF(G(x)) = x для каждого xx, поэтому GG инъективен: два разных входа никогда не переходят в один выход, иначе FF не смог бы восстановить оба. Перевод, который забывает свой вход, нельзя обратить. В игрушечной модели у отображения (в) вообще нет обратного: G(x)G(x) не зависит от xx, поэтому лучшее, что может сделать любой FF, — вернуть медиану xx, и цикловая ошибка равна E∣x∣=2/π≈0.80\mathbb E|x| = \sqrt{2/\pi} \approx 0.80. Отображения (а) и (б) обратимы, с F(y)=2(y−3)F(y) = 2(y - 3) и F(y)=−2(y−3)F(y) = -2(y - 3), и их цикловая ошибка равна нулю.

Чего она не исключает. Отображение (б) переворачивает порядок входов и удовлетворяет цикловой согласованности так же, как (а). Цикл требует, чтобы перевод сохранял достаточно информации для обращения; он не говорит, какое из обратимых соответствий правильное. Для изображений выбор делает архитектура. Свёрточный генератор из остаточных блоков (residual blocks; см. ниже) легко представляет тождественное отображение и меняет изображения локально, поэтому решение, которое он находит первым, сохраняет расположение объектов и меняет текстуру и цвет: полосы на лошади, а не другое животное в другой позе. Когда два домена допускают несколько таких соответствий, сеть может выбрать неверное: в задаче фото → карта сегментации CycleGAN иногда меняет местами метки деревьев и зданий (Zhu et al., 2017, раздел 6).

Функция потерь тождественного отображения#

Перевод картин в фотографии выявил ещё одну свободу: генераторы меняли оттенок изображения, когда в этом не было нужды. Дневной пейзаж Моне часто превращался в фотографию заката, и при этом удовлетворялись и состязательная, и цикловая функции потерь. Функция потерь тождественного отображения (identity loss; Taigman et al., 2017) требует, чтобы каждый генератор оставлял без изменений изображение своего целевого домена:

Lid(G,F)=Ey∼PY ∥G(y)−y∥1+Ex∼PX ∥F(x)−x∥1.\mathcal L_{\text{id}}(G, F) = \mathbb E_{y \sim P_Y}\, \|G(y) - y\|_1 + \mathbb E_{x \sim P_X}\, \|F(x) - x\|_1 .

Зебра, поданная генератору «лошадь → зебра», уже зебра, поэтому генератор должен выдать её как есть. Это устраняет изменения общего цвета, которых не требует ни один из доменов. Статья использует эту функцию потерь в задачах с картинами и с улучшением фотографий; распространённые реализации используют её везде.

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

Рисунок

CycleGAN: два генератора, два дискриминатора и два цикла

Два цикла CycleGANВерхний ряд: x, G, G(x), F, F(G(x)) с дискриминатором D_Y под G(x) и пунктирной стрелкой цикловой функции потерь от F(G(x)) к x. Нижний ряд: то же для y с F, G и D_X.xлошадьGG(x)зебраDYсостязательная: настоящая зебра?FF(G(x))лошадьцикл: ‖F(G(x)) − x‖₁yзебраFF(y)лошадьDXсостязательная: настоящая лошадь?GG(F(y))зебрацикл: ‖G(F(y)) − y‖₁123без изменений: G(y) ≈ yбез изменений: F(x) ≈ x4Два цикла CycleGANВерхний ряд: x, G, G(x), F, F(G(x)) с дискриминатором D_Y под G(x) и пунктирной стрелкой цикловой функции потерь от F(G(x)) к x. Нижний ряд: то же для y с F, G и D_X.xлошадьGG(x)зебраDYсостязательнаяFF(G(x))лошадьцикл: ‖F(G(x)) − x‖₁yзебраFF(y)лошадьDXсостязательнаяGG(F(y))зебрацикл: ‖G(F(y)) − y‖₁123без изменений: G(y) ≈ yбез изменений: F(x) ≈ x4
Зелёные — настоящие изображения, красные — сгенерированные, жёлтые — дискриминаторы. Генератор G переводит лошадей в зебр, F — зебр в лошадей. Состязательные функции потерь требуют, чтобы перевод выглядел как настоящий снимок другого домена, — это проверяют дискриминаторы зебр и лошадей (1, 3); цикловые функции потерь — чтобы перевод туда и обратно возвращал исходное изображение (2, 3); функция потерь тождественного отображения — чтобы изображение, уже принадлежащее целевому домену, почти не менялось (4). Без цикла ничто не связывает выход G с его входом.

Четыре вида функций потерь на рисунке объединяются в одну целевую функцию:

L(G,F,DX,DY)=  LGAN(G,DY)+LGAN(F,DX)+  λcyc Lcyc(G,F)+λid Lid(G,F),\begin{aligned} \mathcal L(G, F, D_X, D_Y) = \;&\mathcal L_{\text{GAN}}(G, D_Y) + \mathcal L_{\text{GAN}}(F, D_X) \\ +\;&\lambda_{\text{cyc}}\, \mathcal L_{\text{cyc}}(G, F) + \lambda_{\text{id}}\, \mathcal L_{\text{id}}(G, F), \end{aligned}

которую минимизируют по генераторам и максимизируют по дискриминаторам, с λcyc=10\lambda_{\text{cyc}} = 10 и λid=0.5 λcyc=5\lambda_{\text{id}} = 0.5\,\lambda_{\text{cyc}} = 5.

  1. Состязательная, X→YX \to Y. GG создаёт G(x)G(x); DYD_Y сравнивает его с настоящими зебрами.
  2. Прямой цикл. FF переводит G(x)G(x) обратно; штрафуется ∥F(G(x))−x∥1\|F(G(x)) - x\|_1.
  3. Обратное направление. То же с переставленными ролями: DXD_X оценивает F(y)F(y), а G(F(y))G(F(y)) должно совпасть с yy.
  4. Тождественное отображение. G(y)≈yG(y) \approx y и F(x)≈xF(x) \approx x.

Нужны оба цикла. С состязательной функцией потерь и только одним циклом обучение часто было неустойчивым и приводило к коллапсу в том направлении, чей цикл убрали (Zhu et al., 2017, раздел 5.1.4).

Сети#

Генератор. Генератор повторяет сеть переноса стиля из работы Johnson et al. (2016). Для изображений 256×256256 \times 256:

  • свёртка 7×77 \times 7 до 64 каналов;
  • две свёртки с шагом (stride) 2 до 128×128×128128 \times 128 \times 128 и 64×64×25664 \times 64 \times 256;
  • девять остаточных блоков размера 64×64×25664 \times 64 \times 256;
  • две свёртки с шагом 12\tfrac12 (транспонированные свёртки, transposed convolutions) обратно до 256×256×64256 \times 256 \times 64;
  • свёртка 7×77 \times 7 до 3 каналов с tanh⁡\tanh.

Каждый остаточный блок вычисляет h+r(h)h + r(h), где rr — две свёртки 3×33 \times 3, поэтому блок, у которого rr близко к нулю, пропускает вход без изменений. В этом и состоит описанная выше склонность к малым локальным изменениям. За каждой свёрткой, кроме выходной, следует нормализация по экземпляру (instance normalization: статистики по каждому изображению и каналу; при одном изображении в батче это естественный выбор, см. заметку о нормализации), а за всеми, кроме выходного слоя и второй свёртки каждого остаточного блока, — ReLU. Дополнение отражением (reflection padding) вместо дополнения нулями (zero-padding) избавляет от тёмных краёв. У генератора 11.38 млн параметров, 93% из них — в остаточных блоках. Для изображений меньшего размера (128×128128 \times 128) берут шесть блоков.

Дискриминатор: PatchGAN 70×7070 \times 70. Четыре свёртки 4×44 \times 4 с 64, 128, 256 и 512 каналами (первые три с шагом 2, последняя с шагом 1; нормализация по экземпляру во всех, кроме первой; LeakyReLU с наклоном 0.2), затем свёртка 4×44 \times 4 до одного канала. На изображении 256×256256 \times 256 он выдаёт карту значений 30×3030 \times 30. Каждое значение зависит от окна входа 70×7070 \times 70 — своего рецептивного поля (receptive field):

r=1+∑ℓ(kℓ−1)∏m<ℓsm=1+3 (1+2+4+8+8)=70,r = 1 + \sum_\ell (k_\ell - 1) \prod_{m < \ell} s_m = 1 + 3\,(1 + 2 + 4 + 8 + 8) = 70 ,

где размеры ядер kℓ=4k_\ell = 4, а шаги s=(2,2,2,1,1)s = (2, 2, 2, 1, 1). Дискриминатор по фрагментам судит о локальной текстуре, которую и меняет большинство переводов, имеет 2.76 млн параметров и работает на изображениях любого размера. Окно 70×7070 \times 70 — номинальное рецептивное поле свёрток: состязательная функция потерь явно оценивает локальную текстуру, поэтому глобальная структура остаётся в основном на долю генератора и цикловой функции потерь. Это не предположение о независимости. 900 перекрывающихся оценок не являются независимыми вероятностными множителями, а слои нормализации по экземпляру связывают все позиции через статистики каналов по всему изображению, так что каждая оценка слабо зависит от всего изображения. С двумя генераторами и двумя дискриминаторами у модели 28.3 млн параметров.

Обучение#

  • Состязательная функция потерь наименьших квадратов. Отрицательный логарифм правдоподобия стандартного GAN заменяется функцией потерь наименьших квадратов (least-squares loss) из GAN наименьших квадратов (least-squares GAN): DYD_Y минимизирует E (DY(y)−1)2+E DY(G(x))2\mathbb E\,(D_Y(y) - 1)^2 + \mathbb E\,D_Y(G(x))^2, а GG минимизирует E (DY(G(x))−1)2\mathbb E\,(D_Y(G(x)) - 1)^2. Она даёт генератору градиенты даже для выходов, которые дискриминатор уже считает настоящими, но которые лежат далеко от настоящих данных, и делает обучение устойчивее. Целевая функция дискриминатора делится на 2; статья описывает это как замедление дискриминатора относительно генераторов (раздел 7.1). С Adam это вдвое уменьшает выводимое значение потерь и сырой градиент, но Adam делит каждый шаг на скользящую оценку масштаба градиента, поэтому постоянный множитель в основном сокращается, если не считать малого ϵ\epsilon в знаменателе; эффективный шаг вдвое не уменьшается.
  • История сгенерированных изображений. Каждый дискриминатор обновляется на подделках из буфера истории (history buffer), где хранятся 50 ранее сгенерированных изображений, а не только на самой новой подделке (Shrivastava et al., 2017). Когда буфер заполнен, каждая новая подделка с вероятностью 12\frac12 заменяет случайную сохранённую, и тогда вместо неё используется старое изображение. Дискриминатор, который видит только текущий генератор, может гоняться за ним по кругу; дискриминатор, который помнит и прежние генераторы, гасит эти колебания.
  • Оптимизация. Adam с шагом обучения (learning rate) 2⋅10−42\cdot10^{-4}, размер батча 1, 100 эпох с постоянным шагом и ещё 100 с шагом, линейно убывающим до нуля. Веса инициализируются из N(0,0.022)\mathcal N(0, 0.02^2).

Результаты#

Два эксперимента из статьи показывают, чего метод достигает и чего нет:

  • Реалистичность. В исследовании восприятия на задаче карты ↔ аэрофотоснимки с разрешением 256×256256 \times 256 участники принимали выходы CycleGAN за настоящие изображения в 26.8% испытаний (карта → фото) и в 23.2% (фото → карта). Более ранние методы без пар обманывали их не более чем в 2.6% испытаний.
  • Соответствие входу. На Cityscapes, в задаче метки → фото, предобученная сеть сегментации восстанавливает входные метки по сгенерированным фотографиям. Попиксельная доля правильных ответов (per-pixel accuracy) равна 0.52, а IoU по классам — 0.11 у CycleGAN против 0.71 и 0.18 у pix2pix, обученного на парах. Одна лишь состязательная функция потерь даёт IoU по классам 0.08, одна лишь цикловая — 0.02.

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

pix2pixCycleGAN
Обучающие данныевыровненные пары (x,y)(x, y)две непарные коллекции
СетиGG; D(x,y)D(x, y) видит входGG, FF, DXD_X, DYD_Y; каждый DD видит один домен
Что связывает выход со входомL1L_1 до истинной цели, λ=100\lambda = 100цикловая функция потерь, λcyc=10\lambda_{\text{cyc}} = 10; функция потерь тождественного отображения
Состязательная функция потерьусловная, логарифм правдоподобиябезусловная для каждого домена, наименьшие квадраты
ГенераторU-NetResNet с 9 остаточными блоками
ДискриминаторPatchGAN 70×7070 \times 70PatchGAN 70×7070 \times 70, буфер истории на 50 изображений

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

  • Геометрия. Изменения цвета и текстуры удаются, изменения формы в основном нет. В задаче собака → кошка выученный перевод вырождается в минимальные изменения входа; авторы осторожно связывают это с архитектурой генератора, приспособленной к изменениям внешнего вида.
  • Смещение набора данных (dataset bias). Модель лошадь → зебра обучена на диких лошадях и зебрах из ImageNet, среди которых нет всадников, и поэтому покрывает полосами и всадника.
  • Разрыв с обучением на парах. Показатели соответствия входу выше остаются намного ниже, чем у pix2pix, а некоторые неоднозначности, например перепутанные метки деревьев и зданий, нельзя разрешить без хотя бы частичной разметки.
  • Скрытая информация. Генератор может удовлетворить цикловую функцию потерь, спрятав нужную ему информацию в почти невидимом высокочастотном сигнале на своём выходе, который затем декодирует другой генератор (Chu, Zhmoginov and Sandler, 2017). Тогда цикл согласован, хотя видимый перевод потерял содержание, а малые возмущения G(x)G(x) могут сильно менять F(G(x))F(G(x)).
  • Один выход на вход. Оба генератора детерминированы, поэтому у лошади ровно один вариант в виде зебры, тогда как многие переводы устроены по принципу «один ко многим» (у наброска много вариантов раскраски).
  • Одна модель на пару доменов. Для всех пар из kk доменов нужно k(k−1)/2k(k-1)/2 CycleGAN с k(k−1)k(k-1) генераторами, и ни один генератор не учится на данных других доменов.

Итоги#

  • Без пар состязательная функция потерь ограничивает только распределение выходов; оптимально любое отображение в целевое распределение, включая то, которое игнорирует вход.
  • Цикловая функция потерь ∥F(G(x))−x∥1+∥G(F(y))−y∥1\|F(G(x)) - x\|_1 + \|G(F(y)) - y\|_1 делает каждый перевод обратимым, так что он сохраняет информацию о входе; выбора среди обратимых соответствий она не делает — его делает склонность архитектуры к малым локальным изменениям.
  • Функция потерь тождественного отображения оставляет изображения целевого домена без изменений и предотвращает беспричинные сдвиги цвета; λcyc=10\lambda_{\text{cyc}} = 10, λid=5\lambda_{\text{id}} = 5.
  • Сети: генератор ResNet с девятью остаточными блоками и нормализацией по экземпляру; PatchGAN 70×7070 \times 70, выдающий значения для сетки 30×3030 \times 30 фрагментов.
  • Обучение: функции потерь GAN наименьших квадратов, буфер истории на 50 подделок, Adam 2⋅10−42\cdot10^{-4}, батч 1, 200 эпох с линейным убыванием шага на последних 100.
  • Типичные сбои: геометрические изменения, смещение набора данных, скрытая информация, детерминированные выходы «один к одному» и одна модель на пару доменов.

Ноутбук#

Ноутбук о CycleGAN из репозитория HSE-LAMBDA Deep Generative Models обучает и запускает CycleGAN на horse2zebra (ячейки нумеруются с 1, считая все ячейки подряд, включая текстовые). Сети, набор данных, буфер воспроизведения (replay buffer) и расписание шага обучения взяты из пакета CycleGAN-PyTorch автора Lornatang, закреплённого на одном коммите.

  • Ячейки 1–2: метод. Перевод без пар, состязательная и цикловая функции потерь, функция потерь тождественного отображения и полная целевая функция. Текстовые ячейки записывают состязательную функцию потерь через log⁡D\log D и дискриминатор с выходами в {0,1}\{0, 1\}; код обучения использует форму наименьших квадратов, как и статья на практике.
  • Ячейки 3–7: подготовка. Shell-скрипты скачивают набор данных horse2zebra и предобученные веса для всех четырёх сетей. Аргументы: 200 эпох, убывание шага на последних 100, размер батча 1, шаг обучения 2⋅10−42\cdot10^{-4}, размер изображения 256, args.cuda = False. Начальное значение генератора случайных чисел (seed) выбирается случайно и не печатается.
  • Ячейки 8–11: данные. Изображения масштабируются до ⌊1.12⋅256⌋=286\lfloor 1.12 \cdot 256 \rfloor = 286 пикселей (бикубической интерполяцией), случайно обрезаются до 256, случайно отражаются и масштабируются в [−1,1][-1, 1]. При unaligned=True каждой лошади в пару ставится случайная зебра, так что батчи не несут никакого соответствия. Ячейка 11 показывает пять случайных пар.
  • Ячейки 12–13: модели. Generator и Discriminator устроены так, как описано выше: генератор — c7s1-64, d128, d256, 9 × R256, u128, u64, c7s1-3 с дополнением отражением и нормализацией по экземпляру. Веса свёрток инициализируются из N(0,0.022)\mathcal N(0, 0.02^2), а затем во все четыре сети загружаются предобученные веса.
  • Ячейки 14–18: инференс. Пять зебр, переведённых в лошадей (ячейка 16), и пять лошадей, переведённых в зебр (ячейка 18), предобученными генераторами.
  • Ячейки 19–20: функции потерь и оптимизаторы.
    • Цикловая функция потерь L1L_1 с весом 10, функция потерь тождественного отображения L1L_1 с весом 5, MSELoss для состязательных слагаемых.
    • Один оптимизатор Adam для обоих генераторов и по одному на каждый дискриминатор, все с betas (0.5,0.999)(0.5, 0.999).
    • LambdaLR с множителем 1−max⁡(0,e−100)/1001 - \max(0, e - 100)/100 на эпохе ee: 1 до эпохи 100, 0.5 на эпохе 150, 0.01 на эпохе 199.
    • Два ReplayBuffer на 50 изображений, которые работают так, как описано в разделе «Обучение».
  • Ячейки 21–22: цикл обучения.
    • Каждый шаг сначала обновляет генераторы по сумме двух функций потерь тождественного отображения, двух состязательных (целевая метка 1) и двух цикловых.
    • Затем он обновляет DAD_A и DBD_B на настоящем изображении (метка 1) и подделке из буфера (метка 0), причём каждая функция потерь делится пополам.
    • Индикатор прогресса печатает функцию потерь дискриминатора, общую, тождественного отображения, GAN и цикловую. Планировщики шага обучения делают шаг раз в эпоху.

Сохранённые выходы. Выход сохранён только у ячейки 16: пять переводов зебра → лошадь предобученным генератором. Цикл обучения не запускался, поэтому значений функций потерь и сэмплов из обучения нет.

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

  • Усреднённые значения по фрагментам. Discriminator.forward усредняет карту значений 30×3030 \times 30 в одно число до вычисления функции потерь, поэтому состязательная функция потерь равна (sˉ−1)2(\bar s - 1)^2, где sˉ\bar s — среднее значение по фрагментам, а не среднему по фрагментам 1900∑p(sp−1)2\frac1{900}\sum_p (s_p - 1)^2, как в эталонной реализации. Они различаются на дисперсию значений: 1900∑p(sp−1)2=(sˉ−1)2+Var⁡p(sp)\frac1{900}\sum_p (s_p - 1)^2 = (\bar s - 1)^2 + \operatorname{Var}_p(s_p). Усреднённая функция потерь требует, чтобы настоящим выглядел не каждый фрагмент, а только их среднее, и это ослабляет PatchGAN.
  • Устройство. args.cuda = False держит всё на CPU, даже когда есть GPU (ячейка 9 лишь печатает предупреждение), и 200 эпох становятся непрактичными. На машине с GPU значение нужно заменить на True.
  • Обучение начинается с предобученных весов. Ячейка 13 загружает их до цикла обучения, поэтому ячейка 22 дообучает предобученную модель, хотя ячейка 21 говорит об обучении с нуля. Чтобы обучать с нуля, пути к весам нужно оставить пустыми.
  • Неиспользуемые списки потерь. g_losses, d_losses и другие списки в ячейке 22 создаются, но не заполняются, поэтому для графиков ничего не записывается.

Дальше#

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

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

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

  • pix2pix (Isola et al., 2017; arXiv v3): одна модель на многих задачах с парами — на рисунке 1; влияние слагаемых L1 и cGAN — на рисунке 4; Cityscapes, фасады, день → ночь, границы → сумки и границы → обувь — на рисунках 13–17; неудачные случаи — на рисунке 21; страница проекта.
  • CycleGAN (Zhu et al., 2017; arXiv v7): Моне ↔ фотография, зебра ↔ лошадь и лето ↔ зима — на рисунке 1; сравнения на Cityscapes и Google Maps — на рисунках 5 и 6; перенос стиля коллекции — на рисунках 10 и 11; лошадь ↔ зебра и другие задачи — на рисунке 13; неудачные случаи, в том числе собака → кошка, — на рисунке 17; страница проекта.

Литература#