ReLU

ReLU (Rectified Linear Unit) — это одна из наиболее популярных активационных функций в современных сверточных нейронных сетях. В ConvNetJS она реализована с высокой оптимизацией и предназначена для ускорения обучения глубоких сетей за счет устранения проблемы затухающего градиента, характерной для сигмоидных и тангенсоидных функций.

Основная идея ReLU

Функция ReLU задается формулой:

[ f(x) = (0, x)]

То есть на отрицательных значениях она возвращает 0, а на положительных — само значение. Этот простой нелинейный переход обеспечивает несколько важных эффектов:

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

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

ConvNetJS предоставляет класс ReLU для использования в качестве слоя активации. Основной конструктор слоя:

var layer = new convnetjs.ReLULayer({
    num_neurons: 100, // количество нейронов в слое
    bias_pref: 0.0    // начальное значение смещения
});
  • num_neurons определяет размер выходного тензора.
  • bias_pref задает начальное смещение для каждого нейрона. В ConvNetJS оно используется для ускорения обучения путем небольшого положительного смещения, предотвращающего нулевые градиенты.

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

Прямое распространение (forward pass) через ReLU вычисляется просто:

layer.forward = function(V) {
    var A = new convnetjs.Vol(V.sx, V.sy, V.depth, 0.0);
    for(var i=0;i<V.w.length;i++) {
        A.w[i] = Math.max(0,V.w[i] + this.bias);
    }
    this.out_act = A;
    this.in_act = V;
    return this.out_act;
}

Ключевые моменты:

  • Создается новый тензор выхода A того же размера, что и вход V.
  • На каждом элементе входного тензора применяется max(0, x + bias).
  • Сохраняются ссылки на входные и выходные активации для обратного распространения.

Обратное распространение

Обратное распространение (backpropagation) для ReLU очень простое, поскольку градиент равен 1 для положительных значений и 0 для отрицательных:

layer.backward = function() {
    var V = this.in_act;
    V.dw = new Float32Array(V.w.length);
    for(var i=0;i<V.w.length;i++) {
        V.dw[i] = V.w[i] > 0 ? this.out_act.dw[i] : 0.0;
    }
}

Особенности:

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

Использование ReLU в сети

ReLU может использоваться как после полносвязных слоев (FullyConnLayer), так и после сверточных слоев (ConvLayer). Пример конфигурации сети:

var layer_defs = [];
layer_defs.push({type:'input', out_sx:32, out_sy:32, out_depth:3});
layer_defs.push({type:'conv', sx:5, filters:16, stride:1, pad:2, activation:'relu'});
layer_defs.push({type:'pool', sx:2, stride:2});
layer_defs.push({type:'conv', sx:5, filters:20, stride:1, pad:2, activation:'relu'});
layer_defs.push({type:'pool', sx:2, stride:2});
layer_defs.push({type:'softmax', num_classes:10});
  • Слои conv с активацией relu обеспечивают нелинейность и ускоряют обучение.
  • Комбинация с пуллингом (pool) уменьшает размерность признаков, сохраняя ключевую информацию.

Важные практические советы

  • Инициализация весов: для ReLU рекомендуется небольшое положительное смещение смещений (bias_pref), чтобы избежать “мертвых” нейронов.
  • Проблема “мертвых” нейронов: если весовая матрица слишком велика или малые градиенты приводят к постоянной отрицательной активации, нейроны перестают обучаться. Контроль начальной инициализации помогает решить проблему.
  • Обработка отрицательных значений: существует модификация Leaky ReLU, где отрицательные значения пропускаются с малым коэффициентом, но ConvNetJS стандартно реализует классическую ReLU.
  • Скорость обучения: ReLU ускоряет сходимость по сравнению с сигмоидой или tanh, особенно в глубоких сетях.

Визуализация работы ReLU

Важный аспект изучения ReLU — визуализировать активации. В ConvNetJS активации можно получить через layer.out_act.w после прямого распространения. Типичный паттерн:

  • Большинство отрицательных значений становятся нулями.
  • Положительные значения проходят без изменений.
  • Разреженность активаций увеличивается с глубиной сети.

Заключение по практическому использованию

ReLU является стандартным инструментом при построении глубоких нейронных сетей в ConvNetJS. Простая реализация, легкая обратная связь и ускорение сходимости делают её основным выбором для большинства задач распознавания изображений и классификации. Комбинация с другими слоями, правильная инициализация и внимательное наблюдение за активными нейронами позволяют добиться стабильного и эффективного обучения.