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

09 / 33 · GAN

Генеративно-состязательные сети

GAN как минимаксная игра двух игроков, функция ценности как бинарная кросс-энтропия, цикл обучения с чередованием шагов, оптимальный дискриминатор, тождество с дивергенцией Йенсена–Шеннона, стоящее за глобальным оптимумом, почему на практике используется ненасыщающаяся функция потерь генератора, вычисляемая по логитам, практические правила, благодаря которым обучение работает (архитектура DCGAN, баланс двух игроков, сглаживание меток, средства против коллапса мод), а также условный GAN, f-GAN и GAN наименьших квадратов.

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

VAE обучает свой генератор через нижнюю оценку правдоподобия и расплачивается за это размытыми сэмплами. Генеративно-состязательная сеть (generative adversarial network, GAN) обходится без правдоподобия вовсе (Goodfellow et al., 2014). Генератор — это сеть, которая превращает шум в сэмплы, и обучается он только через вторую сеть, дискриминатор, которая пытается отличить сгенерированные сэмплы от настоящих. Модель неявная (implicit): из неё можно сэмплировать, но нельзя вычислить её плотность.

Эту заметку организуют два факта; всё остальное показывает, откуда они берутся.

  • Если дискриминатор оптимален, целевая функция генератора — это, по сути, дивергенция Йенсена–Шеннона (Jensen–Shannon divergence) в другой записи: 2 DJS(pdata ∥ pg)−2ln⁡22\,D_{\mathrm{JS}}(p_{\text{data}}\,\|\,p_g) - 2\ln 2. Тогда обучение генератора означает минимизацию DJS(pdata ∥ pg)D_{\mathrm{JS}}(p_{\text{data}}\,\|\,p_g).
  • Если носители (supports) двух распределений не перекрываются, а дискриминатор (почти) оптимален, минимаксная функция потерь генератора не даёт полезного градиента: JS застревает на своём максимуме ln⁡2\ln 2, где бы ни находилось pgp_g, а оптимальный дискриминатор постоянен вокруг сгенерированных сэмплов.

Обозначения. pdata(x)p_{\text{data}}(x) — плотность данных, pz(z)p_z(z) — априорное распределение шума, GG — генератор с параметрами θg\theta_g, pg(x)p_g(x) — плотность сгенерированных сэмплов G(z)G(z), DD — дискриминатор с параметрами θd\theta_d; D(x)∈[0,1]D(x) \in [0, 1] — вероятность того, что xx настоящий, причём ln⁡0=−∞\ln 0 = -\infty. Сеть с сигмоидой на выходе принимает значения в (0,1)(0, 1) и может лишь приближаться к концам отрезка. Логарифмы натуральные.

Порядок чтения. При первом чтении достаточно игры, чередующихся обновлений, оптимального дискриминатора и его связи с JS, ненасыщающейся функции потерь через логиты, коллапса мод, а затем GAN Вассерштейна. Расширения f-GAN и GAN наименьших квадратов — дополнительный материал.

Постановка#

Сэмплируем шум z∼pz(z)z \sim p_z(z), например из стандартного гауссовского распределения, и пропускаем его через генератор. Выход G(z)G(z) — сгенерированный сэмпл, а его распределение — pg(x)p_g(x). Дискриминатор получает либо сгенерированный сэмпл с меткой y=0y = 0 (подделка), либо точку данных x∼pdata(x)x \sim p_{\text{data}}(x) с меткой y=1y = 1 («настоящие») и выдаёт вероятность того, что его вход настоящий.

Рисунок

Игра GAN в виде схемы

Потоки данных через генератор и дискриминаторСлева узел шума z из p_z(z), показанного широкой колоколообразной кривой, передаёт значение вверх в блок G с параметрами theta g. G выдаёт узел G(z) — сгенерированные данные, плотность которых p_g(x) показана двугорбой кривой. Стрелка с подписью y равно 0, подделка, идёт от G(z) к узлу дискриминатора D с параметрами theta d. Снизу узел исходных данных x из p_data(x), также показанного двугорбой кривой, посылает в D стрелку с подписью y равно 1, настоящие. D выдаёт P(вход настоящий).pg(x)xpz(z)zpdata(x)xzшумz ~ pz(z)GθgG(z)сгенерированные данныеy = 0подделкаDθdP(вход настоящий)xданныеx ~ pdata(x)y = 1настоящиеПотоки данных через генератор и дискриминаторВертикальная цепочка. Вверху узел шума z из p_z(z), показанного колоколообразной кривой, передаёт значение в блок G с параметрами theta g, который выдаёт G(z) — сгенерированные данные с плотностью p_g(x). Стрелка с подписью y равно 0, подделка, идёт вниз к дискриминатору D с параметрами theta d. Снизу узел исходных данных x из p_data(x) посылает вверх в D стрелку с подписью y равно 1, настоящие. D выдаёт P(вход настоящий), эта подпись стоит слева от него.pz(z)zpg(x)xpdata(x)xzшумz ~ pzGθgG(z)данныегенератораy = 0подделкаDθdP(входнастоящий)y = 1настоящиеxданныеx ~ pdata
Шум z проходит через генератор G (параметры θ_g); его выходы G(z) имеют распределение p_g и подаются дискриминатору с меткой y = 0. Настоящие данные x ~ p_data поступают с меткой y = 1. Дискриминатор D (параметры θ_d) выдаёт вероятность того, что его вход — настоящие данные. Маленькие графики схематично показывают плотность шума, плотность генератора и плотность данных.

Генератор никогда не видит настоящих данных напрямую. Он учится только через выход дискриминатора, а дискриминатор учится разделять два потока.

Минимаксная игра#

Две сети играют в минимаксную игру: дискриминатор максимизирует свой успех, а генератор минимизирует успех дискриминатора. Успех измеряется функцией ценности (value function)

V(G,D)=Ex∼pdata[ln⁡D(x)]+Ez∼pz[ln⁡(1−D(G(z)))],\begin{aligned} V(G, D) ={}& \mathbb{E}_{x\sim p_{\text{data}}}\big[\ln D(x)\big] \\ &+ \mathbb{E}_{z\sim p_z}\big[\ln\big(1 - D(G(z))\big)\big], \end{aligned}

а сама игра — это min⁡Gmax⁡DV(G,D)\min_G \max_D V(G, D).

Дискриминатор хочет, чтобы D(x)D(x) было близко к 11 на настоящих данных, а D(G(z))D(G(z)) — близко к 00 на подделках; и то и другое увеличивает VV. Генератор хочет, чтобы D(G(z))D(G(z)) было близко к 11, и тогда второе слагаемое становится сильно отрицательным.

Откуда берётся функция ценности: бинарная кросс-энтропия#

Дискриминатор — бинарный классификатор, поэтому начнём с бинарной кросс-энтропии (binary cross-entropy, BCE) между меткой yy и предсказанием y^\hat y:

H(y,y^)=−[ yln⁡y^+(1−y)ln⁡(1−y^) ].H(y, \hat y) = -\big[\,y\ln\hat y + (1 - y)\ln(1 - \hat y)\,\big].
  • Для настоящего сэмпла y=1y = 1, y^=D(x)\hat y = D(x) и H=−ln⁡D(x)H = -\ln D(x).
  • Для поддельного сэмпла y=0y = 0, y^=D(G(z))\hat y = D(G(z)) и H=−ln⁡(1−D(G(z)))H = -\ln\big(1 - D(G(z))\big).

Для одного настоящего и одного поддельного сэмпла сумма равна H=−[ln⁡D(x)+ln⁡(1−D(G(z)))]H = -\big[\ln D(x) + \ln\big(1 - D(G(z))\big)\big]. Усреднение по многим таким парам превращает суммы в математические ожидания:

E[−H]=Ex∼pdata[ln⁡D(x)]+Ez∼pz[ln⁡(1−D(G(z)))],\begin{aligned} \mathbb{E}[-H] ={}& \mathbb{E}_{x\sim p_{\text{data}}}\big[\ln D(x)\big] \\ &+ \mathbb{E}_{z\sim p_z}\big[\ln\big(1 - D(G(z))\big)\big], \end{aligned}

что для непрерывных распределений записывается как

∫pdata(x)ln⁡D(x) dx+∫pz(z)ln⁡(1−D(G(z))) dz.\begin{aligned} &\int p_{\text{data}}(x)\ln D(x)\,dx \\ &\quad + \int p_z(z)\ln\big(1 - D(G(z))\big)\,dz . \end{aligned}

Это в точности V(G,D)V(G, D). Итак, VV — это бинарная кросс-энтропия дискриминатора со знаком минус: максимизировать VV по DD — то же самое, что обучать DD как обычный классификатор с функцией потерь BCE. Два слагаемых входят с равными весами, потому что классификатор видит настоящие и поддельные сэмплы в равной пропорции, то есть априорная вероятность класса равна 12\tfrac12. При других пропорциях меняются и VV, и оптимальный дискриминатор, найденный ниже.

Как оптимизировать: игроки ходят по очереди#

Два игрока ходят по очереди, каждый на мини-батче размера mm (Goodfellow et al., 2014, алгоритм 1).

  1. Фиксируем GG. Берём mm настоящих сэмплов x(1),…,x(m)x^{(1)},\dots,x^{(m)} и mm сэмплов шума z(1),…,z(m)z^{(1)},\dots,z^{(m)} и обновляем θd\theta_d градиентным подъёмом вдоль
∇θd 1m∑i=1m[ln⁡D(x(i))+ln⁡(1−D(G(z(i))))].\begin{aligned} \nabla_{\theta_d}\,\frac1m\sum_{i=1}^{m}\Big[&\ln D\big(x^{(i)}\big) \\ &+ \ln\Big(1 - D\big(G(z^{(i)})\big)\Big)\Big]. \end{aligned}
  1. Фиксируем DD. Берём mm новых сэмплов шума и обновляем θg\theta_g градиентным спуском вдоль
∇θg 1m∑i=1mln⁡(1−D(G(z(i)))).\nabla_{\theta_g}\,\frac1m\sum_{i=1}^{m}\ln\Big(1 - D\big(G(z^{(i)})\big)\Big).

В шаге генератора участвует только второе слагаемое, потому что первое слагаемое не зависит от GG: ln⁡D(x)\ln D(x) содержит только настоящие данные и θd\theta_d, поэтому его градиент по θg\theta_g равен нулю. Шаг 1 можно повторять kk раз на каждый шаг генератора; в исходной статье k=1k = 1. Как выбирать kk, обсуждается в разделе о балансе двух игроков.

Глобальный оптимум: генератор совпадает с данными#

Игра выиграна, когда распределение генератора совпадает с распределением данных. Доказательство состоит из двух шагов (Goodfellow et al., 2014, предложение 1 и теорема 1).

