Сохранение модели в браузерное хранилище (IndexedDB)

Библиотека ml5.js предоставляет удобные инструменты для работы с моделями машинного обучения в браузере. Одной из ключевых возможностей является сохранение обученной модели прямо в браузере с использованием IndexedDB. Это позволяет сохранять состояние модели между сеансами, избегая повторного обучения при каждом открытии страницы.

Принципы работы с IndexedDB в ml5.js

IndexedDB — это встроенная база данных браузера, предназначенная для хранения больших объёмов структурированных данных, включая файлы и бинарные объекты. В контексте ml5.js она используется через механизм сохранения модели с помощью TensorFlow.js, на котором построена ml5.js.

Модель, сохранённая в IndexedDB, состоит из двух частей:

  1. Архитектура модели — JSON-файл, описывающий слои, их конфигурации и связи.
  2. Весовые коэффициенты — бинарные данные, содержащие параметры модели после обучения.

Когда модель сохраняется, ml5.js вызывает методы TensorFlow.js, которые упаковывают эти данные в IndexedDB под уникальным именем.

Сохранение модели

Для сохранения модели используется метод .save(), доступный у объектов моделей ml5.js, таких как NeuralNetwork, ImageClassifier или PoseNet.

Пример сохранения модели в IndexedDB:

// Создание нейронной сети
const nn = ml5.neuralNetwork({
  task: 'classification',
  debug: true
});

// Обучение модели (пример)
nn.addData({ inputFeature: 1 }, { label: 'A' });
nn.addData({ inputFeature: 2 }, { label: 'B' });
nn.normalizeData();

nn.train({ epochs: 50 }, () => {
  // Сохранение модели в IndexedDB
  nn.save('indexeddb://my-model');
});

Ключевые моменты:

  • Префикс indexeddb:// указывает на тип хранилища.
  • 'my-model' — уникальное имя модели. Если модель с таким именем уже существует, она будет перезаписана.
  • Метод .save() работает асинхронно, так что рекомендуется использовать обратные вызовы или async/await.

Загрузка модели из IndexedDB

Загрузка модели из IndexedDB также выполняется с использованием TensorFlow.js через ml5.js:

ml5.neuralNetwork({ task: 'classification' }, async nn => {
  const loadedNN = await nn.load('indexeddb://my-model');
  // Модель готова к использованию
});

Особенности загрузки:

  • Имя должно точно совпадать с тем, под которым модель была сохранена.
  • После загрузки можно использовать методы predict() или classify() без дополнительного обучения.
  • В случае отсутствия модели по указанному имени будет выброшена ошибка.

Работа с несколькими моделями

IndexedDB позволяет хранить одновременно несколько моделей. Рекомендуется использовать структурированную систему именования, чтобы не допустить конфликтов. Например:

nn.save('indexeddb://classifier-v1');
nn.save('indexeddb://regressor-v1');

Также можно создавать версионированные модели, что позволяет сохранять старые версии для тестирования и сравнения.

Ограничения и особенности

  • Размер хранения: IndexedDB в большинстве браузеров ограничен несколькими сотнями мегабайт, что подходит для небольших и средних моделей.
  • Совместимость браузеров: Современные версии Chrome, Firefox, Edge и Safari полностью поддерживают IndexedDB.
  • Асинхронность операций: Все методы сохранения и загрузки являются асинхронными, поэтому необходимо учитывать обработку промисов или использование async/await.
  • Очистка хранилища: Устаревшие модели можно удалять через indexedDB.deleteDatabase('имя') или управлять ими через стандартный интерфейс браузера.

Практическое применение

Сохранение моделей в IndexedDB особенно полезно в следующих сценариях:

  • Веб-приложения с повторным использованием обученной модели без повторного обучения.
  • Демонстрации и образовательные проекты, где требуется быстро загружать модели на клиенте.
  • Прототипирование и эксперименты с различными архитектурами нейронных сетей.

IndexedDB позволяет полностью переносить вычисления на сторону клиента, повышая производительность и снижая нагрузку на сервер.

Рекомендации по организации данных

  • Использовать уникальные, читаемые имена моделей.
  • Сохранять версию модели в имени (v1, v2), чтобы отслеживать изменения.
  • Перед загрузкой проверять наличие модели в IndexedDB, чтобы избежать ошибок при отсутствии сохранений:
const models = await tf.io.listModels();
if ('indexeddb://my-model' in models) {
  const loadedNN = await nn.load('indexeddb://my-model');
}

Это позволяет безопасно управлять локальными моделями и гарантирует устойчивость веб-приложения.