На Хабре есть уже множество статей об крутой библиотеке 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" - и показало немного криво, но людей распознало:
Круто ??? А что дальше? Разве это все на что способен данная библиотека?? Конечно же нет, можно рассмотреть множество ещё других примеров. Например использовать модель SketchRNN, где нейронная сеть рисует объекты в зависимости от того какие параметры мы задаем:
Примеров можете очень много найти в этом git репозиторее.
Подведем итоги
Я лично бы использовал эту для каких-то небольших проектов где мне не потребуется настраивать нижнее уровни нейронной сети. Проще говоря использовать ml5.js как готовый инструмент. Для чего-то большого я лично предпочитаю TensorFlow.js который хорошо справляется со сложными задачами и вообще имеет хорошую поддержку. Кроме этого добавлю также что ml5.js можно было бы использовать как некое начало для новичков, которые хотят обучиться машинного обучения с TensorFlow.
P.S. И да я заснял видео где показывал больше разных предметов веб камере - и круто было посмотреть на то как MobileNet подумал - что блокнот это iPad. Кто хочет посмотреть этот момент перемотайте на 5:38.