Шаг 1: оптимальный дискриминатор при фиксированном генераторе#

Как и в Goodfellow et al. (2014), раздел 4, предположим, что оба распределения имеют плотности на одном и том же пространстве и что DD может быть любой функцией (неограниченная ёмкость, infinite capacity). Когда dim⁡z<dim⁡x\dim z < \dim x, первое предположение нарушается; этот случай разобран ниже, в абзаце о неперекрывающихся носителях.

Перепишем второе математическое ожидание через сгенерированные сэмплы: x=G(z)x = G(z) имеет плотность pgp_g, поэтому Ez∼pz[ln⁡(1−D(G(z)))]=Ex∼pg[ln⁡(1−D(x))]\mathbb{E}_{z\sim p_z}\big[\ln(1 - D(G(z)))\big] = \mathbb{E}_{x\sim p_g}\big[\ln(1 - D(x))\big]. Тогда при фиксированном GG

V(G,D)=∫x[ pdata(x)ln⁡D(x)+pg(x)ln⁡(1−D(x))] dx.\begin{aligned} V(G, D) = \int_x \Big[\,&p_{\text{data}}(x)\ln D(x) \\ &+ p_g(x)\ln\big(1 - D(x)\big)\Big]\,dx . \end{aligned}

DD можно выбирать свободно в каждой точке xx, поэтому подынтегральное выражение можно максимизировать поточечно. Обозначим a=pdata(x)a = p_{\text{data}}(x), b=pg(x)b = p_g(x) и s=D(x)s = D(x). Если a,b>0a, b > 0, то для функции f(s)=aln⁡s+bln⁡(1−s)f(s) = a\ln s + b\ln(1 - s) на (0,1)(0, 1)

f′(s)=as−b1−s=0  ⟹  s∗=aa+b,f′′(s)=−as2−b(1−s)2<0,\begin{aligned} f'(s) &= \frac{a}{s} - \frac{b}{1 - s} = 0 \;\Longrightarrow\; s^* = \frac{a}{a + b}, \\ f''(s) &= -\frac{a}{s^2} - \frac{b}{(1 - s)^2} < 0, \end{aligned}

поэтому s∗s^* — единственный максимум, и он лежит внутри (0,1)(0, 1). Если обращается в нуль ровно одна плотность, ff монотонна на [0,1][0, 1] и её максимум достигается на конце отрезка: s∗=1s^* = 1 там, где b=0b = 0 (только данные), и s∗=0s^* = 0 там, где a=0a = 0 (только подделки). Формула a/(a+b)a/(a + b) даёт и эти значения; выход с сигмоидой может к ним лишь приближаться. Там, где обе плотности равны нулю, DD не имеет значения (Goodfellow et al., 2014, предложение 1).

Рисунок

В каждой точке x — максимизация по одной переменной

a ln s плюс b ln(1 минус s) при s от 0 до 1Две вогнутые кривые на отрезке s от 0 до 1; обе уходят в минус бесконечность на концах. Сплошная зелёная кривая для a = 0.6 и b = 0.3 достигает максимума при s = 2/3 со значением −0.573. Штриховая кривая для a = b = 0.45 достигает максимума при s = 1/2 со значением −0.624. Пунктирные вертикальные линии опущены от двух максимумов на горизонтальную ось s = D(x). По вертикальной оси отложено a ln s + b ln(1 − s).0−1−20½1⅔s = D(x)a ln s + b ln(1 − s)максимум в точкеs* = a/(a+b)a = b ⇒ s* = ½a ln s плюс b ln(1 минус s) при s от 0 до 1Две вогнутые кривые на отрезке s от 0 до 1; обе уходят в минус бесконечность на концах. Сплошная зелёная кривая для a = 0.6 и b = 0.3 достигает максимума при s = 2/3 со значением −0.573. Штриховая кривая для a = b = 0.45 достигает максимума при s = 1/2 со значением −0.624. Пунктирные вертикальные линии опущены от двух максимумов на горизонтальную ось s = D(x). По вертикальной оси отложено a ln s + b ln(1 − s).0−1−20½1⅔s = D(x)a ln s + b ln(1 − s)максимум в точкеs* = a/(a+b)a = b ⇒ s* = ½
При фиксированных a = p_data(x) и b = p_g(x) функция a ln s + b ln(1 − s) вогнута по s = D(x) и достигает максимума в s* = a / (a + b). Сплошная линия: a = 0.6, b = 0.3, поэтому s* = 2/3, а максимум равен −0.573. Штриховая: a = b = 0.45, поэтому s* = ½, а максимум равен −0.624.

Следовательно, при фиксированном генераторе наилучший дискриминатор равен

DG∗(x)=pdata(x)pdata(x)+pg(x).D^*_G(x) = \frac{p_{\text{data}}(x)}{p_{\text{data}}(x) + p_g(x)} .
Рисунок

Оптимальный дискриминатор сравнивает две плотности

Две плотности и оптимальный дискриминаторВерхняя панель: красная плотность данных p_data с высокой модой в минус 1.5 и меньшей в 0.6 и синяя плотность генератора p_g — один колокол в 1.8. Они пересекаются при x около 0.90. Нижняя панель: зелёная кривая D со звёздочкой от x почти равна 1 слева, где массу имеют только данные, проходит через одну вторую ровно в точке пересечения и стремится к 0 справа, где массу имеет только генератор. Штриховая вертикальная линия соединяет точку пересечения на обеих панелях.плотностьpdata(x)pg(x)pdata = pg0½1−4−2024xD*(x)D* = ½ при pdata = pg≈ 1: только данные≈ 0: только подделкиДве плотности и оптимальный дискриминаторВерхняя панель: красная плотность данных p_data с высокой модой в минус 1.5 и меньшей в 0.6 и синяя плотность генератора p_g — один колокол в 1.8. Они пересекаются при x около 0.90. Нижняя панель: зелёная кривая D со звёздочкой от x почти равна 1 слева, где массу имеют только данные, проходит через одну вторую ровно в точке пересечения и стремится к 0 справа, где массу имеет только генератор. Штриховая вертикальная линия соединяет точку пересечения на обеих панелях.плотностьpdata(x)pg(x)pdata = pg0½1−4−2024xD*(x)D* = ½ приpdata = pg≈ 1: толькоданные≈ 0: подделки
При фиксированном генераторе наилучший дискриминатор равен D*(x) = p_data(x) / (p_data(x) + p_g(x)). Он близок к 1 там, где есть только настоящие данные, близок к 0 там, где есть только сгенерированные сэмплы, и равен ровно ½ там, где плотности равны (в пределах показанного диапазона — при x ≈ 0.90). Плотности: p_data = 0.6·N(−1.5, 0.6²) + 0.4·N(0.6, 0.5²), p_g = N(1.8, 0.85²).

Шаг 2: подставляем оптимальный дискриминатор и узнаём JS#

Подставим DG∗D^*_G обратно в VV. Поскольку 1−DG∗=pgpdata+pg1 - D^*_G = \dfrac{p_g}{p_{\text{data}} + p_g},

C(G):=max⁡DV(G,D)=V(G,DG∗)=Ex∼pdataln⁡pdata(x)pdata(x)+pg(x)+Ex∼pgln⁡pg(x)pdata(x)+pg(x).\begin{aligned} C(G) :={}& \max_D V(G, D) = V(G, D^*_G) \\ ={}& \mathbb{E}_{x\sim p_{\text{data}}}\ln\frac{p_{\text{data}}(x)}{p_{\text{data}}(x) + p_g(x)} \\ &+ \mathbb{E}_{x\sim p_g}\ln\frac{p_g(x)}{p_{\text{data}}(x) + p_g(x)} . \end{aligned}

Дивергенция Йенсена–Шеннона (определение здесь) сравнивает каждое распределение со смесью m=12(p1+p2)m = \tfrac12(p_1 + p_2). Через математические ожидания

DJS(p1 ∥ p2)=12DKL(p1 ∥ m)+12DKL(p2 ∥ m)=12 Ex∼p1ln⁡p1(x)m(x)+12 Ex∼p2ln⁡p2(x)m(x).\begin{aligned} D_{\mathrm{JS}}(p_1\,\|\,p_2) &= \tfrac12 D_{\mathrm{KL}}(p_1\,\|\,m) \\ &\quad + \tfrac12 D_{\mathrm{KL}}(p_2\,\|\,m) \\ &= \tfrac12\,\mathbb{E}_{x\sim p_1}\ln\frac{p_1(x)}{m(x)} \\ &\quad + \tfrac12\,\mathbb{E}_{x\sim p_2}\ln\frac{p_2(x)}{m(x)} . \end{aligned}

Чтобы знаменатели совпали, разделим каждый из них на 22 внутри логарифма и заплатим за это ln⁡2\ln 2 в каждом математическом ожидании, поскольку ln⁡pp+q=ln⁡p(p+q)/2−ln⁡2\ln\frac{p}{p+q} = \ln\frac{p}{(p+q)/2} - \ln 2. При m=12(pdata+pg)m = \tfrac12(p_{\text{data}} + p_g)

C(G)=Ex∼pdataln⁡pdata(x)m(x)+Ex∼pgln⁡pg(x)m(x)−2ln⁡2,\begin{aligned} C(G) ={}& \mathbb{E}_{x\sim p_{\text{data}}}\ln\frac{p_{\text{data}}(x)}{m(x)} \\ &+ \mathbb{E}_{x\sim p_g}\ln\frac{p_g(x)}{m(x)} - 2\ln 2 , \end{aligned}

то есть

C(G)=2 DJS(pdata ∥ pg)−2ln⁡2.C(G) = 2\,D_{\mathrm{JS}}(p_{\text{data}}\,\|\,p_g) - 2\ln 2 .

Поскольку DJS≥0D_{\mathrm{JS}} \ge 0 и равенство достигается только при pdata=pgp_{\text{data}} = p_g, минимум по GG достигается только при pg=pdatap_g = p_{\text{data}}:

min⁡GC(G)=−2ln⁡2≈−1.386,\min_G C(G) = -2\ln 2 \approx -1.386 ,

и при этом D∗=12D^* = \tfrac12 всюду. Для двух плотностей с рисунка об оптимальном дискриминаторе DJS≈0.430D_{\mathrm{JS}} \approx 0.430 ната (nats) и C(G)≈−0.526C(G) \approx -0.526; оба значения получены численным интегрированием — и по определению VV, и по формуле через JS.

