Представление данных в формате Vol

В библиотеке ConvNetJS основным объектом для хранения данных, которые проходят через нейронную сеть, является класс Vol. Он представляет собой многомерный массив, способный хранить данные в виде трёхмерного тензора: ширина (width), высота (height) и глубина (depth). Этот формат универсален и позволяет работать как с изображениями, так и с более общими векторными представлениями.


Структура объекта Vol

Объект Vol содержит следующие ключевые свойства:

  • w — массив значений тензора, представленных в виде одномерного массива (Float32Array для оптимизации производительности).
  • sx — ширина тензора.
  • sy — высота тензора.
  • depth — количество каналов или глубина тензора.
  • dw — массив для хранения градиентов, используемый при обратном распространении ошибки.
  • params — дополнительные параметры, такие как смещения или веса нейронов, если Vol используется в слоях с обучаемыми параметрами.

Пример создания Vol:

var x = new convnetjs.Vol(5, 5, 3); // ширина 5, высота 5, глубина 3

В этом примере создаётся трёхмерный тензор размером 5×5×3, где все значения по умолчанию инициализируются нулями.


Инициализация данных

Vol позволяет инициализировать значения различными способами:

  1. Случайная инициализация
var x = new convnetjs.Vol(5, 5, 3, 0.1); 

Здесь каждый элемент тензора получает случайное значение с нормальным распределением и стандартным отклонением 0.1.

  1. Инициализация из массива
var data = [];
for(var i=0;i<75;i++) data.push(Math.random());
var x = new convnetjs.Vol(5, 5, 3, 0.0, data);

Массив data должен содержать количество элементов равное sx * sy * depth.

  1. Передача скаляра
var x = new convnetjs.Vol(5, 5, 3, 1.0);

Все элементы тензора будут установлены в 1.0.


Индексация элементов

Элементы Vol хранятся в линейном массиве w в порядке x → y → depth. Индекс элемента с координатами (x, y, d) вычисляется по формуле:

index = ((sy * y) + x) * depth + d

Это позволяет эффективно работать с отдельными значениями и быстро вычислять производные при обратном распространении.


Операции с Vol

Vol поддерживает базовые арифметические операции:

  • Добавление и умножение на скаляр
x.add(0.5);      // прибавляет 0.5 ко всем элементам
x.mul(2.0);      // умножает все элементы на 2
  • Клонирование и копирование
var y = x.clone(); // создаёт полную копию Vol
y.setFrom(x);      // копирует данные из x в y
  • Прямое обращение к элементам
var val = x.get(xCoord, yCoord, depthCoord);
x.set(xCoord, yCoord, depthCoord, 3.14);

Vol в контексте слоёв ConvNetJS

Каждый слой нейронной сети работает с объектами Vol:

  • Сверточный слой (ConvLayer) принимает входной Vol и создаёт новый Vol с результатами свёртки.
  • Полносвязный слой (FullyConnLayer) использует Vol как одномерный вход, развёрнутый из трёхмерного формата.
  • Слой активации (ReluLayer, SigmoidLayer) напрямую модифицирует значения Vol, применяя функцию активации к каждому элементу.
  • Pooling слой (PoolLayer) создаёт новый Vol меньших размеров, сохраняя важные характеристики исходных данных.

В каждом случае Vol обеспечивает единообразное представление данных, позволяя слоям работать с ними независимо от конкретного типа слоя.


Градиенты и обратное распространение

Каждый Vol имеет массив dw, который хранит градиенты по соответствующим элементам w. В процессе обратного распространения:

  1. Слои вычисляют производные по входу и записывают их в dw.
  2. Эти градиенты используются оптимизатором для обновления параметров.

Пример работы с градиентами:

var x = new convnetjs.Vol(3, 3, 1);
x.dw[4] = 0.7; // производная для элемента с индексом 4

Вспомогательные методы Vol

  • cloneAndZero() — создаёт копию Vol с нулевыми значениями.
  • addFrom(vol) — прибавляет значения из другого Vol.
  • addFromScaled(vol, a) — прибавляет значения из другого Vol с коэффициентом a.
  • setConst(c) — устанавливает все элементы в константу c.
  • toJSON() / fromJSON(json) — сериализация и десериализация Vol для хранения или передачи данных.

Эффективность Vol

Использование одномерного массива для хранения данных Vol позволяет:

  • Оптимизировать операции над тензорами, используя быстрые циклы и векторизацию.
  • Минимизировать накладные расходы на создание сложных многомерных структур.
  • Быстро интегрироваться с слоями сети без необходимости трансформации данных.

Vol является фундаментом всех вычислений ConvNetJS, предоставляя гибкий и эффективный способ представления данных любой размерности.