Позвольте мне дать вам краткий обзор различных типов сверток и их преимуществ. Для простоты я сосредоточусь только на двумерных свертках.

Свертки

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

  • Размер ядра: размер ядра определяет поле обзора свертки. Обычный выбор для 2D - 3, то есть 3x3 пикселя.
  • Шаг: шаг определяет размер шага ядра при перемещении по изображению. Хотя по умолчанию он обычно равен 1, мы можем использовать шаг 2 для понижающей дискретизации изображения, аналогичного MaxPooling.
  • Отступ. Отступ определяет, как обрабатывается граница образца. Свертка с заполнением (наполовину) будет сохранять пространственные выходные размеры равными входным, тогда как свертки без заполнения будут обрезать некоторые границы, если ядро ​​больше 1.
  • Входные и выходные каналы. Сверточный слой занимает определенное количество входных каналов (I) и вычисляет определенное количество выходных каналов (O). Необходимые параметры для такого слоя могут быть вычислены как I * O * K, где K равно количеству значений в ядре.

Расширенные свертки

(также известные как атрозные извилины)

Расширенные свертки вводят в сверточные слои еще один параметр, называемый скоростью расширения. Это определяет интервал между значениями в ядре. Ядро 3x3 с коэффициентом расширения 2 будет иметь такое же поле зрения, что и ядро ​​5x5, при использовании только 9 параметров. Представьте, что вы берете ядро ​​5x5 и удаляете каждый второй столбец и строку.

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

Транспонированные свертки

(также известные как деконволюции или свертки с дробным шагом)

В некоторых источниках используется название «деконволюция», что неуместно, потому что это не деконволюция. Что еще хуже, деконволюции существуют, но они не распространены в области глубокого обучения. Фактическая деконволюция возвращает процесс свертки. Представьте, что вы вводите изображение в один сверточный слой. Теперь возьмите результат, бросьте его в черный ящик и снова получите исходное изображение. Этот черный ящик выполняет деконволюцию. Это математическая инверсия того, что делает сверточный слой.

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

На этом этапе вы должны сильно запутаться, поэтому давайте рассмотрим конкретный пример. Изображение 5x5 загружается в сверточный слой. Шаг установлен на 2, заполнение отключено, а ядро ​​- 3x3. В результате получается изображение 2x2.

Если бы мы хотели обратить этот процесс вспять, нам потребовалась бы обратная математическая операция, чтобы из каждого вводимого пикселя генерировалось 9 значений. После этого мы проходим выходное изображение с шагом 2. Это будет деконволюция.

Транспонированная свертка этого не делает. Единственное, что объединяет, - это гарантия того, что на выходе также будет изображение 5x5, при этом выполняется обычная операция свертки. Чтобы добиться этого, нам нужно выполнить некоторые причудливые отступы на входе.

Как вы теперь можете себе представить, этот шаг не изменит процесс, описанный выше. По крайней мере, не в отношении числовых значений.

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

Разделимые свертки

В разделяемой свертке мы можем разделить операцию ядра на несколько шагов. Представим свертку как y = conv (x, k), где y - выходное изображение, x - входное изображение, а k - это ядро. Легкий. Далее предположим, что k можно вычислить по формуле k = k1.dot (k2). Это сделало бы его разделимой сверткой, потому что вместо двумерной свертки с k мы могли бы получить тот же результат, выполнив 2 одномерных свертки с k1 и k2.

Возьмем, к примеру, ядро ​​Собеля, которое часто используется при обработке изображений. Вы можете получить такое же ядро, умножив вектор [1, 0, -1] и [1,2,1] .T. Это потребует 6 вместо 9 параметров при выполнении той же операции. В приведенном выше примере показана так называемая пространственная разделимая свертка, которая, насколько мне известно, не используется в глубоком обучении.

Edit: На самом деле, можно создать нечто очень похожее на пространственную разделимую свертку, сложив слой ядра 1xN и Nx1. Недавно это было использовано в архитектуре под названием EffNet, показав многообещающие результаты.

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

Допустим, у нас есть сверточный слой 3x3 на 16 входных и 32 выходных каналах. Что происходит в деталях, так это то, что каждый из 16 каналов проходит через 32 ядра 3x3, что приводит к 512 (16x32) картам функций. Затем мы объединяем 1 карту функций из каждого входного канала, складывая их. Поскольку мы можем сделать это 32 раза, мы получаем 32 желаемых выходных канала.

Для разделимой по глубине свертки в том же примере мы просматриваем 16 каналов с 1 ядром 3x3 в каждом, что дает нам 16 карт характеристик. Теперь, прежде чем что-либо объединять, мы просматриваем эти 16 карт функций с 32 свертками 1x1 каждая и только затем начинаем их складывать. В результате получается 656 (16x3x3 + 16x32x1x1) параметров, а не 4608 (16x32x3x3) параметров, указанных выше.

Пример представляет собой конкретную реализацию разделимой по глубине свертки, где так называемый множитель глубины равен 1. Это, безусловно, наиболее распространенная настройка для таких слоев.

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

Вопросов?

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