Визуальное и математическое объяснение 2D сверточного слоя и его аргументов

Вступление

библиотеки и платформы Deep Learning, такие как Tensorflow, Keras, Pytorch, Caffe или Theano помогает нам в повседневной жизни, так что каждый день новые приложения заставляют нас думать «Вау!». У всех нас есть свои любимые фреймворки, но их всех объединяет то, что они упрощают нам жизнь с помощью простых в использовании функций, которые можно настраивать по мере необходимости. Но нам все еще нужно понимать, какие есть аргументы, чтобы воспользоваться всеми возможностями, которые дают нам эти структуры.

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

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

Части этого поста будут разделены по следующим аргументам. Эти аргументы можно найти в документации Pytorch модуля Conv2d:

  • in_channels (int) - количество каналов во входном изображении.
  • out_channels (int) - количество каналов, созданных сверткой.
  • kernel_size (int или tuple) - размер свертывающего ядра.
  • шаг (int или tuple, необязательно) - шаг свертки. По умолчанию: 1
  • заполнение (int или кортеж, необязательно) - заполнение нулями добавляется к обеим сторонам ввода. По умолчанию: 0
  • расширение (int или tuple, необязательно) - интервал между элементами ядра. По умолчанию: 1
  • группы (int, необязательно) - количество заблокированных соединений от входных каналов к выходным каналам. По умолчанию: 1
  • bias (bool, необязательно) - если True, добавляет к выходным данным обучаемое смещение. По умолчанию: True

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

Что такое ядро?

Позвольте мне представить, что такое ядро ​​ (или матрица свертки). Ядро описывает фильтр, который мы собираемся пропустить по входному изображению. Чтобы упростить задачу, ядро ​​будет перемещаться по всему изображению слева направо, сверху вниз, применяя произведение свертки. Результат этой операции называется отфильтрованным изображением.

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

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

Обучаемые параметры и смещение

Обучаемые параметры, которые также называются просто «параметрами», - это все параметры, которые будут обновляться при обучении сети. В Conv2d обучаемые элементы - это значения, составляющие ядра. Итак, для нашего ядра свертки 3 на 3 у нас есть 3 * 3 = 9 обучаемых параметров.

Чтобы быть более полным. Мы можем включать предвзятость или нет. Роль смещения должна быть добавлена ​​к сумме продукта свертки. Это смещение также является обучаемым параметром, благодаря которому количество обучаемых параметров для нашего ядра 3 на 3 увеличивается до 10.

Количество входных и выходных каналов

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

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

Тот же принцип применяется к количеству входных каналов. Давайте рассмотрим ситуацию с изображением в кодировке RGB. Это изображение имеет 3 канала: красный, синий и зеленый. Мы можем решить извлекать информацию с помощью фильтров одинакового размера на каждом из этих 3 каналов, чтобы получить четыре новых канала. Таким образом, для 4 выходных каналов операция повторяется в 3 раза.

Каждый выходной канал представляет собой сумму отфильтрованных входных каналов. Для 4 выходных каналов и 3 входных каналов каждый выходной канал представляет собой сумму 3 отфильтрованных входных каналов. Другими словами, сверточный слой состоит из 4 * 3 = 12 ядер свертки.

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

Размер ядра

До сих пор все примеры были даны с ядрами размером 3 на 3. Фактически, выбор его размера полностью за вами. Возможно создание сверточного слоя с размером сердцевины 1 * 1 или 19 * 19.

Но также вполне возможно, что ядра не будут квадратными. Это возможность выбрать ядра с разной высотой и шириной. Это часто имеет место при анализе изображения сигнала. Если мы знаем, что хотим сканировать изображение сигнала или звука, тогда мы можем предпочесть, например, ядро ​​размером 5 * 1.

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

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

Шаги

Ядра по умолчанию перемещаются слева направо, сверху вниз, смещая пиксель за пикселем. Но и этот сдвиг можно изменить. Часто используется для уменьшения выходного канала. Например, с шагом (1, 3) фильтр сдвигается с 3 до 3 по горизонтали и с 1 до 1 по вертикали. В результате выходные каналы субдискретизированы на 3 по горизонтали.

Шаги не влияют на количество параметров, но время расчета, логически, линейно уменьшается с шагом.

Обивка

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

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

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

Расширение

Расширение - это своего рода ширина ядра. По умолчанию равняется 1, это соответствует смещению между каждым пикселем ядра на входном канале во время свертки.

Я немного преувеличил на своем GIF, но если мы возьмем пример расширения (4, 2), то рецептивное поле ядра на входном канале будет расширено на 4 * (3 -1 ) = 8 по вертикали и 2 * (3–1) = 4 по горизонтали (для ядра 3 на 3).

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

Группы

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

Если есть 2 входных канала и 4 выходных канала с 2 группами. Тогда это похоже на разделение входных каналов на две группы (то есть по 1 входному каналу в каждой группе) и прохождение их через сверточный слой с вдвое меньшим количеством выходных каналов. Затем выходные каналы объединяются.

Важно отметить, что количество групп должно точно делить количество входных каналов и количество выходных каналов (общий делитель).

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

Размер выходного канала

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

Знания - это все о том, чтобы делиться.
Не стесняйтесь подписываться на меня или оставлять отзыв о том, что вам понравилось или не понравилось. ✏️

🔵 Вы также можете связаться со мной в LinkedIn, чтобы быть в курсе моих статей и обсудить

Увидимся скоро! 🥰

Источники

Учебник по глубокому обучению, Ю. Лекун

Документация torch.nn, Pytorch

Сверточные нейронные сети, cs231n

Сверточные слои, Керас

Все изображения самодельные

Все тесты времени вычислений были выполнены с помощью Pytorch на моем графическом процессоре (GeForce GTX 960M) и доступны в этом репозитории GitHub, если вы хотите запустить их самостоятельно или выполнить альтернативные тесты.