​​Как приручить GAN. Советы от Димы, куратора курса Ракета в CV



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



Кто такой GAN:

Есть моделька генератор. Она берёт на вход некоторый вектор x. В векторе x может быть что угодно: случайный вектор, осмысленный эмбеддинг, картинка. А выплёвывает генератор на выходе некоторый вектор y. Обычно y — картинка, но может быть и каким-нибудь вектором.

Есть моделька дискриминатор. Дискриминатор учится на классификацию и отделяет изображения из реального домена от изображений из генератора.



GAN по пунктикам (рис)

1. Генератор генерирует картинку;

2. Полученная картинка идёт в дискриминатор. Считается classification-loss

3. Генератор делает градиентный шаг так, чтобы обмануть дискриминатор. (сдвинуть предсказание дискриминатора в сторону ошибки);

4. Через дискриминатор прогоняется реальная картинка. Считается classification-loss;

5. Дискриминатор делает градиентный шаг, чтобы минимизировать сумму наших classification-loss. Так дискриминатор учится различать реальные и синтетические изображения;

6. Повторять пока не сойдётся.



Проблемки

Из-за этой жесткой конкурентной борьбы генератора и дискриминатор, GAN'ы очень тяжко сходятся. Чтобы ганы чаще добирались до прода, вот пачка советов.



Советики

У меня на практике лучший лосс для GAN'ов это Least Square Gan (LSGAN). Мы просто берём логиты с дискриминатора (до сигмоиды) и тянем их по MSE к 1. Да, делаем классификацию через регрессию, и ганы от этого только лучше учатся. Сверху можно добавить ещё и Relativistic GAN;

Дискриминатор может выдавать не одно число, а например сетку 7x7 как в PatchGAN. Благодаря этому выдается скор реалистичности не для всей картинки, а для регионов. Этот трюк почти всегда улучшает сходимость и качество сети. Можно взять гига-чада от мира дискриминаторов - UnetGAN, который выдаёт скор для каждого пикселя (в топовом RealESRGAN например так). Но там начинаются проблемы со стабильностью. Поэтому уважаемые ресёрчеры учили всё это с moving average 0.999 на веса модели;

Стартовать с какого-нибудь простого претрейна лучше, чем учить GAN с нуля. Можно сначала предобучить генератор с L1-лоссом и получить мыльный результат, а затем дотюнивать вместе с дискриминатором.

Вспомогательные лоссы вообще всегда помогают не разбежаться сетке. Только скор реалистичности далеко не всегда приведёт вас куда надо. Для картинок попробуйте использовать ContentLoss и L1 лосс в добавок. Это будет держать ваш GAN в рамках дозволенного;

Не пытайтесь подбирать число шагов для генератора и дискриминатора. Сильно крутить learning rate, как правило, тоже бесполезно. Можно подобрать порядок, но не упарываться в десятых знаках после запятой. Все пытались и я пытался (ганы прунил, а оно потом не дотюнивалось), и вы будете пытаться. В обучении GANов ваш бро это ADAM, он сам со всем разберётся (почти);

Батчнормы чаще всего зло, генерит артефакты;

Прочитайте StyleGAN и StyleGANv2 там очень много трюков, их часто можно утянуть и к себе в пайплайн.