На Хабре есть уже множество статей об крутой библиотеке TensorFlow.js, но я так и не смог найти что-то об ml5.js - это как TensorFlow, только здесь не надо заботиться об нижних уровнях нейросети. К слову ml5.js не хуже TensorFlow, просто эта библиотека уже больше подходит для каких-то упрощенных проектов где не требуется внедрять нейронную сеть с контролем например: тензоров или оптимизитаров. Да и сама библиотека ещё хорошо подойдет для тех кто ещё свой ищет путь в машинном обучении.

И об этом сегодня и пойдет речь в нашей статье, где мы рассмотрим функционал ml5.js, рассмотрим какие примеры уже есть и как вообще работает код библиотеки. Поэтому, начинаем кодить.

Установка

И все как обычно начинается с установки. Значит какие у нас есть варианты установки? Либо через npm, либо через CDN, либо даже можно просто скачать сами скрипты и так подключить к веб-странице. Я лично для этой статьи буду использовать подключение через CDN, но в рабочих проектах такого лучше не делать - а иметь библиотеку на своем сервере. Окей, что ж начинаем:

<!DOCTYPE html>
<html>
	<head>
		<title>Учим ml5.js</title>
		<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
	</head>
	<body>
	
	</body>
</html>

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

Перед тем как начнём кодить первый скрипт - давайте проверим нашу версию ml5.js:

<!DOCTYPE html>
<html>
	<head>
		<title>Учим ml5.js</title>
		<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
	</head>
	<body>
		
		<script type=”text/javascript”>
			console.log( ml5.version );
		</script>
	</body>
</html>

После этого у нас в консоли должно появиться следующее:

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

Разбираем пример из документации

Давайте перейдем уже к разбору самого простого примера из документации - чтобы вы имели уже приблизительное представление как работает данная библиотека. Ну что ж, документация предлагает новичкам пример из распознаванием объектов на изображению. Здесь также понадобиться подключить библиотеку p5.js если мы хотим нарисовать canvas в котором и будет размещаться наше изображение. Распознавание объектов будет делаться с помощью нейронной сети MobileNet - которая уже размещена внутри библиотеки.

Начнем с того что подключим p5.js:

<!DOCTYPE html>
<html>
	<head>
		<title>Учим ml5.js</title>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
		<script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
</head>
	<body>
	
		<script type=”text/javascript”>
			// Здесь сейчас будет наш код
		</script>
	</body>
</html>

Окей, а сейчас давайте просто сделаем чтобы распознавалось изображение за id, а потом уже результаты выводились в консоль. Начнется все с того чтобы создадим классификатор изображений. А после этого уже будет функция которая все это обработает, так что начинаем:

// Переменная в которой будет наш класификатор изображений
let classifier;

// А здесь уже будет размещаться само наше изображение
let img;

// Preload функция где мы загружаем нейронную сеть MobileNet в
// classifier, и загружаем изображение в img
function preload() {
classifier = ml5.imageClassifier('MobileNet');
	img = loadImage('img/frog.jpg');
}

// С помощью функции createCanvas - создаем поле где нейронная сеть
// будет распозанавать изображение
function setup() {
  createCanvas(400, 400);
  classifier.classify(img, gotResult); // Делаем класификацию изображения
  image(img, 0, 0);
}

// А здесь делаем вывод результата
function gotResult(error, results) {
  if (error) {
    console.error(error); // В случае ошибки - выводим её
  } else {
    console.log(results); // В случае успешного результата выводим на страницу
    createDiv('Label:' + results[0].label);
    createDiv('Confidence:' + nf(results[0].confidence, 0, 2));
  }
}

Окей, ну а теперь давайте проверим нашу страницу.

И что мы видим? MobileNet смог распознать что на изображении находиться лягушка, довольно таки простая задача. Можете также заметить что в поле Confidence выводиться количество интеллекта в тот момент. Если мы также откроем массив который вывелся в консоли - то можем увидеть и другие результаты распознавания картинки:

В последнем результате можно увидеть то как в нейросети увеличился коэффициент интеллекта - и что здесь нейросеть распознала что это за порода лягушки. Круто ????????

