DoodleNet: распознавание рисунков

ml5.js предоставляет высокоуровневый доступ к обученным моделям машинного обучения в браузере на JavaScript. Одной из таких моделей является DoodleNet, предназначенная для распознавания простых рукописных рисунков, таких как объекты, символы или фигуры. DoodleNet основана на модели SketchRNN и позволяет мгновенно классифицировать изображения, созданные пользователем.


Подключение и инициализация модели

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

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

Инициализация модели происходит следующим образом:

let classifier;

function setup() {
  classifier = ml5.imageClassifier('DoodleNet', modelReady);
}

function modelReady() {
  console.log('Модель DoodleNet загружена и готова к использованию.');
}

Ключевой момент: ml5.imageClassifier('DoodleNet') автоматически загружает предобученную модель, оптимизированную для распознавания более чем 340 типов рисунков.


Подготовка канвы для рисования

Для того чтобы использовать DoodleNet, необходимо создать элемент <canvas> и обработку событий мыши для рисования:

let canvas;
let ctx;

function setupCanvas() {
  canvas = document.getElementById('drawingCanvas');
  ctx = canvas.getContext('2d');
  ctx.lineWidth = 5;
  ctx.lineCap = 'round';
  
  canvas.addEventListener('mousedown', startDrawing);
  canvas.addEventListener('mousemove', draw);
  canvas.addEventListener('mouseup', stopDrawing);
  canvas.addEventListener('mouseleave', stopDrawing);
}

let drawing = false;

function startDrawing(e) {
  drawing = true;
  ctx.beginPath();
  ctx.moveTo(e.offsetX, e.offsetY);
}

function draw(e) {
  if (!drawing) return;
  ctx.lineTo(e.offsetX, e.offsetY);
  ctx.stroke();
}

function stopDrawing() {
  drawing = false;
}

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

  • ctx.lineWidth и ctx.lineCap помогают моделям распознавать рисунок более точно.
  • Использование beginPath() при каждом новом нажатии мыши предотвращает соединение линий между разными штрихами.

Классификация рисунка

После завершения рисования изображение передается в DoodleNet для распознавания:

function classifyDrawing() {
  classifier.classify(canvas, gotResult);
}

function gotResult(error, results) {
  if (error) {
    console.error(error);
    return;
  }
  console.log('Распознанный объект:', results[0].label);
  console.log('Уверенность модели:', results[0].confidence.toFixed(2));
}

Принцип работы:

  • classifier.classify() принимает HTMLCanvasElement, HTMLImageElement или видео.
  • Результат — массив объектов с полями label (название объекта) и confidence (доля вероятности).
  • DoodleNet автоматически масштабирует и нормализует рисунок, поэтому дополнительных преобразований обычно не требуется.

Оптимизация работы модели

Для повышения точности распознавания рекомендуется:

  1. Контрастный фон: рисовать на белом фоне темной линией.
  2. Минимизация шумов: очищать канву между попытками распознавания.
  3. Размер штриха: линия должна быть достаточно толстой, чтобы модель распознавала форму, но не слишком толстой, чтобы не терялись детали.
  4. Крупные объекты: модель лучше распознает рисунки, занимающие большую часть канвы.
function clearCanvas() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
}

Интерактивная визуализация предсказаний

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

function gotResult(error, results) {
  if (error) {
    console.error(error);
    return;
  }
  
  let predictions = results.slice(0, 3);
  predictions.forEach((pred, i) => {
    console.log(`${i + 1}. ${pred.label} — уверенность: ${(pred.confidence * 100).toFixed(1)}%`);
  });
}

Совет: использование нескольких топ-предсказаний помогает компенсировать неопределенность при сложных или частично нарисованных объектах.


Интеграция с другими функциями ml5.js

DoodleNet можно комбинировать с:

  • p5.js, для создания интерактивной графики и анимации рисунков.
  • SpeechSynthesis API, для озвучивания распознанного объекта.
  • LocalStorage или IndexedDB, чтобы сохранять рисунки и результаты классификации для анализа.
function speakResult(label) {
  const utterance = new SpeechSynthesisUtterance(label);
  speechSynthesis.speak(utterance);
}

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

  1. Образовательные игры: распознавание рисунков как часть викторин.
  2. Интерактивные приложения для детей: отслеживание успехов в рисовании.
  3. Прототипирование интерфейсов: быстрый ввод элементов с помощью рисования.
  4. Проекты по исследованию машинного обучения: анализ ошибок модели и обучение на пользовательских данных.

Ключевое преимущество: DoodleNet позволяет быстро интегрировать распознавание рисунков без необходимости в обучении собственной модели, что делает её идеальной для прототипов и обучающих проектов.