Создание и регистрация пользовательской функции активации

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

Определение пользовательской функции активации

Функция активации в Synaptic представляется объектом с тремя обязательными методами:

  1. activation(x) — вычисляет значение функции активации для входного значения x.
  2. derivative(x) — вычисляет производную функции активации в точке x, необходимую для обратного распространения ошибки.
  3. squash — указывает тип функции активации и используется внутри сети для совместимости с другими компонентами.

Пример определения новой функции активации:

var MyActivation = {
    // Метод активации
    activation: function(x) {
        return x / (1 + Math.abs(x));
    },
    // Производная функции активации
    derivative: function(x) {
        var fx = this.activation(x);
        return 1 - fx * fx; // примерная формула для производной
    },
    // Тип функции активации
    squash: 'custom'
};

В этом примере функция activation нормализует входное значение, ограничивая его диапазон от -1 до 1, а derivative вычисляет производную для обратного распространения ошибки.

Регистрация функции в Synaptic

После определения функции активации её необходимо зарегистрировать, чтобы использовать при создании нейронов или слоёв сети. Регистрация выполняется через глобальный объект Neuron.squash:

var Neuron = require('synaptic').Neuron;

Neuron.squash['custom'] = MyActivation;

После регистрации можно использовать пользовательскую функцию активации при создании нейронов:

var neuron = new Neuron({
    squash: 'custom'
});

Каждый нейрон с опцией squash: 'custom' будет использовать определённые методы activation и derivative.

Использование пользовательской функции в слоях сети

Для слоёв (Layer) и полностью подключённых сетей (Network) пользовательская функция активации применяется через передачу соответствующего параметра при создании слоя:

var Layer = require('synaptic').Layer;

var inputLayer = new Layer(3);
var hiddenLayer = new Layer(4);
var outputLayer = new Layer(2);

hiddenLayer.set({
    squash: 'custom'
});
outputLayer.set({
    squash: 'custom'
});

// Соединение слоёв
inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);

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

Совместимость с обучением

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

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

  • Диапазон выходных значений должен быть ограничен (обычно [-1,1] или [0,1]), чтобы избежать нестабильности весов.
  • Производная должна соответствовать формуле функции активации.
  • Согласованность типов: поле squash должно быть уникальным для каждой новой функции, чтобы не перезаписывать существующие.

Пример комплексного использования

var Neuron = require('synaptic').Neuron;
var Layer = require('synaptic').Layer;
var Network = require('synaptic').Network;

// Определение пользовательской функции активации
var MyActivation = {
    activation: function(x) {
        return Math.tanh(x);
    },
    derivative: function(x) {
        var fx = this.activation(x);
        return 1 - fx * fx;
    },
    squash: 'tanhCustom'
};

// Регистрация функции
Neuron.squash['tanhCustom'] = MyActivation;

// Создание сети
var input = new Layer(2);
var hidden = new Layer(3);
var output = new Layer(1);

hidden.set({ squash: 'tanhCustom' });
output.set({ squash: 'tanhCustom' });

input.project(hidden);
hidden.project(output);

var myNetwork = new Network({
    input: input,
    hidden: [hidden],
    output: output
});

// Обучение и использование сети
var learningSet = [
    { input: [0,0], output: [0] },
    { input: [0,1], output: [1] },
    { input: [1,0], output: [1] },
    { input: [1,1], output: [0] }
];

for (var i = 0; i < 20000; i++) {
    var data = learningSet[Math.floor(Math.random() * learningSet.length)];
    myNetwork.activate(data.input);
    myNetwork.propagate(0.3, data.output);
}

В этом примере создаётся небольшая сеть с одной скрытой слой и пользовательской функцией активации tanhCustom, которая применяется ко всем нейронам скрытого и выходного слоя.

Рекомендации по разработке функций активации

  • Тестировать функции на единичных нейронах перед интеграцией в сеть.
  • Проверять производную численно для предотвращения ошибок в обратном распространении.
  • Сравнивать поведение с известными функциями (сигмоида, ReLU, tanh) для оценки стабильности обучения.

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