Web Workers позволяют выполнять вычислительные задачи в отдельном потоке, не блокируя основной поток исполнения JavaScript. Это особенно важно при работе с нейронными сетями в библиотеке Synaptic, где обучение и прогнозирование могут потреблять значительное количество ресурсов.
Для создания нового воркера используется конструктор
Worker, которому передается путь к скрипту:
const worker = new Worker('worker.js');
Внутри worker.js можно импортировать библиотеку Synaptic
и реализовать функции для обучения сети:
importScripts('https://cdn.jsdelivr.net/npm/synaptic@1.1.4/dist/synaptic.js');
self.onmess age = function(e) {
const { networkConfig, trainingSet } = e.data;
const { Layer, Network, Trainer } = synaptic;
const inputLayer = new Layer(networkConfig.input);
const hiddenLayer = new Layer(networkConfig.hidden);
const outputLayer = new Layer(networkConfig.output);
inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);
const network = new Network({ input: inputLayer, hidden: [hiddenLayer], output: outputLayer });
const trainer = new Trainer(network);
const results = trainer.train(trainingSet, {
rate: 0.1,
iterations: 2000,
error: 0.005,
shuffle: true,
log: false
});
self.postMessage({ results, trainedNetwork: network.toJSON() });
};
Ключевым моментом является использование postMessage для
передачи данных между основным потоком и воркером. Основной поток не
блокируется, и пользовательский интерфейс остаётся отзывчивым даже при
интенсивном обучении нейронной сети.
Для передачи данных и получения результатов используется событие
message:
worker.onmess age = function(e) {
const { results, trainedNetwork } = e.data;
console.log('Результаты обучения:', results);
// Можно восстановить сеть из JSON
const { Network } = synaptic;
const network = Network.fromJSON(trainedNetwork);
};
Передача данных воркеру осуществляется аналогичным образом:
const trainingSet = [
{ input: [0,0], output: [0] },
{ input: [0,1], output: [1] },
{ input: [1,0], output: [1] },
{ input: [1,1], output: [0] }
];
const networkConfig = { input: 2, hidden: 3, output: 1 };
worker.postMessage({ networkConfig, trainingSet });
Важно учитывать, что объекты, передаваемые через
postMessage, клонируются, а не передаются по ссылке. Для
больших массивов данных это может требовать оптимизации через
Transferable Objects.
Одно из сильных преимуществ Web Workers — возможность параллельного обучения нескольких нейросетей. Для этого создается несколько воркеров:
const workers = [];
for (let i = 0; i < 4; i++) {
const worker = new Worker('worker.js');
workers.push(worker);
worker.onmess age = function(e) {
console.log(`Worker ${i} завершил обучение`);
};
worker.postMessage({ networkConfig, trainingSet });
}
Каждый воркер работает независимо, что позволяет эффективно использовать многопоточность, доступную в современных браузерах, и значительно ускоряет процесс обучения при больших данных.
Модель Synaptic можно передавать только в сериализованном виде.
Методы .toJSON() и Network.fromJSON()
позволяют:
Пример передачи обученной сети:
// В воркере
self.postMessage({ trainedNetwork: network.toJSON() });
// В основном потоке
const trainedNetwork = Network.fromJSON(e.data.trainedNetwork);
ArrayBuffer) для уменьшения копирования при больших
объемах входных данных.Каждый воркер может вызвать событие error, которое важно
обрабатывать для отладки:
worker.oner ror = function(e) {
console.error(`Ошибка в воркере: ${e.message} на строке ${e.lineno}`);
};
После завершения работы воркер следует корректно завершать:
worker.terminate();
Это освобождает ресурсы и предотвращает утечки памяти при длительных вычислениях.
Использование Web Workers совместно с библиотекой Synaptic позволяет реализовать сложные нейронные сети в браузере без тормозов интерфейса, эффективно масштабировать обучение на нескольких ядрах и управлять ресурсами даже при больших объемах данных.