Maxout

Maxout — это тип слоя в нейронных сетях, предложенный для повышения способности модели аппроксимировать сложные функции активации. Он отличается от классических функций активации, таких как ReLU, Sigmoid или Tanh, тем, что выбирает максимальное значение из нескольких линейных комбинаций входных данных, создавая нелинейность без фиксированной формы функции активации.


Принцип работы Maxout

Слой Maxout состоит из множества подслоёв, каждый из которых является линейной комбинацией входов. Для каждого нейрона слоя Maxout вычисляются несколько линейных выражений:

[ z_i = w_i x + b_i]

где (w_i) — веса подслоя, (b_i) — смещение, (x) — входной вектор. Выход нейрона Maxout определяется как:

[ y = (z_1, z_2, , z_k)]

где (k) — количество линейных комбинаций для одного нейрона. Таким образом, нейрон Maxout моделирует функцию:

  • Линейная внутри каждой комбинации;
  • Нелинейная на выходе благодаря операции выбора максимума.

Преимущества Maxout

  1. Устойчивость к исчезновению градиента В отличие от Sigmoid или Tanh, функция Maxout не насыщается, что позволяет градиенту свободно распространяться по сети.

  2. Гибкость аппроксимации Maxout может аппроксимировать любую выпуклую функцию, если увеличить количество линейных комбинаций (k).

  3. Совместимость с Dropout Maxout хорошо работает с регуляризацией Dropout, так как выбор максимума из нескольких подслоёв снижает влияние случайного “выключения” отдельных нейронов.


Реализация в ConvNetJS

В библиотеке ConvNetJS слой Maxout реализуется через объект LayerMaxout. Основные параметры слоя:

  • num_neurons — количество нейронов в слое;
  • group_size — количество линейных комбинаций на один нейрон.

Пример создания слоя:

var layer = new convnetjs.LayerMaxout({
    num_neurons: 100,
    group_size: 2,
    stride: 1
});
  • num_neurons = 100 — это количество выходных нейронов слоя.
  • group_size = 2 — каждый нейрон вычисляется как максимум из двух линейных комбинаций входов.
  • stride — смещение по входу (для сверточных Maxout слоёв).

Прямое и обратное распространение

Forward pass (прямое распространение)

  1. Вычисляются все линейные комбинации для каждого нейрона.
  2. Для каждого нейрона выбирается максимальное значение среди подслоёв.
  3. Сохраняются индексы максимальных подслоёв для обратного распространения.

Пример:

layer.forward(V, is_training=true);

где V — объект Vol, содержащий входные данные.

Backward pass (обратное распространение)

  1. Градиент передается только через подслой, который был максимальным на forward pass.
  2. Остальные подслои получают градиент равный нулю.
  3. Обновление весов происходит стандартным методом оптимизации (SGD, Adam и др.).
layer.backward();

Практические рекомендации

  • Выбор group_size Малое значение (2–4) ускоряет обучение, но снижает аппроксимирующую способность. Большое значение (5–10) увеличивает точность, но требует больше вычислительных ресурсов.

  • Инициализация весов Рекомендуется использовать нормальное распределение с небольшим стандартным отклонением. ConvNetJS по умолчанию применяет инициализацию Gaussian(0, 0.01).

  • Сочетание с другими слоями Maxout часто используют после сверточных слоёв или полносвязных слоёв для усиления нелинейности перед выходом или слоем Dropout.


Отличие от ReLU и других активаций

Свойство ReLU Maxout
Форма функции y = max(0,x) y = max(z1, z2,…, zk)
Насыщение нет нет
Аппроксимация функций ограничена универсальна для выпуклых
Совместимость с Dropout высокая очень высокая

Maxout позволяет сети автоматически выбирать оптимальную форму активации для каждого нейрона, что делает её более гибкой по сравнению с фиксированными функциями активации.


Пример использования в полной сети

var layer_defs = [];
layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:784});
layer_defs.push({type:'fc', num_neurons:256, activation:'relu'});
layer_defs.push({type:'dropout', rate:0.5});
layer_defs.push({type:'maxout', num_neurons:128, group_size:2});
layer_defs.push({type:'softmax', num_classes:10});

var net = new convnetjs.Net();
net.makeLayers(layer_defs);
  • В этом примере слой Maxout используется после полносвязного слоя с ReLU и Dropout, чтобы усилить нелинейность перед финальной классификацией.
  • Такой подход часто применяется в задачах распознавания изображений и текста.

Maxout в ConvNetJS представляет собой мощный инструмент для создания гибких нейронных сетей с высокой аппроксимационной способностью и хорошей совместимостью с регуляризацией. Правильная настройка параметров group_size и num_neurons позволяет значительно повысить качество моделей, особенно в глубоких сетях.