Что такое деконволюционные слои?


188

Недавно я прочитал « Полностью сверточные сети для семантической сегментации » Джонатана Лонга, Эвана Шелхамера, Тревора Даррелла. Я не понимаю, что делают "деконволюционные слои" / как они работают.

Соответствующая часть

3.3. Апсэмплинг - обратная свертка

Другим способом подключения грубых выходов к плотным пикселям является интерполяция. Например, простая билинейная интерполяция вычисляет каждый выход yij из ближайших четырех входов по линейной карте, которая зависит только от относительных положений входных и выходных ячеек.
В некотором смысле повышение частоты дискретизации с коэффициентом f является сверткой с дробным шагом ввода 1 / f. До тех пор, пока целочисленный, естественным способом повышения частоты является обратная свертка (иногда называемая деконволюцией) с выходным шагом . Такая операция тривиальна для реализации, так как она просто меняет прямой и обратный проходы свертки.фff
Таким образом, повышающая дискретизация выполняется в сети для сквозного обучения путем обратного распространения по пиксельным потерям.
Обратите внимание, что фильтр деконволюции в таком слое не нужно фиксировать (например, для билинейного повышения дискретизации), но можно изучить. Стек деконволюционных слоев и функций активации может даже изучить нелинейную повышающую дискретизацию.
В наших экспериментах мы обнаружили, что повышение частоты дискретизации в сети является быстрым и эффективным для обучения плотному прогнозированию. Наша лучшая архитектура сегментации использует эти уровни, чтобы научиться подбирать более точные прогнозы в Разделе 4.2.

Я не думаю, что я действительно понял, как обучают сверточные слои.

Я думаю, что я понял, что сверточные слои с размером ядра изучают фильтры размером . Выход сверточного слоя с размером ядра , шагом и n фильтров имеет размерность Input dimk × k k s Nkk×kksNn. Однако я не знаю, как работает изучение сверточных слоев. (Я понимаю, как простые MLPs учатся с градиентным спуском, если это помогает).Input dims2n

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

Кто-нибудь может помочь мне понять деконволюционные слои?


3
В этой видео-лекции рассказывается о деконволюции / повышающей дискретизации: youtu.be/ByjaPdWXKJ4?t=16m59s
user199309

6
Надеясь, что это может пригодиться кому угодно, я сделал блокнот, чтобы изучить, как свертка и транспонированная свертка могут использоваться в TensorFlow (0.11). Возможно, наличие практических примеров и рисунков может помочь немного понять, как они работают.
AkiRoss

1
Для меня эта страница дала мне лучшее объяснение, она также объясняет разницу между деконволюцией и транспонированием свертки: intodatascience.com/…
T.Antoni

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

Примечание. Название «деконволюционный слой» вводит в заблуждение, поскольку этот слой не выполняет деконволюцию .
user76284

Ответы:


210

Деконволюционный слой - очень неудачное имя, и его лучше назвать транспонированным сверточным слоем .

Визуально, для транспонированной свертки с шагом один и без заполнения, мы просто заполняем исходный ввод (синие записи) нулями (белые записи) (рисунок 1).

фигура 1

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

фигура 2

Вы можете найти больше (отличных) визуализаций сверточной арифметики здесь .


16
Просто чтобы убедиться, что я понял это: «Деконволюция» - это почти то же самое, что и свертка, но вы добавили немного отступов? (Вокруг изображения / когда s> 1 также вокруг каждого пикселя)?
Мартин Тома

17
Да, слой деконволюции также выполняет свертку! Вот почему транспонированная свертка подходит гораздо лучше, чем имя, и термин деконволюция фактически вводит в заблуждение.
Дэвид Дао

11
Почему вы говорите «без заполнения» на рисунке 1, если на самом деле ввод заполнен нулями?
Стас С

8
Кстати: теперь это называется транспонированная свертка в TensorFlow
Мартин Тома,

9
Спасибо за этот очень интуитивный ответ, но меня смущает, почему второй случай «второго шага», он ведет себя точно так же, как первый, когда ядро ​​движется.
Демонстрация

49

Я думаю, что один из способов получить действительно базовую интуицию на уровне свертки состоит в том, что вы перемещаете K-фильтры, которые вы можете рассматривать как K-трафареты, по входному изображению и производите K-активаций - каждый из которых представляет степень соответствия с конкретным трафаретом. , Обратной операцией этого было бы взять K активаций и превратить их в прообраз операции свертки. Таким образом, интуитивное объяснение обратной операции - это, примерно, реконструкция изображения с учетом трафаретов (фильтров) и активаций (степень соответствия для каждого трафарета), и поэтому на базовом интуитивном уровне мы хотим взорвать каждую активацию маской трафарета. и сложите их.

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