Это объясняет и предупреждение о неперекрывающихся носителях. Если pdatap_{\text{data}} и pgp_g сосредоточены на непересекающихся множествах, то D∗=1D^* = 1 на данных и D∗=0D^* = 0 на подделках, DJS=ln⁡2D_{\mathrm{JS}} = \ln 2 и C(G)=0C(G) = 0 независимо от того, где именно находится pgp_g. Значит, CC постоянна по параметрам генератора. Однако обратное распространение ошибки дифференцирует не CC: оно передаёт градиент ln⁡(1−D(G(z)))\ln\big(1 - D(G(z))\big) через фиксированный DD, и этот градиент содержит ∇xD\nabla_x D в сгенерированных сэмплах. Когда носители — непересекающиеся компактные множества или многообразия, которые не выровнены идеально (do not perfectly align), существует оптимальный дискриминатор, равный 00 на целой окрестности сгенерированных сэмплов, поэтому там ∇xD∗=0\nabla_x D^* = 0 и градиент генератора исчезает (Arjovsky and Bottou, 2017, теоремы 2.1–2.2). Для дискриминатора, который отличается от D∗D^* не более чем на ε\varepsilon по значению и по градиенту, норма градиента не превосходит Mε/(1−ε)M\varepsilon/(1 - \varepsilon), где MM — верхняя граница нормы якобиана генератора (теорема 2.4).

Это не экзотический случай. Генератор, составленный из аффинных отображений и поэлементных нелинейностей, переводит zz в счётное объединение многообразий размерности не выше dim⁡z\dim z (лемма 1), а естественные изображения, как считается, сосредоточены вблизи многообразия малой размерности. Два таких многообразия почти никогда не перекрываются на множестве положительной меры: они могут пересекаться, но только по множеству меньшей размерности (леммы 2–3). Поэтому идеальный дискриминатор существует и DJS=ln⁡2D_{\mathrm{JS}} = \ln 2, как бы близко ни находились два многообразия (теоремы 2.2–2.3). Это то же насыщение JS, которое мы наблюдали в одномерном случае в заметке о подгонке распределений. Чтобы исправить его, заметка о WGAN заменяет JS на расстояние Вассерштейна-1.

Обучение в картинках#

Рисунок

Как движутся два игрока во время обучения

Четыре стадии обучения GANЧетыре панели с одной и той же красной плотностью данных с двумя модами. Панель 1, в начале: синяя плотность генератора — узкий колокол далеко справа, а зелёная кривая дискриминатора — произвольная волнистая линия около 0.6. Панель 2, после обновления параметров дискриминатора: зелёная кривая — оптимальный дискриминатор, близкий к 1 над данными и падающий до 0 над колоколом генератора. Панель 3, после обновления параметров генератора: синяя плотность сдвинулась влево, на данные; старый колокол нарисован штриховой линией, и от него влево идёт стрелка, а зелёная кривая та же, что на панели 2. Панель 4, в итоге: синяя плотность совпадает с красной, а зелёный дискриминатор — горизонтальная линия на уровне одной второй.1. В началеD(x)pdatapg2. После обновления θdD ≈ D*pdatapg3. После обновления θgD не изменилсяpdatapg4. В итогеD(x) = ½pg = pdataЧетыре стадии обучения GANЧетыре панели с одной и той же красной плотностью данных с двумя модами. Панель 1, в начале: синяя плотность генератора — узкий колокол далеко справа, а зелёная кривая дискриминатора — произвольная волнистая линия около 0.6. Панель 2, после обновления параметров дискриминатора: зелёная кривая — оптимальный дискриминатор, близкий к 1 над данными и падающий до 0 над колоколом генератора. Панель 3, после обновления параметров генератора: синяя плотность сдвинулась влево, на данные; старый колокол нарисован штриховой линией, и от него влево идёт стрелка, а зелёная кривая та же, что на панели 2. Панель 4, в итоге: синяя плотность совпадает с красной, а зелёный дискриминатор — горизонтальная линия на уровне одной второй.1. В началеD(x)pdatapg2. После обновления θdD ≈ D*pdatapg3. После обновления θgD не изменилсяpdatapg4. В итогеD(x) = ½pg = pdata
Красная кривая — плотность данных p_data, синяя — плотность генератора p_g, зелёная — выход дискриминатора D(x) в той же шкале от 0 до 1. Шаг дискриминатора приближает D к D* = p_data / (p_data + p_g). Шаг генератора сдвигает p_g туда, где D высок, а сам D при этом не меняется. На панели 3 штриховая синяя кривая — p_g до шага генератора. В равновесии p_g = p_data и D(x) = ½ всюду. Кривые вычислены по явно заданным плотностям.
  1. В начале pgp_g далеко от pdatap_{\text{data}}, а дискриминатор произволен.
  2. После обновления θd\theta_d дискриминатор DD приближается к D∗D^*: он высок над данными и низок над сгенерированными сэмплами.
  3. После обновления θg\theta_g градиент DD направляет G(z)G(z) в области, которые DD относит к данным, поэтому pgp_g сдвигается к pdatap_{\text{data}}.
  4. В итоге pg=pdatap_g = p_{\text{data}}, и дискриминатор не может их различить: D(x)=12D(x) = \tfrac12.

Эта картина идеализирована. Теория предполагает, что DD достигает оптимума после каждого шага генератора и что оба игрока могут представить любую функцию. На практике оба — нейронные сети, которые обучаются по нескольку шагов за раз, и чередующиеся обновления могут колебаться или схлопываться к нескольким модам данных (коллапс мод, mode collapse) вместо того, чтобы сходиться (Goodfellow, 2016, раздел 5.1.1). Средства против него собраны в разделе о коллапсе мод и борьбе с ним.

Какая функция потерь генератора используется на практике?#

Минимаксную функцию потерь генератора Ezln⁡(1−D(G(z)))\mathbb{E}_z\ln\big(1 - D(G(z))\big) редко минимизируют напрямую. Уже исходная статья рекомендует (Goodfellow et al., 2014, раздел 3) вместо этого обучать генератор максимизировать ln⁡D(G(z))\ln D(G(z)), то есть минимизировать

LG=−Ezln⁡D(G(z)),\mathcal L_G = -\mathbb{E}_z\ln D\big(G(z)\big),

ненасыщающуюся функцию потерь (non-saturating loss). В коде это BCE между выходом дискриминатора на сгенерированных сэмплах и меткой «настоящий».

Проблема минимаксной функции потерь. Когда DD хорош, он уверенно отвергает подделки: d=D(G(z))≈0d = D(G(z)) \approx 0. Тогда ln⁡(1−d)≈ln⁡1=0\ln(1 - d) \approx \ln 1 = 0. Малое значение само по себе не означает малого градиента; важен наклон функции потерь по dd и дальше, при обратном проходе через сеть:

∂∂dln⁡(1−d)=−11−d≈−1,∂∂d(−ln⁡d)=−1d→−∞(d→0).\begin{aligned} \frac{\partial}{\partial d}\ln(1 - d) &= -\frac{1}{1 - d} \approx -1, \\ \frac{\partial}{\partial d}\big(-\ln d\big) &= -\frac1d \to -\infty \quad (d \to 0). \end{aligned}

При d=0.05d = 0.05 наклоны равны −1.05-1.05 и −20-20. Дискриминатор заканчивается сигмоидой, d=σ(ℓ)d = \sigma(\ell), и ∂d/∂ℓ=d(1−d)\partial d/\partial\ell = d(1 - d). Поэтому по логиту градиенты равны −d→0-d \to 0 для минимаксной функции потерь и −(1−d)→−1-(1 - d) \to -1 для ненасыщающейся. Минимаксная функция потерь насыщается по логиту, то есть там, где градиент входит в сеть: её градиент исчезает именно тогда, когда генератор хуже всего, а градиент ненасыщающейся функции потерь там как раз наибольший.

Рисунок

Насыщающаяся и ненасыщающаяся функции потерь генератора

Две функции потерь генератора в зависимости от d и от логита дискриминатораДве панели одна над другой. Верхняя: по горизонтальной оси d = D(G(z)) от 0 до 1, область около 0 затенена и подписана «D: нет» (дискриминатор считает вход подделкой). Янтарная кривая ln(1 − d) начинается в 0 при d = 0 и уходит в минус бесконечность при d, стремящемся к 1; при d = 0.05 наклон её касательной около −1.05, подпись «пологий». Синяя кривая минус ln d начинается в плюс бесконечности около d = 0 и падает до 0 при d = 1; при d = 0.05 наклон её касательной равен −20, подпись «крутой». Нижняя: по горизонтальной оси логит ℓ от −6 до 3. Янтарная кривая ln(1 − σ(ℓ)) почти горизонтальна на уровне 0 при сильно отрицательных логитах и загибается вниз при положительных; её наклон при логите, соответствующем 0.05, равен −0.05, подпись «насыщение». Синяя кривая −ln σ(ℓ) почти прямая с наклоном −1 при отрицательных логитах и выполаживается к 0 при положительных; её наклон в той же точке равен −0.95.D:«нет»−4−202400.250.50.751d = D(G(z))потери генераторакрутой: наклон −1/d = −20пологий: наклон −1.05−ln D(G(z))ненасыщающаяся (в коде)ln(1 − D(G(z)))минимаксная / насыщающаяся−20246−6−4−202логит ℓ, d = σ(ℓ)потери генераторанасыщение: наклон −d = −0.05→ 0 по мере роста уверенности DD: «подделка»линейная: наклон −(1 − d) = −0.95−ln σ(ℓ)ln(1 − σ(ℓ))Две функции потерь генератора в зависимости от d и от логита дискриминатораДве панели одна над другой. Верхняя: по горизонтальной оси d = D(G(z)) от 0 до 1, область около 0 затенена и подписана «D: нет» (дискриминатор считает вход подделкой). Янтарная кривая ln(1 − d) начинается в 0 при d = 0 и уходит в минус бесконечность при d, стремящемся к 1; при d = 0.05 наклон её касательной около −1.05, подпись «пологий». Синяя кривая минус ln d начинается в плюс бесконечности около d = 0 и падает до 0 при d = 1; при d = 0.05 наклон её касательной равен −20, подпись «крутой». Нижняя: по горизонтальной оси логит ℓ от −6 до 3. Янтарная кривая ln(1 − σ(ℓ)) почти горизонтальна на уровне 0 при сильно отрицательных логитах и загибается вниз при положительных; её наклон при логите, соответствующем 0.05, равен −0.05, подпись «насыщение». Синяя кривая −ln σ(ℓ) почти прямая с наклоном −1 при отрицательных логитах и выполаживается к 0 при положительных; её наклон в той же точке равен −0.95.D:«нет»−4−202400.250.50.751d = D(G(z))потери генераторакрутой: наклон −1/d = −20пологий: −1.05−ln D(G(z))ненасыщающаяся (в коде)ln(1 − D(G(z)))минимаксная / насыщающаяся−20246−6−4−202логит ℓ, d = σ(ℓ)потери генераторанасыщение: −d = −0.05D: «подделка»линейная: наклон −(1 − d) = −0.95−ln σ(ℓ)ln(1 − σ(ℓ))
Вверху: обе функции потерь убывают по d = D(G(z)), поэтому минимизация любой из них увеличивает D(G(z)). Там, где D уверенно отвергает подделки, при d = 0.05, наклон минимаксной функции потерь ln(1 − d) равен −1.05: он ограничен, но не равен нулю. Наклон функции потерь −ln d там равен −20. Внизу: те же функции потерь в зависимости от логита дискриминатора ℓ, где d = σ(ℓ); именно этим путём градиент возвращается в сети. Здесь ln(1 − σ(ℓ)) насыщается: её наклон −d равен −0.05 и стремится к 0 по мере того, как D становится увереннее. Функция потерь −ln σ(ℓ) остаётся почти линейной с наклоном −(1 − d) = −0.95.

