Батчирование данных — ключевой аспект при обучении нейронных сетей, напрямую влияющий на скорость сходимости модели, стабильность градиентов и эффективность использования памяти. ConvNetJS предоставляет гибкие возможности для организации батчей при обучении как полносвязных, так и сверточных сетей.
В ConvNetJS под батчем понимается группа входных образцов, подаваемых в сеть одновременно для вычисления градиентов и обновления весов. Батч может состоять из одного примера (online learning) или нескольких примеров (mini-batch learning). Применение батчей позволяет:
Функция trainer.train() в ConvNetJS автоматически
обрабатывает батчи, если передать массив входных данных вместо одного
примера.
Для формирования батчей можно использовать два подхода:
function createBatches(data, batchSize) {
const batches = [];
for (let i = 0; i < data.length; i += batchSize) {
batches.push(data.slice(i, i + batchSize));
}
return batches;
}
function getRandomBatch(data, batchSize) {
const batch = [];
for (let i = 0; i < batchSize; i++) {
const idx = Math.floor(Math.random() * data.length);
batch.push(data[idx]);
}
return batch;
}
Выбор размера батча (batchSize) является компромиссом
между качеством градиентов и эффективностью вычислений:
ConvNetJS позволяет гибко задавать размер батча при создании
Trainer:
var trainer = new convnetjs.SGDTrainer(net, {
learning_rate: 0.01,
batch_size: 64,
l2_decay: 0.001
});
Перемешивание данных перед формированием батчей предотвращает
обучение сети на упорядоченных примерах, что особенно важно при
последовательных данных (например, временных рядах или текстах). В
ConvNetJS рекомендуется использовать функцию shuffle():
function shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
data = shuffle(data);
Перемешивание можно выполнять на каждой эпохе, чтобы батчи были уникальными и улучшали способность модели к обобщению.
Для больших наборов данных или потоковых источников (например, видео или онлайн-сенсоры) имеет смысл формировать батчи на лету, используя генераторы:
function* batchGenerator(data, batchSize) {
let i = 0;
while (true) {
const batch = [];
for (let j = 0; j < batchSize; j++) {
if (i >= data.length) i = 0;
batch.push(data[i]);
i++;
}
yield batch;
}
}
const gen = batchGenerator(data, 32);
const batch = gen.next().value;
trainer.train(batch, labels);
Такой подход экономит память и позволяет использовать очень большие датасеты без полной загрузки в оперативную память.
При работе с ConvNetJS для сверточных сетей каждый пример — это
трехмерный тензор (vol) с размерами
[width, height, depth]. Батчирование для сверточных слоев
не требует дополнительных изменений в структуре данных, однако важно,
чтобы все примеры в батче имели одинаковые размеры. Если данные разного
размера, необходимо применять предварительную обработку (resize,
padding).
var x = new convnetjs.Vol(32, 32, 3); // один пример изображения 32x32 RGB
var batch = [];
for (let i = 0; i < batchSize; i++) {
batch.push(x);
}
trainer.train(batch, labels);
При обучении с батчами ConvNetJS суммирует градиенты по всем примерам в батче и затем выполняет обновление весов. Это обеспечивает более стабильное направление градиентного спуска по сравнению с отдельными примерами. Важно понимать, что эффективный learning rate зависит от размера батча: увеличение размера батча может потребовать корректировки скорости обучения для поддержания оптимальной сходимости.
Батчирование данных в ConvNetJS является фундаментальной техникой для повышения эффективности обучения, контроля за сходимостью и стабильностью градиентов. Грамотно подобранный размер батча, перемешивание данных и потоковое формирование батчей позволяют добиться высокой производительности нейронных сетей в JavaScript.