Почему часто простота не означает простоту использования

Введение

На днях я смотрел много видео Кодинг-поезд. Это действительно прекрасный канал на YouTube с очень забавным и полным энтузиазма ведущим Дэниелом Шиффманом. Одним из основных материалов этого канала являются Вызовы по кодированию, где Даниэль использует в основном фреймворки JavaScript для реализации интересных небольших приложений. Одним из таких фреймворков, о котором он даже сделал серию статей, является ml5.js. Эта библиотека построена на основе Tensorflow.js и, согласно ее собственному веб-сайту,

Добрососедский подход к созданию и изучению искусственного интеллекта в браузере.

Я попробовал ml5.js, и я разочарован. Вот почему.

Нестандартная модель

Насколько я понимаю, ml5.js хочет сделать разработку и развертывание моделей машинного обучения максимально простой и удобной для начинающих. Это хорошая идея, поэтому давайте начнем с простой модели. Мы можем очень удобно включить фреймворк, включив ссылку cdn в заголовок HTML (листинг 1).

Теперь мы уже готовы идти! К счастью, ml5.js уже поставляется с некоторыми моделями предварительной сборки, поэтому мы можем просто использовать одну из них. Кроме того, он легко интегрируется с p5.js, фреймворком, упрощающим работу с мультимедиа и графикой. Таким образом, использование p5.js для захвата кадра с веб-камеры и передачи его в модель ml5.js требует всего 30 строк кода (листинг 2).

Это работает очень хорошо и заняло не более 15 минут, чтобы настроить. Итак, что, если мы хотим использовать нашу собственную пользовательскую модель? Вот тут и начались мои проблемы.

Индивидуальная модель

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

Я действительно не хочу делать ничего необычного, поэтому я просто реализую классификатор для MNIST. Перейдя к ссылке, они описывают, как реализовать сверточную нейронную сеть для классификации изображений (изображение 1):

Хорошо, я понимаю, что ml5.js хочет быть удобным для начинающих, но это кажется слишком коротким. Библиотека должна упростить задачу, а не полностью скрывать все поведение от пользователя. Что здесь происходит на самом деле? Сколько у нас слоев? Сколько фильтров? Размер шага? Функция активации? Мы не знаем. Предлагать это как способ создания нейронной сети кажется немного неправильным.

Но я не хочу быть слишком придирчивым, потому что всего несколькими строками ниже нам рассказывают, как определить нашу собственную нейронную сеть (изображение 2):

Следующее, что меня сразу поразило, это то, что почти не было упоминаний о Tensorflow. На самом деле, на лендинге было только что упомянуто, что ml5.js строится поверх него, но в самой документации его нигде нет. Итак, если я определяю свою собственную сеть, как на изображении 2, я могу использовать все доступные слои из Tensorflow? И у них одинаковое имя? В ссылке это не упоминается и не дается список доступных слоев, так что мы не знаем.

Интерфейс нейросети также отличается от Tensorflow (изображение 3)

Вместо простого .predict() у нас есть четыре разных метода: .predict(), .predictMultiple(), .classify() и classifyMultiple(). Кроме того, мы не можем передать данные в метод .train(), но должны предварительно вызвать .addData(). Это… кажется слишком сложным и не очень удобным для пользователя.

Хорошо, давайте не будем слишком останавливаться на этом, потому что, как было сказано выше, чаще используется уже обученная модель, чем обучается в браузере. Итак, как мы можем загрузить предварительно обученную модель Tensorflow в ml5.js? Его нет в ссылке. Думать об этом. Эта библиотека построена на основе Tensorflow, и нам не даются четких инструкций о том, как на самом деле загрузить модель Tensorflow. Изучив документацию Tensorflow.js и изучив репозиторий GitHub, в котором также используется ml5.js, я понял, что, похоже, существует пакет Python под названием tensorflowjs, который преобразует обычную модель Tensorflow в файл .json с архитектурой и файлами .bin. с весами моделей. Один поясняющий абзац в документации по ml5.js очень помог бы здесь.

В любом случае, давайте двигаться дальше. После того, как я прочитал изображение с веб-камеры, я хочу изменить его размер, чтобы передать его в свою нейронную сеть. В справочнике ml5.js есть вкладка «Utils», где мы должны найти такую ​​​​функциональность. Я нажимаю туда и… там указан один метод. Один. Метод. Весь раздел Utils состоит из метода .flipImage(). Это все утилиты. Другие методы управления изображением или звуком? Неа. Это совсем не полезно. Итак, мне нужно изменить разрешение моей веб-камеры, это не так уж сложно.

Хорошо, теперь я могу загрузить свою собственную модель (листинг 3)

Когда я выполняю этот код, я получаю сообщение об ошибке (изображение 4)

Эм, это интересно. Как я уже сказал выше, я обучил свою модель набору данных MNIST, поэтому, конечно, ожидаемый ввод имеет размерность (28, 28, 1). Но почему моя сеть ожидает ввод размера (1 224 224)? Я никогда не уточнял это? Я изменил разрешение изображения, которое я получаю с веб-камеры, на (28, 28), чтобы оно соответствовало моей сети. Покопавшись в репозитории ml5.js на GitHub, я нашел эту строку (листинг 4):

Итак… размер изображения жестко запрограммирован на 224? Наверняка должна быть возможность изменить это, верно? Неправильный! У класса ImageClassifier есть параметры, которые мы можем установить (изображение 5), но размер изображения не входит в их число.

Подводя итог: у меня есть обученная модель, но независимо от того, как я изменяю размер входных изображений, этот класс всегда будет изменять его размер до (224, 224), и у меня нет возможности изменить это. Зачем… зачем мне это? Зачем кому-то это? В этот момент я сдался. Мол, что мне делать? Вывести мой собственный класс из базового класса ImageClassifier и изменить эту константу? Клонировать весь код ml5.js только для того, чтобы изменить эту строку? Вопросы над вопросами. Можно ли развернуть классификатор MNIST в ml5.js? Возможно, но я действительно не знаю, как.

Резюме: модель, включенная в ml5.js, была исключительно проста в использовании, но развертывание моей собственной модели практически невозможно. Интерфейс в каком-то смысле странный (на мой взгляд!), мне не дают инструкций, как импортировать модель Tensorflow, абсолютно нет служебных функций, облегчающих задачу, а ключевой параметр жестко запрограммирован и, по-видимому, не может быть изменен. .

Вывод

Вся эта статья читается как соленая тирада об этой конкретной библиотеке, но на самом деле это не мое намерение. Я знаю, что многие проекты с открытым исходным кодом разрабатываются волонтерами в свободное время, и я более чем благодарен за это. Но в последнее время я наткнулся на множество библиотек машинного обучения, которые рекламировались с такими лозунгами, как «Модель кода xy всего в 10 строках кода», «5 строк кода для модели SOTA компьютерного зрения — используйте фреймворк xy сейчас!» или что-то подобное. Это не то, чего я хочу. Конечно, для новичков в машинном обучении действительно приятно иметь модель из коробки, работающую в нескольких строках кода, но людям, которые действительно хотят применять эти фреймворки, нужны настраиваемость и гибкость — я бы лучше написал 50 строк. кода, чем 5, если это дает мне больше власти над моей моделью.