Регуляризация: L1, L2 и их реализация

Регуляризация — ключевой метод предотвращения переобучения нейронных сетей. Она добавляет штрафы к функции потерь, сдерживая слишком большие значения весов и стимулируя модель к более устойчивым решениям. В библиотеке Synaptic на JavaScript можно реализовать регуляризацию вручную, так как встроенной поддержки L1 и L2 нет, но структура библиотеки позволяет гибко управлять весами и обучением сети.


Основные концепции L1 и L2

L1-регуляризация (Lasso)

  • Добавляет к функции потерь сумму абсолютных значений весов: [ L = L_0 + _i |w_i|]
  • Основной эффект: склонность к разреженности весов (многие веса становятся нулевыми), что полезно для отбора признаков.
  • Сильные градиенты в L1 возникают при больших весах, а малые веса постепенно «схлопываются» к нулю.

L2-регуляризация (Ridge)

  • Добавляет к функции потерь сумму квадратов весов: [ L = L_0 + _i w_i^2]
  • Эффект: сдерживание роста больших весов без создания полностью нулевых, веса распределяются более плавно.
  • Чаще используется для предотвращения переобучения в глубоких сетях, так как уменьшает разброс весов.

Выбор коэффициента регуляризации λ (lambda) определяет силу штрафа. Малые значения дают мягкое влияние, большие — сильное, что может привести к недообучению.


Применение регуляризации в Synaptic

Synaptic строит нейронные сети через объекты Network, Layer и Neuron. Прямой поддержки L1/L2 нет, поэтому регуляризация реализуется через модификацию весов после обратного распространения ошибки.

Шаги реализации:

  1. Создание сети и обучение
const synaptic = require('synaptic');
const { Layer, Network, Trainer } = synaptic;

// Простая сеть с одним скрытым слоем
const inputLayer = new Layer(2);
const hiddenLayer = new Layer(3);
const outputLayer = new Layer(1);

inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);

const myNetwork = new Network({
    input: inputLayer,
    hidden: [hiddenLayer],
    output: outputLayer
});
  1. Определение функции регуляризации L1
function applyL1Regularization(network, lambda) {
    network.layers.input.list.concat(
        ...network.layers.hidden.map(layer => layer.list),
        network.layers.output.list
    ).forEach(neuron => {
        Object.keys(neuron.connections.projected).forEach(key => {
            const conn = neuron.connections.projected[key];
            const gradient = conn.weight > 0 ? 1 : -1;
            conn.weight -= lambda * gradient;
        });
    });
}
  1. Определение функции регуляризации L2
function applyL2Regularization(network, lambda) {
    network.layers.input.list.concat(
        ...network.layers.hidden.map(layer => layer.list),
        network.layers.output.list
    ).forEach(neuron => {
        Object.keys(neuron.connections.projected).forEach(key => {
            const conn = neuron.connections.projected[key];
            conn.weight -= lambda * conn.weight;
        });
    });
}
  1. Интеграция с обучением
const trainer = new Trainer(myNetwork);

for (let i = 0; i < 1000; i++) {
    trainer.train([{ input: [0, 0], output: [0] },
                   { input: [0, 1], output: [1] },
                   { input: [1, 0], output: [1] },
                   { input: [1, 1], output: [0] }], 
                   { rate: 0.1, iterations: 1, error: 0.005, shuffle: true });
    
    // Применяем L2 регуляризацию после каждого шага обучения
    applyL2Regularization(myNetwork, 0.01);
}

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

  • Комбинация с learning rate: при регуляризации стоит уменьшать скорость обучения, так как добавленный штраф увеличивает скорость изменения весов.
  • Выбор L1 vs L2: L1 эффективна для отбора признаков, L2 — для общего контроля переобучения. Иногда используется смешанная регуляризация Elastic Net: [ _1 _i |w_i| + _2 _i w_i^2]
  • Мониторинг весов: регуляризация может быстро снижать значения весов до очень малых чисел. Желательно контролировать распределение весов во время обучения.

Особенности реализации в Synaptic

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

Регуляризация L1 и L2 в Synaptic позволяет контролировать переобучение и улучшать обобщающую способность сети, создавая более стабильные и предсказуемые модели. Правильная настройка коэффициентов λ и интеграция с циклом обучения — ключ к успешной работе.