Распознавание рисованных символов с использованием TensorFlow.js

В первой части этой серии я представил глубокое обучение в JavaScript - мы выяснили, почему вам следует рассмотреть возможность использования Javascript для глубокого обучения, а затем перешли к созданию нейронной сети для прогнозирования областей, сильно пострадавших от лесных пожаров.

Как вы могли заметить, если вы читали первую часть или знакомы с TF.js иным образом, обучение и логический вывод происходили непосредственно в браузере. Хотя обучение в браузере может быть быстрым и эффективным для небольших наборов данных, оно быстро становится трудноразрешимым по мере масштабирования данных. В основном это связано с тем, что объем памяти, выделенный браузеру, минимален.

Чтобы использовать возможности глубокого обучения, особенно для задач восприятия, таких как распознавание изображений, обнаружение объектов или оценка позы, вам потребуется доступ к большей вычислительной мощности.

Чтобы решить эту проблему, нам нужно провести обучение на бэкэнде (на стороне сервера). Но вместо использования Python мы можем использовать версию узла TensorFlow.js (tfjs-node).

Эта версия TensorFlow.js (узел) может быть установлена ​​в среде узла и, по словам создателей, имеет доступ к низкоуровневой среде выполнения C ++, той же среде выполнения, что и в Python TensorFlow.

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

Ссылка на полный код

Чтобы создать эту демонстрацию, нам необходимо загрузить наборы данных рукописных цифр MNIST. Вы можете скачать его с Kaggle здесь.

Набор данных содержит 42 000 изображений в оттенках серого, которые были преобразованы в значения пикселей и сохранены в формате CSV. Каждая строка набора данных содержит 745 столбцов, причем первый столбец является меткой, а значение каждого пикселя имеет диапазон [0–255]. Мы собираемся создать сверточную нейронную сеть (CNN), которая поможет нам классифицировать эти цифры от 0 до 9.

Прежде чем мы продолжим, я предполагаю, что вы знакомы с CNN в целом и понимаете некоторые из основных концепций свертки, отсева и так далее. Если вы не понимаете этих концепций, я советую вам потратить немного времени, чтобы ознакомиться с ними, прежде чем переходить к следующим разделам. Вы можете найти хорошие уроки по этой теме здесь:





А теперь приступим!

Настройка вашего рабочего места

Во-первых, на вашем компьютере должен быть установлен Node.js. Если вы этого не сделаете, вы можете найти подробную информацию об установке на официальном сайте здесь.

Затем откройте терминал в каталоге вашего проекта и установите express-generator.

npm install -g express-generator

express-generator поможет нам быстро создать простое приложение Scaffold Node. Мы будем работать над этим, чтобы не беспокоиться о структуре каталогов.

Чтобы использовать express-generator, выполните следующую команду в своем терминале

express --view=handlebars mnist-classification

Вы можете настроить express-generator, установив механизм просмотра с помощью команды - view. Хотя мы не будем отображать представления в этом приложении, я предпочитаю использовать ручки по умолчанию.

Структура каталогов, созданная express-generator, показана ниже:

├── app.js
├── bin
│ └── www
├── package.json
├── public
│ ├── images
│ ├── javascripts
│ └── таблицы стилей
├── маршруты
│ ├── index.js
│ └── users.js
└── просмотры

Наше приложение будет состоять из двух частей. Бэкэнд для обучения и интерфейс для вывода. Файл app.js и другие скрипты (model.js и data.js), которые мы создадим в ближайшее время, будут обрабатывать весь прием данных и обучение модели, а файлы в общей папке будут обрабатывать пользовательский интерфейс и вывод модели.

Теперь создайте два дополнительных сценария (model.js и data.js) и папку набора данных (dataset) в корневом каталоге. Ваша структура каталогов теперь должна выглядеть так:

├── набор данных
├── app.js
├── bin
│ └── www
├── data. js
├── model.js
├── package.json
├── public
│ ├── images < br /> │ ├── javascripts
│ └── таблицы стилей
├── маршруты
│ ├── index.js
│ └── users.js
└── просмотров

Прежде чем продолжить, загрузите набор данных train из Kaggle и переместите его в папку набора данных.

├── набор данных
│ ├── train.csv

Затем давайте добавим в наше приложение пакет TensorFlow.js. Откройте файл package.json и добавьте зависимости @tensorflow/tfjs-node и argparse, как показано ниже:

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

Затем давайте посмотрим на сценарии обучения моделей и разберемся с их функциями.

Основная точка входа в наше приложение (app.js)

