Транспонированный сверточный слой широко применяется в Auto Encoder и Generative Adversarial Networks (GAN), который служит одним из способов повышения дискретизации данных.

Это простая концепция, но в процессе обучения меня смущало множество противоречивых материалов. Поэтому я хотел бы создать этот учебник, используя как анимацию, так и код PyTorch, чтобы четко объяснить параметры и математику транспонированных сверточных слоев. Все исходные файлы находятся на моем Github Repo.

Благодарность: стиль дизайна анимации вдохновлен conv_arithmetic. (Хотя в процессе обучения это меня сильно сбивало с толку.)

1. Случай по умолчанию

Начнем с простейшего случая.

На рисунке 1 показан процесс вычисления транспонированного сверточного слоя с kernel_size равным 3, а для других параметров заданы значения по умолчанию. Размеры входа (2x2) и выхода (4x4) можно было легко распознать.

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

Давайте проверим тот же расчет с помощью PyTorch:

2. шаг

Далее изменим параметр шаг, все остальное оставим как в первом случае.

В документе PyTorch указано:

stride управляет шагом взаимной корреляции.

Документ носит справочный характер. Лично я сначала этого не понял. Но следующая визуализация должна быть ясной. Значение шага по умолчанию - 1, здесь мы устанавливаем шаг равным 2.

Как видите, после каждого шага умножения матрица ядра перемещается на 2 шага по горизонтали, пока не достигнет конца, а затем перемещается на 2 шага по вертикали и начинается с начала.

Давайте посмотрим на процессы расчета:

Проверим с помощью pytorch:

3. набивка

Мы продолжим построение на основе случая шага, на этот раз мы изменим параметр padding на 1. В предыдущих случаях padding имел значение по умолчанию 0.

Конечным результатом в данном случае является центральная матрица 3x3. Вы можете интерпретировать это как отбрасывание после расчета граничных ячеек матрицы. Вы должны представить себе, что если мы установим отступ равным 2, результатом будет центральная ячейка (1x1).

На рисунке 6 показаны процессы расчета, как вы можете видеть, он почти идентичен рисунку 4. Единственное отличие состоит в том, что мы «удалили» внешние ячейки.

Посмотрим, согласится ли с нами PyTorch:

4. выходное заполнение

Да, у нас есть другой вид набивки. Их отличие простое:

Заполнение вывода добавляет ячейки к одной стороне вывода, а заполнение удаляет ячейки с обеих сторон вывода.

В этом случае мы устанавливаем параметр output_padding равным 1 (по умолчанию 0), а шаг равным 2. Как показано на рисунке 7, одна сторона выходной матрицы имеет добавлены ячейки, значение которых равно 0.

Если у вас возникли трудности с пониманием этого, пожалуйста, сравните рисунок 7 с рисунком 3.

Ниже приведены шаги расчета:

Давайте еще раз подтвердим с помощью PyTorch.

5. расширение

Расширение влияет на структуру матрицы ядра.

В документации PyTorch указывается,

dilation управляет интервалом между точками ядра;

Понятия не имею, когда я впервые это увидел, потому что это очень абстрактно. Однако, взглянув на рисунок 9, вы, возможно, сможете это понять. Чтобы упростить задачу, давайте воспользуемся ядром 2x2 в этом примере. (В предыдущих примерах мы использовали ядро ​​3x3.)

Выше показано, как выглядит матрица ядра с разными значениями расширения. Обычно, если значение расширения равно n, тогда матрица ядра будет вставлена ​​в ячейки n-1, заполненные 0 На этом этапе нетрудно представить себе такое же преобразование для больших матриц ядра. А остальные расчеты остаются такими же, как и раньше, как показано на рисунке 10.

Чтобы уточнить, на рисунке 10 я проигнорировал 0-значные ячейки ядра, сделав его прозрачным.

Ниже приведены шаги расчета:

Ниже представлена ​​реализация PyTorch.

6. Математика выходной формы

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

Формула для размера вывода:

Где n - размер вывода (матрица n x n), m - размер ввода ( m x m матрица). Кроме того, в формуле 5 параметров: K - размер ядра, S - значение шага, P - значение заполнения, D - это значение расширения, а P_out - значение output_padding.

Выглядит сложно, но на самом деле очень просто. Давайте рассмотрим это шаг за шагом.

(1) Учитывайте только S (шаг) и K (размер ядра)

Поскольку размер входных данных равен m, у нас есть m * m шагов расчета. Но на самом деле нам нужно рассмотреть только первые m шагов, поскольку первый шаг m фиксирует ширину выходной матрицы.

Мы можем представить, что по мере продолжения вычислений результат будет постепенно расти, как показано на рисунке 2, 4, 6, 8, 11.

  • На 1-м шаге выходной размер равен K.
  • На 2-м шаге промежуточная матрица сдвигается на S, поэтому выходной размер равен K + S.
  • На третьем этапе промежуточная матрица сдвигается на S, поэтому выходной размер равен K + 2S.
  • На m- -м шаге промежуточная матрица сдвигается на S, поэтому размер вывода равен K + (m-1) S .

Следовательно, если мы рассмотрим только S и K, формула будет выглядеть так:

(2) Рассмотрим D (расширение)

Как мы уже говорили, расширение изменяет размер ядра. Здесь давайте использовать K ’ для обозначения преобразованного размера ядра. Как показано на рисунке 9, преобразование расширения вставляет ячейки (K-1) (D-1) в ядро. Следовательно, отношения между K ’, K, D должны быть:

Таким образом, мы имеем:

Заменим K в (2) на K ’, мы получим:

На этом мы почти закончили, остальные параметры понятны.

(3) Рассмотрите P (заполнение) и P_out (output_padding)

Поскольку заполнение удаляет ячейки с двух сторон, его влияние на размер вывода равно - 2P. Точно так же output_padding добавляет ячейки с одной стороны, поэтому его влияние на размер вывода равно + P_out. Добавляя эти части в (4), мы получили (1).

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

Пожалуйста, оставляйте комментарии. Все предложения, вопросы приветствуются!