DeconvolutionLayer<Dtype>::Forward_gpu
ConvolutionLayer<Dtype>::Backward_gpu
CuDNNConvolutionLayer<Dtype>::Backward_gpu
BaseConvolutionLayer<Dtype>::backward_cpu_gemm

Вы можете видеть, что он реализован в Caffe точно так же, как backprop для обычного прямого сверточного уровня (для меня это было более очевидно после того, как я сравнил реализацию backprop в cuDNN conv layer против ConvolutionLayer :: Backward_gpu, реализованной с использованием GEMM). Поэтому, если вы поработаете над тем, как выполняется обратное распространение для регулярной свертки, вы поймете, что происходит на уровне механических вычислений. Способ, которым это вычисление работает, соответствует интуиции, описанной в первом параграфе этого объявления.

Однако я не знаю, как работает изучение сверточных слоев. (Я понимаю, как простые MLPs учатся с градиентным спуском, если это помогает).

Чтобы ответить на ваш второй вопрос в вашем первом вопросе, есть два основных различия между обратным распространением MLP (полностью связанный слой) и сверточными сетями:

1) влияние весов локализовано, поэтому сначала выясните, как сделать backprop для, скажем, фильтра 3x3, свернутого с небольшой областью 3x3 входного изображения, сопоставляя его с одной точкой в ​​результирующем изображении.

2) веса сверточных фильтров являются общими для пространственной инвариантности. На практике это означает, что при прямом проходе один и тот же фильтр 3x3 с одинаковыми весами перетаскивается по всему изображению с одинаковыми весами для прямого вычисления для получения выходного изображения (для этого конкретного фильтра). Для backprop это означает, что градиенты backprop для каждой точки исходного изображения суммируются по всему диапазону, который мы перетаскивали на этом фильтре во время прямого прохода. Обратите внимание, что существуют также разные градиенты потерь по x, w и смещению, поскольку dLoss / dx необходимо распространять в обратном направлении, а dLoss / dw - это то, как мы обновляем весы. w и bias являются независимыми входами в расчетной DAG (предварительных входов нет), поэтому нет необходимости выполнять обратное распространение на них.

(my notation here assumes that convolution is y = x*w+b where '*' is the convolution operation)

7
Я думаю, что это лучший ответ на этот вопрос.
kli_nlpr

8
Я согласен, что это лучший ответ. В верхнем ответе есть красивые анимации, но пока я не прочитал этот ответ, они просто выглядели как обычные свертки с некоторыми произвольными отступами для меня. О, как люди качаются на глаз конфеты.
Рейи Накано

1
Согласитесь, принятый ответ ничего не объяснял. Это намного лучше.
BjornW

Спасибо за ваше великолепное объяснение. В настоящее время я не могу понять, как сделать бэкпроп правильно. Не могли бы вы дать мне подсказку на это, пожалуйста?
Бастиан

33

Пошаговая математика, объясняющая, как транспонированная свертка выполняет 2-кратную повышающую дискретизацию с фильтром 3x3 и шагом 2:

введите описание изображения здесь

Простейший фрагмент TensorFlow для проверки математики:

import tensorflow as tf
import numpy as np

def test_conv2d_transpose():
    # input batch shape = (1, 2, 2, 1) -> (batch_size, height, width, channels) - 2x2x1 image in batch of 1
    x = tf.constant(np.array([[
        [[1], [2]], 
        [[3], [4]]
    ]]), tf.float32)

    # shape = (3, 3, 1, 1) -> (height, width, input_channels, output_channels) - 3x3x1 filter
    f = tf.constant(np.array([
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]], 
        [[[1]], [[1]], [[1]]]
    ]), tf.float32)

    conv = tf.nn.conv2d_transpose(x, f, output_shape=(1, 4, 4, 1), strides=[1, 2, 2, 1], padding='SAME')

    with tf.Session() as session:
        result = session.run(conv)

    assert (np.array([[
        [[1.0], [1.0],  [3.0], [2.0]],
        [[1.0], [1.0],  [3.0], [2.0]],
        [[4.0], [4.0], [10.0], [6.0]],
        [[3.0], [3.0],  [7.0], [4.0]]]]) == result).all()