Файл app.js - это точка входа нашего приложения в серверную часть. Он принимает и анализирует аргументы обучения, такие как количество эпох, путь сохранения модели и т. Д., И вызывает соответствующие функции для начала обучения модели.

  • Первый набор из шести строк кода в основном require все пакеты, которые мы будем использовать. Они автоматически добавляются пользователем express-generator. В следующей строке требуется пакет модели, который мы вскоре увидим.
  • Все строки кода перед разделом argparse генерируются экспрессом и в основном используются для визуализации представления и анализа объектов запроса.
  • Следующая часть - это аргументы парсера. Здесь мы используем argparse библиотеку для require некоторых аргументов командной строки. В частности, вы можете указать размер эпохи (— epochs) и размер пакета ( — batch_size), указать, следует ли обучать модель без разделения на обучающие и тестовые наборы или нет (— train_mode), и, наконец, указать путь к локальному файлу для сохранения обученной модели в (— model_save_path).

Получение данных и их предварительная обработка (data.js)

Файл data.js обрабатывает все, что связано с приемом и подготовкой данных. Здесь мы воспользуемся tf.data.csv в TensorFlow для чтения наших данных. Скопируйте и вставьте код ниже:

  • Сначала (и это важно) мы require пакет TensorFlow. Мы будем использовать это для чтения и обработки набора данных CSV.
  • Затем мы устанавливаем полный путь к файлу набора данных. Полный путь к файлу (включая префикс «file: //») важен; в противном случае TensorFlow выдаст ошибку при чтении файла.

Обратите внимание, что каждая ОС имеет свой формат пути к файлу. Обязательно добавьте тот, который подходит для вашей установки. Я использовал Ubuntu для этого урока.

  • Затем мы устанавливаем некоторые важные параметры для нашего набора данных. Набор данных MNIST содержит 28 x 28 изображений в оттенках серого. Это означает, что если мы будем выполнять свертку для каждого изображения с помощью CNN, нам придется изменить форму каждого изображения до 28 x 28 x 1, что соответствует высоте x ширине x каналу.
  • Затем мы устанавливаем количество классов, которые мы прогнозируем (10), общий размер набора обучающих данных и размер удерживаемого теста.
  • Затем мы создаем два пустых массива для хранения обработанных данных и меток.
  • В следующем блоке кода мы загружаем набор данных CSV, передавая путь к данным функции tf.data.csv. Мы указываем цель набора данных как столбец (метка), и это инструктирует TensorFlow извлечь цель в отдельный массив. Затем мы вызываем функцию обработки для каждой строки в файле CSV.
  • Функция обработки просто извлекает функции, называемые xs в TensorFlow.js, и цель (ys). Затем он отправляет их в массивы, которые мы инициализировали ранее.
  • Затем мы превращаем функциональность набора данных в класс. Это обеспечивает чистый API для загрузки и извлечения набора данных. В функции loadData созданного нами Mnistclass мы выполняем важную предварительную обработку:

Сначала мы выделили набор для поезда и тестирования из массива функций, затем изменили форму обоих наборов, чтобы они имели форму [size, 28,28,1], где размер зависит от чисел, которые мы указали ранее. В моем случае я указал 38000 для обучения и 4000 для тестирования. Это означает, что обучающий набор данных будет иметь форму тензора [48000, 28,28,1], в то время как набор тестов будет иметь форму [4000, 28,28,1].

Затем мы горячо закодировали цели. Поскольку у нас 10 классов, мы будем использовать функцию вывода softmax в нашей CNN. Таким образом, цель должна быть закодирована в горячем режиме, чтобы иметь 10 классов.

Создание и обучение модели (model.js)

В файле model.js находится наш CNN. Здесь мы создаем модель, проводим обучение и оценку, а затем сохраняем ее в указанной папке. Давайте рассмотрим код ниже:

  • Сначала мы импортируем пакет TensorFlow, так как это поможет нам создать модель CNN. Затем мы require модуль данных, который будет использоваться для передачи данных в нашу модель.
  • Далее мы создаем функцию getModel. Эта функция помогает нам создавать CNN. CNN имеет 2 сверточных слоя и следующий за ним слой maxpool. После пары conv-maxpool мы добавляем плоский слой. Затем мы указываем размер фильтра и индивидуальные размеры ядра.

Обратите внимание на форму ввода. Здесь мы указываем ширину, высоту и канал изображения, то есть [28,28,1]. Эта архитектура определенно не оптимальна, и ее можно изменить или настроить.

  • После сглаживания слоя мы добавляем выпадающий слой, чтобы помочь обуздать переоснащение, а затем передавали результат на плотный слой с 512 нейронами. И, наконец, мы добавили наш выходной слой и использовали функцию активации softmax.
  • Затем мы компилируем модель, указывая используемый оптимизатор (rmsprop), функцию потерь - категориальную кросс-энтропию, поскольку мы прогнозируем более двух классов - и, наконец, точность в качестве нашей метрики.
  • В последней функции (trainModel) мы сначала инициализируем класс набора данных MNIST, который мы создали ранее, а затем загружаем данные и соответствующие им метки.
  • Далее мы подтверждаем, установлен ли режим обучения на полный или нет. В режиме частичного обучения (0) мы разделяем набор данных на отдельные обучающие и тестовые наборы и вычисляем метрику оценки. Это помогает нам точно настроить сеть. В полном режиме (1) мы используем весь набор данных для обучения CNN, а затем сохраняем его в указанной папке.

Вы должны устанавливать train_mode на 1 только в том случае, если вас устраивает результат тренировки в частичном режиме.

Частичное обучение модели (train_mode = 0)

Функция режима частичного обучения содержит следующее:

  • Метод fit, который принимает такие параметры, как эпохи и размер пакета, полученные из аргументов командной строки, и выполняет обучение модели. Обратите внимание на параметр ValidationSplit? Он информирует TensorFlow о процентном соотношении данных из поезда, которое нужно отложить для проверки. Здесь мы указываем 20% данных.
  • Затем мы добавили обратный вызов, который печатает точность как для поезда, так и для набора проверки в конце каждой эпохи во время частичного обучения.
  • Затем мы оцениваем модель после завершения обучения. Оценка проводится на тестовом наборе, который модель еще не видела (проверка). Также выводим результат в консоль.

Полное обучение модели (train_mode = 1)

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

Вот и все! Теперь готов весь код, необходимый для обучения и сохранения модели. Далее приступим к тренировкам.

В вашем терминале, открытом в корневом каталоге вашего приложения, введите следующие команды, чтобы начать частичное обучение:

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

Прежде чем приступить к полноценному обучению, сначала необходимо создать новую папку в общедоступном каталоге под названием assets. В папке assets создайте еще одну папку с именем model. Здесь мы сохраним файл нашей обученной модели. Это также гарантирует, что у нас есть доступ к файлам модели во внешнем интерфейсе.

├── общедоступные
│ ├── активы
│ │ └── модель

Затем получите полный путь к папке модели. В большинстве ОС это можно получить, щелкнув папку правой кнопкой мыши и скопировав ссылку на путь.

Если вы, как и я, используете VSCode, вы можете получить полный путь, щелкнув правой кнопкой мыши папку модели и выбрав C opy Path.

Затем в терминале установите train_mode на 1 и укажите путь к модели, который вы скопировали, как показано ниже:

Важно добавить префикс «file: //» к вашему model_save_path; в противном случае TensorFlow выдаст ошибку.

Теперь сядьте, расслабьтесь и наблюдайте за своей моделью поезда.

Когда обучение будет завершено, модель будет сохранена по указанному пути. Вы должны увидеть файл model.json и файл weights.bin.

Поздравляю! Вы только что обучили сверточную нейронную сеть на большом наборе данных рукописных изображений с помощью TensorFlow.js в среде Node.

В следующем посте я покажу вам, как подключить интерфейс этого приложения и использовать сохраненную модель для быстрого вывода в реальном времени. В качестве дополнительной функции мы создадим холст ввода, на котором мы сможем нарисовать число и предсказать его класс с помощью TensorFlow.js.

Если у вас есть какие-либо вопросы, предложения или отзывы, не стесняйтесь использовать раздел комментариев ниже. Пока что оставайтесь в безопасности и продолжайте учиться!

Свяжитесь со мной в Твиттере.

Свяжитесь со мной в LinkedIn.

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

Независимая редакция, Heartbeat спонсируется и публикуется Comet, платформой MLOps, которая позволяет специалистам по обработке данных и группам машинного обучения отслеживать, сравнивать, объяснять и оптимизировать свои эксперименты. Мы платим участникам и не продаем рекламу.

Если вы хотите внести свой вклад, отправляйтесь на наш призыв к участникам. Вы также можете подписаться на наши еженедельные информационные бюллетени (Deep Learning Weekly и Comet Newsletter), присоединиться к нам в » «Slack и подписаться на Comet в Twitter и LinkedIn для получения ресурсов, событий и гораздо больше, что поможет вам быстрее и лучше строить модели машинного обучения.