Как работает свёрточный слой?
Что проверяют
Можете ли вы разложить свёрточный слой до арифметики: что обучается, как считаются выходной размер и число параметров. Следом часто просят посчитать параметры конкретного слоя или спрашивают, почему в сетях ставят цепочки ядер 3x3, а не одно большое.
Как отвечать
Слой хранит набор фильтров. Каждый фильтр это тензор C_in × K × K, то есть он охватывает все входные каналы сразу, плюс смещение. Фильтр скользит по входу, в каждой позиции считается сумма поэлементных произведений по всем каналам, и получается одна карта признаков. Сколько фильтров, столько выходных каналов. Строго говоря, фреймворки считают взаимную корреляцию без переворота ядра, но веса обучаются, так что разницы нет.
Ключевые параметры nn.Conv2d в PyTorch:
kernel_size: размер окна, чаще всего 3;stride: шаг, при 2 карта уменьшается вдвое;padding: дополнение краёв,padding="same"сохраняет размер при шаге 1;dilation: ядро с пропусками, расширяет поле восприятия без новых параметров;groups: приgroups=C_inполучается depthwise-свёртка, как в MobileNet.
Выходная сторона: floor((H+2P-K)/S)+1. Параметры: C_out × (C_in × K × K + 1). Слой 3x3 из 64 в 128 каналов даёт 128 × (64 × 9 + 1) = 73 856 параметров, и от размера картинки это не зависит.
Почему это работает: локальная связность и общие веса. Один детектор края применяется во всех позициях, поэтому параметров на порядки меньше, чем у полносвязного слоя. Поле восприятия растёт с глубиной: две свёртки 3x3 видят окно 5x5, но весят 18·C² против 25·C² у одного ядра 5x5.
Где спотыкаются
Считают, что фильтр применяется к каждому входному каналу отдельно. Так ведёт себя depthwise-свёртка, а обычная суммирует по всем каналам.
Называют свёртку инвариантной к сдвигу. Она эквивариантна: сдвиг входа сдвигает карту признаков. Приближённую инвариантность дают пулинг и глобальное усреднение в конце.
Путаются в раскладке тензора: в PyTorch по умолчанию NCHW, в Keras NHWC, и переставленные оси дают ошибку формы или неверный результат.