PixelRNN и PixelCNN — различия между версиями
Forliss (обсуждение | вклад) м  | 
				Forliss (обсуждение | вклад)   (→Сравнение подходов)  | 
				||
| (не показано 47 промежуточных версий этого же участника) | |||
| Строка 5: | Строка 5: | ||
Основным преимуществом ''PixelRNN'' и ''PixelCNN'' является уменьшение времени обучения, по сравнению с наивными способами попиксельной генерации изображений.  | Основным преимуществом ''PixelRNN'' и ''PixelCNN'' является уменьшение времени обучения, по сравнению с наивными способами попиксельной генерации изображений.  | ||
== Постановка задачи ==  | == Постановка задачи ==  | ||
| − | Пусть дано черно-белое изображение <tex>X</tex> размером <tex>N\times N</tex>. Построчно преобразуем картинку в вектор <tex>V_X = \{x_1, x_2, \dots, x_{N^2} \}</tex>, соединяя конец текущей строки с началом следующей.   | + | Пусть дано черно-белое изображение <tex>X</tex> размером <tex>N\times N</tex>. Построчно преобразуем картинку в вектор <tex>V_X = \{x_1, x_2, \dots, x_{N^2} \}</tex>, соединяя конец текущей строки с началом следующей. При таком представлении изображения можно предположить, что значение любого пикселя <tex>x_i\in V_X</tex> может зависеть от значений предыдущих пикселей <tex>x_j, j = 1,2,\dots i-1</tex>.    | 
| − | Тогда значение пикселя <tex>x_i\in V_X</tex> можно выразить через условную вероятность <tex>p(x_i|x_1, x_2, \dots x_{i-1})</tex>  | + | Тогда значение пикселя <tex>x_i\in V_X</tex> можно выразить через условную вероятность <tex>p(x_i|x_1, x_2, \dots x_{i-1})</tex> и цепное правило для вероятностей<ref name=ChainRule>[https://en.wikipedia.org/wiki/Chain_rule_(probability) Chain rule (probability)]</ref>. Оценка совместного распределения всех пикселей будет записываться в следующем виде: <tex>p(X)=\prod_{i=1}^{N^2}p(x_i|x_1, x_2, \dots x_{i-1})</tex>.  | 
Задача алгоритма {{---}} восстановить данное распределение. Учитывая тот факт, что любой пиксель принимает значение <tex>0<=x_i<=255</tex>, необходимо восстановить лишь дискретное распределение.  | Задача алгоритма {{---}} восстановить данное распределение. Учитывая тот факт, что любой пиксель принимает значение <tex>0<=x_i<=255</tex>, необходимо восстановить лишь дискретное распределение.  | ||
| Строка 13: | Строка 13: | ||
== Идея ==  | == Идея ==  | ||
| − | Так как утверждается, что значение текущего пикселя зависит от   | + | Так как утверждается, что значение текущего пикселя зависит от значения предыдущего, то уместно использовать [[:Рекуррентные_нейронные_сети|''рекуррентные нейронные сети (RNN)'']], а точнее [[Долгая краткосрочная память|''долгую краткосрочную память (LSTM)'']]. В ранних работах<ref name=SpatialLSTM>[https://arxiv.org/abs/1506.03478 Generative Image Modeling Using Spatial LSTMs]</ref> уже использовался данный подход, и вычисление скрытого состояния происходило следующим образом: <tex>h_{i,j}=f(h_{i-1,j}, h_{i,j-1}, x_{i,j})</tex>, т.е. для того, чтобы вычислить текущее скрытое состояние, нужно было подсчитать все предыдущие, что занимает достаточно много времени.    | 
| − | + | У алгоритма [[Долгая краткосрочная память|''LSTM'']] существует две модификации: '''''RowLSTM''''' и '''''Diagonal BiLSTM'''''. Основным преимуществом модификаций является возможность проводить вычисления параллельно, что ускоряет общее время обучения модели.  | |
=== RowLSTM ===  | === RowLSTM ===  | ||
| Строка 23: | Строка 23: | ||
Как видно из формулы и Рисунка 2, значение текущего скрытого состояния не зависит от предыдущего слева, а зависит только от предыдущих сверху, которые считаются параллельно.    | Как видно из формулы и Рисунка 2, значение текущего скрытого состояния не зависит от предыдущего слева, а зависит только от предыдущих сверху, которые считаются параллельно.    | ||
| − | Таким образом, главным преимуществом алгоритма перед наивным [[Долгая краткосрочная память|''LSTM'']] является более быстрое обучение модели, однако качество получаемых изображений ухудшается.   | + | Таким образом, главным преимуществом алгоритма перед наивным [[Долгая краткосрочная память|''LSTM'']] является более быстрое обучение модели, однако качество получаемых изображений ухудшается. Это связанно как минимум с тем, что мы используем контекст пикселей с предыдущей строки, но никак не используем контекст соседнего слева пикселя, которые является достаточно важным, т.к. является ближайшим с точки зрения построчной генерации изображения. Значит надо научиться находить скрытое состояние слева, но делать это эффективно.  | 
=== Diagonal BiLSTM ===  | === Diagonal BiLSTM ===  | ||
| Строка 30: | Строка 30: | ||
=== PixelCNN ===  | === PixelCNN ===  | ||
| − | Идея в том, что   | + | Идея в том, что наиболее важные данные для пикселя содержатся в соседних пикселях (в рамках ядра 9x9), поэтому предлагается просто использовать известные пиксели для вычисления нового, как показано на рисунке 2.  | 
== Архитектура ==  | == Архитектура ==  | ||
| − | В алгоритмах ''PixelRNN'' и ''PixelCNN'' используются несколько архитектурных трюков, позволяющих производить вычисления   | + | В алгоритмах ''PixelRNN'' и ''PixelCNN'' используются несколько архитектурных трюков, позволяющих производить вычисления быстро и надежно.  | 
| + | |||
| + | [[File:0_UbiGmm8uyZ-GKhv5_.jpg|350px|thumb|Рисунок 4. MaskA и MaskB.]]  | ||
=== Маскированные сверточные слои ===  | === Маскированные сверточные слои ===  | ||
| Строка 44: | Строка 46: | ||
=== Уменьшение размерности ===    | === Уменьшение размерности ===    | ||
| − | [[File:pixel-4.png|  | + | [[File:pixel-4.png|320px|thumb|Рисунок 5. Блоки уменьшения размерности. Слева {{---}} блок для ''PixelCNN'', справа {{---}} ''PixelRNN''. ]]  | 
На вход в любой их указанных выше алгоритмов (''PixelCNN'', ''RowLSTM'', ''Diagonal BiLSTM'') подается большое количество объектов, поэтому внутри каждого из них сначала происходит уменьшение их количества в два раза, а затем обратное увеличение до исходного размера. Структура алгоритма с учетом уменьшения размерности показана на рисунке 4.  | На вход в любой их указанных выше алгоритмов (''PixelCNN'', ''RowLSTM'', ''Diagonal BiLSTM'') подается большое количество объектов, поэтому внутри каждого из них сначала происходит уменьшение их количества в два раза, а затем обратное увеличение до исходного размера. Структура алгоритма с учетом уменьшения размерности показана на рисунке 4.  | ||
| + | |||
| + | [[File:pixel-5.png|320px|thumb|Рисунок 6. Простой LSTM-блок с тремя вентилями: входным, выходным и забывания.]]  | ||
=== Внутреннее устройство LSTM ===    | === Внутреннее устройство LSTM ===    | ||
| Строка 57: | Строка 61: | ||
<tex>  | <tex>  | ||
| − | [o_i, f_i, i_i, g_i] = \sigma (K_{ss}\circledast h_{i-1} + K_{is}\circledast x_{i}) \\  | + | [o_i, f_i, i_i, g_i] = \sigma (K_{ss}\circledast h_{i-1} + K_{is}\circledast x_{i}), \\  | 
| − | c_i=f_i\odot c_{i-1} + i_i\odot g_i\\  | + | c_i=f_i\odot c_{i-1} + i_i\odot g_i,\\  | 
| − | h_i = o_i\odot tanh(c_i)  | + | h_i = o_i\odot tanh(c_i),  | 
</tex>  | </tex>  | ||
| − | где <tex>\sigma</tex> {{---}} функция активации,   | + | где <tex>\sigma</tex> {{---}} функция активации,    | 
| + | |||
| + | <tex>\circledast</tex> {{---}} операция свертки,    | ||
| + | |||
| + | <tex>\odot</tex> {{---}} поэлементное умножение,   | ||
| + | |||
| + | <tex>f_i</tex> {{---}} вектор вентиля забывания, вес запоминания старой информации,   | ||
| + | |||
| + | <tex>i_i</tex> {{---}} вектор входного вентиля, вес получения новой информации,   | ||
| + | |||
| + | <tex>o_i</tex> {{---}} вектор выходного вентиля, кандидат на выход,   | ||
| + | |||
| + | <tex>g_i</tex> {{---}} вектор вентиля данных,   | ||
| + | |||
| + | <tex>x_i</tex> {{---}} строка <tex>i</tex> входных данных,   | ||
| + | |||
| + | <tex>h_i</tex> {{---}} вектор краткосрочной памяти,   | ||
| + | |||
| + | <tex>c_i</tex> {{---}} вектор долгосрочной памяти,   | ||
| + | |||
| + | <tex>K_{is}</tex> и <tex>K_{ss}</tex> {{---}} ядерные веса компонент ''input-to-state'' и ''state-to-state'' соответственно.  | ||
=== Архитектура PixelRNN ===  | === Архитектура PixelRNN ===  | ||
| − | # ''MaskA'' размером <tex>7\times 7</tex>    | + | # ''MaskA'' размером <tex>7\times 7</tex>.  | 
| − | # Блоки уменьшения размеренности с ''RowLSTM'' блоком, в котором <tex>K_{is}</tex> имеет размер <tex>3\times 1</tex>, <tex>K_{ss}</tex> {{---}} <tex>3\times 2</tex>. Для ''Diagonal BiLSTM'' <tex>K_{is}</tex> имеет размер <tex>1\times 1</tex>, <tex>K_{ss}</tex> {{---}} <tex>1\times 2</tex>. Количество блоков варьируется.    | + | # Блоки уменьшения размеренности с ''RowLSTM'' блоком, в котором <tex>K_{is}</tex> имеет размер <tex>3\times 1</tex>, <tex>K_{ss}</tex> {{---}} <tex>3\times 2</tex>. Для ''Diagonal BiLSTM'' <tex>K_{is}</tex> имеет размер.<tex>1\times 1</tex>, <tex>K_{ss}</tex> {{---}} <tex>1\times 2</tex>. Количество блоков варьируется.    | 
| − | # ''ReLU'' активация     | + | # ''ReLU'' активация.     | 
| − | # Сверточный слой размером <tex>1\times 1</tex>    | + | # Сверточный слой размером <tex>1\times 1</tex>.  | 
| − | # ''Softmax'' слой  | + | # ''Softmax'' слой.  | 
| + | |||
| + | [[File:exampleCNN.png|450px|thumb|Рисунок 7. Лица, сгенерированные с помощью PixelCNN сетей <ref name=NaturalModeling>[https://arxiv.org/pdf/1612.08185v4.pdf#page=8 Natural Modeling]</ref>]]  | ||
=== Архитектура PixelCNN ===  | === Архитектура PixelCNN ===  | ||
| − | # ''MaskA'' размером <tex>7\times 7</tex>    | + | # ''MaskA'' размером <tex>7\times 7</tex>.  | 
# Блоки уменьшения размеренности для ''PixelCNN''.    | # Блоки уменьшения размеренности для ''PixelCNN''.    | ||
| − | # ''ReLU'' активация   | + | # ''ReLU'' активация.  | 
| − | # Сверточный слой размером <tex>1\times 1</tex>    | + | # Сверточный слой размером <tex>1\times 1</tex>.   | 
| − | # ''Softmax'' слой  | + | # ''Softmax'' слой.  | 
== Сравнение подходов ==  | == Сравнение подходов ==  | ||
| + | [[File:exampleGAN.png|450px|thumb|Рисунок 8. Лица, сгенерированные с помощью GAN <ref name=ForwardScience>[https://towardsdatascience.com/how-to-train-stylegan-to-generate-realistic-faces-d4afca48e705 Towards data science]</ref>]]  | ||
| + | |||
| + | Если сравнивать [[Generative Adversarial Nets (GAN) | GAN]] с PixelCNN/PixelRNN, то можно отметить более хорошее качество получаемых изображений у генеративно-состязательного метода. Однако у метода GAN время обучения медленнее, чем у PixelCNN и PixelRNN. Для реализации GAN требуется найти равновесие Нэша, но в настоящее время нет алгоритма делающего это. Поэтому обучение GAN более нестабильное, если сравнивать с другими методами<ref name=Reg>[https://towardsdatascience.com/auto-regressive-generative-models-pixelrnn-pixelcnn-32d192911173 Auto-Regressive Generative Models]</ref>. В настоящее время многие мировые компании используют GAN для генерации изображений, например: [https://neurohive.io/ru/papers/pggan-progressivnaja-generativnaja-nejroset-ot-nvidia/ PGGAN] от ''Nvidia'', [https://bdol.github.io/exemplar_gans/ Exemplar GAN] от ''Facebook'' и другие.  | ||
| + | |||
{| class="wikitable"  | {| class="wikitable"  | ||
! style="font-weight:bold;" | Критерий\название  | ! style="font-weight:bold;" | Критерий\название  | ||
| Строка 84: | Строка 114: | ||
! style="font-weight:bold;" | PixelRNN(Row LSTM)  | ! style="font-weight:bold;" | PixelRNN(Row LSTM)  | ||
! style="font-weight:bold;" | PixelRNN(Diagonal BiLSTM)  | ! style="font-weight:bold;" | PixelRNN(Diagonal BiLSTM)  | ||
| + | ! style="font-weight:bold;" | GAN  | ||
|-  | |-  | ||
| Время обучения  | | Время обучения  | ||
| Быстрый  | | Быстрый  | ||
| Средний  | | Средний  | ||
| + | | Медленный  | ||
| Медленный  | | Медленный  | ||
|-  | |-  | ||
| Строка 94: | Строка 126: | ||
| Средне-низкое  | | Средне-низкое  | ||
| Средне-высокое  | | Средне-высокое  | ||
| + | | Высокое  | ||
|}  | |}  | ||
== Примеры реализации ==  | == Примеры реализации ==  | ||
| − | * [https://github.com/singh-hrituraj/PixelCNN-Pytorch PixelCNN на Pytorch  | + | * [https://github.com/singh-hrituraj/PixelCNN-Pytorch PixelCNN на Pytorch]  | 
| − | * [https://github.com/ardapekis/pixel-rnn PixelRNN на Pytorch  | + | * [https://github.com/ardapekis/pixel-rnn PixelRNN на Pytorch]  | 
| − | * [https://github.com/shirgur/PixelRNN PixelRNN на Keras  | + | * [https://github.com/shirgur/PixelRNN PixelRNN на Keras]  | 
==См. также==  | ==См. также==  | ||
| Строка 105: | Строка 138: | ||
* [[Долгая краткосрочная память]]  | * [[Долгая краткосрочная память]]  | ||
* [[Нейронные сети, перцептрон]]  | * [[Нейронные сети, перцептрон]]  | ||
| + | * [[Генерация объектов]]  | ||
==Примечания==  | ==Примечания==  | ||
<references/>  | <references/>  | ||
== Источники информации ==  | == Источники информации ==  | ||
| − | * [https://towardsdatascience.com/auto-regressive-generative-models-pixelrnn-pixelcnn-32d192911173 Auto-Regressive Generative Models  | + | * [https://towardsdatascience.com/auto-regressive-generative-models-pixelrnn-pixelcnn-32d192911173 Auto-Regressive Generative Models]  | 
| − | * [http://slazebni.cs.illinois.edu/spring17/lec13_advanced.pdf Advanced Generation Methods  | + | * [http://slazebni.cs.illinois.edu/spring17/lec13_advanced.pdf Advanced Generation Methods]  | 
| − | * [https://github.com/tensorflow/magenta/blob/master/magenta/reviews/pixelrnn.md Pixel Recurrent Neural Networks  | + | * [https://github.com/tensorflow/magenta/blob/master/magenta/reviews/pixelrnn.md Pixel Recurrent Neural Networks]  | 
| − | * [http://bjlkeng.github.io/posts/pixelcnn/ PixelCNN.]  | + | * [http://bjlkeng.github.io/posts/pixelcnn/ PixelCNN]  | 
| + | * [https://arxiv.org/pdf/1612.08185v4.pdf#page=8 Natural Modeling]  | ||
| + | * [https://towardsdatascience.com/how-to-train-stylegan-to-generate-realistic-faces-d4afca48e705 Towards data science]  | ||
[[Категория: Машинное обучение]]  | [[Категория: Машинное обучение]]  | ||
| + | [[Категория: Генерация объектов]]  | ||
Версия 20:41, 3 января 2021
PixelRNN и PixelCNN — алгоритмы машинного обучения, входящие в семейство авторегрессивных моделей и использующиеся для генерации и дополнения изображений. Алгоритмы были представлены в 2016 году компанией DeepMind[1] и являются предшественниками алгоритма WaveNet[2], который используется в голосовом помощнике Google.
Основным преимуществом PixelRNN и PixelCNN является уменьшение времени обучения, по сравнению с наивными способами попиксельной генерации изображений.
Содержание
Постановка задачи
Пусть дано черно-белое изображение размером . Построчно преобразуем картинку в вектор , соединяя конец текущей строки с началом следующей. При таком представлении изображения можно предположить, что значение любого пикселя может зависеть от значений предыдущих пикселей .
Тогда значение пикселя можно выразить через условную вероятность и цепное правило для вероятностей[3]. Оценка совместного распределения всех пикселей будет записываться в следующем виде: .
Задача алгоритма — восстановить данное распределение. Учитывая тот факт, что любой пиксель принимает значение , необходимо восстановить лишь дискретное распределение.
Идея
Так как утверждается, что значение текущего пикселя зависит от значения предыдущего, то уместно использовать рекуррентные нейронные сети (RNN), а точнее долгую краткосрочную память (LSTM). В ранних работах[4] уже использовался данный подход, и вычисление скрытого состояния происходило следующим образом: , т.е. для того, чтобы вычислить текущее скрытое состояние, нужно было подсчитать все предыдущие, что занимает достаточно много времени.
У алгоритма LSTM существует две модификации: RowLSTM и Diagonal BiLSTM. Основным преимуществом модификаций является возможность проводить вычисления параллельно, что ускоряет общее время обучения модели.
RowLSTM
В данной модификации LSTM скрытое состояние считается по формуле: .
Как видно из формулы и Рисунка 2, значение текущего скрытого состояния не зависит от предыдущего слева, а зависит только от предыдущих сверху, которые считаются параллельно.
Таким образом, главным преимуществом алгоритма перед наивным LSTM является более быстрое обучение модели, однако качество получаемых изображений ухудшается. Это связанно как минимум с тем, что мы используем контекст пикселей с предыдущей строки, но никак не используем контекст соседнего слева пикселя, которые является достаточно важным, т.к. является ближайшим с точки зрения построчной генерации изображения. Значит надо научиться находить скрытое состояние слева, но делать это эффективно.
Diagonal BiLSTM
В данной версии скрытое состояние считается таким же образом, как и в наивном подходе: , но использует следующую хитрость в самом вычислении — построчно сдвинем строки вправо на один пиксель относительно предыдущей, а затем вычислим скрытые состояния в каждом столбце, как показано на Рисунке 3. Как следствие, контекст учитывается более качественно, что повышает качество изображения, однако такая модификация замедляет модель по сравнению с подходом RowLSTM.
PixelCNN
Идея в том, что наиболее важные данные для пикселя содержатся в соседних пикселях (в рамках ядра 9x9), поэтому предлагается просто использовать известные пиксели для вычисления нового, как показано на рисунке 2.
Архитектура
В алгоритмах PixelRNN и PixelCNN используются несколько архитектурных трюков, позволяющих производить вычисления быстро и надежно.
Маскированные сверточные слои
В описаниях алгоритмов фигурируют два типа маскированных сверточных слоя — MaskA, MaskB. Они необходимы для сокрытия от алгоритма лишней информации и учета контекста — чтобы ускорить обработку изображения после каждого подсчета, предлагается вместо удаления значения пикселей применять маску к изображению, что является более быстрой операцией.
Для каждого пикселя в цветном изображении в порядке очереди существуют три контекста: красный канал, зеленый и синий. В данном алгоритме очередь важна, т.е. если сейчас обрабатывается красный канал, то контекст только от предыдущих значений красного канала, если зеленый — то от всех значений на красном канале и предыдущих значениях на зеленом и т.д.
MaskA используется для того, чтобы учитывать контекст предыдущих каналов, но при этом не учитывать контекст от предыдущих значений текущего канала и следующих каналов. MaskB выполняет ту же функцию, что и MaskA, но при этом учитывает контекст от предыдущих значений текущего канала.
Уменьшение размерности
На вход в любой их указанных выше алгоритмов (PixelCNN, RowLSTM, Diagonal BiLSTM) подается большое количество объектов, поэтому внутри каждого из них сначала происходит уменьшение их количества в два раза, а затем обратное увеличение до исходного размера. Структура алгоритма с учетом уменьшения размерности показана на рисунке 4.
Внутреннее устройство LSTM
Внутреннее устройство RowLSTM и Diagonal BiLSTM блоков одинаково, за исключением того, что во втором случае добавляется операция сдвига в начале и возврат к исходной структуре изображения в конце.
Структура LSTM блока:
- MaskB слой input-to-state учитывает контекст из входа.
 - Сверточный слой state-to-state учитывает контекст из предыдущих скрытых слоев.
 
Используя эти два сверточных слоя формально вычисление LSTM блока можно записать следующим образом:
где — функция активации,
— операция свертки,
— поэлементное умножение,
— вектор вентиля забывания, вес запоминания старой информации,
— вектор входного вентиля, вес получения новой информации,
— вектор выходного вентиля, кандидат на выход,
— вектор вентиля данных,
— строка входных данных,
— вектор краткосрочной памяти,
— вектор долгосрочной памяти,
и — ядерные веса компонент input-to-state и state-to-state соответственно.
Архитектура PixelRNN
- MaskA размером .
 - Блоки уменьшения размеренности с RowLSTM блоком, в котором имеет размер , — . Для Diagonal BiLSTM имеет размер., — . Количество блоков варьируется.
 - ReLU активация.
 - Сверточный слой размером .
 - Softmax слой.
 
Архитектура PixelCNN
- MaskA размером .
 - Блоки уменьшения размеренности для PixelCNN.
 - ReLU активация.
 - Сверточный слой размером .
 - Softmax слой.
 
Сравнение подходов
Если сравнивать GAN с PixelCNN/PixelRNN, то можно отметить более хорошее качество получаемых изображений у генеративно-состязательного метода. Однако у метода GAN время обучения медленнее, чем у PixelCNN и PixelRNN. Для реализации GAN требуется найти равновесие Нэша, но в настоящее время нет алгоритма делающего это. Поэтому обучение GAN более нестабильное, если сравнивать с другими методами[7]. В настоящее время многие мировые компании используют GAN для генерации изображений, например: PGGAN от Nvidia, Exemplar GAN от Facebook и другие.
| Критерий\название | PixelCNN | PixelRNN(Row LSTM) | PixelRNN(Diagonal BiLSTM) | GAN | 
|---|---|---|---|---|
| Время обучения | Быстрый | Средний | Медленный | Медленный | 
| Качество генерируемых изображений | Наихудшее | Средне-низкое | Средне-высокое | Высокое | 
Примеры реализации
См. также
- Рекуррентные нейронные сети
 - Долгая краткосрочная память
 - Нейронные сети, перцептрон
 - Генерация объектов
 