Обе функции потерь убывают с ростом D(G(z))D(G(z)), поэтому толкают генератор в одном направлении, и при оптимальном дискриминаторе у них общая неподвижная точка pg=pdatap_g = p_{\text{data}} (Goodfellow et al., 2014, раздел 3). Ненасыщающийся вариант уже не является в точности минимаксной игрой. При D=D∗D = D^* его ожидаемый градиент равен градиенту DKL(pg ∥ pdata)−2 DJS(pdata ∥ pg)D_{\mathrm{KL}}(p_g\,\|\,p_{\text{data}}) - 2\,D_{\mathrm{JS}}(p_{\text{data}}\,\|\,p_g) (Arjovsky and Bottou, 2017, теорема 2.5). Первое слагаемое — обратная KL (reverse KL): она сильно штрафует неправдоподобные, не похожие на настоящие сэмплы и лишь слабо — пропущенные моды; это одно из объяснений пропуска мод (mode dropping). Ненасыщающаяся функция потерь устраняет слабые градиенты в начале обучения, но не проблему непересекающихся носителей из предыдущего раздела: если моделировать ошибку дискриминатора вокруг D∗D^* как независимый шум, обновления генератора не исчезают, а становятся неустойчивыми, с бесконечной дисперсией (теорема 2.6).

Вычисление функций потерь по логитам#

Сеть дискриминатора заканчивается логитом ℓ\ell, и D=σ(ℓ)D = \sigma(\ell). Оба логарифма в функциях потерь — функции от ℓ\ell, для которых само значение σ(ℓ)\sigma(\ell) вычислять не нужно:

ln⁡D=ln⁡σ(ℓ)=−softplus⁡(−ℓ),ln⁡(1−D)=ln⁡σ(−ℓ)=−softplus⁡(ℓ),\begin{aligned} \ln D &= \ln\sigma(\ell) = -\operatorname{softplus}(-\ell),\\ \ln(1 - D) &= \ln\sigma(-\ell) = -\operatorname{softplus}(\ell), \end{aligned}

где softplus⁡(t)=ln⁡(1+et)\operatorname{softplus}(t) = \ln(1 + e^{t}). Первая строка следует из σ(ℓ)=1/(1+e−ℓ)\sigma(\ell) = 1/(1 + e^{-\ell}), а вторая использует 1−σ(ℓ)=σ(−ℓ)1 - \sigma(\ell) = \sigma(-\ell). Softplus вычисляют как max⁡(t,0)+ln⁡(1+e−∣t∣)\max(t, 0) + \ln(1 + e^{-\lvert t\rvert}), поэтому экспонента никогда не переполняется. Функция потерь дискриминатора −V-V принимает вид Exsoftplus⁡(−ℓ(x))+Ezsoftplus⁡(ℓ(G(z)))\mathbb E_x\operatorname{softplus}(-\ell(x)) + \mathbb E_z\operatorname{softplus}(\ell(G(z))), а ненасыщающаяся функция потерь генератора — Ezsoftplus⁡(−ℓ(G(z)))\mathbb E_z\operatorname{softplus}(-\ell(G(z))).

Если сначала вычислить σ\sigma, а потом логарифм, вычисление ломается именно там, где дискриминатор уверен. В 32-битной арифметике с плавающей точкой σ(ℓ)\sigma(\ell) округляется ровно до 11, как только ℓ\ell превышает примерно 17, поэтому ln⁡(1−σ(ℓ))\ln(1 - \sigma(\ell)) возвращает −∞-\infty там, где форма через softplus даёт около −17-17, и через округлённую сигмоиду не проходит никакой градиент. Библиотеки глубокого обучения предоставляют устойчивую форму как бинарную кросс-энтропию по логитам (binary_cross_entropy_with_logits в PyTorch).

Обучение GAN на практике#

Теория выше предполагает оптимальный дискриминатор и сети неограниченной ёмкости. Настоящий GAN — это две сети конечной ёмкости, которые обучаются по нескольку шагов за раз, и будет ли обучение вообще работать, решает набор эмпирических правил. Ни одно из них не теорема; каждое приводится здесь вместе с причиной, по которой оно помогает.

Архитектура: рекомендации DCGAN#

Первые свёрточные GAN, которые надёжно обучались на изображениях, следовали пяти правилам (Radford, Metz and Chintala, 2016, раздел 3):

  1. Никакого пулинга (pooling). Дискриминатор понижает разрешение свёртками с шагом больше 1 (strided convolutions), а генератор повышает его свёртками с дробным шагом (fractionally strided), то есть транспонированными свёртками (transposed convolutions), так что обе сети сами учатся менять разрешение.
  2. Батч-нормализация (batch normalization) в обеих сетях, кроме выходного слоя генератора и входного слоя дискриминатора, где из-за неё сэмплы начинали колебаться.
  3. Никаких полносвязных скрытых слоёв. Первый слой генератора — матричное умножение, выход которого переформируется в небольшую пространственную карту: 4×44 \times 4 с 1024 каналами в генераторе 64×6464 \times 64 из статьи. Последние свёрточные признаки дискриминатора вытягиваются в вектор и дают один выход с сигмоидой.
  4. ReLU в генераторе и Tanh на его выходе, чтобы изображения лежали в [−1,1][-1, 1], как и обучающие изображения, отмасштабированные в этот диапазон.
  5. LeakyReLU в дискриминаторе с наклоном 0.20.2.

Стандартными стали и детали обучения (раздел 4): Adam с шагом обучения (learning rate) 2⋅10−42\cdot10^{-4} и β1=0.5\beta_1 = 0.5, потому что обычное β1=0.9\beta_1 = 0.9 приводило к колебаниям; мини-батчи по 128 примеров; веса, инициализированные из N(0,0.022)\mathcal N(0, 0.02^2); и 100-мерный вектор шума из равномерного распределения.

У этих правил есть причины, которые объясняют предыдущие заметки. Свёртки с шагом и LeakyReLU сохраняют градиенты плотными: max-пулинг передаёт градиент только одному входу каждого окна, а ReLU при отрицательных входах не передаёт его вовсе, тогда как LeakyReLU сохраняет там наклон 0.20.2 (см. распространённые решения проблемы затухающих градиентов). Именно батч-нормализация позволила глубоким генераторам начать обучаться, и она не давала им схлопнуть все сэмплы в одну точку (раздел 3). Внутри дискриминатора она к тому же делает каждый выход зависящим от статистик всего мини-батча — это слабая форма описанной ниже дискриминации по мини-батчу (minibatch discrimination; Salimans et al., 2016, разделы 3.2 и 3.5).

Более поздние архитектуры меняют часть правил, но сохраняют их назначение.

  • Повышение разрешения. Транспонированная свёртка, размер ядра которой не делится на шаг, перекрывается неравномерно и может оставлять шахматные артефакты (checkerboard artifacts). Изменение размера с последующей обычной свёрткой избегает неравномерного перекрытия (транспонированная свёртка или повышение разрешения + свёртка?).
  • Полностью свёрточный дискриминатор. Последним слоем может быть свёртка, ядро которой покрывает всю оставшуюся карту признаков, например 4×44 \times 4 на карте 4×44 \times 4; она возвращает один логит на изображение без полносвязного слоя. Radford et al. обнаружили, что глобальный усредняющий пулинг (global average pooling) на этом месте повышал устойчивость, но замедлял сходимость (раздел 3).
  • Дропаут (dropout) в дискриминаторе. Случайное выбрасывание целых карт признаков, как в шумоподавляющем автоэнкодере (denoising autoencoder), регуляризует дискриминатор, так что он меньше подстраивается под обучающие изображения.
  • Латентный код. Никакая теория не задаёт его размер. Слишком маленький код не может представить разнообразие данных; DCGAN использует 100 измерений, и обычны значения от 100 до 256. Свёрточный генератор может также начинать с небольшой пространственной сетки шума, например 4×44 \times 4 с несколькими каналами, и удваивать разрешение в каждом блоке: 4→8→16→32→644 \to 8 \to 16 \to 32 \to 64.
  • Сэмплирование из суженного априорного распределения. Если при сэмплировании уменьшить масштаб шума, например брать z∼N(0,0.72I)z \sim \mathcal N(0, 0.7^2 I) вместо N(0,I)\mathcal N(0, I), изображения получаются более типичными, но менее разнообразными. Тогда сэмплы приходят не из того распределения, на котором обучался генератор. Такое сужение априорного распределения — эвристика, похожая на усечение, которую часто вольно называют трюком усечения (truncation trick); она жертвует полнотой (recall) ради точности (precision). Строго говоря, масштабирование гауссианы — не сэмплирование усечённой гауссианы, которое BigGAN выполняет, пересэмплируя значения за порогом. Любая метрика, посчитанная по таким сэмплам, измеряет изменённое распределение, поэтому масштаб сэмплирования нужно сообщать вместе с ней.

Баланс двух игроков#

Дискриминатор — единственный источник градиента для генератора, поэтому оба игрока должны улучшаться с сопоставимой скоростью. Уже исходная статья предупреждает, что генератор, который слишком долго обучается против фиксированного дискриминатора, отображает слишком много значений zz в один и тот же xx (Goodfellow et al., 2014, раздел 6). Регуляторы здесь — число kk шагов дискриминатора на шаг генератора, два шага обучения и ёмкость каждой сети.

  • Дискриминатор насыщается: он почти наверняка отвергает подделки, и градиенты генератора уменьшаются. Минимаксная функция потерь насыщается, а при непересекающихся носителях даже оптимальный дискриминатор не указывает направления. Тогда дискриминатор обновляют реже, снижают его шаг обучения или уменьшают его ёмкость.
  • Генератор не справляется или схлопывается к нескольким модам, а обратная связь от дискриминатора неустойчива: дискриминатор отстаёт и указывает плохие направления. Тогда его обновляют чаще, k>1k > 1.

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

