Сегодня мы собираемся создать RESTFUL API, который принимает изображение и делает прогнозы с использованием предварительно обученной модели TensorFlow M obileNet.
В TensorFlow.js есть множество предварительно обученных моделей, которые можно использовать в проектах из коробки. Это избавляет разработчиков от необходимости обучать модель с нуля. Здесь мы собираемся изучить предварительно обученную архитектуру MobileNet.
Разработка
Если вы еще не установили NodeJs на свой компьютер, перейдите по этой ссылке, чтобы загрузить и установить.
Откройте свой терминал и следуйте инструкциям ниже.
- Вставьте и запустите команду ниже, чтобы:
- Создайте папку.
- Перейдите в папку.
- И инициализируйте новый проект, который создает файл package.json.
mkdir image-classifier-api && cd image-classifier-api && npm init --yes
2. Не выходя из терминала, выполните следующую команду для установки зависимостей:
npm i express logger @tensorflow-models/mobilenet @tensorflow/tfjs get-image-data multer morgan nodemon jimp cors --save
3. Откройте вновь созданную папку в любом редакторе кода по вашему выбору.
4. Создайте файл с именем app.js в корне папки и вставьте следующий код:
const express = require('express'); const logger = require('morgan'); const cors = require('cors'); const app = express(); const corsOptions = { origin: '*', }; app.use(logger('dev')); app.use(express.json()); app.use(cors(corsOptions)); app.use(express.urlencoded({ extended: false })); app.get('/', (req, res) => { res.send('Image Classifier API') }); PORT = process.env.PORT || 3000; app.listen(PORT); console.log(`Running server at http://localhost:${PORT}`);
Приведенный выше код создает новый сервер узла для запуска нашего приложения.
5. Откройте файл package.json и добавьте эту задачу в свойство script:
"start": "nodemon app.js"
Также измените основной скрипт на app.js.
Файл package.json должен выглядеть так:
6. На вашем терминале запустите npm start.
. Это запустит сервер, вы должны увидеть сообщение консоли Запуск сервера по адресу« http: // localhost: 3000 .»
7. Создадим каталоги. Вернувшись в терминал в корне проекта, выполните следующие команды:
mkdir routes && mkdir controllers && mkdir images
8. Перейдите в папку контроллеры и создайте новый файл с именем pred.controller.js. Также перейдите в папку routes и создайте новый файл под названием pred.route.js.
9. В файл pred.route.js вставьте следующий код:
const express = require('express'); const multer = require('multer'); const controller = require('../controllers/predict.controller'); // configure multer const storage = multer.diskStorage({ destination: (req, file, callback) => { callback(null, 'images'); }, filename: (req, file, callback) => { callback(null, 'test-image.jpg'); }, }); const imageFileFilter = (req, file, callback) => { if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) { return callback(new Error('You can upload only image files'), false); } callback(null, true); }; const upload = multer({ storage, fileFilter: imageFileFilter }); const router = express.Router(); router.route('/').post(upload.single('file'), controller.makePredictions); module.exports = router;
В приведенном выше коде мы настраиваем multer для обработки входного изображения и сохранения его в папке / image. Изображение переименовано в test-image.png для удобства чтения в нашем файле контроллера. Затем мы создаем экспресс-маршрутизатор, включающий многопользовательское промежуточное программное обеспечение, и вызываем функцию makePredictions, которую мы создадим дальше.
9. Теперь мы сделаем три вещи:
- Загрузите модель MobileNet.
- Прочтите файл необработанного изображения и преобразуйте его пиксельные данные в Tensor.
- Удалите файл, чтобы освободить место.
Откройте файл pred.controller.js и вставьте следующий код:
const tf = require('@tensorflow/tfjs'); const mobilenet = require('@tensorflow-models/mobilenet'); const image = require('get-image-data'); const fs = require('fs'); exports.makePredictions = async (req, res, next) => { const imagePath = './images/test-image.jpg'; try { const loadModel = async (img) => { const output = {}; // laod model console.log('Loading.......') const model = await mobilenet.load(); // classify output.predictions = await model.classify(img); console.log(output); res.statusCode = 200; res.json(output); }; await image(imagePath, async (err, imageData) => { // pre-process image const numChannels = 3; const numPixels = imageData.width * imageData.height; const values = new Int32Array(numPixels * numChannels); const pixels = imageData.data; for (let i = 0; i < numPixels; i++) { for (let channel = 0; channel < numChannels; ++channel) { values[i * numChannels + channel] = pixels[i * 4 + channel]; } } const outShape = [imageData.height, imageData.width, numChannels]; const input = tf.tensor3d(values, outShape, 'int32'); await loadModel(input); // delete image file fs.unlinkSync(imagePath, (error) => { if (error) { console.error(error); } }); }); } catch (error) { console.log(error) } };
Приведенный выше код сначала создает функцию makePrediction, которая включает функцию, которая загружает модель MobileNet и выводит прогнозы для параметра изображения. Затем мы читаем и декодируем данные изображения с помощью пакета get-image-data. Этот пакет декодирует ширину, высоту и двоичные данные изображения. После этого мы извлекаем значения пикселей изображения и преобразуем их в тензор. Затем мы вызываем функцию loadModel и передаем данные тензора изображения, чтобы сделать прогнозы. После этого удаляем файл изображения из памяти.
10. Наконец, давайте обновим файл app.js, добавив следующий код непосредственно над строкой PORT = process.env.PORT || 3000;
const predictRouter = require('./routes/predict.route') app.use('/predict', predictRouter);
Здесь мы импортируем прогнозируемый маршрут и предоставляем его в конечной точке / прогнозируемой.
Для тестирования API воспользуемся почтальоном, скачать здесь. Убедитесь, что ваш сервер запущен, запустите npm start
, чтобы запустить сервер.
Откройте почтальон и введите http: // localhost: 3000 / прогноз в разделе URL-адреса запроса, измените метод на POST, щелкните вкладку Body и выберите form-data . Нажмите кнопку раскрывающегося списка в разделе ключ и выберите Файл.
Введите значение «файл» в качестве ключа и нажмите «Выбрать файлы», чтобы загрузить файл изображения в качестве значения.
Нажмите кнопку Отправить. Через некоторое время вы должны увидеть следующее сообщение консоли:
Я выбрал изображение с гитарой, отсюда и результат.
ПРИМЕЧАНИЕ. Весь процесс занимает примерно 63 секунды и по умолчанию дает три лучших прогноза. Мы можем изменить это, передав параметр topk с числовым значением при вызове метода classify модели.
Также вы заметите сообщение в консоли, потому что я использовал пакет TensorFlow tfjs, у которого теперь есть альтернативный пакет для NodeJS здесь. К сожалению, он не поддерживает 32-битные машины, согласно T EnsorFlow.
Если вы работаете на 64-битной машине, вам нужно будет внести некоторые изменения, сначала при запуске терминала npm i @tensorflow/tfjs-node.
, а затем в файле прогноз.controller.js обновите файл tf переменная в const tf = require('@tensorflow/tfjs-node').
Развертывание
Наш API готов к развертыванию! См. Полный проект на моем github здесь
Я буду развертывать проект на Heroku. Вы можете выполнить следующие действия.
- Если у вас нет учетной записи Heroku, зарегистрируйтесь здесь.
- Следуйте статье здесь, чтобы установить и настроить Heroku CLI.
- Клонируйте проект repo, потому что я добавил несколько изменений, таких как файл .gitignore и файл README.md, чтобы при постановке оставалась пустая папка / images.
- Откройте терминал и перейдите в папку клонированного проекта.
- Вставьте следующую команду и запустите.
git init && git add . && git commit -m “initial project commit” && heroku create && heroku apps:rename image-clf-api
Команда инициализирует пустой локальный репозиторий git, куда вы можете добавить все файлы проекта и выполнить фиксацию. Затем он создает новое приложение Heroku и переименовывает его в image-clf-api.
У вас должен быть результат, аналогичный изображенному ниже:
Наконец, давайте запустим следующую команду для развертывания на Heroku:
git push heroku master
Теперь протестируем наш живой API в почтальоне.
В предыдущем окне почтальона замените URL-адрес на https://image-clf-api.herokuapp.com/predict и нажмите Отправить. Теперь вы должны получать прогнозы за меньшее время. Примерно 17 секунд здесь.
Мы также можем протестировать это в веб-среде. Создайте файл index.html в любом каталоге и вставьте приведенный ниже код.
<!DOCTYPE html> <html lang="en"> <body> <form name="myForm" method="post" enctype="multipart/form-data"> Select Image: <input type='file' name='file' id='image-upload'> <button type='submit' id="submit-btn">Submit</button> </form> <div id="result"></div> <script> const button = document.querySelector('#submit-btn') button.addEventListener('click', async (e) => { e.preventDefault(); const URL = 'https://image-clf-api.herokuapp.com/predict' const image = document.querySelector('#image-upload'); const resultDiv = document.querySelector('#result') const formData = new FormData(); formData.append("file", image.files[0]); const response = await fetch(URL, { method: 'POST', body: formData }); const result = await response.json(); resultDiv.innerHTML = JSON.stringify(result.predictions); console.log(result); }); </script> </body> </html>
Откройте файл в любом браузере, загрузите изображение и нажмите Отправить.
Заключение
Я надеюсь, что эта статья послужила целью дать вам фору в понимании того, как реализовать модели Tensorflow.js в NodeJS. API можно настроить для использования в любых клиентских приложениях и для любых моделей концентраторов TensorFlow.
Свяжитесь со мной в Твиттере здесь
Примечание редактора. Heartbeat - это онлайн-издание и сообщество, созданное авторами и посвященное предоставлению первоклассных образовательных ресурсов для специалистов по науке о данных, машинному обучению и глубокому обучению. Мы стремимся поддерживать и вдохновлять разработчиков и инженеров из всех слоев общества.
Независимо от редакции, Heartbeat спонсируется и публикуется Comet, платформой MLOps, которая позволяет специалистам по данным и группам машинного обучения отслеживать, сравнивать, объяснять и оптимизировать свои эксперименты. Мы платим участникам и не продаем рекламу.
Если вы хотите внести свой вклад, отправляйтесь на наш призыв к участникам. Вы также можете подписаться на наши еженедельные информационные бюллетени (Deep Learning Weekly и Comet Newsletter), присоединиться к нам в » «Slack и подписаться на Comet в Twitter и LinkedIn для получения ресурсов, событий и гораздо больше, что поможет вам быстрее и лучше строить лучшие модели машинного обучения.