Generative Adversarial Nets (GAN) — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
(Применение)
(Метки: правка с мобильного устройства, правка из мобильной версии)
(ошибка в формуле + текстовые опечатки)
(не показаны 23 промежуточные версии 12 участников)
Строка 1: Строка 1:
 
[[File:Арх_ган.png|450px|thumb|Оригинальная архитектура GAN]]
 
[[File:Арх_ган.png|450px|thumb|Оригинальная архитектура GAN]]
'''Порождающие состязательные сети''' (англ. ''Generative Adversarial Nets, GAN'') {{---}} это алгоритм машинного обучения, входящий в семейство [[:Порождающие модели|порождающих моделей]]<sup>[на 14.11.18 не создан]</sup> и построенный на комбинации из двух нейронных сетей, одна из которых генерирует образцы, а другая же пытается отличить настоящие образцы от сгенерированных. Впервые такие сети были представлены Иэном Гудфеллоу в 2014 году.  
+
 
 +
'''Порождающие состязательные сети''' (англ. ''Generative Adversarial Nets, GAN'') {{---}} алгоритм машинного обучения, входящий в семейство [[:Порождающие модели|порождающих моделей]] и построенный на комбинации из двух нейронных сетей: генеративная модель <tex>G</tex>, которая строит приближение распределения данных, и дискриминативная модель <tex>D</tex>, оценивающая вероятность, что образец пришел из тренировочных данных, а не сгенерированных моделью <tex>G</tex>. Обучение для модели <tex>G</tex> заключается в максимизации вероятности ошибки дискрминатора <tex>D</tex>. Впервые такие сети были представлены Иэном Гудфеллоу в 2014 году.  
  
 
==Постановка задачи и метод==
 
==Постановка задачи и метод==
Имеется множество образцов <tex>X</tex> из распределения <tex>p_{data}</tex>, заданного на <tex> \mathbb R^n </tex>, а также некоторое пространство латентных факторов <tex>Z</tex> из распределения <tex>p_{z}</tex>, например, случайные вектора из равномерного распределения <tex> \mathbb U^p(0,1) </tex>.
+
Как было указано ранее в описании метода, мы хотим обучить две модели: генеративную и дискриминативную. Поскольку, удобнее всего использовать многослойные перцептроны для обучения состязательной модели, будем использовать именно их для детального описания работы модели.
 
+
Чтобы вывести вероятностное распределение генератора <tex>p_{g}</tex> над набором данных <tex>X</tex>, определим априорную вероятность шума <tex>p_{z}(z)</tex> и представим генератор, как отображение <tex>G(z, \gamma_{g})</tex>, где <tex>G</tex> дифференцируемая функция, представленная многослойным перцептроном с параметром <tex>\gamma_{g}</tex>. Аналогичным образом представим второй многослойный перцептрон <tex>D(z, \gamma_{d})</tex>, который на выход подает одно скалярное значение - вероятность того, что <tex>x</tex> пришло из тренировочных данных, а не <tex>p_{g}</tex>. Во время тренировки <tex>D</tex> мы стремимся максимизировать вероятность правильной идентификации объектов из тренировочной и сгенерированной выборок. И в то же время тренируем <tex>G</tex> так, чтобы минимизировать <tex>log(1 - D(G(z)))</tex>:
Рассмотрим две нейронные сети: первая {{---}} ''генератор'' <tex> G: Z \rightarrow \mathbb R^n </tex> с параметрами <tex>\theta</tex>, цель которой сгенерировать похожий образец из <tex>p_{data}</tex>, и вторая {{---}} ''дискриминатор'' <tex>D: \mathbb R^n \rightarrow \mathbb [0,1] </tex> с параметрами <tex>\gamma</tex>, цель которой выдавать максимальную оценку на образцах из <tex>X</tex> и минимальную на сгенерированных образцах из <tex>G</tex>. Распределение, порождаемое генератором будем обозначать <tex>p_{gen}</tex>. Так же заметим, что в текущем изложении не принципиальны архитектуры нейронных сетей, поэтому можно считать, что параметры <tex>\theta</tex> и <tex>\gamma</tex> являются просто параметрами многослойных персептронов.
+
Другими словами, <tex>D</tex> и <tex>G</tex> играют в "минимакс игру":
 
+
<center><tex>\min\limits_{G}\max\limits_{D} V(D,G) = \mathop{E}\limits_{x \sim p_{data}(x)}[logD(x)] + \mathop{E}\limits_{z \sim p_{z}(z)}[log(1-D(z))]</tex></center>
В качестве примера можно рассматривать генерацию реалистичных фотографий: в этом случае, входом для генератора может быть случайный многомерный шум, а выходом генератора (и входом для дискриминатора) RGB-изображение; выходом же для дискриминатора будет вероятность, что фотография настоящая, т.е число от 0 до 1.
 
 
 
Наша задача выучить распределение <tex>p_{gen}</tex> так, чтобы оно как можно лучше описывало <tex>p_{data}</tex>. Зададим функцию ошибки для получившейся модели. Со стороны дискриминатора мы хотим распознавать образцы из <tex>X</tex> как правильные, т.е в сторону единицы, и образцы из <tex>G</tex> как неправильные, т.е в сторону нуля, таким образом нужно максимизировать следующую величину:
 
 
 