Я думаю, что ваш расчет здесь неверен. Промежуточный вывод должен быть 3+ 2 * 2 = 7, тогда для ядра 3x3 конечный вывод должен быть 7-3 + 1 = 5x5
Alex

Извините, @Alex, но я не понимаю, почему промежуточный результат равен 7. Не могли бы вы уточнить?
Андрей

2
@andriys На изображении, которое вы показали, почему окончательный результат обрезается?
Джеймс Бонд

28

В примечания , которые сопровождают Stanford CS класса CS231n : сверточные нейронные сети для визуального распознавания, Андрей Karpathy , делает отличную работу по объяснению сверточных нейронных сетей.

Чтение этого документа должно дать вам общее представление о:

  • Деконволюционные сети Мэтью Д. Зейлер, Дилип Кришнан, Грэм У. Тейлор и Роб Фергус, факультет компьютерных наук, Институт Куранта, Нью-Йоркский университет

Эти слайды отлично подходят для деконволюционных сетей.


29
Можно ли кратко изложить содержание любой из этих ссылок? Ссылки могут быть полезны для дальнейшего исследования, но в идеале ответ об обмене стека должен иметь достаточно текста, чтобы ответить на основной вопрос, не выходя из сайта.
Нил Слэйтер

Извините, но содержание этих страниц слишком велико, чтобы их можно было кратко изложить.
Азраэль

12
Полное резюме не требуется, только заголовок - например, «Деконволюционная нейронная сеть похожа на CNN, но обучена так, чтобы функции в любом скрытом слое могли использоваться для реконструкции предыдущего уровня (и путем повторения между уровнями, в конце концов входные данные могут быть восстановлены из выходных данных.) Это позволяет обучать их без присмотра, чтобы изучить общие высокоуровневые функции в проблемной области - обычно обработку изображений "(заметьте, я даже не уверен, что это правильно, поэтому не пишу свои собственный ответ).
Нил Слэйтер

6
Хотя ссылки хороши, краткое описание модели на ваши слова было бы лучше.
SmallChess

11

Только что нашел отличную статью на сайте theaon на эту тему [1]:

Необходимость в транспонированных свертках обычно возникает из-за желания использовать преобразование, идущее в направлении, противоположном нормальной [...] свертке, для проецирования карт признаков в пространство более высокого измерения. [...] то есть, карта из 4-мерного пространства в 16-мерное пространство, сохраняя при этом схему связности свертки.

Транспонированные извилины - также называемые извилинами с дробным шагом - работают, меняя передний и задний проходы свертки. Один из способов выразить это - отметить, что ядро ​​определяет свертку, но то, является ли это прямой сверткой или транспонированной сверткой, определяется тем, как вычисляются прямой и обратный проходы.

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

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

Таким образом, в простом выражении «транспонированная свертка» является математической операцией с использованием матриц (точно так же как свертка), но она более эффективна, чем обычная операция свертки, в случае, когда вы хотите вернуться от свернутых значений к исходным (противоположное направление). Вот почему в реализациях предпочтительнее свертки при вычислении противоположного направления (то есть, чтобы избежать многих ненужных 0 умножений, вызванных разреженной матрицей, которая получается в результате заполнения ввода).

Image ---> convolution ---> Result

Result ---> transposed convolution ---> "originalish Image"

Иногда вы сохраняете некоторые значения по пути свертки и повторно используете эту информацию при «возврате»:

Result ---> transposed convolution ---> Image

Это, вероятно, причина, почему это неправильно называют "деконволюцией". Однако это как-то связано с транспонированием матрицы свертки (C ^ T), отсюда и более подходящее название «транспонированная свертка».

Так что это имеет большой смысл при рассмотрении стоимости вычислений. Вы бы заплатили намного больше за Amazon Gpus, если бы не использовали транспонированную свертку.

Внимательно прочитайте и посмотрите анимацию: http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#no-zero-padding-unit-strides-transposed

Некоторые другие соответствующие чтения:

Транспонирование (или, в более общем случае, эрмитово или сопряженное транспонирование) фильтра - это просто согласованный фильтр [3]. Это обнаруживается путём обращения ядра к времени и получения сопряжённости всех значений [2].

Я также новичок в этом и был бы благодарен за любые отзывы или исправления.

[1] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html

[2] http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#transposed-convolution-arithmetic

[3] https://en.wikipedia.org/wiki/Matched_filter


