Индикаторы загрузки и UX при работе с ML

Основы асинхронной загрузки моделей

При работе с Keras.js модели загружаются в браузер из JSON-файлов и бинарных весов. Этот процесс может занимать значительное время, особенно при больших нейронных сетях. Для улучшения пользовательского опыта важно применять асинхронную загрузку через промисы и события.

const model = new KerasJS.Model({
  filepath: 'model/model.json',
  gpu: true
});

model.ready()
  .then(() => {
    console.log('Модель загружена и готова к использованию');
  })
  .catch(err => {
    console.error('Ошибка загрузки модели:', err);
  });

Ключевой момент: model.ready() возвращает промис, который сигнализирует о готовности модели. В этот момент можно скрывать индикатор загрузки и показывать интерфейс для ввода данных.


Создание индикатора прогресса

Для больших моделей или при медленном соединении необходимо отображать индикатор загрузки. В Keras.js можно отследить прогресс загрузки весов с помощью событий XMLHttpRequest или пользовательских обработчиков.

Пример прогресса через fetch:

function loadWeightsWithProgress(url, onProgress) {
  return fetch(url)
    .then(response => {
      const contentLength = response.headers.get('Content-Length');
      const total = parseInt(contentLength, 10);
      let loaded = 0;

      return new Response(
        new ReadableStream({
          start(controller) {
            const reader = response.body.getReader();

            function read() {
              reader.read().then(({ done, value }) => {
                if (done) {
                  controller.close();
                  return;
                }
                loaded += value.length;
                onProgress(loaded / total);
                controller.enqueue(value);
                read();
              });
            }

            read();
          }
        })
      );
    })
    .then(res => res.arrayBuffer());
}

loadWeightsWithProgress('model/weights.bin', progress => {
  document.getElementById('progress-bar').style.width = `${progress * 100}%`;
});

Особенности реализации:

  • ReadableStream позволяет получать данные по частям.
  • onProgress вызывается с текущим прогрессом в диапазоне [0,1].
  • Можно подключать визуальные индикаторы, такие как полосы загрузки, спиннеры или текстовое отображение процентов.

UX при вычислениях модели

Даже после загрузки модели выполнение предсказаний может занимать время. Особенно это заметно на больших свёрточных сетях. Для улучшения UX применяются следующие подходы:

  1. Асинхронные предсказания через async/await
async function predict(inputData) {
  document.getElementById('spinner').style.display = 'block';
  const outputData = await model.predict({ input: inputData });
  document.getElementById('spinner').style.display = 'none';
  return outputData;
}
  1. Использование Web Workers Выполнение модели в отдельном потоке предотвращает зависание интерфейса. Для этого Keras.js можно подключить внутри воркера и передавать данные через postMessage.

  2. Пошаговое обновление прогресса Если предсказание делится на батчи, можно обновлять индикатор по мере обработки каждого батча, чтобы пользователь видел динамику выполнения.


Визуальные элементы для улучшения восприятия

  • Полосы загрузки: простое горизонтальное заполнение, изменяющееся пропорционально прогрессу загрузки весов.
  • Спиннеры: применяются при неизвестной продолжительности загрузки или вычисления.
  • Текстовые уведомления: отображение текущего шага, например, “Загрузка модели”, “Инициализация весов”, “Предсказание”.
<div id="loading-container">
  <div id="spinner"></div>
  <div id="progress-bar-container">
    <div id="progress-bar"></div>
  </div>
  <p id="status-text">Загрузка модели...</p>
</div>

Совет по UX: сочетание спиннера с текстовым прогрессом обеспечивает наиболее информативное представление процесса для пользователя.


Оптимизация времени ожидания

  1. Минификация и сжатие весов модели: уменьшает время загрузки по сети.
  2. Загрузка частями: можно загружать только нужные слои модели для ускорения старта.
  3. Кэширование: после первой загрузки модель можно хранить в IndexedDB или Cache API, чтобы повторные визиты были мгновенными.

Практика интеграции в интерфейс

  • Добавлять индикатор сразу перед вызовом model.ready().
  • После завершения загрузки и инициализации скрывать все элементы загрузки и показывать рабочий интерфейс.
  • Использовать анимацию плавного перехода от индикатора к основному UI для повышения ощущения скорости работы.

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