Инициализация весов является фундаментальным этапом при построении и обучении нейронных сетей. В библиотеке ConvNetJS, реализующей сверточные и полносвязные нейронные сети на Javascript, правильная установка начальных значений весов критически важна для сходимости и стабильности обучения.
Весовые коэффициенты определяют, как сильно сигнал от одного нейрона влияет на следующий. Если веса инициализируются слишком большими, активации могут выйти за пределы диапазона и привести к эффекту затухающего или взрывающегося градиента. С другой стороны, слишком малые веса могут замедлить обучение из-за слабого распространения сигнала.
В ConvNetJS предусмотрены несколько способов инициализации весов, которые зависят от типа слоя и используемой функции активации.
fc)Полносвязные слои создаются через конструктор
new convnetjs.LayerFC({num_neurons: N}). Веса каждого
соединения хранятся в массиве filters объекта
Vol, где каждый Vol представляет собой тензор
весов и смещений.
По умолчанию ConvNetJS использует случайное распределение с нормальным распределением среднего 0 и стандартного отклонения 0.01.
Пример:
var layer = new convnetjs.LayerFC({num_neurons: 100});
console.log(layer.filters[0].w); // случайные значения около 0
Для функций активации ReLU рекомендуется применять инициализацию He, чтобы избежать затухания сигнала. В ConvNetJS это можно реализовать вручную, масштабируя стандартное отклонение:
var fan_in = layer.out_depth;
var scale = Math.sqrt(2.0 / fan_in);
for (var i = 0; i < layer.filters.length; i++) {
for (var j = 0; j < layer.filters[i].w.length; j++) {
layer.filters[i].w[j] = convnetjs.randn(0, 1) * scale;
}
}
conv)Сверточные слои хранят фильтры в виде массива filters,
каждый из которых — это объект Vol. Для слоя
conv стандартная инициализация также случайная с малым
стандартным отклонением, но важна зависимость от размерности
фильтра и количества входных каналов.
var convLayer = new convnetjs.LayerConv({sx: 3, filters: 16, stride: 1, pad: 1});
Для нормальной работы активаций ReLU рекомендуется масштабировать веса:
[ = ]
Реализация в коде:
var filter_size = convLayer.sx * convLayer.sy * convLayer.in_depth;
var scale = Math.sqrt(2.0 / filter_size);
for (var i = 0; i < convLayer.filters.length; i++) {
for (var j = 0; j < convLayer.filters[i].w.length; j++) {
convLayer.filters[i].w[j] = convnetjs.randn(0, 1) * scale;
}
}
Каждый слой содержит смещения, которые добавляются к линейной комбинации входов перед функцией активации. По умолчанию они инициализируются нулями:
layer.filters[i].bias = 0.0;
Для ReLU-интенсивных сетей иногда используют небольшое положительное значение, например 0.1, чтобы ускорить обучение на начальных эпохах.
ConvNetJS предоставляет возможность полностью контролировать начальные веса и смещения. Это полезно при:
Пример загрузки весов:
var net = new convnetjs.Net();
net.makeLayers(layer_defs);
net.fromJSON(pretrained_weights);
Инициализация вручную позволяет использовать различные стратегии: нормальное распределение, равномерное распределение, Xavier, He и другие.
Инициализация весов — это не только технический шаг, но и стратегическая часть проектирования сети, особенно при глубоких архитектурах. ConvNetJS предоставляет гибкие механизмы для точного контроля начальных значений и адаптации под конкретные функции активации.