<center> <tex>\mathop{E}\limits_{x \sim p_{data}}[logD(x)] + \mathop{E}\limits_{x \sim p_{gen}}[log(1-D(x))]</tex>, где <tex>\mathop{E}\limits_{x \sim p_{gen}}[log(1-D(x))] = \mathop{E}\limits_{z \sim p_{z}}[log(1-D(G(z))]</tex> </center>
 
 
 
Со стороны же генератора требуется научиться "обманывать" дискриминатор, т.е минимизировать по <tex>p_{gen}</tex> второе слагаемое предыдущего выражения. Другими словами, <tex>G</tex> и <tex>D</tex> играют в так называемую ''минимаксную игру'', решая следующую задачу оптимизации:
 
  
<center> <tex> \min\limits_{G}\max\limits_{D} \mathop{E}\limits_{x \sim p_{data}}[logD(x)+ \mathop{E}\limits_{z \sim p_{z}}[log(1-D(G(z))</tex> </center>  
+
==Интуитивный процесс тренировки==
 
+
[[File:GANIntuitive.jpg|500px|thumb|right|Иллюстрация процесса тренировки порождающих состязательных сетей GAN. Источник: https://arxiv.org/pdf/1701.07875.pdf]]
Теоретическое обоснование того, что такой метод заставляет <tex>p_{gen}</tex> сходится к <tex>p_{data}</tex> описано в исходной статье. <ref> [https://arxiv.org/pdf/1406.2661.pdf  Ian J. Goodfellow {{---}} Generative Adversarial Nets]</ref>
+
Генеративные состязательные сети обучаются путем одновременного обновления дискриминирующего распределения (<tex>D</tex> синяя пунктирная линия), так чтобы дискриминатор мог различать объекты из распределения тренировочного сета(черная пунктирная в точку линия) и из распределения генератора (<tex>D</tex> зеленая сплошная линия). Нижняя горизонтальная линия представляет собой область, из которой составлена выборка <tex>z</tex>, в нашем случае равномерно. Горизонтальная линия над ней является частью области <tex>x</tex>. Стрелками на картинке показано, как отображение <tex>x = G(z)</tex>, накладывает неравномерное распределение <tex>p_{g}</tex> на тренировочное. <tex>G</tex> сжимается в областях с высокой плотностью и расширяется в областях с низкой.
 +
Рассмотрим описанный на картинках процесс. (a) Близкая сходимость состязающейся пары: <tex>p_{g}</tex> похоже на распределение <tex>p_{data} и D</tex> частично-точный классификатор. (b) Во внутреннем цикле алгоритма <tex>D</tex> обучается отличать объекты из тренировочных данных, сходясь к <tex>\frac{p_{data}(x)}{p_{data}(x) + p_{g}(x)}</tex>. (c) После обновления <tex>G</tex> градиент <tex>D</tex> привел <tex>G(z)</tex> к передвижению в область, с большей вероятностью быть классифицированным как данные. (d) После нескольких шагов обучения <tex>G</tex> и <tex>D</tex> придут в состояние, в котором не смогу улучшиться, так как будет выполняться условие <tex>p_{g} = p_{data}</tex> и диксриминатор не сможет различать два распределения и его выход всегда будет <tex>D(x) = \frac{1}{2}</tex>.
  
 
==Оригинальный алгоритм обучения GAN==
 
==Оригинальный алгоритм обучения GAN==
 
[[File:Обучение_ган.png|450px|thumb|right|Визуализация генерирования фотографии с помощью DCGAN по одному и тому же шуму в зависимости от итерации обучения. Источник: https://arxiv.org/pdf/1701.07875.pdf]]
 
[[File:Обучение_ган.png|450px|thumb|right|Визуализация генерирования фотографии с помощью DCGAN по одному и тому же шуму в зависимости от итерации обучения. Источник: https://arxiv.org/pdf/1701.07875.pdf]]
  
В процессе обучения требуется делать два шага оптимизации поочередно: сначала обновлять веса генератора <tex>\theta</tex> при фиксированном <tex>\gamma</tex>, а затем веса дискриминатора <tex>\gamma</tex> при фиксированном <tex>\theta</tex>. На практике дискриминатор обновляется <tex>k</tex> раз вместо одного; <tex>k</tex> является гиперпараметром.
+
В процессе обучения требуется делать два шага оптимизации поочередно: сначала обновлять веса генератора <tex>\gamma_{g}</tex> при фиксированном <tex>\gamma_{d}</tex>, а затем веса дискриминатора <tex>\gamma_{d}</tex> при фиксированном <tex>\gamma_{g}</tex>. На практике дискриминатор обновляется <tex>k</tex> раз вместо одного, поскольку, полностью оптимизировать дискриминатор вычислительно не выгодно и на конечных сетах он может переобучиться. Таким образом <tex>k</tex> является гиперпараметром.
  
 
  <font color=green>// num_iteration {{---}} число итераций обучения </font>
 
  <font color=green>// num_iteration {{---}} число итераций обучения </font>
  '''for''' i = 1..num_iteration '''do'''
+
  '''function''' GAN:
  '''for''' j = 1..k '''do'''
+
  '''for''' i = 1..num_iteration '''do'''
    Сэмплируем мини-батч $\{z_1, . . . , z_m\}$ из распределения $p_z$.
+
    '''for''' j = 1..k '''do'''
    Сэмплируем мини-батч $\{x_1, . . . , x_m\}$ из распределения $p_{data}$.
+
      <font color=green>//Получаем мини-батч $\{z_1, . . . , z_m\}$ из распределения $p_z$</font>
    Обновляем дискриминатор в сторону возрастания его градиента:
+
      $z$ = getBatchFromNoisePrior($p_z$) 
    <tex>\mathop{\nabla}_{\gamma} { \frac{1}{m} \sum_{t = 1}^m \limits} [logD(x_t)]  + [log(1-D(G(z_t))] </tex>
+
      <font color=green>//Получаем мини-батч $\{x_1, . . . , x_m\}$ из распределения $p_{data}$ </font>
  '''end''' '''for'''  
+
      $x$ = getBatchFromDataGeneratingDistribution($p_{data}$)
  Сэмплируем мини-батч $\{z_1, . . . , z_m\}$ из распределения $p_z$
+
      <font color=green>//Обновляем дискриминатор в сторону возрастания его градиента</font>
  Обновляем генератор в сторону убывания его градиента:
+
      <tex>d_w \leftarrow \mathop{\nabla}_{\gamma_{d}} { \frac{1}{m} \sum_{t = 1}^m \limits} [logD(x_t)]  + [log(1-D(G(z_t))] </tex>
  <tex>\mathop{\nabla}_{\theta}  { \frac{1}{m} \sum_{t = 1}^m \limits} [log(1-D(G(z_t))] </tex>
+
    '''end''' '''for'''
'''end''' '''for'''
+
    <font color=green>//Получаем мини-батч $\{z_1, . . . , z_m\}$ из распределения $p_z$ </font>
 
+
    $z$ = getBatchFromNoisePrior($p_z$)
Обновления на основе градиента могут быть сделаны любым стандартным способом, например, в оригинальной статье использовался [[:Cтохастический градиентный спуск|стохастический градиентный спуск]]<sup>[на 14.11.18 не создан]</sup> с импульсом.
+
    <font color=green>//Обновляем генератор в сторону убывания его градиента </font>
 +
    <tex>g_w \leftarrow \mathop{\nabla}_{\gamma_{g}}  { \frac{1}{m} \sum_{t = 1}^m \limits} [log(1-D(G(z_t))] </tex>
 +
  '''end''' '''for'''
 +
На практике не всегда удобно использовать уравнение описанной выше. В начале обучения, когда <tex>G</tex> плохо настроен дискриминатор <tex>D</tex> может не учитывать объекты, с высокой уверенностью в классификации, так как они сильно отличаются от тренировчного сета, в таком случае <tex>log(1 - D(G(z)))</tex> стагнирует. Чтобы избежать этого, можно вместо минимизации <tex>log(1 - D(G(z)))</tex> максимизировать <tex>log D(G(z))</tex>.
  
 
==Улучшение обучения GAN==
 
==Улучшение обучения GAN==
  
 
Большинство GAN'ов подвержено следующим проблемам:
 
Большинство GAN'ов подвержено следующим проблемам:
* Несходимость (non-convergence): параметры модели дестабилизируются и не сходятся,
+
* Несходимость (non-convergence): параметры модели дестабилизируются и не сходятся;
* Схлопывание мод распределения (mode collapse): генератор коллапсирует, т.е выдает ограниченное количество разных образцов,
+
* Схлопывание мод распределения (mode collapse): генератор коллапсирует, т.е выдает ограниченное количество разных образцов;
* Исчезающий градиент (diminished gradient): дискриминатор становится слишком "сильным", а градиент генератора исчезает и обучение не происходит,
+
* Исчезающий градиент (diminished gradient): дискриминатор становится слишком "сильным", а градиент генератора исчезает и обучение не происходит;
 
* Высокая чувствительность к гиперпараметрам.
 
* Высокая чувствительность к гиперпараметрам.
  
 
Универсального подхода к их решению нет, но существуют практические советы<ref> [https://github.com/soumith/ganhacks  How to Train a GAN? Tips and tricks to make GANs work]</ref>, которые могут помочь. Основными из них являются:
 
Универсального подхода к их решению нет, но существуют практические советы<ref> [https://github.com/soumith/ganhacks  How to Train a GAN? Tips and tricks to make GANs work]</ref>, которые могут помочь. Основными из них являются:
# Нормализация данных. Все признаки в диапазоне $[-1; 1]$.
+
# Нормализация данных. Все признаки в диапазоне $[-1; 1]$;
# Замена функции ошибки для $G$ с $\min log (1-D)$ на $\max log D$, потому что исходный вариант имеет маленький градиент на раннем этапе обучения и большой градиент при сходимости, а предложенный наоборот.
+
# Замена функции ошибки для $G$ с $\min log (1-D)$ на $\max log D$, потому что исходный вариант имеет маленький градиент на раннем этапе обучения и большой градиент при сходимости, а предложенный наоборот;
# Сэмплирование из многомерного нормального распределения вместо равномерного.  
+
# Сэмплирование из многомерного нормального распределения вместо равномерного;  
# Использовать нормализационные слои (например, batch normalization или layer normalization) в $G$ и $D$.
+
# Использовать нормализационные слои (например, batch normalization или layer normalization) в $G$ и $D$;
 
# Использовать метки для данных, если они имеются, т.е обучать дискриминатор еще и классифицировать образцы.
 
# Использовать метки для данных, если они имеются, т.е обучать дискриминатор еще и классифицировать образцы.
  
Строка 60: Строка 58:
 
Чаще всего GAN'ы используются для генерации реалистичных фотографий. Серьезные улучшения в этом направлении были сделаны следующими работами:
 
Чаще всего GAN'ы используются для генерации реалистичных фотографий. Серьезные улучшения в этом направлении были сделаны следующими работами:
  
* Auxiliary GAN<ref> [https://arxiv.org/pdf/1610.09585.pdf Augustus Odena {{---}} Conditional Image Synthesis with Auxiliary Classifier GANs]</ref>: вариант GAN-архитектуры, использующий метки данных.
+
* Auxiliary GAN<ref> [https://arxiv.org/pdf/1610.09585.pdf Augustus Odena {{---}} Conditional Image Synthesis with Auxiliary Classifier GANs]</ref>: вариант GAN-архитектуры, использующий метки данных;
* SN-GAN<ref> [https://arxiv.org/pdf/1802.05957.pdf Takeru Miyato {{---}} SPECTRAL NORMALIZATION FOR GENERATIVE ADVERSARIAL NETWORKS]</ref>: GAN с новым подходом решения проблемы нестабильного обучения через спектральную нормализацию.
+
* SN-GAN<ref> [https://arxiv.org/pdf/1802.05957.pdf Takeru Miyato {{---}} SPECTRAL NORMALIZATION FOR GENERATIVE ADVERSARIAL NETWORKS]</ref>: GAN с новым подходом решения проблемы нестабильного обучения через спектральную нормализацию;
* SAGAN<ref> [https://arxiv.org/pdf/1805.08318.pdf Han Zhang {{---}} Self-Attention Generative Adversarial Networks]</ref>: GAN, основанный на механизме внимания.
+
* SAGAN<ref> [https://arxiv.org/pdf/1805.08318.pdf Han Zhang {{---}} Self-Attention Generative Adversarial Networks]</ref>: GAN, основанный на механизме внимания;
* BigGAN<ref> [https://arxiv.org/pdf/1809.11096.pdf Andrew Brock {{---}} LARGE SCALE GAN TRAINING FOR HIGH FIDELITY NATURAL IMAGE SYNTHESIS]</ref>: GAN с ортогональной регуляризацией, позволившей разрешить проблему коллапсирования при долгом обучении.
+
* BigGAN<ref> [https://arxiv.org/pdf/1809.11096.pdf Andrew Brock {{---}} LARGE SCALE GAN TRAINING FOR HIGH FIDELITY NATURAL IMAGE SYNTHESIS]</ref>: GAN с ортогональной регуляризацией, позволившей разрешить проблему коллапсирования при долгом обучении;
  
 
Кроме простой генерации изображений, существуют достаточно необычные применения, дающие впечатляющие результаты не только на картинках, но и на звуке:
 
Кроме простой генерации изображений, существуют достаточно необычные применения, дающие впечатляющие результаты не только на картинках, но и на звуке:
  
* CycleGAN<ref> [https://junyanz.github.io/CycleGAN/ Jun-Yan Zhu & Taesung Park {{---}} Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks]</ref>: меняет изображения c одного домена на другой, например, лошадей на зебр,
+
* CycleGAN<ref> [https://junyanz.github.io/CycleGAN/ Jun-Yan Zhu & Taesung Park {{---}} Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks]</ref>: меняет изображения c одного домена на другой, например, лошадей на зебр;
* SRGAN<ref> [https://arxiv.org/abs/1609.04802 Christian Ledig {{---}} Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network]</ref>: создает изображения с высоким разрешением из более низкого разрешения,
+
* SRGAN<ref> [https://arxiv.org/abs/1609.04802 Christian Ledig {{---}} Photo-Realistic Single Image Super-Resolution Using a Generative Adversarial Network]</ref>: создает изображения с высоким разрешением из более низкого разрешения;
* Pix2Pix<ref> [https://phillipi.github.io/pix2pix/ Phillip Isola {{---}} Image-to-Image Translation with Conditional Adversarial Nets]</ref>: создает изображения по семантической окраске,
+
* Pix2Pix<ref> [https://phillipi.github.io/pix2pix/ Phillip Isola {{---}} Image-to-Image Translation with Conditional Adversarial Nets]</ref>: создает изображения по семантической окраске;
* StackGAN<ref> [https://arxiv.org/abs/1612.03242 Han Zhang {{---}} StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks]</ref>: создает изображения по заданному тексту,
+
* StackGAN<ref> [https://arxiv.org/abs/1612.03242 Han Zhang {{---}} StackGAN: Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks]</ref>: создает изображения по заданному тексту;
 
* MidiNet<ref> [https://arxiv.org/abs/1703.10847 Li-Chia Yang {{---}} MIDINET: A CONVOLUTIONAL GENERATIVE ADVERSARIAL NETWORK FOR SYMBOLIC-DOMAIN MUSIC GENERATION]</ref>: генерирует последовательность нот, таким образом, создает мелодию.
 
* MidiNet<ref> [https://arxiv.org/abs/1703.10847 Li-Chia Yang {{---}} MIDINET: A CONVOLUTIONAL GENERATIVE ADVERSARIAL NETWORK FOR SYMBOLIC-DOMAIN MUSIC GENERATION]</ref>: генерирует последовательность нот, таким образом, создает мелодию.
 +
 +
==CGAN (Conditional Generative Adversarial Nets)==
 +
 +
[[File:CGAN_architecture.png|450px|thumb|Архитектура CGAN. Источник: https://arxiv.org/pdf/1411.1784.pdf]]
 +
 +
'''Условные порождающие состязательные сети''' (англ. ''Conditional Generative Adversarial Nets, CGAN'') $-$ это модифицированная версия алгоритма GAN, которая может быть сконструирована при помощи подачи данных '''y''', являющихся условием для генератора и дискриминатора. '''y''' может быть любой дополнительной информацией, например, меткой класса или данными из других моделей, что может позволить контролировать процесс генерации данных. Например, можно подавать параметр '''y''', как условие на класс для генерации чисел, похожих на MNIST.
 +
 +
Как уже было упомянуто на вход генератори и дискримантора из GAN подается дополнительная информация '''y''', например в случае с многослойными перецептронами условие может быть представлено дополнительным входным слоем.
 +
В генераторе априорная вероятность шума <tex>p_{z}(z)</tex> и условие <tex>y</tex> комбинируются в объединённое скрытое представление, а состязательная тренирующая модель предоставляет достаточно свободы в том как это представление составляется.<ref>[https://arxiv.org/pdf/1207.4404.pdf Yoshua Bengio, Gre ́goire Mesnil, Yann Dauphin and Salah Rifai {{---}} Better Mixing via Deep Representations ]</ref>
 +
В дискриминаторе '''x''' и '''y''' представлены как входные параметры.
 +
 +
В таком случае задача оптимизации будет выглядеть следующим образом:
 +
 +
<center> <tex> \min\limits_{G}\max\limits_{D} \mathop{E}\limits_{x \sim p_{data}}[logD(x|y)]  + \mathop{E}\limits_{z \sim p_{z}}[log(1-D(G(z|y))]  </tex> </center>
 +
 +
В качестве примера использования данного алгоритма можно рассмотреть задачу генерации рукописных цифр. ''CGAN'' был натренирован на датасете ''MNIST'' с метками классов представленных в виде ''one-hot'' векторов.
 +
 +
[[File:CGAN_generated.png|450px|thumb|right|Цифры, сгенерированные с помощью CGAN. Источник: https://arxiv.org/pdf/1411.1784.pdf]]
 +
 +
==DCGAN (Deep Convolutional Generative Adversarial Nets)==
 +
 +
[[File:DCGAN_generator.png|450px|thumb|right|Архитектура генератора в DCGAN. Источник: https://arxiv.org/pdf/1511.06434.pdf]]
 +
 +
'''DCGAN''' $-$ модификация алгоритма ''GAN'', в основе которых лежат сверточные нейронные сети (''CNN''). Задача поиска удобного представления признаков на больших объемах не размеченных данных является одной из наибольнее активных сфер исследований, в частности представление изображений и видио. Одним из удобных способов поиска представлений может быть '''DCGAN'''. Использование сверточных нейронных сетей напрямую не давало хороших результатов, поэтому было внесены ограничения на слои сверток. Эти ограничения и лежат в основе '''DCGAN''':
 +
 +
* Замена всех пулинговых слоев на страйдинговые свертки (''strided convolutions'') в дискриминаторе и частично-страйдинговые свертки (''fractional-strided-convolutions'') в генераторе, что позволяет сетям находить подходящие понижения и повышения размерностей;
 +
* Использование батчинговой нормализации для генератора и дискриминатора, то есть нормализация входа так, чтобы среднее значения было равно нулю и дисперсия была равна единице. Не стоит использовать батч-нормализация для выходного слоя генератора и входного дискриминатор.
 +
* Удаление всех полносвязных скрытых уровней для более глубоких архитектур;
 +
* Использование ''ReLU'' в качестве функции активации в генераторе для всех слоев, кроме последнего, где используется ''tanh'';
 +
* Использование ''LeakyReLU'' в качестве функции активации в дискриминаторе для всех слоев.
 +
 +
Помимо задачи генерации объектов, данный алгоритм хорошо показывает себя в извлечении признаков.
 +
Данный алгоритм был натренирован на наборе данных ''Imagenet-1k''<ref name = "datasets">[http://neerc.ifmo.ru/wiki/index.php?title=Известные_наборы_данных Известные наборы данных]</ref>, после чего были использованы значения со сверточных слоев дискриминатора, подвергнутые ''max-pooling'''у, чтобы образовать матрицы
 +
<tex> 4 \times 4 </tex> и получить общий вектор признаков на их основе. ''L2-SVM'', c полученным представлением, на наборе данных ''CIFAR-10''<ref name="datasets" /> превосходит по точности решения, основанные на алгоритме
 +
''K-Means''. Подробнее об этом вы можете прочитать в статье. <ref> [https://arxiv.org/pdf/1511.06434.pdf  Alec Radford, Luke Metz, Soumith Chintala {{---}} Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks]</ref>
 +
 +
 +
==StackGAN (Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks)==
 +
 +
[[File:StackGANexample.jpg|500px|thumb|right| Пример работы порождающей состязателной сети для генерации фото-реалистичных изображений StackGAN. Источник: https://arxiv.org/pdf/1612.03242.pdf]]
 +
 +
'''StackGAN''' $-$ порождающая состязательная сеть для генерации фото-реалистичных изображений (256x256) исходя из текстового описания. Генерировать фото-реалистичные изображения на обычных GAN сложно, поэтому была придумана двух-этапная модель генерации. Stage-I GAN рисует скетчи с примитивными формами и цветами, основанные на текстовом описании, в низком разрешении. Stage-II GAN принимает на вход изображения с первого этапа и текстовое описание и генерирует изображение в высоком разрешении с фото-реалистичными деталями. Чтобы улучшить разнообразие синтезированных изображений и стабилизировать обучение, вместо CGAN использовался метод Conditioning Augmentation.
 +
 +
Раннее использовались CGAN, поскольку на вход им можно было подавать условия, но просто добавляя слои, увеличивающие размер изображения, достичь хороших результатов не удалось. Поэтому основной задачей было повысить разрешение изображений.
 +
 +
Одной из ключевых особенностей StackGAN является Conditioning Augmentation, так как оно позволило расширить количество примеров тренировочного сета, путем небольших случайных изменений в исходных изображениях, что увеличивало многообразие данных. Как показано на картинке, текстовое описание <tex>t</tex> кодировщиком переводится в векторное представление <tex>\varphi_{t}</tex>. Раннее векторное представление нелинейно трансформировалось, чтобы получить скрытые условные переменные, которые подавались на вход генератору, однако простарнство значений скрытых переменных имеет большую размерность, что приводило к разрывам в многообразии данных, что не выгодно для генератора. Чтобы избавиться от этого как раз нужно Conditioning Augmentation, которое в отличии от предоставления фиксированных значений переменных выбирает их из нормального распределения <tex>\mathcal{N}(\mu(\varphi_{t}), \Sigma(\varphi_{t}))</tex>, где среднее значение <tex>\mu(\varphi_{t})</tex> и ковариация <tex>\Sigma(\varphi_{t}))</tex> это функции от входного вектора <tex>\varphi_{t}</tex>. В добавок к уже упомянотому, чтобы сделать многообразие гладким и не переобучиться, нужно добавить регуляризацию, <tex>D_{KL}(\mathcal{N}(\mu(\varphi_{t}), \Sigma(\varphi_{t})) || \mathcal{N}(0, I))</tex> (KL divergence)<ref> [https://ru.wikipedia.org/wiki/Расстояние_Кульбака_—_Лейблера Kullback-Leibler divergence]</ref>.
 +
[[File:StackGANProcess.jpg|1200px|thumb|right|Процесс обучения StackGAN. Источник: https://arxiv.org/pdf/1612.03242.pdf]]
 +
Stage-I GAN тренирует дискриминатор <tex>D_{0}</tex> и генератор <tex>G_{0}</tex> поочередной максимизицаии <tex>L_{D_{0}}</tex> и минимизации <tex>L_{G_{0}}</tex>, как указано в уравенинях:
 +
<center><tex>L_{D_0} = E_{(I_0, t)\sim p_{data}}[\log D_{0}(I_0, \varphi_t)] + E_{z\sim t, t \sim p_{data}}[\log (1 - D_0(G_{0}(z, \hat{c_0}), \varphi_t))]</tex></center>
 +
<center><tex>L_{G_0} = E_{z\sim t, t \sim p_{data}}[\log (1 - D_0(G_{0}(z, \hat{c_0}), \varphi_t))] + \lambda D_{KL}(\mathcal{N}(\mu(\varphi_{t}), \Sigma(\varphi_{t}) || \mathcal{N}(0, I))</tex></center>
 +
Где реальное изображение <tex>I_0</tex> и описание текста <tex>t</tex> берутся из реального распределения данных <tex>p_{data}</tex>. <tex>z</tex> шумовой вектор взятого случайно из нормального распределения, <tex>\lambda</tex> параметр регуляризации.
 +
 +
В изображениях с низким разрешенеим, сгенерированные Stage-I GAN, обычно недостает ярких деталей и могут быть искривления форм, некоторые детали изображения также могут быть опущены на первом этапе. Stage-II GAN построен над Stage-I GAN и принимает на вход его выход, и текстовое описание, чтобы исправить и дополнить изображение. Его дискриминатор и генератор тренируются путем поочередной макисимизации <tex>L_D</tex> и минимизации <tex>L_G</tex>, как показано в уравнениях:
 +
<center><tex>L_{D} = E_{(I, t)\sim p_{data}}[\log D(I, \varphi_t)] + E_{s_0\sim p_{G_0}, t \sim p_{data}}[\log (1 - D(G(s_0, \hat{c}), \varphi_t))]</tex></center>
 +
<center><tex>L_{G} = E_{s_0\sim p_{G_0}, t \sim p_{data}}[\log (1 - D(G(s_0, \hat{c}), \varphi_t))] + \lambda D_{KL}(\mathcal{N}(\mu(\varphi_{t}), \Sigma(\varphi_{t}) || \mathcal{N}(0, I))</tex></center>
 +
Где <tex>s_0 = G_0(z,\hat{c_0})</tex> результат работы генератора Stage-I GAN и скрытый параметр <tex>\hat{c}</tex> подаются на вход дискриминатору и генератору Stage-II GAN, при этом на вход не подается случайное значение, как на первой стадии, поскольку хватает подачи случайного <tex>z</tex> на вход Stage-I GAN. При этом Stage-I GAN и Stage-II GAN имеют разные полно-связные слои, чтобы отличаться по среднему значению и стандартному отклонению, таким образом на разных этапах фокусируюемся на разных деталях исходного текста.
 +
 +
==LAPGAN (Laplacian Pyramid of Adversarial Networks)==
 +
 +
'''LAPGAN''' $-$ генеративная параметрическая модель, представленная пирамидой лапласианов с каскадом сверточных нейронных сетей внутри, которая генерирует изображения постепенно от исходного изображения с низким разрешением к изображению с высоким. На каждом уровне пирамиды обучается сверточная генеративная модель, используя подход порождающих состязательных сетей. Такая стратегия позволяет декомпозировать задачу генерации изображений на последовательность уровней, что упрощает ее решение.
 +
 +
Пирамида лапласианов $-$ это линейное обратимое представление изображений, состоящее из набора частотных полос изображений. Пусть <tex>d(\cdot)</tex> - это операция сжатия изображения размера <tex>j \times j</tex> так, что новое изображение <tex>d(I)</tex> имеет размеры <tex>j/2 \times j/2</tex>, также <tex>u(\cdot)</tex> - операция расширения такой, что <tex>u(I)</tex> имеет размеры <tex>2j \times 2j</tex>. Тогда пирамида гаусианов имеет вид <tex>\mathcal{G}(I) = [I_0, I_1,..., I_k]</tex>, где <tex>I_0 = I</tex> и <tex>I_k</tex> представляет собой <tex>k</tex> раз выполненное применение <tex>d(\cdot)</tex>. Коэффициенты <tex>h_k</tex> на каждом уровне пирамиды лапласианов считаются так:
 +
<center><tex>h_k = \mathcal{L_k}(I) = \mathcal{G_k}(I) - u(\mathcal{G_{k + 1}}(I)) = I_k - u(I_{k + 1})</tex></center>
 +
Интуитивно каждый уровень захватывает структуру изображения. Конечный слой пирамиды лапласианов <tex>h_k</tex> это не разница изображений, а низко-частотное представление равное гаусиану <tex>h_k = I_k</tex>. Реконструкция по пирамиде лапласианов происходит обратным проходом по ней:
 +
<center><tex>I_k = u(I_{k + 1}) + h_k</tex></center>
 +
 +
Подход представленный в '''LAPGAN''' работает по такому же принципу, только на каждому шаге вместо коэфициентов <tex>h_k</tex> используются генераторы <tex>\{G_0,G_1,...,G_k\}</tex>, каждый из которых захватывает распределение коэфициентов <tex>h_k</tex> для реальных изображений на разных уровнях пирамиды лапласиана:
 +
<center><tex>\tilde{I_k} = u(\tilde{I_{k + 1}}) + \tilde{h_k} = u(\tilde{I_{k + 1}}) + G_k(z_k, u(\tilde{I_{k + 1}}))</tex></center>
 +
 +
[[File:LAPGANtest.jpg|500px|thumb|right|Процедура семплинга для модели LAPGAN. Источник: https://arxiv.org/pdf/1506.05751.pdf]]
 +
 +
Процедура семплинга для нашей модели '''LAPGAN'''. Начинаем с шума <tex>z_3</tex> и используем генеративную модель <tex>G_3</tex> для создания <tex>\tilde{I_3}</tex>. Потом расширяем изображение до <tex>l_2</tex> для следующиего уровня генерации <tex>G_2</tex>. Вместе с еще одним шумом <tex>z_2</tex> получаем изображение различия <tex>\tilde{I_2}</tex>. Продолжаем процесс, пока не получим <tex>I_0</tex>.
 +
 +
[[File:LAPGANtrain.jpg|500px|thumb|right|Процедура обучения модели LAPGAN. Источник: https://arxiv.org/pdf/1506.05751.pdf]]
 +
 +
Процедура обучения '''LAPGAN'''. Начинаем с изображения <tex>I</tex> размера <tex>64 \times 64</tex> из тренировчного набора. Берем <tex>I_0 = I </tex> и сжимаем его(красная стрелка) чтобы получить <tex>I_1</tex>; затем расширяем его(зеленая стрелка), чтобы получить <tex>l_0</tex> низко-частотное изображение <tex>I_0</tex>; с равной вероятностью используем его для создния либо реального, либо сгенерированного примера для дискриминатора <tex>D_0</tex>. В случае реального изображения(синяя стрелка) считаем цветовой контраст <tex>h_0 = I_0 - l_0</tex>, которая подается на вход дискриминатору <tex>D_0</tex>, для опредления реальное изображение или нет. В случае сгенерированного(розовая стрелка), генеративная сеть <tex>G_0</tex> получает на вход шум <tex>z_0</tex> и <tex>l_0</tex>. Оно генерирует цветовой контраст <tex>\tilde{h_0} = G_0(z_0,l_0)</tex>, который подается на вход <tex>D_0</tex>. В обоих случаях дискриминатор также получает <tex>l_0</tex> (оранжевая стрелка). Оптимизируя минмакс игру условной порождающей сети <tex>G_0</tex> учится генерировать реалистичную высоко-частотную структуру <tex>\tilde{h_0}</tex> с помощью низко-частотного представления <tex>l_0</tex>. Такая процедура проходит на всех слоях, кроме последнего, где можно уже использовать обычный GAN.
  
 
==См. также==
 
==См. также==
 
*[[:Порождающие модели|Порождающие модели]]
 
*[[:Порождающие модели|Порождающие модели]]
*[[:Variational autoencoder (VAE)|Variational autoencoder (VAE)]]
+
*[[:Вариационный автокодировщик|Variational autoencoder (VAE)]]
 +
*[[:Автокодировщик|Автокодировщик]]
 +
 
 
==Примечания==
 
==Примечания==
 
<references/>
 
<references/>
Строка 81: Строка 157:
 
* Сергей Николенко, Артур Кадурин, Екатерина Архангельская. Глубокое обучение. Погружение в мир нейронных сетей. — «Питер», 2018. — С. 348-360.
 
* Сергей Николенко, Артур Кадурин, Екатерина Архангельская. Глубокое обучение. Погружение в мир нейронных сетей. — «Питер», 2018. — С. 348-360.
 
* [https://medium.com/@jonathan_hui/gan-why-it-is-so-hard-to-train-generative-advisory-networks-819a86b3750b Medium | GAN — Why it is so hard to train Generative Adversarial Networks! ]
 
* [https://medium.com/@jonathan_hui/gan-why-it-is-so-hard-to-train-generative-advisory-networks-819a86b3750b Medium | GAN — Why it is so hard to train Generative Adversarial Networks! ]
 +
* [https://arxiv.org/pdf/1411.1784.pdf CGAN Paper]
 +
* [https://arxiv.org/pdf/1511.06434.pdf DCGAN Paper]
 +
* [https://arxiv.org/pdf/1612.03242.pdf StackGAN Paper]
 +
* [https://arxiv.org/pdf/1506.05751.pdf LAPGAN Paper]
 
[[Категория: Машинное обучение]]
 
[[Категория: Машинное обучение]]
 
[[Категория: Порождающие модели]]
 
[[Категория: Порождающие модели]]

Версия 17:30, 30 марта 2020

Оригинальная архитектура GAN

Порождающие состязательные сети (англ. Generative Adversarial Nets, GAN) — алгоритм машинного обучения, входящий в семейство порождающих моделей и построенный на комбинации из двух нейронных сетей: генеративная модель [math]G[/math], которая строит приближение распределения данных, и дискриминативная модель [math]D[/math], оценивающая вероятность, что образец пришел из тренировочных данных, а не сгенерированных моделью [math]G[/math]. Обучение для модели [math]G[/math] заключается в максимизации вероятности ошибки дискрминатора [math]D[/math]. Впервые такие сети были представлены Иэном Гудфеллоу в 2014 году.

Постановка задачи и метод

Как было указано ранее в описании метода, мы хотим обучить две модели: генеративную и дискриминативную. Поскольку, удобнее всего использовать многослойные перцептроны для обучения состязательной модели, будем использовать именно их для детального описания работы модели. Чтобы вывести вероятностное распределение генератора [math]p_{g}[/math] над набором данных [math]X[/math], определим априорную вероятность шума [math]p_{z}(z)[/math] и представим генератор, как отображение [math]G(z, \gamma_{g})[/math], где [math]G[/math] дифференцируемая функция, представленная многослойным перцептроном с параметром [math]\gamma_{g}[/math]. Аналогичным образом представим второй многослойный перцептрон [math]D(z, \gamma_{d})[/math], который на выход подает одно скалярное значение - вероятность того, что [math]x[/math] пришло из тренировочных данных, а не [math]p_{g}[/math]. Во время тренировки [math]D[/math] мы стремимся максимизировать вероятность правильной идентификации объектов из тренировочной и сгенерированной выборок. И в то же время тренируем [math]G[/math] так, чтобы минимизировать [math]log(1 - D(G(z)))[/math]: Другими словами, [math]D[/math] и [math]G[/math] играют в "минимакс игру":

[math]\min\limits_{G}\max\limits_{D} V(D,G) = \mathop{E}\limits_{x \sim p_{data}(x)}[logD(x)] + \mathop{E}\limits_{z \sim p_{z}(z)}[log(1-D(z))][/math]

Интуитивный процесс тренировки

Иллюстрация процесса тренировки порождающих состязательных сетей GAN. Источник: https://arxiv.org/pdf/1701.07875.pdf

Генеративные состязательные сети обучаются путем одновременного обновления дискриминирующего распределения ([math]D[/math] синяя пунктирная линия), так чтобы дискриминатор мог различать объекты из распределения тренировочного сета(черная пунктирная в точку линия) и из распределения генератора ([math]D[/math] зеленая сплошная линия). Нижняя горизонтальная линия представляет собой область, из которой составлена выборка [math]z[/math], в нашем случае равномерно. Горизонтальная линия над ней является частью области [math]x[/math]. Стрелками на картинке показано, как отображение [math]x = G(z)[/math], накладывает неравномерное распределение [math]p_{g}[/math] на тренировочное. [math]G[/math] сжимается в областях с высокой плотностью и расширяется в областях с низкой. Рассмотрим описанный на картинках процесс. (a) Близкая сходимость состязающейся пары: [math]p_{g}[/math] похоже на распределение [math]p_{data} и D[/math] частично-точный классификатор. (b) Во внутреннем цикле алгоритма [math]D[/math] обучается отличать объекты из тренировочных данных, сходясь к [math]\frac{p_{data}(x)}{p_{data}(x) + p_{g}(x)}[/math]. (c) После обновления [math]G[/math] градиент [math]D[/math] привел [math]G(z)[/math] к передвижению в область, с большей вероятностью быть классифицированным как данные. (d) После нескольких шагов обучения [math]G[/math] и [math]D[/math] придут в состояние, в котором не смогу улучшиться, так как будет выполняться условие [math]p_{g} = p_{data}[/math] и диксриминатор не сможет различать два распределения и его выход всегда будет [math]D(x) = \frac{1}{2}[/math].

Оригинальный алгоритм обучения GAN

Визуализация генерирования фотографии с помощью DCGAN по одному и тому же шуму в зависимости от итерации обучения. Источник: https://arxiv.org/pdf/1701.07875.pdf

В процессе обучения требуется делать два шага оптимизации поочередно: сначала обновлять веса генератора [math]\gamma_{g}[/math] при фиксированном [math]\gamma_{d}[/math], а затем веса дискриминатора [math]\gamma_{d}[/math] при фиксированном [math]\gamma_{g}[/math]. На практике дискриминатор обновляется [math]k[/math] раз вместо одного, поскольку, полностью оптимизировать дискриминатор вычислительно не выгодно и на конечных сетах он может переобучиться. Таким образом [math]k[/math] является гиперпараметром.

// num_iteration — число итераций обучения 
function GAN:
  for i = 1..num_iteration do
    for j = 1..k do
      //Получаем мини-батч $\{z_1, . . . , z_m\}$ из распределения $p_z$
      $z$ = getBatchFromNoisePrior($p_z$)  
      //Получаем мини-батч $\{x_1, . . . , x_m\}$ из распределения $p_{data}$ 
      $x$ = getBatchFromDataGeneratingDistribution($p_{data}$)
      //Обновляем дискриминатор в сторону возрастания его градиента
      [math]d_w \leftarrow \mathop{\nabla}_{\gamma_{d}} { \frac{1}{m} \sum_{t = 1}^m \limits} [logD(x_t)]  + [log(1-D(G(z_t))] [/math]
    end for
    //Получаем мини-батч $\{z_1, . . . , z_m\}$ из распределения $p_z$ 
    $z$ = getBatchFromNoisePrior($p_z$)
    //Обновляем генератор в сторону убывания его градиента 
    [math]g_w \leftarrow \mathop{\nabla}_{\gamma_{g}}  { \frac{1}{m} \sum_{t = 1}^m \limits} [log(1-D(G(z_t))] [/math]
  end for

На практике не всегда удобно использовать уравнение описанной выше. В начале обучения, когда [math]G[/math] плохо настроен дискриминатор [math]D[/math] может не учитывать объекты, с высокой уверенностью в классификации, так как они сильно отличаются от тренировчного сета, в таком случае [math]log(1 - D(G(z)))[/math] стагнирует. Чтобы избежать этого, можно вместо минимизации [math]log(1 - D(G(z)))[/math] максимизировать [math]log D(G(z))[/math].

Улучшение обучения GAN

Большинство GAN'ов подвержено следующим проблемам:

  • Несходимость (non-convergence): параметры модели дестабилизируются и не сходятся;
  • Схлопывание мод распределения (mode collapse): генератор коллапсирует, т.е выдает ограниченное количество разных образцов;
  • Исчезающий градиент (diminished gradient): дискриминатор становится слишком "сильным", а градиент генератора исчезает и обучение не происходит;
  • Высокая чувствительность к гиперпараметрам.

Универсального подхода к их решению нет, но существуют практические советы[1], которые могут помочь. Основными из них являются:

  1. Нормализация данных. Все признаки в диапазоне $[-1; 1]$;
  2. Замена функции ошибки для $G$ с $\min log (1-D)$ на $\max log D$, потому что исходный вариант имеет маленький градиент на раннем этапе обучения и большой градиент при сходимости, а предложенный наоборот;
  3. Сэмплирование из многомерного нормального распределения вместо равномерного;
  4. Использовать нормализационные слои (например, batch normalization или layer normalization) в $G$ и $D$;
  5. Использовать метки для данных, если они имеются, т.е обучать дискриминатор еще и классифицировать образцы.

Применение

Прогресс в генерации фотографий с помощью GAN. Источник: https://twitter.com/goodfellow_ian

Чаще всего GAN'ы используются для генерации реалистичных фотографий. Серьезные улучшения в этом направлении были сделаны следующими работами:

  • Auxiliary GAN[2]: вариант GAN-архитектуры, использующий метки данных;
  • SN-GAN[3]: GAN с новым подходом решения проблемы нестабильного обучения через спектральную нормализацию;
  • SAGAN[4]: GAN, основанный на механизме внимания;
  • BigGAN[5]: GAN с ортогональной регуляризацией, позволившей разрешить проблему коллапсирования при долгом обучении;

Кроме простой генерации изображений, существуют достаточно необычные применения, дающие впечатляющие результаты не только на картинках, но и на звуке:

  • CycleGAN[6]: меняет изображения c одного домена на другой, например, лошадей на зебр;
  • SRGAN[7]: создает изображения с высоким разрешением из более низкого разрешения;
  • Pix2Pix[8]: создает изображения по семантической окраске;
  • StackGAN[9]: создает изображения по заданному тексту;
  • MidiNet[10]: генерирует последовательность нот, таким образом, создает мелодию.

CGAN (Conditional Generative Adversarial Nets)

Архитектура CGAN. Источник: https://arxiv.org/pdf/1411.1784.pdf

Условные порождающие состязательные сети (англ. Conditional Generative Adversarial Nets, CGAN) $-$ это модифицированная версия алгоритма GAN, которая может быть сконструирована при помощи подачи данных y, являющихся условием для генератора и дискриминатора. y может быть любой дополнительной информацией, например, меткой класса или данными из других моделей, что может позволить контролировать процесс генерации данных. Например, можно подавать параметр y, как условие на класс для генерации чисел, похожих на MNIST.

Как уже было упомянуто на вход генератори и дискримантора из GAN подается дополнительная информация y, например в случае с многослойными перецептронами условие может быть представлено дополнительным входным слоем. В генераторе априорная вероятность шума [math]p_{z}(z)[/math] и условие [math]y[/math] комбинируются в объединённое скрытое представление, а состязательная тренирующая модель предоставляет достаточно свободы в том как это представление составляется.[11] В дискриминаторе x и y представлены как входные параметры.

В таком случае задача оптимизации будет выглядеть следующим образом:

[math] \min\limits_{G}\max\limits_{D} \mathop{E}\limits_{x \sim p_{data}}[logD(x|y)] + \mathop{E}\limits_{z \sim p_{z}}[log(1-D(G(z|y))] [/math]

В качестве примера использования данного алгоритма можно рассмотреть задачу генерации рукописных цифр. CGAN был натренирован на датасете MNIST с метками классов представленных в виде one-hot векторов.

Цифры, сгенерированные с помощью CGAN. Источник: https://arxiv.org/pdf/1411.1784.pdf

DCGAN (Deep Convolutional Generative Adversarial Nets)

Архитектура генератора в DCGAN. Источник: https://arxiv.org/pdf/1511.06434.pdf

DCGAN $-$ модификация алгоритма GAN, в основе которых лежат сверточные нейронные сети (CNN). Задача поиска удобного представления признаков на больших объемах не размеченных данных является одной из наибольнее активных сфер исследований, в частности представление изображений и видио. Одним из удобных способов поиска представлений может быть DCGAN. Использование сверточных нейронных сетей напрямую не давало хороших результатов, поэтому было внесены ограничения на слои сверток. Эти ограничения и лежат в основе DCGAN:

  • Замена всех пулинговых слоев на страйдинговые свертки (strided convolutions) в дискриминаторе и частично-страйдинговые свертки (fractional-strided-convolutions) в генераторе, что позволяет сетям находить подходящие понижения и повышения размерностей;
  • Использование батчинговой нормализации для генератора и дискриминатора, то есть нормализация входа так, чтобы среднее значения было равно нулю и дисперсия была равна единице. Не стоит использовать батч-нормализация для выходного слоя генератора и входного дискриминатор.
  • Удаление всех полносвязных скрытых уровней для более глубоких архитектур;
  • Использование ReLU в качестве функции активации в генераторе для всех слоев, кроме последнего, где используется tanh;
  • Использование LeakyReLU в качестве функции активации в дискриминаторе для всех слоев.

Помимо задачи генерации объектов, данный алгоритм хорошо показывает себя в извлечении признаков. Данный алгоритм был натренирован на наборе данных Imagenet-1k[12], после чего были использованы значения со сверточных слоев дискриминатора, подвергнутые max-pooling'у, чтобы образовать матрицы [math] 4 \times 4 [/math] и получить общий вектор признаков на их основе. L2-SVM, c полученным представлением, на наборе данных CIFAR-10[12] превосходит по точности решения, основанные на алгоритме K-Means. Подробнее об этом вы можете прочитать в статье. [13]


StackGAN (Text to Photo-realistic Image Synthesis with Stacked Generative Adversarial Networks)

Пример работы порождающей состязателной сети для генерации фото-реалистичных изображений StackGAN. Источник: https://arxiv.org/pdf/1612.03242.pdf

StackGAN $-$ порождающая состязательная сеть для генерации фото-реалистичных изображений (256x256) исходя из текстового описания. Генерировать фото-реалистичные изображения на обычных GAN сложно, поэтому была придумана двух-этапная модель генерации. Stage-I GAN рисует скетчи с примитивными формами и цветами, основанные на текстовом описании, в низком разрешении. Stage-II GAN принимает на вход изображения с первого этапа и текстовое описание и генерирует изображение в высоком разрешении с фото-реалистичными деталями. Чтобы улучшить разнообразие синтезированных изображений и стабилизировать обучение, вместо CGAN использовался метод Conditioning Augmentation.

Раннее использовались CGAN, поскольку на вход им можно было подавать условия, но просто добавляя слои, увеличивающие размер изображения, достичь хороших результатов не удалось. Поэтому основной задачей было повысить разрешение изображений.

Одной из ключевых особенностей StackGAN является Conditioning Augmentation, так как оно позволило расширить количество примеров тренировочного сета, путем небольших случайных изменений в исходных изображениях, что увеличивало многообразие данных. Как показано на картинке, текстовое описание [math]t[/math] кодировщиком переводится в векторное представление [math]\varphi_{t}[/math]. Раннее векторное представление нелинейно трансформировалось, чтобы получить скрытые условные переменные, которые подавались на вход генератору, однако простарнство значений скрытых переменных имеет большую размерность, что приводило к разрывам в многообразии данных, что не выгодно для генератора. Чтобы избавиться от этого как раз нужно Conditioning Augmentation, которое в отличии от предоставления фиксированных значений переменных выбирает их из нормального распределения [math]\mathcal{N}(\mu(\varphi_{t}), \Sigma(\varphi_{t}))[/math], где среднее значение [math]\mu(\varphi_{t})[/math] и ковариация [math]\Sigma(\varphi_{t}))[/math] это функции от входного вектора [math]\varphi_{t}[/math]. В добавок к уже упомянотому, чтобы сделать многообразие гладким и не переобучиться, нужно добавить регуляризацию, [math]D_{KL}(\mathcal{N}(\mu(\varphi_{t}), \Sigma(\varphi_{t})) || \mathcal{N}(0, I))[/math] (KL divergence)[14].

Процесс обучения StackGAN. Источник: https://arxiv.org/pdf/1612.03242.pdf

Stage-I GAN тренирует дискриминатор [math]D_{0}[/math] и генератор [math]G_{0}[/math] поочередной максимизицаии [math]L_{D_{0}}[/math] и минимизации [math]L_{G_{0}}[/math], как указано в уравенинях:

[math]L_{D_0} = E_{(I_0, t)\sim p_{data}}[\log D_{0}(I_0, \varphi_t)] + E_{z\sim t, t \sim p_{data}}[\log (1 - D_0(G_{0}(z, \hat{c_0}), \varphi_t))][/math]
[math]L_{G_0} = E_{z\sim t, t \sim p_{data}}[\log (1 - D_0(G_{0}(z, \hat{c_0}), \varphi_t))] + \lambda D_{KL}(\mathcal{N}(\mu(\varphi_{t}), \Sigma(\varphi_{t}) || \mathcal{N}(0, I))[/math]

Где реальное изображение [math]I_0[/math] и описание текста [math]t[/math] берутся из реального распределения данных [math]p_{data}[/math]. [math]z[/math] шумовой вектор взятого случайно из нормального распределения, [math]\lambda[/math] параметр регуляризации.

В изображениях с низким разрешенеим, сгенерированные Stage-I GAN, обычно недостает ярких деталей и могут быть искривления форм, некоторые детали изображения также могут быть опущены на первом этапе. Stage-II GAN построен над Stage-I GAN и принимает на вход его выход, и текстовое описание, чтобы исправить и дополнить изображение. Его дискриминатор и генератор тренируются путем поочередной макисимизации [math]L_D[/math] и минимизации [math]L_G[/math], как показано в уравнениях:

[math]L_{D} = E_{(I, t)\sim p_{data}}[\log D(I, \varphi_t)] + E_{s_0\sim p_{G_0}, t \sim p_{data}}[\log (1 - D(G(s_0, \hat{c}), \varphi_t))][/math]
[math]L_{G} = E_{s_0\sim p_{G_0}, t \sim p_{data}}[\log (1 - D(G(s_0, \hat{c}), \varphi_t))] + \lambda D_{KL}(\mathcal{N}(\mu(\varphi_{t}), \Sigma(\varphi_{t}) || \mathcal{N}(0, I))[/math]

Где [math]s_0 = G_0(z,\hat{c_0})[/math] результат работы генератора Stage-I GAN и скрытый параметр [math]\hat{c}[/math] подаются на вход дискриминатору и генератору Stage-II GAN, при этом на вход не подается случайное значение, как на первой стадии, поскольку хватает подачи случайного [math]z[/math] на вход Stage-I GAN. При этом Stage-I GAN и Stage-II GAN имеют разные полно-связные слои, чтобы отличаться по среднему значению и стандартному отклонению, таким образом на разных этапах фокусируюемся на разных деталях исходного текста.

LAPGAN (Laplacian Pyramid of Adversarial Networks)

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

Пирамида лапласианов $-$ это линейное обратимое представление изображений, состоящее из набора частотных полос изображений. Пусть [math]d(\cdot)[/math] - это операция сжатия изображения размера [math]j \times j[/math] так, что новое изображение [math]d(I)[/math] имеет размеры [math]j/2 \times j/2[/math], также [math]u(\cdot)[/math] - операция расширения такой, что [math]u(I)[/math] имеет размеры [math]2j \times 2j[/math]. Тогда пирамида гаусианов имеет вид [math]\mathcal{G}(I) = [I_0, I_1,..., I_k][/math], где [math]I_0 = I[/math] и [math]I_k[/math] представляет собой [math]k[/math] раз выполненное применение [math]d(\cdot)[/math]. Коэффициенты [math]h_k[/math] на каждом уровне пирамиды лапласианов считаются так:

[math]h_k = \mathcal{L_k}(I) = \mathcal{G_k}(I) - u(\mathcal{G_{k + 1}}(I)) = I_k - u(I_{k + 1})[/math]

Интуитивно каждый уровень захватывает структуру изображения. Конечный слой пирамиды лапласианов [math]h_k[/math] это не разница изображений, а низко-частотное представление равное гаусиану [math]h_k = I_k[/math]. Реконструкция по пирамиде лапласианов происходит обратным проходом по ней:

[math]I_k = u(I_{k + 1}) + h_k[/math]

Подход представленный в LAPGAN работает по такому же принципу, только на каждому шаге вместо коэфициентов [math]h_k[/math] используются генераторы [math]\{G_0,G_1,...,G_k\}[/math], каждый из которых захватывает распределение коэфициентов [math]h_k[/math] для реальных изображений на разных уровнях пирамиды лапласиана:

[math]\tilde{I_k} = u(\tilde{I_{k + 1}}) + \tilde{h_k} = u(\tilde{I_{k + 1}}) + G_k(z_k, u(\tilde{I_{k + 1}}))[/math]
Процедура семплинга для модели LAPGAN. Источник: https://arxiv.org/pdf/1506.05751.pdf

Процедура семплинга для нашей модели LAPGAN. Начинаем с шума [math]z_3[/math] и используем генеративную модель [math]G_3[/math] для создания [math]\tilde{I_3}[/math]. Потом расширяем изображение до [math]l_2[/math] для следующиего уровня генерации [math]G_2[/math]. Вместе с еще одним шумом [math]z_2[/math] получаем изображение различия [math]\tilde{I_2}[/math]. Продолжаем процесс, пока не получим [math]I_0[/math].

Процедура обучения модели LAPGAN. Источник: https://arxiv.org/pdf/1506.05751.pdf

Процедура обучения LAPGAN. Начинаем с изображения [math]I[/math] размера [math]64 \times 64[/math] из тренировчного набора. Берем [math]I_0 = I [/math] и сжимаем его(красная стрелка) чтобы получить [math]I_1[/math]; затем расширяем его(зеленая стрелка), чтобы получить [math]l_0[/math] низко-частотное изображение [math]I_0[/math]; с равной вероятностью используем его для создния либо реального, либо сгенерированного примера для дискриминатора [math]D_0[/math]. В случае реального изображения(синяя стрелка) считаем цветовой контраст [math]h_0 = I_0 - l_0[/math], которая подается на вход дискриминатору [math]D_0[/math], для опредления реальное изображение или нет. В случае сгенерированного(розовая стрелка), генеративная сеть [math]G_0[/math] получает на вход шум [math]z_0[/math] и [math]l_0[/math]. Оно генерирует цветовой контраст [math]\tilde{h_0} = G_0(z_0,l_0)[/math], который подается на вход [math]D_0[/math]. В обоих случаях дискриминатор также получает [math]l_0[/math] (оранжевая стрелка). Оптимизируя минмакс игру условной порождающей сети [math]G_0[/math] учится генерировать реалистичную высоко-частотную структуру [math]\tilde{h_0}[/math] с помощью низко-частотного представления [math]l_0[/math]. Такая процедура проходит на всех слоях, кроме последнего, где можно уже использовать обычный GAN.

См. также

Примечания

Источники информации