1
Придирчивость, но ссылка должна быть: deeplearning.net/software/theano_versions/dev/tutorial/…
Герберт

1
Я думаю, что это лучший ответ !!!
kli_nlpr

10

Мы могли бы использовать PCA для аналогии.

При использовании conv прямой проход должен извлечь коэффициенты основных компонентов из входного изображения, а обратный проход (который обновляет входные данные) должен использовать (градиент) коэффициентов для восстановления нового входного изображения, так что Новое входное изображение имеет коэффициенты ПК, которые лучше соответствуют желаемым коэффициентам.

При использовании deconv прямой проход и обратный проход меняются местами. Прямой проход пытается восстановить изображение из коэффициентов ПК, а обратный проход обновляет коэффициенты ПК, заданные (градиент) изображения.

Прямой проход deconv выполняет в точности вычисление градиента извилины, приведенное в этом посте: http://andrew.gibiansky.com/blog/machine-learning/convolutional-neural-networks/

Вот почему в caffe-реализации deconv (см. Ответ Андрея Покровского) прямая передача deconv вызывает backward_cpu_gemm (), а обратная передача вызывает forward_cpu_gemm ().


6

В дополнение к ответу Дэвида Дао: можно также думать иначе. Вместо того, чтобы фокусироваться на том, какие входные пиксели (с низким разрешением) используются для создания одного выходного пикселя, вы также можете сосредоточиться на том, какие отдельные входные пиксели вносят вклад в какую область выходных пикселей.

Это сделано в этой публикации , включая серию очень интуитивных и интерактивных визуализаций. Одним из преимуществ размышлений в этом направлении является то, что объяснение артефактов шахматной доски становится легким.


5

Свертки с точки зрения DSP

Я немного опоздал на это, но все же хотел бы поделиться своими взглядами и идеями. Я занимаюсь теоретической физикой и цифровой обработкой сигналов. В частности я изучал вейвлеты и свертки почти у меня в позвоночнике;)

То, как люди в сообществе глубокого обучения говорят о свертках, меня также смущало. С моей точки зрения, что, кажется, не хватает, это правильное разделение интересов. Я объясню глубокие свертки обучения, используя некоторые инструменты DSP.

отказ

Мои объяснения будут немного волнистыми и не математически строгими, чтобы объяснить основные моменты.


Определения

Давайте сначала определим несколько вещей. Я ограничиваю свое обсуждение одним измерением (расширение до большего измерения является прямым) бесконечными (так что нам не нужно возиться с границами) последовательностей ИксNзнак равно{ИксN}Nзнак равно-знак равно{...,Икс-1,Икс0,Икс1,...} .

YNИксN

(Y*Икс)Nзнак равноΣКзнак равно-YN-КИксК

