Уменьшение размера модели

ConvNetJS — это чисто JavaScript-библиотека для построения и обучения сверточных нейронных сетей. При работе с ограниченными ресурсами, такими как браузер или мобильные устройства, критически важным становится уменьшение размера модели без значительной потери точности.

Сжатие весов

Весовые коэффициенты (weights) в ConvNetJS хранятся как массивы чисел с плавающей точкой. Сокращение их объема напрямую влияет на размер модели:

  • Квантование: преобразование весов из 32-битных чисел с плавающей точкой в 16- или 8-битные форматы. Это снижает размер памяти почти в 2–4 раза. В ConvNetJS можно реализовать квантование вручную, округляя значения весов:
for (let i = 0; i < layer.filters.length; i++) {
    for (let j = 0; j < layer.filters[i].w.length; j++) {
        layer.filters[i].w[j] = Math.round(layer.filters[i].w[j] * 128) / 128;
    }
}
  • Прореживание (pruning): обнуление малых весов, которые вносят минимальный вклад в выход сети. Например, веса меньше порога epsilon можно приравнять к нулю. Это уменьшает как размер модели, так и количество вычислений:
const epsilon = 0.01;
for (let i = 0; i < layer.filters.length; i++) {
    for (let j = 0; j < layer.filters[i].w.length; j++) {
        if (Math.abs(layer.filters[i].w[j]) < epsilon) {
            layer.filters[i].w[j] = 0;
        }
    }
}

Сокращение числа параметров

  • Меньшее количество фильтров: уменьшение числа фильтров в сверточных слоях напрямую сокращает количество весов. Если изначально слой имеет 64 фильтра размером 3×3, переход на 32 фильтра уменьшает количество параметров вдвое.

  • Меньшие размеры фильтров: вместо 5×5 можно использовать несколько последовательных 3×3 слоев. ConvNetJS поддерживает любую размерность фильтра, что позволяет уменьшить число параметров без значительной потери качества распознавания.

  • Использование слоев с пропуском: dropout слои не уменьшают размер модели на диске, но помогают во время обучения сократить переобучение, что позволяет применять более компактные модели без снижения точности.

Сжатие через хранение в бинарном формате

ConvNetJS по умолчанию использует JSON для сохранения модели, что увеличивает размер файла за счет текстового представления чисел. Для уменьшения:

  • Преобразование в двоичный формат: веса можно хранить как массивы Float32Array или Uint8Array, а затем сериализовать их в бинарный файл. Это снижает размер примерно в 4 раза по сравнению с JSON.

Пример преобразования:

function serializeWeights(layer) {
    const flatWeights = [];
    for (let i = 0; i < layer.filters.length; i++) {
        flatWeights.push(...layer.filters[i].w);
    }
    return new Float32Array(flatWeights);
}
  • Сжатие gzip: если модель все же сохраняется в JSON, можно дополнительно сжимать файл через gzip перед загрузкой в браузер.

Объединение слоев и оптимизация архитектуры

  • Замена нескольких слоев одним: последовательные сверточные слои 1×1 можно объединять для снижения числа операций и весов. ConvNetJS поддерживает произвольные конфигурации слоев, что позволяет экспериментировать с комбинированными слоями.

  • Использование слоев с разделяемыми весами: при наличии повторяющихся фильтров можно использовать один фильтр несколько раз, уменьшив объем хранимых данных.

Баланс между размером и точностью

Уменьшение модели всегда сопровождается компромиссом между размером и точностью:

  • Сначала уменьшаются малозначимые веса.
  • Затем сокращается количество фильтров и размер слоев.
  • После этого применяются квантование и бинарное хранение.
  • В конце проводится дообучение модели с уменьшенным размером, чтобы восстановить потерянную точность.

Практические советы

  • Минимизировать количество слоев с большим количеством фильтров.
  • Использовать последовательные 3×3 слои вместо крупных фильтров.
  • Применять квантование и обнуление малых весов.
  • Хранить модель в бинарном формате и использовать сжатие.
  • Дообучать уменьшенную модель, чтобы компенсировать потери точности.

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