Throttling и регулировка частоты предсказаний

В работе с ml5.js при создании интерактивных приложений на JavaScript часто возникает необходимость контролировать частоту предсказаний модели. Особенно это важно при использовании моделей реального времени, таких как poseNet, objectDetector или imageClassifier, когда поток данных от камеры или сенсоров может быть очень быстрым. Без регулировки система может испытывать перегрузку, а интерфейс — тормоза.


Основные причины использования throttling

  1. Оптимизация производительности Постоянные вызовы функции предсказания создают нагрузку на основной поток выполнения JavaScript. Throttling позволяет вызывать функцию через фиксированные интервалы времени, уменьшая частоту вычислений и снижая потребление ресурсов.

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

  3. Предотвращение блокировки интерфейса В браузере JavaScript работает в однопоточном режиме. Без контроля частоты предсказаний пользовательский интерфейс может «замерзнуть» при тяжелых вычислениях модели.


Методы реализации throttling

1. Использование setInterval или setTimeout

Простейший способ — запускать функцию предсказания через регулярные интервалы времени:

let video;
let classifier;
let predicting = false;

function setup() {
  createCanvas(640, 480);
  video = createCapture(VIDEO);
  video.hide();
  classifier = ml5.imageClassifier('MobileNet', video, modelReady);

  setInterval(() => {
    if (!predicting) {
      predicting = true;
      classifier.predict(video, gotResult);
    }
  }, 200); // вызов каждые 200 мс
}

function modelReady() {
  console.log('Model Loaded!');
}

function gotResult(error, results) {
  predicting = false;
  if (error) {
    console.error(error);
    return;
  }
  console.log(results[0].label, results[0].confidence);
}

Пояснение:

  • Флаг predicting предотвращает наложение предсказаний.
  • Интервал в 200 мс задаёт частоту предсказаний ~5 раз в секунду.
  • Такой подход подходит для любых моделей ml5.js, использующих поток видео.

2. Использование функции throttle из библиотеки lodash

Lodash предоставляет готовую функцию throttle, которая удобно ограничивает частоту вызова функции:

const throttledPredict = _.throttle(() => {
  classifier.predict(video, gotResult);
}, 300); // вызов не чаще одного раза в 300 мс

function draw() {
  image(video, 0, 0);

  throttledPredict();
}

Преимущества метода:

  • Более чистый код, без ручного управления флагами.
  • Лёгкая настройка интервала вызовов.
  • Поддержка мгновенного вызова первой функции или пропуска первых вызовов, в зависимости от конфигурации.

3. Управление частотой с помощью requestAnimationFrame

Иногда нужно привязать предсказания к рендерингу кадра на холсте p5.js:

let lastPredictionTime = 0;
const interval = 250; // мс

function draw() {
  image(video, 0, 0);

  const now = millis();
  if (now - lastPredictionTime > interval) {
    classifier.predict(video, gotResult);
    lastPredictionTime = now;
  }
}

Преимущество:

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

Динамическая настройка частоты предсказаний

Для приложений с изменяющейся нагрузкой полезно адаптировать интервал вызова в зависимости от текущего времени обработки модели:

let lastPredictionTime = 0;
let dynamicInterval = 200;

function draw() {
  image(video, 0, 0);

  const now = millis();
  if (now - lastPredictionTime > dynamicInterval) {
    const start = performance.now();
    classifier.predict(video, (err, results) => {
      const duration = performance.now() - start;
      dynamicInterval = Math.max(100, duration * 2); // подстраиваем частоту
      lastPredictionTime = now;

      if (err) {
        console.error(err);
        return;
      }
      console.log(results[0].label, results[0].confidence);
    });
  }
}

Особенности подхода:

  • Интервал меняется в зависимости от времени, затраченного на предсказание.
  • Защищает от перегрузки в реальном времени.
  • Позволяет моделям работать максимально эффективно без пропусков кадров.

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

  • Для Web-камеры 30 FPS достаточно вызывать предсказание 5–10 раз в секунду.
  • Для тяжёлых моделей (например, Style Transfer) интервалы нужно увеличивать, чтобы не блокировать интерфейс.
  • Для приложений на мобильных устройствах throttling критически важен для экономии батареи и предотвращения перегрева.
  • Всегда использовать флаги или таймеры, чтобы избежать одновременных вызовов предсказаний.

Регулировка частоты предсказаний — ключевой инструмент для создания плавных и отзывчивых интерактивных приложений на ml5.js, позволяющий балансировать между производительностью модели и удобством пользователя.