ConvNetJS — это библиотека для построения нейронных сетей на языке JavaScript, включая сверточные и полносвязные сети. Помимо классических моделей для задач классификации изображений, она поддерживает обучение последовательностей с помощью рекуррентных нейронных сетей (RNN) и Long Short-Term Memory (LSTM). Эти модели полезны для обработки текстовых данных, временных рядов, музыкальных последовательностей и любых данных с временной зависимостью.
Для работы с последовательными данными используется объект
RNN или слой LSTM. Основная идея заключается в
передаче состояния сети от одного временного шага к следующему. Это
позволяет модели учитывать контекст предыдущих элементов
последовательности при обработке текущего.
Пример конфигурации RNN:
var layer_defs = [];
layer_defs.push({type:'input', out_sx:1, out_sy:1, out_depth:vocab_size});
layer_defs.push({type:'rnn', num_neurons:128, activation:'tanh'});
layer_defs.push({type:'softmax', num_classes:vocab_size});
var net = new convnetjs.Net();
net.makeLayers(layer_defs);
input — задаёт размер входного
вектора. Для текстовых данных это обычно one-hot encoding слов или
символов.rnn — слой рекуррентной сети. Параметр
num_neurons задаёт количество скрытых нейронов,
activation — функцию активации.softmax — слой для классификации,
который выдаёт вероятности для каждого возможного следующего элемента
последовательности.Для LSTM слой задаётся аналогично:
layer_defs.push({type:'lstm', num_neurons:128});
LSTM обеспечивает более устойчивое обучение длинных последовательностей за счёт механизма «запоминания» и «забывания» информации.
Последовательные данные необходимо преобразовать в подходящий формат. Обычно последовательность разбивается на шаги:
vocab_size, где единица ставится в позиции соответствующего
символа или слова.Пример подготовки входных и выходных данных:
function buildDataset(text, vocab) {
var X = [], Y = [];
for(var i=0;i<text.length-1;i++){
var x_vec = new Array(vocab.length).fill(0);
x_vec[vocab.indexOf(text[i])] = 1;
X.push(x_vec);
var y_vec = new Array(vocab.length).fill(0);
y_vec[vocab.indexOf(text[i+1])] = 1;
Y.push(y_vec);
}
return {X: X, Y: Y};
}
ConvNetJS использует объект Trainer для оптимизации
весов сети. Для RNN и LSTM рекомендуется использовать стохастический
градиентный спуск (SGD) с небольшой скоростью обучения. Параметры
тренера включают:
method — метод оптимизации
(sgd, adadelta, adam).learning_rate — скорость обучения. Для
последовательностей обычно берут 0.01–0.001.momentum — ускорение сходимости.batch_size — количество
последовательностей в одном обновлении весов.Пример инициализации тренера:
var trainer = new convnetjs.Trainer(net, {
method: 'adam',
learning_rate: 0.001,
batch_size: 20
});
Обучение RNN происходит итеративно по каждому шагу последовательности. На каждом шаге сеть получает текущий элемент, предсказывает следующий, затем вычисляется ошибка и проводится обратное распространение по времени (BPTT — Backpropagation Through Time).
Пример цикла обучения:
for(var iter=0; iter<num_iters; iter++){
var loss = 0.0;
for(var i=0; i<X.length; i++){
loss += trainer.train(X[i], Y[i]);
}
if(iter % 100 == 0) console.log('iter', iter, 'loss', loss/X.length);
}
train — выполняет прямой и обратный
проход, обновляет веса.loss — средняя ошибка на текущем
батче, важный показатель для контроля сходимости.После обучения сеть может использоваться для генерации новых последовательностей. Для этого:
Пример генерации текста:
var seed = X[0];
var generated = [];
for(var t=0; t<100; t++){
var probs = net.forward(seed);
var next_idx = sampleIndex(probs);
generated.push(vocab[next_idx]);
var next_input = new Array(vocab.length).fill(0);
next_input[next_idx] = 1;
seed = next_input;
}
sampleIndex — функция случайного
выбора индекса с учётом вероятностей.forward.ConvNetJS позволяет полностью управлять архитектурой RNN и LSTM, настраивать оптимизаторы, шаги обучения и генерацию новых последовательностей. Несмотря на относительную простоту по сравнению с Python-библиотеками, она обеспечивает полный контроль над процессом обучения и хорошо подходит для экспериментов с обучением текста, музыки или временных рядов непосредственно в браузере или на Node.js.