ConvNetJS — это полностью клиентская библиотека для построения и
обучения нейронных сетей на JavaScript. Она ориентирована на сверточные
нейронные сети (CNN), но поддерживает и стандартные полносвязные сети.
Основным объектом для работы является Net, который содержит
архитектуру сети, веса и методы обучения.
Сеть создаётся с помощью конструктора convnetjs.Net().
После создания объект сети пуст и требует конфигурации слоёв через
makeLayers(layer_defs). Конфигурация задаётся массивом
объектов, каждый из которых описывает слой:
var layer_defs = [];
layer_defs.push({type:'input', out_sx:32, out_sy:32, out_depth:3}); // входной слой
layer_defs.push({type:'conv', sx:5, filters:8, stride:1, pad:2, activation:'relu'}); // сверточный слой
layer_defs.push({type:'pool', sx:2, stride:2}); // слой подвыборки
layer_defs.push({type:'softmax', num_classes:10}); // выходной слой
После определения слоёв вызывается метод:
net.makeLayers(layer_defs);
Этот метод автоматически инициализирует веса всех слоёв, используя небольшие случайные значения для весов и нулевые смещения.
Каждый слой сети хранит свои веса и смещения в виде объекта
vol (объект класса Vol). Для сверточного слоя
веса представляют собой 4-мерный тензор
[sx, sy, depth, filters], где:
sx, sy — размеры фильтра по ширине и
высотеdepth — глубина входного объёмаfilters — количество фильтровСмещения хранятся в отдельном векторе размерности равной количеству
фильтров. Для полносвязного слоя веса хранятся в форме матрицы
[num_inputs, num_neurons], а смещения — в виде вектора
[num_neurons].
Пример доступа к весам сверточного слоя:
var conv_layer = net.layers[1];
console.log(conv_layer.filters[0].w); // массив весов первого фильтра
console.log(conv_layer.filters[0].dw); // массив градиентов по весам
ConvNetJS использует небольшое случайное распределение для
инициализации весов, что предотвращает «затухание градиентов». Значения
обычно находятся в диапазоне [-0.01, 0.01]. Смещения
инициализируются нулями.
Для более сложных стратегий можно вручную изменять веса после создания сети:
for(var i=0;i
Обучение в ConvNetJS реализуется через стохастический градиентный
спуск (SGD) и другие оптимизаторы (adagrad,
adam). Метод train принимает входные данные и
правильный класс, автоматически вычисляет градиенты и обновляет
веса:
var trainer = new convnetjs.SGDTrainer(net, {learning_rate:0.01, momentum:0.9, batch_size:20});
trainer.train(x, y); // x — Vol, y — правильная метка
Каждый шаг обучения вычисляет dw для каждого фильтра и
смещения. После этого веса обновляются по формуле:
[ w = w - dw]
где η — скорость обучения, dw — градиент.
При использовании момента учитывается накопленный предыдущий
градиент:
[ v = v - dw] [ w = w + v]
где μ — коэффициент момента.
ConvNetJS поддерживает экспорт и импорт весов в JSON-формате. Это удобно для сохранения состояния сети и повторного использования:
var json = net.toJSON(); // экспорт сети и весов
var net2 = new convnetjs.Net();
net2.fromJSON(json); // загрузка сети с весами
В JSON сохраняются все параметры слоёв, включая веса, смещения и типы активаций.
L1 и L2
можно добавить через trainer для предотвращения
переобучения.В ConvNetJS основным контейнером для весов, смещений и активаций
является класс Vol. Он поддерживает:
Пример создания собственного объёма весов:
var v = new convnetjs.Vol(3,3,2); // 3x3 фильтр, глубина 2
v.w[0] = 0.1; // присвоение конкретного веса
Использование Vol позволяет легко манипулировать весами
и интегрировать их в вычисления сети.
ConvNetJS допускает прямое вмешательство в веса для экспериментов или тонкой настройки:
var fc_layer = net.layers[2]; // полносвязный слой
for(var i=0;i
Эта возможность особенно полезна при проведении исследований влияния инициализации и регуляризации на обучение сети.