В своих проектах активно использую сверточные сети на базе фреймворка Caffe. Но они все работают в изолированных средах, а обмен данными идет либо через СУБД, либо через достаточно сложные http-сервисы.
Поэтому, пару недель назад тренируясь с питоном и caffe задумался как можно попроще запускать нейросеть на caffe для веб-сервиса на node.js. По сути задача сводится к запуску процесса по запросу.
Кому интересно — внутри коротко как это реализовал и ссылка на пример.
Для наглядности взял колоризатор черно-белых фото. Данная система написана на питоне и имеет входной тестовый скрипт colorize.py
.
Задача сводится к тому, чтобы по запросу запустить процесс с питоном, colorize.py
и аргументами, затем вернуть результаты. Для таких задач в node.js есть модуль child_process. В документации написано, что метод spawn() асинхронно запускает процесс с заданной командой, а это как раз то, что надо.
В нашем случае команда:
python ./colorize.py -img_in PATH_TO_MY_BW.PNG -img_out PATH_TO_MY_COLOR.PNG
Код для child_process
получается такой:
const spawn = require('child_process').spawn;
const arg = ['colorize.py', '-img_in', 'PATH_TO_MY_BW.PNG', '-img_out', 'PATH_TO_MY_BW.PNG'];
const py = spawn('python', arg);
py.stdout.on('data', (data) => {
console.log(`stdout: ${data}`);
});
py.stderr.on('data', (data) => {
console.log(`stderr: ${data}`);
});
py.on('close', (code) => {
console.log(`child process exited with code ${code}`);
});
Для обработки запросов использовал Express. Фронтенд — Angular. Весь исходный код можно посмотреть здесь. Конкретно сам обработчик находится здесь.
Может быть, я сам такой "зеленый", но данная задача была не совсем тривиальной для меня. Надеюсь кому-то данный пост сэкономит хоть какое-то время.
Комментарии (14)
napa3um
19.04.2017 14:02+1(И где-то у вас в коде проблема с параллельным доступом к сервису нескольких пользователей, похоже, — пытался раскрасить чёрно-белого Ленина, а в результате мне выдали фотографию Илона Маска. Подозреваю, что кто-то вместо меня получил Ленина.)
ooby
19.04.2017 14:08Для идентификации используется fingerprintjs. Разработчики уверяют, что точность достаточная для простого использования в веб-сервисах. Видимо, Вы крайне везучий на попадание в погрешности
napa3um
19.04.2017 14:11Вам не нужен никакой фингерпринт, достаточно просто аккуратнее обращаться с сессией. Помимо уверений разработчиков сторонних библиотек на качество реализации вашего сервиса влияют и ваши собственные компетенции программиста.
ooby
19.04.2017 15:38Вы не так поняли. Именно идентификация, а не сессия. Изначально подразумевал, что возможно нужно ограничивать по времени пользователя. Например, возможность обработки одной фотографии, в течении 10 минут.
Roman_Kh
19.04.2017 16:01Это вы не так поняли и сделали не так, как надо. Сейчас вы записываете обработанный файл в
/tmp/<fingerpint>.out.png
, но нет гарантий, что у двух разных пользователейfingerprint
не будет одинаковым. Что и произошло с napa3um. Вы отдали ему чужую картинку.ooby
19.04.2017 16:05да, тут согласен, нужно было сделать иначе, но вероятность такого исхода крайне небольшая, что меня и удивило
napa3um
«Простой веб-сервис, запускающий исполняемые файлы на сервере» — с таким заголовком разочарования вашей статьёй будет гораздо меньше.
ooby
Неужели сейчас есть надобность кому-то объяснять как ставить, настраивать и запускать свертку в каффе? По сути задача просто сводится к запуску процесса по запросу, что я и написал
napa3um
Если не считаете, что нужно, не объясняйте. Просто подбирайте более корректные заголовки к тому, что объясняете (неужели сейчас есть надобность кому-то объяснять как настраивать Node.JS и запускать из под неё дочерние процессы?).
ooby
я по себе судил, мне надо было объяснить как запускать из под ноды дочерние процессы
napa3um
Посудите теперь за других, которые привыкли выбирать себе статьи для чтения по заголовкам.
ooby
Убедили, сменил. Так больше подходит?
ooby
Добавил в текст до ката. Извиняюсь что так разочаровал
napa3um
Нейросетей в вашей статье нет, заголовок некорректен.