Картину дополняют три привычки. Обрезка нормы градиента (gradient clipping; распространённые решения) защищает от редких взрывных обновлений; Nowozin, Cseke и Tomioka сочли Adam и обрезку полезными в своём самом крупном эксперименте (2016, раздел 3.2). Небольшая архитектура или небольшой набор данных сначала проверяют, что весь конвейер работает. И на сэмплы стоит смотреть часто: две функции потерь меняются в противоположные стороны и не измеряют качество сэмплов, поэтому заметить коллапс рано позволяют именно сэмплы, а позже и метрики вроде Inception Score.

Сглаживание и инвертирование меток#

Одностороннее сглаживание меток (one-sided label smoothing) обучает дискриминатор на настоящих сэмплах с целевым значением α=0.9\alpha = 0.9 вместо 11, чтобы он никогда не становился полностью уверенным (Salimans et al., 2016, раздел 3.4). Почему только на настоящих сэмплах? Пусть целевые значения равны α\alpha для настоящих и β\beta для поддельных сэмплов. Подынтегральное выражение из шага 1 принимает вид Aln⁡s+Bln⁡(1−s)A\ln s + B\ln(1 - s), где A=α pdata+β pgA = \alpha\,p_{\text{data}} + \beta\,p_g и B=(1−α) pdata+(1−β) pgB = (1 - \alpha)\,p_{\text{data}} + (1 - \beta)\,p_g, поэтому его максимум достигается в точке A/(A+B)A/(A + B):

D∗(x)=α pdata(x)+β pg(x)pdata(x)+pg(x).D^*(x) = \frac{\alpha\,p_{\text{data}}(x) + \beta\,p_g(x)}{p_{\text{data}}(x) + p_g(x)} .

Рассмотрим область, где генератор помещает гораздо больше массы, чем данные, так что отношение r=pdata/pgr = p_{\text{data}}/p_g мало. Там с точностью до первого порядка по rr имеем D∗≈β+(α−β) rD^* \approx \beta + (\alpha - \beta)\,r.

  • При β=0\beta = 0 ненасыщающаяся функция потерь −ln⁡D∗≈−ln⁡α−ln⁡r-\ln D^* \approx -\ln\alpha - \ln r следует за логарифмом отношения плотностей, и её градиент не уменьшается вместе с rr.
  • При β>0\beta > 0 она равна −ln⁡D∗≈−ln⁡β−α−ββ r-\ln D^* \approx -\ln\beta - \frac{\alpha - \beta}{\beta}\,r, и её градиент −α−ββ r ∇ln⁡r-\frac{\alpha - \beta}{\beta}\,r\,\nabla\ln r содержит малый множитель rr: подделки, далёкие от данных, почти не сдвигаются.

Поэтому сглаживают только метку настоящих сэмплов. При β=0\beta = 0 оптимальный выход не превосходит α\alpha: там, где две плотности равны, он равен 0.450.45 вместо 0.50.5.

Случайное инвертирование меток (random label flipping) меняет на противоположные метки небольшой случайной доли ε\varepsilon обучающих примеров дискриминатора. Бинарная кросс-энтропия H(y,y^)=−[yln⁡y^+(1−y)ln⁡(1−y^)]H(y, \hat y) = -[y\ln\hat y + (1 - y)\ln(1 - \hat y)] линейна по целевому значению yy, поэтому в среднем инвертирование заменяет целевые значения 11 и 00 на 1−ε1 - \varepsilon и ε\varepsilon. Это двустороннее сглаживание меток с α=1−ε\alpha = 1 - \varepsilon и β=ε\beta = \varepsilon плюс шум. Оно не даёт дискриминатору стать излишне уверенным, но, согласно рассуждению выше, его половина, относящаяся к подделкам, ослабляет притяжение далёких от данных подделок, поэтому его применяют осторожно, если применяют вообще.

Коллапс мод и борьба с ним#

При коллапсе мод генератор отображает большую часть своего шума в несколько выходов, которые принимает текущий дискриминатор. Salimans et al. (2016, раздел 3.2) описывают механизм. Дискриминатор рассматривает каждый сэмпл по отдельности, поэтому его градиент указывает в одну и ту же сторону для всех похожих сэмплов, и ничто не требует от выходов генератора отличаться друг от друга. Когда дискриминатор научится отвергать схлопнувшуюся моду, генератор переходит к другой, и они могут гоняться друг за другом бесконечно. Вторая причина — слагаемое с обратной KL в ненасыщающейся функции потерь (выше): пропуск моды обходится ей дёшево. Средства борьбы воздействуют на разные части этого механизма.

  • Дискриминация по мини-батчу позволяет дискриминатору сравнивать сэмплы (Salimans et al., 2016, раздел 3.2). Промежуточный вектор признаков f(xi)∈RAf(x_i) \in \mathbb R^A умножается на обучаемый тензор T∈RA×B×CT \in \mathbb R^{A\times B\times C}, что даёт матрицу Mi∈RB×CM_i \in \mathbb R^{B\times C}. Для каждой её строки bb близость двух сэмплов равна cb(xi,xj)=exp⁡(−∥Mi,b−Mj,b∥1)c_b(x_i, x_j) = \exp\big(-\lVert M_{i,b} - M_{j,b}\rVert_1\big), и слой выдаёт o(xi)b=∑jcb(xi,xj)o(x_i)_b = \sum_{j} c_b(x_i, x_j) — сумму по мини-батчу. Вектор o(xi)∈RBo(x_i) \in \mathbb R^B присоединяется к f(xi)f(x_i) и подаётся на следующий слой, отдельно для мини-батчей настоящих и сгенерированных сэмплов. Схлопнувшийся батч содержит много почти одинаковых сэмплов и поэтому даёт большие значения oo, и дискриминатор может научиться такие батчи отвергать.
  • Развёрнутые GAN (unrolled GANs) позволяют генератору предвидеть ответ дискриминатора (Metz et al., 2017, разделы 2.2–2.4). Запишем функцию ценности как V(θG,θD)V(\theta_G, \theta_D). Начиная с θD0=θD\theta_D^0 = \theta_D, сделаем KK шагов градиентного подъёма дискриминатора, θDk+1=θDk+η ∂V(θG,θDk)/∂θDk\theta_D^{k+1} = \theta_D^k + \eta\,\partial V(\theta_G, \theta_D^k)/\partial\theta_D^k, и определим суррогат VK(θG,θD)=V(θG,θDK(θG,θD))V_K(\theta_G, \theta_D) = V\big(\theta_G, \theta_D^K(\theta_G, \theta_D)\big). Генератор спускается по VKV_K, распространяя градиент обратно через все KK шагов, а дискриминатор по-прежнему обновляется по VV. По правилу дифференцирования сложной функции градиент VKV_K состоит из двух слагаемых (раздел 2.4): обычной производной ∂V/∂θG\partial V/\partial\theta_G при развёрнутом дискриминаторе и слагаемого через dθDK/dθGd\theta_D^K/d\theta_G, которое описывает, как дискриминатор отреагировал бы на ход генератора. Первое слагаемое само по себе толкает к коллапсу: против фиксированного дискриминатора наилучший генератор помещает всю массу в единственную точку, которая больше всего нравится дискриминатору. Второе слагаемое «видит», что схлопнувшийся генератор быстро был бы отвергнут, и тем самым препятствует коллапсу. K=0K = 0 — стандартный GAN. Если KK внутренних шагов сходятся к оптимальному дискриминатору, то при K→∞K \to \infty суррогат приближается к истинной целевой функции генератора V(θG,θD∗(θG))V(\theta_G, \theta_D^*(\theta_G)); у нейросетевого дискриминатора внутренний подъём может не сойтись или дойти лишь до локального оптимума, так что большое KK — приближение, а не гарантия.
  • История. Историческое усреднение (historical averaging) добавляет к функции потерь каждого игрока слагаемое ∥θ−1t∑i=1tθ[i]∥2\big\lVert\theta - \tfrac1t\sum_{i=1}^{t}\theta[i]\big\rVert^2, где θ[i]\theta[i] — параметры на прошлом шаге ii: это притяжение к среднему всех прошлых значений параметров, которое гасит колебания (Salimans et al., 2016, раздел 3.3). Если обучать дискриминатор частично на буфере сэмплов от прежних генераторов (в Shrivastava et al. (2017), раздел 2.3, это половина каждого мини-батча дискриминатора), он не забывает моды, которые генератор посещал раньше, и генератор не может безнаказанно к ним вернуться.
  • Несколько дискриминаторов. GMAN обучает генератор против NN дискриминаторов и объединяет их значения сглаженным максимумом, который переходит от среднего к максимуму, когда параметр λ\lambda растёт от 00 до ∞\infty (Durugkar, Gemp and Mahadevan, 2017, раздел 4.1). Среднее — снисходительный учитель, а максимум — суровый противник.
  • Другое расстояние. GAN Вассерштейна (Wasserstein GAN) со штрафом на градиент (gradient penalty) или спектральной нормализацией критика даёт полезные градиенты, даже когда носители не перекрываются. Исходный WGAN, обученный с обрезкой весов (weight clipping), не показал признаков коллапса мод ни в одном из экспериментов его авторов (Arjovsky, Chintala and Bottou, 2017, раздел 4.3).

Расширения#

Условный GAN#

Условный GAN (conditional GAN; Mirza and Osindero, 2014) даёт обеим сетям метку cc, например класс: генератор выдаёт G(z,c)G(z, c), а дискриминатор оценивает пары D(x,c)D(x, c). Пусть pdata(x,c)p_{\text{data}}(x, c) — совместное распределение данных и меток, а pcp_c — его маргинальное распределение меток. Функция ценности становится такой:

Vcond=E(x,c)∼pdata[ln⁡D(x,c)]+Ec, z[ln⁡(1−D(G(z,c),c))],\begin{aligned} V_{\text{cond}} ={}& \mathbb{E}_{(x,c)\sim p_{\text{data}}}\big[\ln D(x,c)\big] \\ &+ \mathbb{E}_{c,\,z}\big[\ln\big(1-D(G(z,c),c)\big)\big], \end{aligned}

где второе математическое ожидание берётся по c∼pcc \sim p_c и z∼pzz \sim p_z. Это исходная игра, разыгранная на парах (x,c)(x, c): у сгенерированных пар совместное распределение pg(x,c)=pc(c) pg(x∣c)p_g(x, c) = p_c(c)\,p_g(x \mid c), и рассуждение из предыдущих разделов, применённое к парам, показывает, что в оптимуме совместные распределения совпадают: pg(x,c)=pdata(x,c)p_g(x, c) = p_{\text{data}}(x, c). Реалистичное изображение в паре с неверной меткой лежит вне совместного распределения данных, поэтому дискриминатор может его отвергнуть, и генератор учится следовать условию. Это аналог условного VAE для GAN.

f-GAN#