Если мы запишем это в терминах матричных векторных операций, то это будет выглядеть так (при условии простого ядра Qзнак равно(Q0,Q1,Q2)Иксзнак равно(Икс0,Икс1,Икс2,Икс3)T

Q*Иксзнак равно(Q1Q000Q2Q1Q000Q2Q1Q000Q2Q1)(Икс0Икс1Икс2Икс3)

КN

КИксNзнак равноИксNК

КК-1

КИксNзнак равно{ИксN/КN/КZ0в противном случае

Кзнак равно3

3{...,Икс0,Икс1,Икс2,Икс3,Икс4,Икс5,Икс6,...}знак равно{...,Икс0,Икс3,Икс6,...}
3{...,Икс0,Икс1,Икс2,...}знак равно{...Икс0,0,0,Икс1,0,0,Икс2,0,0,...}

Кзнак равно2

2Иксзнак равно(Икс0Икс2)знак равно(10000010)(Икс0Икс1Икс2Икс3)

а также

2Иксзнак равно(Икс00Икс10)знак равно(10000100)(Икс0Икс1)

Кзнак равноКT


Глубокие учебные свертки по частям

QИкс

  • КК(Q*Икс) ,
  • К(КQ)*Икс ,
  • КQ*(КИкс)

Q*(КИкс)знак равноQ*(КTИкс)знак равно(К(Q*)T)TИкс

(Q*)Q

Q*(КИкс)знак равно(Q1Q000Q2Q1Q000Q2Q1Q000Q2Q1)(10000100)(Икс0Икс1)знак равно(Q1Q200Q0Q1Q200Q0Q1Q200Q0Q1)T(10000010)T(Икс0Икс1)знак равно((10000010)(Q1Q200Q0Q1Q200Q0Q1Q200Q0Q1))T(Икс0Икс1)знак равно(К(Q*)T)TИкс

Как видно, это транспонированная операция, то есть имя.

Подключение к ближайшему соседу

2(11)*ИксQ2(11)*Q*ИксQзнак равно(Q0Q1Q2)

(11)*Qзнак равно(Q0Q0+Q1Q1+Q2Q2),

то есть мы можем заменить повторную повышающую дискретизацию с коэффициентом 2 и свертку с ядром размером 3 на транспонированную свертку с размером ядра 4. Эта транспонированная свертка обладает той же «пропускной способностью интерполяции», но могла бы выучить лучше сопоставляемые интерполяции.


Выводы и заключительные замечания

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

Я не покрывал объединение здесь. Но это просто нелинейный понижающий дискретизатор, и его можно рассматривать и в этой записи.


Отличный ответ. Взятие математической / символической перспективы часто проясняет вещи. Правильно ли я считаю, что термин «деконволюция» в этом контексте противоречит существующей терминологии ?
user76284

Это действительно не конфликтует, это просто не имеет смысла. Деконволюция просто свертка с оператором повышенной дискретизации. Термин деконволюция звучит так, будто это была бы какая-то обратная операция. Говорить об обратном здесь имеет смысл только в контексте матричных операций. Это умножение с обратной матрицей, а не обратная операция свертки (как деление против умножения).
Андре Бергнер

Zθ*Иксзнак равноZZθ*Zзнак равноИкс

(Наименьшей нормой) деконволюции это эквивалентно умножению на обратную матрицу свертки (или , точнее, его псевдо обратного). Это,θ*Zзнак равноИксZзнак равно(θ*)+Икс

Короче говоря, так называемый «слой деконволюции» OP фактически не выполняет деконволюцию. Это делает что-то еще (что вы описали в своем ответе).
user76284

4

Мне было очень трудно понять, что именно произошло в газете, пока я не наткнулся на это сообщение в блоге: http://warmspringwinds.github.io/tensorflow/tf-slim/2016/11/22/upsampling-and-image-segmentation -с-tensorflow-и-тс-тонкий /

Вот краткое изложение того, как я понимаю, что происходит при 2-кратном повышении частоты дискретизации:

Информация из бумаги

  • Что такое повышение частоты дискретизации?
    • "повышающая дискретизация с коэффициентом f является сверткой с дробным входным шагом 1 / f"
    • → дробно свернутые извилины также известны как транспонированная извилина согласно, например, http://deeplearning.net/software/theano/tutorial/conv_arithmetic.html
  • Каковы параметры этой свертки?
  • Вес фиксирован или готов к тренировке?
    • В документе говорится: «мы инициализируем 2-кратную повышающую дискретизацию до билинейной интерполяции, но разрешаем изучение параметров [...]».
    • Тем не менее, соответствующая страница github гласит: «В наших оригинальных экспериментах интерполяционные слои были инициализированы для билинейных ядер, а затем изучены. В последующих экспериментах и ​​в этой эталонной реализации билинейные ядра фиксированы»
    • → фиксированные веса

Простой пример

  1. представьте следующее входное изображение:

Входное изображение

  1. Дробно свернутые свертки работают, вставляя коэффициенты-1 = 2-1 = 1 нули между этими значениями, а затем допуская шаг = 1 позже. Таким образом, вы получите следующее 6x6 дополненное изображение

дополненное изображение

  1. Билинейный фильтр 4х4 выглядит следующим образом. Его значения выбираются таким образом, чтобы используемые веса (= все веса, не умноженные на вставленный ноль) суммировались до 1. Его три уникальных значения: 0,56, 0,19 и 0,06. Кроме того, центр фильтра по общему правилу - пиксель в третьей строке и третьем столбце.

фильтр

  1. Применение фильтра 4x4 к дополненному изображению (используя padding = 'same' и stride = 1) дает следующее изображение с повышенной дискретизацией 6x6:

Upscaled изображение

  1. Этот вид повышающей дискретизации выполняется для каждого канала индивидуально (см. Строку 59 в https://github.com/shelhamer/fcn.berkeleyvision.org/blob/master/surgery.py ). В итоге, 2-кратное повышение частоты дискретизации - это действительно очень простое изменение размера с использованием билинейной интерполяции и соглашений о том, как обрабатывать границы. Я полагаю, что повышение частоты дискретизации 16x или 32x работает примерно так же.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.