Регрессия — это задача прогнозирования непрерывного численного значения на основе входных данных. В отличие от классификации, где сеть выбирает один из дискретных классов, регрессия требует, чтобы выходной сигнал нейронной сети был числом, обычно в диапазоне от (-) до (+) или ограниченном определёнными значениями.
В контексте ConvNetJS регрессия реализуется через многослойный перцептрон (MLP) с одной или несколькими скрытыми слоями, где выходной слой имеет один нейрон без функции активации или с линейной активацией. Важным аспектом является выбор функции потерь: для регрессии стандартной является среднеквадратичная ошибка (MSE, mean squared error).
ConvNetJS предоставляет объект convnetjs.Net,
позволяющий задавать структуру сети через последовательность слоёв,
каждый из которых имеет свои параметры. Пример структуры для
регрессии:
var layer_defs = [];
layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:NUM_INPUTS});
layer_defs.push({type:'fc', num_neurons:50, activation:'relu'});
layer_defs.push({type:'fc', num_neurons:20, activation:'relu'});
layer_defs.push({type:'regression', num_neurons:1});
var net = new convnetjs.Net();
net.makeLayers(layer_defs);
Ключевые моменты структуры:
input: задаёт размерность входного вектора
NUM_INPUTS.fc (fully connected): скрытые слои с функцией активации
relu (можно использовать tanh или
sigmoid).regression: выходной слой для регрессии, количество
нейронов соответствует количеству прогнозируемых чисел (1 для одномерной
регрессии).Для регрессии в ConvNetJS применяется функция потерь типа
regression. Тренировщик (Trainer)
конфигурируется следующим образом:
var trainer = new convnetjs.SGDTrainer(net, {
method: 'adadelta',
batch_size: 16,
l2_decay: 0.001,
learning_rate: 0.01
});
Параметры:
method: метод оптимизации. Подходят sgd,
adadelta, adam.batch_size: количество примеров за одну итерацию
градиентного спуска.l2_decay: регуляризация для предотвращения
переобучения.learning_rate: шаг градиентного спуска.Процесс обучения регрессионной модели заключается в последовательной подаче входных векторов и соответствующих числовых целей:
for(var i=0;i<train_data.length;i++) {
var x = new convnetjs.Vol(train_data[i].input);
var y = [train_data[i].target]; // одномерная цель
trainer.train(x, y);
}
Особенности:
Vol представляет собой входной вектор для
сети.После обучения сеть может использоваться для предсказаний:
var x = new convnetjs.Vol(test_input);
var predicted = net.forward(x).w[0]; // получаем численное значение
forward возвращает объект Vol, содержащий
массив w, где хранятся значения выходных нейронов.
Для регрессии особенно важно масштабировать входные и выходные данные:
function normalize(data) {
var mean = data.reduce((a,b)=>a+b,0)/data.length;
var std = Math.sqrt(data.map(x => Math.pow(x-mean,2)).reduce((a,b)=>a+b,0)/data.length);
return data.map(x => (x-mean)/std);
}
Помимо функции потерь, для оценки модели применяют метрики:
Пример вычисления MSE:
function mse(predictions, targets) {
var n = predictions.length;
var sum = 0;
for(var i=0;i<n;i++) {
sum += Math.pow(predictions[i]-targets[i],2);
}
return sum/n;
}
Регрессия чувствительна к:
relu,
tanh, sigmoid).Тщательная настройка этих параметров позволяет уменьшить переобучение и ускорить сходимость.
Если требуется предсказывать несколько зависимых величин одновременно, выходной слой настраивается на нужное количество нейронов:
layer_defs.push({type:'regression', num_neurons:NUM_OUTPUTS});
В этом случае каждая цель представляется массивом значений
[y1, y2, ..., yN].
regression.net.forward.Эта схема обеспечивает гибкость ConvNetJS для решения регрессионных задач в браузере и на сервере с помощью JavaScript.