Дополнительный материал: игра для любой f-дивергенции через сопряжённые функции. Остальная часть заметки на него не опирается.

Исходный GAN минимизирует JS. f-GAN (Nowozin, Cseke and Tomioka, 2016) обобщает игру на любую f-дивергенцию (f-divergence)

Df(P ∥ Q)=∫q(x) f ⁣(p(x)q(x))dx,D_f(P\,\|\,Q) = \int q(x)\, f\!\left(\frac{p(x)}{q(x)}\right) dx ,

где ff — выпуклая полунепрерывная снизу функция с f(1)=0f(1) = 0; f(u)=uln⁡uf(u) = u\ln u даёт DKL(P ∥ Q)D_{\mathrm{KL}}(P\,\|\,Q). Ключевой инструмент — сопряжённая по Фенхелю функция (convex conjugate) f∗(t)=sup⁡u{ut−f(u)}f^*(t) = \sup_u \{ut - f(u)\}. После перестановки слагаемых определение даёт неравенство f(u)≥tu−f∗(t)f(u) \ge tu - f^*(t) при любом tt: каждая прямая с наклоном tt и свободным членом −f∗(t)-f^*(t) лежит под графиком ff, а для дифференцируемой ff прямая с t=f′(u)t = f'(u) касается графика в точке uu. Для выпуклой полунепрерывной снизу ff эти прямые восстанавливают ff в точности: f(u)=sup⁡t{tu−f∗(t)}f(u) = \sup_t \{tu - f^*(t)\} (теорема Фенхеля–Моро). Например, f(u)=12(u−1)2f(u) = \tfrac12(u - 1)^2, половина порождающей функции дивергенции χ2\chi^2 Пирсона, даёт f∗(t)=t+12t2f^*(t) = t + \tfrac12 t^2: супремум tu−12(u−1)2tu - \tfrac12(u-1)^2 достигается при u=1+tu = 1 + t.

Рисунок

Сопряжённая по Фенхелю функция как свободный член касательной

Геометрический смысл сопряжённой по Фенхелю функцииВыпуклая парабола f от u с минимумом 0 при u, равном 1. Янтарная прямая с наклоном t, равным 1, касается параболы в единственной точке u со звёздочкой, равной 2, на высоте одна вторая и пересекает вертикальную ось в точке минус 1.5 с подписью минус f со звёздочкой от t. Штриховая прямая y равно t u проходит через начало координат; при u со звёздочкой вертикальный зазор между штриховой прямой и параболой равен 1.5 и отмечен зелёной двусторонней стрелкой с подписью f со звёздочкой от t, наибольший зазор. Маленький треугольник наклона на касательной показывает подъём t на единицу смещения по горизонтали.uy0f(u)y = t uy = t u − f*(t)1tu*прямая с наклоном t касается fв одной точке: f′(u*) = tf*(t) = наибольшийзазор между t u и f(u)−f*(t)Геометрический смысл сопряжённой по Фенхелю функцииВыпуклая парабола f от u с минимумом 0 при u, равном 1. Янтарная прямая с наклоном t, равным 1, касается параболы в единственной точке u со звёздочкой, равной 2, на высоте одна вторая и пересекает вертикальную ось в точке минус 1.5 с подписью минус f со звёздочкой от t. Штриховая прямая y равно t u проходит через начало координат; при u со звёздочкой вертикальный зазор между штриховой прямой и параболой равен 1.5 и отмечен зелёной двусторонней стрелкой с подписью f со звёздочкой от t, наибольший зазор. Маленький треугольник наклона на касательной показывает подъём t на единицу смещения по горизонтали.uy0f(u)y = t uy = t u − f*(t)1tu*f*(t)−f*(t)
Выпуклая функция f(u) = ½(u − 1)² с f(1) = 0 (синяя) и наклон t = 1. Прямая с наклоном t, касающаяся f ровно в одной точке (янтарная), касается её в u* = 2, где f′(u*) = t. Её свободный член равен −f*(t) = −1.5. Эквивалентно, f*(t) = max по u от t·u − f(u) — это наибольший вертикальный зазор между прямой t·u, проходящей через начало координат (штриховая), и f; он достигается в той же точке u* (зелёная стрелка). В замкнутой форме f*(t) = t + t²/2.

Подставим это представление в каждой точке, положив u(x)=p(x)/q(x)u(x) = p(x)/q(x), и позволим наклону t=T(x)t = T(x) зависеть от xx (Nguyen, Wainwright and Jordan, 2010; Nowozin, Cseke and Tomioka, 2016, раздел 2.2, формулы 4–5):

Df(P ∥ Q)=∫q(x)sup⁡t{tu(x)−f∗(t)} dx=sup⁡T∫[p(x) T(x)−q(x) f∗(T(x))] dx≥sup⁡T∈T{Ex∼P[T(x)]−Ex∼Q[f∗(T(x))]}.\begin{aligned} D_f(P\,\|\,Q) &= \int q(x) \sup_t \big\{ t u(x) - f^*(t) \big\}\,dx \\ &= \sup_T \int \Big[ p(x)\,T(x) \\ &\qquad - q(x)\,f^*\big(T(x)\big) \Big]\, dx \\ &\ge \sup_{T \in \mathcal T} \Big\{\mathbb{E}_{x\sim P}\big[T(x)\big] \\ &\qquad - \mathbb{E}_{x\sim Q}\big[f^*(T(x))\big]\Big\}. \end{aligned}

Во второй строке наилучший наклон выбирается отдельно в каждой точке. Если TT пробегает все функции со значениями в области определения f∗f^*, при этом ничего не теряется: для дифференцируемой ff супремум достигается при T∗(x)=f′(p(x)/q(x))T^*(x) = f'\big(p(x)/q(x)\big). Неравенство появляется в третьей строке, где TT ограничена классом T\mathcal T, например семейством нейронных сетей.

При P=pdataP = p_{\text{data}}, Q=pgQ = p_g и нейронной сети TT правая часть — игра двух игроков: TT играет роль дискриминатора и максимизирует, а генератор минимизирует. Обоим математическим ожиданиям нужны только сэмплы, а не плотности, и именно поэтому оценка пригодна для неявной модели. Исходный GAN — один из частных случаев, с ненормированной порождающей функцией. При f(u)=uln⁡u−(u+1)ln⁡(u+1)f(u) = u\ln u - (u + 1)\ln(u + 1) имеем f(1)=−2ln⁡2=−ln⁡4f(1) = -2\ln 2 = -\ln 4, а не 00: эта ff — нормированная порождающая функция плюс константа −ln⁡4-\ln 4, и поскольку ∫q (−ln⁡4) dx=−ln⁡4\int q\,(-\ln 4)\,dx = -\ln 4, дивергенция сдвигается на ту же константу: Df(P ∥ Q)=2 DJS(P ∥ Q)−ln⁡4D_f(P\,\|\,Q) = 2\,D_{\mathrm{JS}}(P\,\|\,Q) - \ln 4, а сопряжённая функция равна f∗(t)=−ln⁡(1−et)f^*(t) = -\ln(1 - e^t) при t<0t < 0. Подстановка T(x)=ln⁡D(x)T(x) = \ln D(x) с D(x)∈(0,1)D(x) \in (0, 1) даёт f∗(T(x))=−ln⁡(1−D(x))f^*(T(x)) = -\ln(1 - D(x)), и оценка превращается в точности в V(G,D)V(G, D) (Nowozin, Cseke and Tomioka, 2016, раздел 2.4, таблицы 1 и 6).

Выходные активации. Оценке нужно, чтобы T(x)T(x) лежало в области определения f∗f^*, а для большинства дивергенций это не вся вещественная прямая. Поэтому в f-GAN сеть выдаёт неограниченное число v(x)v(x), которое затем проходит через фиксированную возрастающую выходную активацию (output activation) gfg_f, так что T(x)=gf(v(x))T(x) = g_f(v(x)) (раздел 2.4, формула 7). Игра принимает вид

F=Ex∼P[gf(v(x))]−Ex∼Q[f∗(gf(v(x)))].\begin{aligned} F ={}& \mathbb{E}_{x\sim P}\big[g_f(v(x))\big] \\ &- \mathbb{E}_{x\sim Q}\big[f^*\big(g_f(v(x))\big)\big] . \end{aligned}

В таблице собраны обычные варианты (таблицы 1 и 2). Соглашение то же, что выше: Df(P ∥ Q)=∫q f(p/q) dxD_f(P\,\|\,Q) = \int q\, f(p/q)\,dx при P=pdataP = p_{\text{data}} и Q=pgQ = p_g, а порождающие функции ff взяты у Nowozin et al. Условие после f∗(t)f^*(t) задаёт её область определения.

Дивергенцияf(u)f(u)gf(v)g_f(v)f∗(t)f^*(t)
DKL(P∥Q)D_{\mathrm{KL}}(P\Vert Q)uln⁡uu\ln uvvet−1e^{t-1}
DKL(Q∥P)D_{\mathrm{KL}}(Q\Vert P)−ln⁡u-\ln u−e−v-e^{-v}−1−ln⁡(−t)-1-\ln(-t), t<0t<0
χ2\chi^2 Пирсона(u−1)2(u-1)^2vvt+t2/4t + t^2/4
квадрат расстояния Хеллингера(u−1)2(\sqrt u - 1)^21−e−v1 - e^{-v}t/(1−t)t/(1-t), t<1t<1
2DJS2D_{\mathrm{JS}}uln⁡u−(u+1)ln⁡u+12u\ln u - (u+1)\ln\frac{u+1}{2}ln⁡2−ln⁡(1+e−v)\ln 2 - \ln(1 + e^{-v})−ln⁡(2−et)-\ln(2 - e^{t}), t<ln⁡2t<\ln 2
GAN: 2DJS−ln⁡42D_{\mathrm{JS}} - \ln 4, без нормировкиuln⁡u−(u+1)ln⁡(u+1)u\ln u - (u+1)\ln(u+1)−ln⁡(1+e−v)-\ln(1 + e^{-v})−ln⁡(1−et)-\ln(1 - e^{t}), t<0t<0

Три замечания к таблице.

  • Каждая gfg_f возрастает, поэтому большое v(x)v(x) всегда означает «выглядит настоящим».
  • Nowozin et al. называют пятую строку дивергенцией Йенсена–Шеннона, но при этой ff получается удвоенная DJSD_{\mathrm{JS}} в смысле определения из заметки об энтропии. Её ff больше, чем в строке GAN, на (u+1)ln⁡2(u+1)\ln 2, поэтому две дивергенции отличаются на константу ln⁡4\ln 4, и обучение по этим двум строкам идёт одинаково.
  • Строка Пирсона использует f(u)=(u−1)2f(u) = (u - 1)^2. Порождающая функция 12(u−1)2\tfrac12(u - 1)^2 из примера выше даёт половину этой дивергенции и сопряжённую функцию t+t2/2t + t^2/2.