Значит только что мы разобрали пример из документации - мы просто рассмотрели довольно таки простой пример. И возможно те кто уже читают данную статью имеют хотя бы какое-то представление о том как работает ml5.js. Получается что мы создаем классификатор для того что мы хотим распознать, загружаем изображение/видео, классификатор делает анализ и выводит нам результат.

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

Распознавание по веб камере

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

// Переменная в котором будет класификатор изображений
let classifier;

// Здесь будет располагаться видео с веб камеры
let video;

// А вот здесь уже результаты распознавания 
// которые будут показываться в реальном режиме времени
let resultsP;

function setup() {
  noCanvas(); // Указываем что нам не нужен canvas для распозанвания
  video = createCapture(VIDEO); // Получаем доступ к камере
  classifier = ml5.imageClassifier('MobileNet', video, modelReady); // Указываем что хотим 
  // работать с видео
  resultsP = createP('Loading model and video...'); // Грузим видео
}

function modelReady() {
  console.log('Model Ready'); // Когда распознаватель загрузился 
  // - то можно запустить процесс распознавания
  classifyVideo(); // Запускаем функцию для класификации видео
}

function classifyVideo() {
  classifier.classify(gotResult); // Получаем результат распознавания
}

// Получаем результаты
function gotResult(err, results) {
  if ( err ) {
   	console.log( err ); // Выводим ошибку если она есть
  } else {
  	resultsP.html( results[0].label + ' ' + nf(results[0].confidence, 0, 2) ); 
    // Выводим что распознала нейронная сеть и какой уровень интеллекта в этот момент
  	classifyVideo();
  }
}

Я записал небольшое видео где показывал перед веб камерой свои гитару и бас гитару - и мне было интересно сможет ли нейросеть MobileNet в режиме реального времени распознать эти предметы:

Гифку пришлось сильно сжать чтобы сюда загрузилось ????. Можете также заметить что-то нейронная сеть часто замечала что на фоне находиться мой ПК. Как я и говорил - то рекомендую сейчас всем попробовать данный пример - ведь реально круто смотреть на то насколько более менее умна данная нейронная сеть.

Ещё пример с распознаванием YOLO с веб камерой

А теперь давайте сделаем пример с распознаванием людей по веб камере с помощью YOLO метода. Поэтому пишем уже код:

// Здесь распологаем видео с веб камеры
let video;

// Здесь YOLO метод
let yolo;

// Тут выводим статус распознавания
let status;

// А здесь будет массивы объектов
let objects = [];

// Делаем setup всех переменных и создаем canvas
function setup() {
  createCanvas(320, 240); // Создание канваса 320x240
  video = createCapture(VIDEO); // Получаем доступ к веб камере
  video.size(320, 240); // Делаем чтобы видео было размером канваса

  // Достаем YOLO метод и указываем там видео,
  // а также делаем детекцию видео с помощью функции
  // startDetecting() которую создадим в дальнейшем
  yolo = ml5.YOLO(video, startDetecting);

  // Прятаем оригинальное видео
  video.hide();
  // В div с id - status выводим статус загрузки
  status = select('#status');
}

// С помощью данной функции идёт вывод результатов в видео
// какие именно объекты были распознаны
function draw() {
  image(video, 0, 0, width, height);
  // В цикле for просто идёт прорисовка этих объектов в canvas
  for (let i = 0; i < objects.length; i += 1) {
    noStroke();
    fill(0, 255, 0);
    text(objects[i].label, objects[i].x + 5, objects[i].y + 15);
    noFill();
    strokeWeight(4);
    stroke(0, 255, 0);
    rect(objects[i].x, objects[i].y, objects[i].width, objects[i].height);
  }
}

// Начало детекции
function startDetecting() {
  status.html('Model loaded!'); // Выводим статус
  detect(); // Запускаем детекцию в режиме реального времени
}

function detect() {
  yolo.detect(function(err, results) {
    objects = results; // Получаем объекты
    detect(); // И продолжаем постоянно делать детекцию
  });
}

Также добавляем div с id - status:

<DOCTYPE html>
<html>
  <head>
    <title>Учим ml5.js</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
    <script src="https://unpkg.com/ml5@latest/dist/ml5.min.js"></script>
  </head>
  <body>

    <div id="status"></div>
    
    <!-- script -->
    <!-- ./ script -->
  </body>
