ConvND¶
Описание¶
Общая информация¶
Этот модуль выполняет операцию n-мерной свёртки.
Свертка в общих словах - операция над парой тензоров D и B, результатом которой является тензор C=D∗B, причём тензор D является субтензором некоего тензора A. Каждый элемент результата вычисляется как скалярное произведение тензора B и субтензора A такого же размера (от положения A зависит положение вычисленного элемента в результате).
Лучше всего это продемонстрировано на рисунке 1 (см. параметр "Шаг свёртки").
Для входного тензора с размерами (N, C_{in}, Dims_{in}) и выходного с размерами (N, C_{out}, Dims_{out}) операция проводится следующим образом (рассматриваем i-й элемент батча и j-ую карту выходного тензора):
где
N - размер батча;
C - количество карт в тензоре;
Dims - вектор размеров карты тензора по каждому измерению (например, (H, W) для двумерных карт);
bias - тензор смещений слоя свёртки;
weight - тензор весов слоя свёртки;
\star - оператор взаимной корреляции.
Параметры операции¶
Операцию свертки характеризуют следующие параметры и объекты:
Ядро свёртки size
Если посмотреть на вышеприведенное определение, то ядро свертки - это тензор B. Ядро свертки характеризуется своим размером, формой и набором значений своих элементов. Для свёрточных слоёв нейронной сети набор значений элементов ядра - это веса, которые являются обучаемым параметром.
Important
В рамках данной библиотеки форма ядер свёртки всегда равносторонняя, т.е. квадрат для двумерной свёртки и куб для трёхмерной.
Шаг свёртки stride
Шаг свертки определяет, через какое количество элементов тензора ядро свертки будет умножаться на подмножество элементов тензора. Шаг, равный единице, означает, что ядро скользит непрерывно и не пропускает элементов. Шаг, равный двум, означает, что ядро идет через один элемент тензора. Данная характеристика помогает уменьшить количество вычислений и размерность выходного тензора, работая с одними и теми же исходными данными.
Работа свёртки при разном шаге хорошо продемонстрирована на рисунках 1 и 2 (на примере двумерной свёртки):
size=3
, stride=1
)size=3
, stride=2
)Паддинг pad
Параметр паддинга определяет количество дополнительных слоев элементов по периметру исходного входного тензора, заполненных значениями по определенным правилам. Это нужно для того, чтобы, например, получить тензор того же размера, что и входной (рисунок 3).
size=3
, stride=1
, pad=1
)Другой причиной может стать желание избежать потери граничных элементов карт при определенных наборах остальных параметров. На рисунке 4 представлена ситуация, когда элементы не были потеряны: без паддинга последние граничные 2 столбца и строки не были бы задействованы при получении выходного тензора.
size=3
, stride=2
, pad=1
)Чаще всего дополнительные ряды элементов заполняются нулями. Кроме этого могут быть установлены другие простые правила заполнения, например, скопировано значение ближайшего элемента.
Разрежение dilation
Параметр разрежения определяет количество раз, в которое будет увеличен размер ядра свертки. При этом элементы ядра удаляются друг от друга в заданное число раз, а образовавшиеся пустые значения заполняются нулями.
dilation=1
, dilation=2
и dilation=4
При применении разрежения экспоненциально растет размер рецептивного поля (receptive field). Для первого изображения оно равно 3х3, для второго уже 7х7, для третьего - 15х15.
Другой пример разреженной свёртки представлен на рисунке 6:
size=3
, stride=1
, dilation=1
)Приятным свойством применения этой техники является то, что она дешева с точки зрения вычислений. То есть мы используем свертки гораздо большей размерности, увеличиваем поля чувствительности, имея возможность отслеживать более глобальные признаки - но не добавляем при этом нагрузки на железо.
Количество связей входных и выходных карт groups
Техника использования групп при операции свертки в англоязычной литературе называется Depthwise Convolution, которая является частью техники Depthwise Separable Convolution.
Depthwise Separable Convolution разбивает процесс вычисления свертки на две части: depthwise свертка и pointwise свертка. Рассмотрим технику на примере двумерной свёртки.
На первом этапе в результате свертки получается тензор без изменения глубины: мы используем ядра свертки глубины 1 и размера size
в количестве, равном количеству входных карт, и применяем каждое такое ядро отдельно к каждой карте соответственно.
size=5
, stride=1
)На втором этапе применяется точечное ядро для получения желаемого количества выходных карт (на рисунке количество выходных карт 256):
size=1
, stride=1
)То есть, можно сказать, что мы провели замену одного свёрточного слоя с весами (C_{out}, C_{in}, size, size) на две свёртки: depthwise (C, 1, size, size) и затем pointwise (C_{out}, C, 1, 1), где
C_{out} - количество выходных карт тензора;
C_{in} - количество входных карт тензора;
C - промежуточное количество карт, равное C_{in};
size - размер ядра.
Info
В рамках этой библиотеки depthwise свертка осуществляется варьированием параметра groups
. Для более подробной информации см. примеры классов наследников.
Данная техника позволяет значительно уменьшить количество вычислений.
Дополнительные источники¶
- Детальное описание операции свертки и сверточных нейронных сетей: ссылка;
- Подробный разбор техники паддинга: ссылка;
- Статья по разреженным свёрткам: ссылка;
- Разбор Depthwise convolution на английском: ссылка;
- Разбор Depthwise convolution на русском: ссылка.
Инициализация¶
def __init__(self, nd, inmaps, outmaps, size, stride=1, pad=0, dilation=1, wscale=1.0, useBias=True, name=None,
initscheme=None, empty=False, groups=1):
Параметры
Параметр | Возможные типы | Описание | По умолчанию |
---|---|---|---|
nd | int | Размерность операции | - |
inmaps | int | Количество карт во входном тензоре | - |
outmaps | int | Количество карт в выходном тензоре | - |
size | int | Размер ядра свёртки | - |
stride | Union[int, tuple] | Шаг свёртки | 1 |
pad | Union[int, tuple] | Паддинг карт | 0 |
dilation | Union[int, tuple] | Разрежение окна свёртки | 1 |
wscale | float | Дисперсия случайных весов слоя | 1.0 |
useBias | bool | Использовать или нет вектор смещений | True |
initscheme | Union[tuple, str] | Указывает схему инициализации весов слоя (см. createTensorWithScheme) | None -> ("xavier_uniform", "in") |
name | str | Имя слоя | None |
empty | bool | Инициализировать ли матрицу весов и смещений | False |
groups | int | На сколько групп разбиваются карты для раздельной обработки | 1 |
Пояснения
См. классы потомки.