Сначала композиция, потом вычисление. Если вычислять сначала gfg_f, а затем f∗f^*, теряется точность — по той же причине, что и при σ\sigma с последующим ln⁡\ln (выше), и Nowozin et al. рекомендуют реализовывать композицию f∗(gf(v))f^*(g_f(v)) напрямую (раздел 2.4, сноска 1). Для каждой строки она проста: сверху вниз ev−1e^{v-1}, v−1v - 1, v+v2/4v + v^2/4, ev−1e^{v} - 1, softplus⁡(v)−ln⁡2\operatorname{softplus}(v) - \ln 2 и softplus⁡(v)\operatorname{softplus}(v). Для строки GAN gf(v)=−softplus⁡(−v)=ln⁡σ(v)g_f(v) = -\operatorname{softplus}(-v) = \ln\sigma(v), поэтому FF — в точности бинарная кросс-энтропия дискриминатора со знаком минус, вычисленная по его логиту vv.

Шаг генератора. Как и в GAN, генератор может максимизировать Ex∼Q[gf(v(x))]\mathbb E_{x\sim Q}\big[g_f(v(x))\big] вместо того, чтобы минимизировать относящееся к подделкам слагаемое FF. Стационарная точка при этом сохраняется, и Nowozin et al. сочли такой шаг полезным и для дивергенций, отличных от дивергенции GAN (раздел 3.2).

GAN наименьших квадратов#

Дополнительный материал: квадратичная функция потерь дискриминатора и то, что минимизирует её оптимум. Остальная часть заметки на него не опирается.

Ненасыщающаяся функция потерь исправляет градиент для подделок, которые дискриминатор уверенно отвергает. GAN наименьших квадратов (least-squares GAN, LSGAN) исправляет и противоположный случай — подделки, которые дискриминатор уже принимает, но которые всё ещё далеки от данных (Mao et al., 2017). У его дискриминатора нет сигмоиды. Это регрессионная сеть с вещественным выходом, которую обучают выдавать значение bb на настоящих сэмплах и aa на подделках, а генератор хочет, чтобы его сэмплы получали значение cc (раздел 3.2, формула 2):

min⁡D  12 Ex∼pdata[(D(x)−b)2]+12 Ez∼pz[(D(G(z))−a)2],min⁡G  12 Ez∼pz[(D(G(z))−c)2].\begin{aligned} \min_D\;& \tfrac12\,\mathbb E_{x\sim p_{\text{data}}}\big[(D(x) - b)^2\big] \\ &+ \tfrac12\,\mathbb E_{z\sim p_z}\big[(D(G(z)) - a)^2\big],\\ \min_G\;& \tfrac12\,\mathbb E_{z\sim p_z}\big[(D(G(z)) - c)^2\big]. \end{aligned}

Обычный выбор — кодирование 0–1, a=0a = 0, b=c=1b = c = 1 (формула 9): дискриминатор учится выдавать 1 на настоящих сэмплах и 0 на подделках, а генератор добивается значения 1. Mao et al. обнаружили, что это кодирование работает так же, как кодирование для χ2\chi^2, описанное ниже, и использовали его в своих экспериментах (раздел 3.2.3).

Почему помогают наименьшие квадраты. Граница решений (decision boundary) проходит там, где DD находится посередине между aa и bb. Подделка может лежать по «настоящую» сторону этой границы, так что дискриминатор уже считает её настоящей, и всё же быть далеко от данных. При сигмоиде и кросс-энтропии у такого сэмпла почти нет ни потерь, ни градиента: ненасыщающаяся функция потерь −ln⁡σ(ℓ)-\ln\sigma(\ell) выполаживается с ростом логита ℓ\ell, и её наклон −(1−σ(ℓ))→0-(1 - \sigma(\ell)) \to 0. Квадратичная функция потерь плоская только при D=cD = c, поэтому подделку, получившую значение дальше cc, тянет обратно, но лишь до линии уровня D=cD = c. Во время шага генератора дискриминатор фиксирован, поэтому такие подделки сдвигаются к границе решений, а для успешного обучения граница должна проходить через данные (раздел 3.2.1).

Рисунок

Наименьшие квадраты тянут далёкие подделки обратно

Сдвиг подделок под BCE и под наименьшими квадратамиВерхняя панель: красный колокол данных с центром в 1 и синий колокол подделок с центром в минус 1; вертикальная штриховая линия в x = 0 — граница решений. Нижняя панель, та же ось x от минус 4 до 6: янтарная кривая BCE начинается около 1.1 слева, проходит через 1 в x = минус 1 и падает к нулю справа от 2. Зелёная прямая наименьших квадратов убывает от 2 в x = минус 4, пересекает ноль в x = 2 и становится отрицательной справа, достигая минус 1.33 в x = 6. В x = 4 отмечены обе кривые: янтарная почти на нуле, зелёная около минус 0.67.подделки Qданные Pграница, D = ½−1012−4−20246положение подделки xсдвиг (отн. x = −1)BCEнаим. квадратыD(x) = 10.0004−0.67справа от 2: BCE почти 0,наим. квадраты тянут назадСдвиг подделок под BCE и под наименьшими квадратамиВерхняя панель: красный колокол данных с центром в 1 и синий колокол подделок с центром в минус 1; вертикальная штриховая линия в x = 0 — граница решений. Нижняя панель, та же ось x от минус 4 до 6: янтарная кривая BCE начинается около 1.1 слева, проходит через 1 в x = минус 1 и падает к нулю справа от 2. Зелёная прямая наименьших квадратов убывает от 2 в x = минус 4, пересекает ноль в x = 2 и становится отрицательной справа, достигая минус 1.33 в x = 6. В x = 4 отмечены обе кривые: янтарная почти на нуле, зелёная около минус 0.67.подделки Qданные Pграница, D = ½−1012−4−20246положение подделки xсдвиг (отн. x = −1)BCEнаим. квадратыD(x) = 10.0004−0.67
Вверху: настоящие данные P = N(1, 1) (красные) и сгенерированные сэмплы Q = N(−1, 1) (синие). На них обучены два линейных дискриминатора: с BCE (логистическая регрессия с логитом 2x, здесь она совпадает с оптимальным дискриминатором) и с наименьшими квадратами и целями 1 для настоящих и 0 для поддельных, D(x) = 0.25x + 0.5. Оба проводят границу решений через x = 0. Внизу: сдвиг −∂L_G/∂x, который получает подделка в точке x от функции потерь генератора: ненасыщающейся BCE −ln σ(2x) и наименьших квадратов ½(D(x) − 1)². Каждая кривая поделена на своё значение в x = −1, центре подделок; положительные значения двигают сэмпл вправо, к данным. Подделка в x = 4, далеко на «настоящей» стороне границы, получает по BCE сдвиг всего 0.0004 и остаётся на месте. Сдвиг по наименьшим квадратам равен −0.67: он возвращает её к x = 2, где D(x) = 1.

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

Оптимальный дискриминатор и χ2\chi^2 Пирсона. При фиксированном генераторе функцию потерь дискриминатора можно минимизировать поточечно, как в шаге 1. Подынтегральное выражение 12pdata(D−b)2+12pg(D−a)2\tfrac12 p_{\text{data}}(D - b)^2 + \tfrac12 p_g(D - a)^2 — парабола по DD с минимумом в точке (формула 5)

D∗(x)=b pdata(x)+a pg(x)pdata(x)+pg(x).D^*(x) = \frac{b\,p_{\text{data}}(x) + a\,p_g(x)}{p_{\text{data}}(x) + p_g(x)} .

Добавим к функции потерь генератора слагаемое 12 Ex∼pdata[(D(x)−c)2]\tfrac12\,\mathbb E_{x\sim p_{\text{data}}}\big[(D(x) - c)^2\big]; оно не зависит от GG и потому не меняет ни одного градиента. При D=D∗D = D^*, используя D∗−c=((b−c) pdata+(a−c) pg)/(pdata+pg)D^* - c = \big((b - c)\,p_{\text{data}} + (a - c)\,p_g\big)/(p_{\text{data}} + p_g), получаем расширенную функцию потерь (формулы 4 и 6)

2C(G)=∫(pdata+pg)(D∗−c)2 dx=∫((b−c) pdata+(a−c) pg)2pdata+pg dx.\begin{aligned} 2C(G) &= \int \big(p_{\text{data}} + p_g\big)\big(D^* - c\big)^2\,dx \\ &= \int \frac{\big((b - c)\,p_{\text{data}} + (a - c)\,p_g\big)^2}{p_{\text{data}} + p_g}\,dx . \end{aligned}

Выберем b−c=1b - c = 1 и b−a=2b - a = 2, например a=−1a = -1, b=1b = 1, c=0c = 0 (формула 8). Тогда a−c=−1a - c = -1, и числитель равен (pdata−pg)2(p_{\text{data}} - p_g)^2. Для смеси m=12(pdata+pg)m = \tfrac12(p_{\text{data}} + p_g) имеем pdata−pg=2(m−pg)p_{\text{data}} - p_g = 2(m - p_g) и pdata+pg=2mp_{\text{data}} + p_g = 2m, поэтому

C(G)=∫(pg(x)−m(x))2m(x) dx=χPearson2(pg ∥ m),C(G) = \int \frac{\big(p_g(x) - m(x)\big)^2}{m(x)}\,dx = \chi^2_{\text{Pearson}}(p_g\,\|\,m),

то есть строка Пирсона из таблицы f-GAN, где pgp_g стоит на месте PP, а mm — на месте QQ. Это повторяет тождество с JS для исходного GAN, которое сравнивает оба распределения с той же смесью через KL-дивергенции. C(G)C(G) равна нулю, только когда pg=mp_g = m, то есть pg=pdatap_g = p_{\text{data}}. Mao et al. записывают ту же величину как χPearson2(pdata+pg ∥ 2pg)\chi^2_{\text{Pearson}}(p_{\text{data}} + p_g\,\|\,2p_g) (формула 7), с опорной мерой в качестве первого аргумента. Для двух гауссиан с рисунка C(G)≈0.550C(G) \approx 0.550 (значение для игрушечного примера, полученное численным интегрированием).

Кодирование 0–1 этим условиям не удовлетворяет: в нём b−c=0b - c = 0, и 2C(G)=∫pg2/(pdata+pg) dx2C(G) = \int p_g^2/(p_{\text{data}} + p_g)\,dx, что при pg=pdatap_g = p_{\text{data}} равно 12\tfrac12, а не 00. Тем не менее минимум достигается именно там. Подынтегральное выражение выпукло по pg(x)p_g(x), а при pg=pdatap_g = p_{\text{data}} его производная по pg(x)p_g(x), (pg2+2pg pdata)/(pdata+pg)2(p_g^2 + 2p_g\,p_{\text{data}})/(p_{\text{data}} + p_g)^2, равна 34\tfrac34 в каждой точке xx — это и есть условие оптимальности для выпуклой целевой функции при ограничении ∫pg=1\int p_g = 1.