</html>

А теперь смотрим на результат, я решил показать веб камере плакат с группой "Sum 41" - и показало немного криво, но людей распознало:

Да, видно нейронная сеть думает что угол в моей комнате это тоже участник группы Sum 41
Да, видно нейронная сеть думает что угол в моей комнате это тоже участник группы Sum 41

Круто ???????????? А что дальше? Разве это все на что способен данная библиотека????? Конечно же нет, можно рассмотреть множество ещё других примеров. Например использовать модель SketchRNN, где нейронная сеть рисует объекты в зависимости от того какие параметры мы задаем:

Это нейронная сеть нарисовала глазик
Это нейронная сеть нарисовала глазик

Примеров можете очень много найти в этом git репозиторее.

Подведем итоги

Я лично бы использовал эту для каких-то небольших проектов где мне не потребуется настраивать нижнее уровни нейронной сети. Проще говоря использовать ml5.js как готовый инструмент. Для чего-то большого я лично предпочитаю TensorFlow.js который хорошо справляется со сложными задачами и вообще имеет хорошую поддержку. Кроме этого добавлю также что ml5.js можно было бы использовать как некое начало для новичков, которые хотят обучиться машинного обучения с TensorFlow.

P.S. И да я заснял видео где показывал больше разных предметов веб камере - и круто было посмотреть на то как MobileNet подумал - что блокнот это iPad. Кто хочет посмотреть этот момент перемотайте на 5:38.

Комментарии (10)


  1. vgrinin
    06.09.2021 10:17
    +9

    В примере про лягушку. Confidence - это не коэффициент интеллекта, а уверенность. Уверенность сети в том выводе, который она сделала. Или иначе - оценка вероятности того, что вывод она сделала правильный. И далее вы видите в массиве три предположения сети о том, что изображено на картинке. И для каждого предположения указана вероятность. Так вот вероятности там отсортированы, и для третьего элемента там самая маленькая вероятность, всего 6% (сравните с 20% для первого элемента массива). Именно поэтому выведен самый первый результат, как имеющий наибольшую вероятность.


    1. Drag13
      06.09.2021 10:21

      И 21% как то не очень много, мне кажется.


      1. vgrinin
        06.09.2021 10:31

        Ну а кому сейчас легко? Я так понимаю, что нейросеть выполняет predict на локальном компе, в браузере... Видимо не самая мощная архитектура сетки выполняется.


        1. Drag13
          06.09.2021 10:37

          Я не большой специалист в ML, но разве это не делает либу практически бесполезной?


          1. kahi4
            06.09.2021 11:30
            +3

            Насколько я понимаю, ресурсоемким является именно обучение модели. Когда она уже обучена - дальше нужно относительно небольшое количество вычислений (но все ещё очень много из-за того что на вхоже картинка и вам так или иначе нужно пройтись по всем пикселям), вопрос лишь к исходной модели. Но исходная модель растёт вместе с ростом корпуса (чем больше и точнее она может распознавать, тем больше размер самой модели), что для js библиотеки большая проблема.

            видимо, для этой модели нашли такой баланс. Ну она распознала лягушку, даже конкретную (tree frog / древесная лягушка), что уже неплохо, как по мне


            1. DemianKost Автор
              06.09.2021 11:59
              -1

              да распознает так неплохо, но немного слабо как по мне в сравнении с tensorflow


              1. vgrinin
                06.09.2021 21:59
                +2

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


    1. DemianKost Автор
      06.09.2021 11:58

      Да, все именно так)


  1. mellonges
    14.09.2021 16:12

    Интересная статья, правда непонятно зачем создавать канвас именно через эту библиотеку? И вообще зачем нужен канвас вместо <img />?


    1. DemianKost Автор
      14.09.2021 16:14

      хороший вопрос) я пробовал без канваса сразу же через img - но это не работает, типо устройство библиотеки требует чтобы был создан канвас для того чтобы нейронная сеть могла его использовать как свое рабочее поле - проще говоря всегда когда мы создаем канвас и загружаем туда изображение или видео, то это отдельное рабочее место для нейронной сети