Обучение регрессора поверх MobileNet

Для работы с библиотекой ml5.js требуется подключение её скрипта в проект. Наиболее удобный способ — использовать CDN:

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ml5/0.12.2/ml5.min.js"></script>

p5.js обеспечивает удобный интерфейс для работы с canvas, камерой и визуализацией, а ml5.js предоставляет готовые модели машинного обучения с простым API.

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


Инициализация видеопотока

Для захвата изображения с веб-камеры используется объект createCapture из p5.js:

let video;

function setup() {
  createCanvas(640, 480);
  video = createCapture(VIDEO);
  video.size(640, 480);
  video.hide();
}

Скрытие потока video.hide() необходимо для последующей отрисовки только на canvas, а не напрямую на странице.


Подключение MobileNet

MobileNet в ml5.js используется как feature extractor — извлекатель признаков, поверх которого создаётся собственная модель регрессии.

let featureExtractor;
let regressor;

function setup() {
  createCanvas(640, 480);
  video = createCapture(VIDEO);
  video.size(640, 480);
  video.hide();

  featureExtractor = ml5.featureExtractor('MobileNet', modelReady);
  regressor = featureExtractor.regression(video);
}

function modelReady() {
  console.log('Feature extractor (MobileNet) загружен');
}

Ключевой момент: MobileNet обучен распознавать тысячи классов, но в режиме featureExtractor он не классифицирует сам, а предоставляет вектор признаков для последующей задачи (регрессии или классификации).


Добавление тренировочных данных

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

function addExample(label) {
  regressor.addImage(label);
}

// Пример использования:
// addExample(0.2); // Добавляет кадр с меткой 0.2
// addExample(0.8); // Добавляет кадр с меткой 0.8

Важное замечание: значения меток должны быть числовыми. Регрессор не работает с категориальными метками — для этого используется классификатор.


Обучение регрессора

После добавления всех примеров можно запускать обучение:

function trainModel() {
  regressor.train((lossValue) => {
    if (lossValue) {
      console.log('Текущий loss: ', lossValue);
    } else {
      console.log('Обучение завершено');
      predict();
    }
  });
}

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

  • Функция обратного вызова вызывается на каждой итерации. lossValue уменьшается по мере обучения.
  • Если lossValue равен null, это означает завершение обучения.

Прогнозирование значений

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

function predict() {
  regressor.predict((err, result) => {
    if (err) {
      console.error(err);
    } else {
      console.log('Предсказанное значение: ', result);
      // Автоматически продолжаем прогноз
      predict();
    }
  });
}

Ключевой момент: функция predict может вызываться рекурсивно, создавая непрерывное предсказание в реальном времени для видеопотока.


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

  • Разнообразие данных: для точного регрессора требуется множество кадров с разными углами, освещением и позицией объекта.
  • Нормализация меток: полезно приводить значения меток к диапазону [0, 1], особенно если они представляют относительные позиции или размеры.
  • Количество примеров: чем больше примеров, тем стабильнее обучение, особенно если объект движется быстро.
  • Интерактивность: регрессор можно использовать для управления элементами интерфейса в реальном времени, например, перемещать ползунок или изменять цвет объекта в зависимости от предсказанного значения.

Интеграция с визуализацией

Для наглядной работы регрессора поверх видео можно использовать p5.js canvas:

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

  // Пример: отображение предсказанного значения как круга по горизонтали
  let predictedValue = lastPrediction || 0.5; // lastPrediction обновляется в callback predict
  let x = predictedValue * width;
  fill(255, 0, 0);
  noStroke();
  ellipse(x, height / 2, 50, 50);
}

Особенности:

  • lastPrediction обновляется внутри функции predict.
  • Отображение на canvas позволяет визуально оценить корректность регрессора и реакцию модели на изменения сцены.

Настройка гиперпараметров

ml5.js позволяет настраивать параметры обучения:

regressor.train({
  epochs: 50,
  batchSize: 4,
  learningRate: 0.01
}, lossCallback);
  • epochs: количество проходов через весь тренировочный набор. Большие значения могут улучшить точность, но увеличивают время обучения.
  • batchSize: количество примеров, обрабатываемых за один шаг градиентного спуска. Меньший batchSize — более плавное обучение, но более шумный градиент.
  • learningRate: скорость обучения модели. Слишком большое значение может привести к нестабильному обучению, слишком маленькое — к медленному снижению ошибки.

Сохранение и загрузка модели

После обучения модель можно сохранить для повторного использования:

regressor.save('myRegressionModel');

Для загрузки ранее сохранённой модели:

regressor.load('myRegressionModel/model.json', () => {
  console.log('Модель загружена и готова к предсказаниям');
  predict();
});

Преимущество: возможность обучать модель один раз и использовать её на других страницах без повторного сбора данных.


Хотите, я могу подготовить подробный пример полноценного проекта, где регрессор управляет положением объекта на canvas в реальном времени с видеопотока? Это покажет все этапы работы от данных до интерактивной визуализации.