Сильные и слабые стороны#

Сильные стороны.

  • Сэмплирование — один прямой проход генератора, а для обучения нужно только обратное распространение ошибки: ни марковских цепей, ни вывода латентных переменных во время обучения, ни вычислительно неразрешимых (intractable) интегралов (Goodfellow et al., 2014, раздел 6).
  • Модель может представлять очень острые, даже вырожденные распределения (раздел 6). Ничто не усредняет правдоподобные изображения в размытое пятно, как это делает квадратичная ошибка гауссовского декодера.
  • Та же игра допускает метки, другие дивергенции и другие функции потерь, как показывают расширения выше.

Слабые стороны.

  • Нет плотности. У pg(x)p_g(x) нет явного выражения (раздел 6), поэтому правдоподобие тестовых данных вычислить нельзя, и сравнивать по нему модели тоже нельзя. Две функции потерь не измеряют качество сэмплов, и ясного критерия остановки нет. Для оценки качества нужны метрики, вычисляемые по сэмплам; им посвящены заметка об Inception Score и следующие за ней.
  • Нет обратного пути. Генератор отображает zz в xx, но ничто не отображает изображение обратно в его код. Чтобы найти код данного изображения, нужна оптимизация по zz или дополнительная сеть, обученная для этой цели.
  • Неустойчивое обучение. Чередующиеся обновления могут колебаться, и двух игроков нужно держать в равновесии.
  • Коллапс мод. Генератор может хорошо покрывать несколько мод и пропускать остальные.
  • Запоминание (memorization). Генератор может воспроизводить обучающие изображения, поэтому сэмплы стоит сравнивать с ближайшими к ним обучающими изображениями. Radford et al. удалили дубликаты из своего самого большого обучающего набора, чтобы сделать запоминание менее вероятным (2016, раздел 4.1.1).

Ноутбук#

Ноутбук о GAN из репозитория HSE-LAMBDA Deep Generative Models (закреплённый коммит; ячейки нумеруются с 1, считая все ячейки подряд) реализует все три модели. В ноутбуке нет сохранённых выходов, поэтому он документирует процедуры, а не результаты.

  • Ячейки 1–2: минимаксная целевая функция и список приёмов, которые использует ноутбук: одностороннее сглаживание меток, обрезка градиентов, дропаут в дискриминаторе, уменьшенная дисперсия латентной переменной при сэмплировании, сбалансированное соотношение числа обновлений и батч-нормализация в генераторе.
  • Ячейки 5–16: безусловный GAN на изображениях цифры 0 из MNIST, приведённых к размеру 32×3232\times32 и отмасштабированных в [−1,1][-1, 1], размер батча 128 с drop_last=True.
    • Ячейка 9: сети. Латентная переменная — не вектор, а пространственная сетка, 4 канала на сетке 4×44 \times 4, и сэмплируется она внутри метода forward генератора. Каждый UpsampleBlock удваивает разрешение билинейной интерполяцией, а затем дважды применяет свёртку 3×33 \times 3, батч-нормализацию и LeakyReLU(0.2). Три блока переводят 4×44 \times 4 в 32×3232 \times 32 с 32, 64 и 128 каналами, а свёртка 1×11 \times 1 с Tanh даёт изображение. Каждый DownsampleBlock применяет свёртку 3×33 \times 3 с шагом 2 и свёртку 3×33 \times 3, после каждой из которых идут батч-нормализация, LeakyReLU(0.2) и Dropout2d(0.3), и три блока переводят 32×3232 \times 32 в 4×44 \times 4. Дискриминатор полностью свёрточный: последняя свёртка 4×44 \times 4 превращает карту 4×4×1284 \times 4 \times 128 в один логит. Строки документации (docstrings) говорят о четырёх блоках и о глобальном усреднении, но в коде три блока и никакого пулинга. В отличие от рекомендаций DCGAN, генератор использует LeakyReLU вместо ReLU и изменение размера со свёрткой вместо транспонированных свёрток, число каналов генератора с ростом разрешения растёт, а не уменьшается, а дискриминатор применяет батч-нормализацию сразу после первой свёртки.
    • Ячейка 10 задаёт гиперпараметры: шаг обучения 10−410^{-4} для обеих сетей, 30 эпох, один шаг дискриминатора на шаг генератора (update_ratio = 1), обрезка нормы градиента на уровне 11 и одностороннее сглаживание меток 0.90.9.
    • Ячейка 11 даёт рекомендации по соотношению числа обновлений, изложенные в разделе о балансе двух игроков.
    • Ячейка 12 строит сети и оптимизаторы: Adam с betas по умолчанию для GG и betas (0.5,0.999)(0.5, 0.999) для DD, каждый со ступенчатым расписанием, которое уменьшает шаг обучения вдвое каждые 20 эпох.
    • Ячейка 13 — цикл обучения с binary_cross_entropy_with_logits. Функция потерь дискриминатора — среднее BCE на настоящих изображениях (целевое значение 0.9) и на отсоединённых от графа вычислений подделках (целевое значение 0); это −V-V с точностью до множителя 12\tfrac12 и сглаживания. Функция потерь генератора — ненасыщающаяся BCE с меткой «настоящий». При этом сглаженное целевое значение 0.90.9 используется и для генератора, так что точная функция потерь равна −Ez[0.9ln⁡D(G(z))+0.1ln⁡(1−D(G(z)))]-\mathbb{E}_z\big[0.9\ln D(G(z)) + 0.1\ln(1 - D(G(z)))\big] и минимальна при D(G(z))=0.9D(G(z)) = 0.9, а не 11. Планировщики шага обучения вызываются раз в эпоху. Каждые 5 эпох цикл сохраняет контрольную точку (checkpoint) в weights/, как и условный цикл из ячейки 23; ноутбук нигде не создаёт эту папку, поэтому torch.save завершается ошибкой, если её ещё нет.
    • Ячейки 14–16 строят графики функций потерь, сэмплируют сетку изображений и перечисляют распространённые приёмы: одностороннее сглаживание меток, случайное инвертирование меток, батч-нормализацию в обеих сетях, «избегание разреженных градиентов» (avoiding sparse gradients) с помощью log-sigmoid (это форма функций потерь через логиты), а также коллапс мод и средства против него: дискриминацию по мини-батчу, историю прежних генераторов и WGAN. Ячейка 15 при сэмплировании умножает латентную переменную на 0.70.7, поэтому сетка показывает генератор, применённый к априорному распределению с уменьшенной дисперсией, а не сэмплы из самого pgp_g, — это похожее на усечение сужение априорного распределения; ячейки 25 и 33 делают то же самое для двух других моделей.
  • Ячейки 17–26: условный GAN на CIFAR-100. Ячейка 19 задаёт размер батча 32, шаг обучения 2⋅10−42\cdot10^{-4} и betas Adam (0.5,0.999)(0.5, 0.999) для обеих сетей, без расписания шага обучения, 30 эпох, сглаживание 0.90.9 (снова и в целевом значении генератора) и обрезку градиентов на уровне 11. В ячейке 22 генератор переводит метку в эмбеддинг слоем Embedding(100, 16) и переформирует его в один канал 4×44 \times 4 рядом с 4 каналами шума, а дискриминатор — слоем Embedding(100, 1024), переформированным в один канал 32×3232 \times 32 рядом с RGB-изображением. Блоки те же, что в ячейке 9, с дропаутом 0.3 в дискриминаторе. Ячейка 23 чередует один шаг дискриминатора и один шаг генератора. Ячейка 26 перечисляет, что даёт условие: контроль над классом, сэмплы, сосредоточенные на признаках своего класса, и разнообразие между классами.
  • Ячейки 27–33: f-GAN. Activation_g и Conjugate_f (ячейка 29) реализуют gfg_f и f∗f^* из таблицы для "KLD", "RKL", "CHI", "SQH", "JSD" и "GAN" в том же соглашении: сопряжённая функция Пирсона равна t2/4+tt^2/4 + t. VLoss — среднее gf(v)g_f(v), а QLoss — среднее −f∗(gf(v))-f^*(g_f(v)). Ячейка 31 выбирает JS и повторно использует сети безусловной модели: шаг обучения 10−410^{-4}, Adam с betas по умолчанию для GG и (0.5,0.999)(0.5, 0.999) для DD, 100 эпох, без обрезки, сглаживания и расписания. В ячейке 32 генератор максимизирует TT на сгенерированных сэмплах, а не минимизирует относящееся к подделкам слагаемое оценки; это ненасыщающийся суррогат из абзаца о шаге генератора, а прямая форма оставлена закомментированной альтернативой. Два замечания о реализации. Активация и сопряжённая функция вычисляются одна за другой обычными exp и log. В 32-битной арифметике с плавающей точкой сопряжённые функции для JS и GAN возвращают +∞+\infty, как только выход vv на подделке превышает примерно 17, потому что 2−et2 - e^{t} или 1−et1 - e^{t} округляется до 00, а активация GAN возвращает −∞-\infty при vv ниже примерно −89-89, где exp(-v) переполняется. Композиции softplus⁡(v)−ln⁡2\operatorname{softplus}(v) - \ln 2 и softplus⁡(v)\operatorname{softplus}(v) избегают обеих проблем (сначала композиция, потом вычисление). Кроме того, loss_real.backward(retain_graph=True) сохраняет граф, который больше нигде не используется.
  • Ячейки 34–36: выбор размерности латентного пространства (100-мерный вектор или небольшая сетка 4×44 \times 4, разрешение которой удваивает каждый слой повышения разрешения), сравнение транспонированных свёрток с повышением разрешения и последующей свёрткой, сравнение вариантов (исходный GAN, WGAN, LSGAN, f-GAN и условный GAN), основные трудности и средства против них (штрафы на градиент, развёрнутые GAN и несколько дискриминаторов против коллапса мод; сглаживание меток, сбалансированные шаги обучения и спектральная нормализация для устойчивости; Inception Score, FID и KID для оценки качества), практические советы и список достоинств и недостатков. Основной текст разбирает их в разделах «Обучение GAN на практике», «GAN наименьших квадратов» и «Сильные и слабые стороны»; KID разобран вместе с FID.

Дальше#

Рассуждение о непересекающихся носителях показало, что JS не даёт градиента, когда носители не пересекаются, даже если сэмплы генератора близки к данным. Следующая заметка заменяет её расстоянием, которое непрерывно уменьшается по мере сближения двух распределений, — расстоянием Вассерштейна.

Литература#