Я давно думал о создании API, который другие разработчики могли бы использовать в облаке. Но я не хотел, чтобы это был традиционный Hello World API или простой SQL Flask API, поддерживающий классические запросы GET, PUT, POST, DELETE REST для имени пользователя и электронной почты. Поскольку AI и ML сейчас настолько распространены, я подумал о том, чтобы попробовать ML - и это легко :)
Классификация изображений с помощью PyTorch
Поскольку все в облаке и бесплатные версии, мне нужен был проект AI / ML с небольшими легковесными зависимостями для облака. Я разветвил проект под названием Img2vec, который использует PyTorch для генерации векторов признаков для набора данных изображений, а затем выполняет простое сопоставление (косинусное сходство в sklearn) тестового изображения с другими, используя предварительно обученные модели. . В файле readme достаточно фрагментов, чтобы демонстрация работала в вашей системе.
Обучение набора данных изображения
Для простоты я пропускаю часть обучения по набору данных - в Интернете есть много документации. Для нашего API я создаю векторы изображений и сохраняю их как файлы csv. Поскольку вычисления будут происходить в облаке, если мы сгенерируем векторы во время выполнения, API всегда будет тайм-аут. Но API сгенерирует вектор для данных изображения, которые вы будете пинговать, и прочитает другие векторы из файлов csv.
Настройка приложения Flask
Для простого сопоставления изображений мне понадобился запрос POST или PUT. Есть много фреймворков, поддерживающих функции REST, я использовал flask на Python 3.6. Как гласит официальный сайт
Flask - это легкий фреймворк для веб-приложений WSGI. Он разработан для того, чтобы начать работу быстро и легко
Итак, идея такая:
- Сервер получает изображение в виде байтового потока.
- Эти байты кодируются обратно в изображение с помощью Pillow в Python.
- Для этого изображения создается вектор признаков.
- Этот вектор сопоставляется с изображениями обучающих данных.
- Самые близкие подходящие изображения возвращаются обратно (с URL-адресом загрузки и значением процентного соответствия)
Вот суть API:
# endpoint to detect image @app.route("/image_clustering", methods=["PUT"]) def image_clustering(): # Image converted in Base64 encoded byte stream bytes = request.get_data() results = search(bytes) # returns a list of image matches return jsonify(results)
Примечание. Опубликованное тестовое изображение не является обычным байтовым потоком, это его байтовый поток изображения в кодировке base64 - стандартный способ доставки двоичных данных по сетям.
Примечание: исходный код можно получить здесь.
Настройка сервера Heroku
Настроить сервер довольно просто, но я столкнулся с несколькими проблемами:
- Размер слага. Heroku предоставляет максимальный размер слага 500 МБ - общий объем данных, которые приложение может хранить (код, исполняемые файлы и мультимедийные файлы, такие как изображения, PDF-файлы) после сжатия. Это проблема, поскольку библиотеки Python, такие как SciPy и PyTorch, довольно большие по размеру - PyTorch с CUDA 8 занимает около 600 МБ. Но есть обходные пути.
- Версия PyTorch. PyTorch предоставляет вариант сборки только для ЦП, небольшую библиотеку размером 45 МБ, обеспечивающую все функции, необходимые для развертывания.
- Ручная установка SciPy: Не знаю почему, но онлайн-установка SciPy на Heroku оказывается некорректной (подробнее здесь). Вместо этого я загрузил SciPy whl (или исходный код) в виде файла и вручную установил его на сервер.
- JPEG против PNG: В демонстрационном коде я использовал файлы расширения JPEG (с данными в кодировке base64, начинающимися с / 9j / 9…). Поэтому, если вы отправите эхо-запрос на сервер с изображениями в других форматах, например PNG (данные в кодировке base64 начинаются с iVi…), вы получите сообщение об ошибке.
Демо-время
Вы можете пройти демо разными способами
- Вы можете установить приложение (получить здесь) на свое устройство Android. Нажмите на изображение, это займет некоторое время, и будут отображены наиболее подходящие изображения.
- Вы можете использовать этот скрипт на питоне. Просто введите относительный путь к изображению на рабочем столе, и он отобразит результаты.
- Вы можете сделать PUT-запрос онлайн (я рекомендую Hurl.it для начинающих) к этому URL-адресу с данными изображения в кодировке base64 в качестве тела.
Для показанного образца изображения кошки результаты следующие:
[ [ 0.8155140106062471, "https://www.googleapis.com/download/storage/v1/b/python-clustering-api.appspot.com/o/images%2FFace%2F124.jpg?generation=1522585329188523&alt=media" ], [ 0.8145577585207011, "https://www.googleapis.com/download/storage/v1/b/python-clustering-api.appspot.com/o/images%2FFace%2F242.jpg?generation=1522585299229997&alt=media" ], [ 0.7914929138145477, "https://www.googleapis.com/download/storage/v1/b/python-clustering-api.appspot.com/o/images%2FFace%2F212.jpg?generation=1522584727478100&alt=media" ], [ 0.7806927914191767, "https://www.googleapis.com/download/storage/v1/b/python-clustering-api.appspot.com/o/images%2FFace%2F099.jpg?generation=1522585251917855&alt=media" ], [ 0.6948463995381056, "https://www.googleapis.com/download/storage/v1/b/python-clustering-api.appspot.com/o/images%2FFace%2F119.jpg?generation=1522584693369035&alt=media" ] ]
Если статья вам помогла, я хочу пару аплодисментов. Не стесняйтесь комментировать, если у вас возникнут проблемы.
Следите за мной и будьте в курсе моих новых сообщений: Medium, Github, Facebook, Twitter или LinkedIn.