Активационная функция после слоя объединения или сверточного слоя?

Теория из этих ссылок показывает, что порядок сверточной сети: Convolutional Layer - Non-linear Activation - Pooling Layer.

  1. Нейронные сети и глубокое обучение (уравнение (125)
  2. Книга глубокого обучения (стр. 304, 1-й абзац)
  3. Ленет (уравнение)
  4. Источник в этом заголовке

Но в последней реализации с этих сайтов было сказано, что порядок: Convolutional Layer - Pooling Layer - Non-linear Activation

  1. network3.py
  2. Исходный код, класс LeNetConvPoolLayer

Я тоже пытался изучить синтаксис операции Conv2D, но функции активации нет, это только свертка с перевернутым ядром. Может кто-нибудь помочь мне объяснить, почему это происходит?

Ответ 1

Ну, максимальный пул и монотонно растущие нелинейности коммутируют. Это означает, что MaxPool (Relu (x)) = Relu (MaxPool (x)) для любого входа. Так что результат в этом случае тот же. Таким образом, технически лучше сначала выполнить подвыбор с помощью max-pooling, а затем применить нелинейность (если это дорого, например, сигмоид). На практике это часто делается наоборот - кажется, что производительность не сильно меняется.

Что касается conv2D, он не переворачивает ядро. Он реализует в точности определение свертки. Это линейная операция, поэтому вы должны сами добавить нелинейность на следующем шаге, например, theano.tensor.nnet.relu.

Ответ 2

Во многих документах люди используют conv -> pooling -> non-linearity. Это не означает, что вы не можете использовать другой порядок и получать разумные результаты. В случае максимального слоя объединения и ReLU порядок не имеет значения (оба вычисляют одно и то же):

введите описание изображения здесь

Вы можете доказать, что это так, если вспомнить, что ReLU - это элементная операция и неубывающая функция, поэтому

введите описание изображения здесь

То же самое происходит почти для каждой функции активации (большинство из них не убывает). Но не работает для общего слоя объединения (средний пул).


Тем не менее оба заказа дают одинаковый результат, Activation(MaxPool(x)) делает это значительно быстрее, выполняя меньшее количество операций. Для слоя объединения размером k он использует k^2 раз меньше вызовов функции активации.

К сожалению, эта оптимизация для CNN незначительна, поскольку большая часть времени используется в сверточных слоях.