ConvNetJS — это чисто JavaScript-библиотека для построения и обучения сверточных нейронных сетей (CNN) и полносвязных сетей. Одним из важных аспектов работы с моделями является возможность конвертации весов между различными форматами и сохранение/загрузка параметров сети для последующего использования.
В ConvNetJS веса и смещения каждой слоя хранятся в объектах типа
Vol (volume), представляющих многомерные массивы. Основные
свойства:
w — массив весов в виде одномерного Float32Array.dw — массив градиентов соответствующих весов.sx, sy, depth — размеры
объемного тензора.get(x, y, d) и set(x, y, d, v) — методы
доступа к элементам.Для конвертации и сохранения модели используется метод
toJSON() у объекта сети (Net). Он возвращает
объект, содержащий:
layers — массив описаний всех слоев сети.Пример структуры JSON для слоя:
{
"layer_type": "fc",
"num_inputs": 100,
"num_neurons": 10,
"biases": {
"sx": 1,
"sy": 1,
"depth": 10,
"w": [0.1, -0.2, 0.05, ...]
},
"filters": [
{
"sx": 10,
"sy": 10,
"depth": 1,
"w": [...]
}
]
}
Сохранение весов в JSON позволяет:
Пример сохранения модели в JSON:
var json = net.toJSON();
var jsonString = JSON.stringify(json);
JSON-строку можно сохранить на сервере или в локальном хранилище
браузера (localStorage).
Для восстановления сети используется метод
fromJSON(json):
var json = JSON.parse(jsonString);
net.fromJSON(json);
При этом структура сети должна полностью совпадать с той, из которой был сохранён JSON, иначе веса не будут корректно назначены.
Иногда требуется конвертировать веса из других библиотек (например, TensorFlow или PyTorch) в формат ConvNetJS. Для этого необходимо:
Vol.w.width × height × depth, а многие библиотеки
используют depth × height × width.Vol с размерностями слоя:var vol = new convnetjs.Vol(sx, sy, depth, 0.0);
for (var i = 0; i < weightsArray.length; i++) {
vol.w[i] = weightsArray[i];
}
layer.filters[j] = vol;
fc) и слоя смещений
(biases) используется аналогичный подход.Можно написать функцию, которая принимает массивы весов и смещений из другой библиотеки и автоматически распределяет их по слоям ConvNetJS:
function convertWeights(convnetLayers, externalWeights) {
for (var i = 0; i < convnetLayers.length; i++) {
var layer = convnetLayers[i];
if (layer.layer_type === 'fc') {
for (var j = 0; j < layer.filters.length; j++) {
var vol = new convnetjs.Vol(layer.filters[j].sx, layer.filters[j].sy, layer.filters[j].depth);
vol.w = externalWeights[i][j];
layer.filters[j] = vol;
}
var biasVol = new convnetjs.Vol(1, 1, layer.biases.depth);
biasVol.w = externalWeights[i].biases;
layer.biases = biasVol;
} else if (layer.layer_type === 'conv') {
for (var j = 0; j < layer.filters.length; j++) {
var vol = new convnetjs.Vol(layer.filters[j].sx, layer.filters[j].sy, layer.filters[j].depth);
vol.w = externalWeights[i][j];
layer.filters[j] = vol;
}
var biasVol = new convnetjs.Vol(1, 1, layer.biases.depth);
biasVol.w = externalWeights[i].biases;
layer.biases = biasVol;
}
}
}
Эта функция гарантирует, что все веса и смещения будут корректно размещены в слоях ConvNetJS, сохраняя совместимость сети.
relu,
sigmoid, tanh, softmax). Если
исходная модель использует другую функцию, её необходимо заменить.После конвертации веса можно использовать для:
Использование методов toJSON и fromJSON в
сочетании с ручной конвертацией обеспечивает гибкую интеграцию
ConvNetJS с внешними моделями, позволяя строить обучаемые
веб-приложения с заранее подготовленными сетями.