Да и вообще, можно ли создать сервис, уверенно распознающий котов с учётом присущего последним стремления принять самую неожиданную позу? Давайте попробуем.
Для решения поставленной задачи была выбрана PaaS-платформа IBM Bluemix, которая объединяет около сотни различных сервисов на все случаи жизни. Там есть отдельная группа Watson, содержащая различные инструменты для решения задач когнитивных вычислений – очень похоже на то, что нам нужно.
Среди сервисов Watson обнаружилось нечто под названием AlchemyAPI, что, в свою очередь, выглядит как универсальный набор когнитивного алхимика, представленный в виде унифицированных REST API. И там есть API для Image Tagging. API очень простой. Просто передаём ему изображение либо в виде файла, либо в виде URL, а он возвращает JSON c набором тегов и коэффициентов релевантности. То есть всё, что нужно будет сделать, это написать небольшой сервис, который будет получать файл с картинкой, отправлять его AlchemyAPI и говорить нам, что в результате получилось.
Разработка была на питоне, в качестве HTTP-сервера взяли Tornado. В принципе, можно взять любой другой, просто к Tornado я привык и на нём все получается просто и быстро.
Теперь нам нужно создать условия для разработки нашего приложения. Сделаем это таким образом, чтобы писать и отлаживать код можно было на своём компьютере, а затем перенести то, что получилось в облако Bluemix не внося никаких дополнительных изменении.
Начнем с того, что создадим под нашим аккаунтом на Bluemix рабочую среду на питоне. Если у вас ещё нет аккаунта, зарегистрируйтесь – это быстро, бесплатно и без СМС. Идём в раздел Dashboard и нажимаем Create App, затем выбираем тип приложения Web и получаем список доступных сред для работы нашего сервиса (нам нужен Python). Добавляем сервису имя (я назвал его catreco) и где-то через полминуты вы увидите, что среда создана, и там находится Hello World посмотреть на который можно по ссылке http://catreco.mybluemix.net.
Теперь пора заняться делом. Bluemix предлагает два способа сихронизации рабочей среды между локальным компьютером и облаком: интерфейс командной строки CF и привычный большинству из нас GIT, который мы и выберем. В меню слева нажимаем на Overview и попадаем на страницу нашего приложения. Нажимаем кнопку Add GIT и у нас появляется GIT URL, указывающий на только что созданный репозиторий, содержащий Hello World.
Сам по себе Hello World мало интересен, однако, репозиторий содержит несколько полезных файлов, необходимых для развертывания нашего приложения в облаке.
Склонируем этот репозиторий на наш компьютер:
git clone <адрес репозитория>
Нам понадобятся следующие файлы (остальное можно удалить):
manifest.yml,
Procfile,
requirements.txt.
Теперь дело за нашим сервисом-распознавателем. Его код я выложил сюда. Загрузите его на свой компьютер и скопируйте содержимое в папку catreco. В самом коде нет ничего заслуживающего особого внимания – лишь несколько десятков строк, поэтому я не буду его подробно комментировать. Хотя и есть несколько нюансов.
Во-первых, нужно подключить сервис AlchemyAPI, для чего возвращаемся на Bluemix в раздел Dashboard и нажимаем кнопку Use Services or APIs, а затем выбираем сервис AlchemyAPI. На странице конфигурации сервиса указано, что нужно создать аккаунт на самом AlchemyAPI – заходим по ссылке, создаём аккаунт и получаем на почту ключ. Этот ключ нужно скопировать в переменную APIKEY в файле webserver.py. На этом конфигурацию сервиса можно считать законченной.
Во-вторых, при запуске HTTP-сервера в своей рабочей среде Bluemix использует специальный порт, отличный от 80-го и уже затем, с помощью внутренних механизмов маршрутизации, позволяет вам обращаться к вашему приложению по 80 порту. Нужно это предусмотреть в коде сервера webserver.py:
PORT = int(os.getenv('VCAP_APP_PORT', 8080))
…
application.listen(PORT)
То есть если мы находимся в среде Bluemix, то сервер будет запущен по порту, содержащемуся в переменной 'VCAP_APP_PORT', а с локальной машины по порту 8080 или тому, который будет удобен. В большинстве случаев, это единственная специфическая настройка, которую вам нужно предусмотреть при переносе вашего кода в среду Bluemix.
В третьих, нужно подготовить среду на Bluemix к запуску нашего приложения. В данный момент там есть только python 2.7.8 и стандартные библиотеки, а нам нужно ещё установить Tornado и модуль requests, объяснить Bluemix какой файл должен быть запущен. За это и отвечают файлы, которые мы забрали из Hello World.
Файл manifest.yml содержит конфигурацию нашей рабочей среды. Здесь мы ничего менять не будем:
applications:
- disk_quota: 1024M
host: catreco
name: catreco
path: .
domain: mybluemix.net
instances: 1
memory: 128M
Файл Procfile содержит информацию о том, какой командой запускать наше приложение. Наш исполняемый файл называется webserver.py, поэтому пишем:
web: python webserver.py
Файл requirements.txt содержит список модулей, которые должны быть установлены в рабочей среде. Увидев этот список, Bluemix запустит pip и установит всё необходимое:
tornado>=4.0
requests>=2.7
На этом подготовка закончена. Мы сконфигурировали внешний сервис AlchemyAPI, учли особенности среды Bluemix при запуске HTTP-сервера и задали необходимые параметры для развёртывания нашего приложения в облаке.
Попробовать запустить приложение можно на локальной машине, для чего в командной строке пишем python webserver.py и набираем в браузере заветный localhost:8080
То есть то, что лежит у меня на коленях, является котом с вероятностью 91%. Я пробовал другие ракурсы, брал картинки из сети – работает! Так что дело за малым – перенестись в облака. В папке, куда мы сначала склонировали Hello World, а затем разместили код нашего проекта, уже есть всё необходимое – дальще просто обновляем локальный репозиторий:
git add .
git commit –m "first deployment"
И отправляем его обратно на Bluemix:
git push
Bluemix проделает все необходимые операции по сборке нового приложения (вместо Hello World теперь будет наш код) и запустит его. Как только статус нашего приложения станет Your app is running, можно пойти по ссылке http://catreco.mybluemix.net/ и убедиться, что наш сервис работает в облаке, его можно попробовать с любого устройства. Красивый плагин для загрузки файлов взят отсюда.
Примеры работы:
Cat — 94%
Cat — 48%, pet — 63%
Cat — 89%, rabbit — 80%
Cat — 99%, kitten — 50%
Cat — 71%, dog — 59%
Предыдущая картинка похожа на тигра, при этом: tiger — 99%, cat — 75%
Dog — 99%, puppy — 68%
Dog — 99%
Cat — 99%, dog — 57%
Cat: 99%
Cat — 65%, eagle — 43%
Если вы где-то ошиблись и что-то пошло не так – don’t panic. Над статусом вашего приложения на панели Bluemix есть волшебная кнопка Edit Code, нажатие которой перенесёт вас в сервис DevOps, где есть редактор кода, средства управления репозиторием и построением билдов, а также доступ ко всем логам. Сервис большой и его описание займёт больше времени, чем весь наш проект – если и потребуется, то обратитесь к документации.
Вместо вывода:
- Мы научились распознавать котов с помощью простого веб-приложения и сервиса, предоставляемого платформой Bluemix;
- Мы теперь знаем, как подготовить приложение для размещения в облаке Bluemix и как, собственно, разместить его с помощью одной команды git;
- Мы знаем куда смотреть если что-то пошло не так;
- Как вы уже поняли, дело может не ограничиваться только лишь котами.
По-моему, неплохо для одного дождливого утра? Расчехляйте папки с котиками, пробуйте. Котики, мотайте на ус, как теперь лучше маскироваться.
UPD:
Сервисы от пользователей (если вдруг кончился лимит):
le_den catreco.eu-gb.mybluemix.net
inwardik rcat.mybluemix.net
Петр П. (аккаунта нет, скинул в ВК) 2catreco.mybluemix.net
Спасибо вам, что не остались в стороне :) Проблема распознавания котов действительно очень важна.
Комментарии (43)
impwx
17.07.2015 18:11+5Отличный пятничный пост.
Правда, сервису не под силу найти серую кошку в тёмной комнатеНа этой фотографии вообще не находит ничего:
tishka87
17.07.2015 18:11+27> Проблемой распознавания котов на изображениях нельзя пренебрегать.
Вы сделали мой день!
Rasalom
17.07.2015 18:13+6Хотел узнать насколько я кот, загрузил фотографию, а там: «person: 0.999447». расстроился.
le_den
17.07.2015 18:17Отличный и полезный сервис! Но первая же попытка распознать кота обернулась неудачей:
Traceback (most recent call last): File "/app/.heroku/python/lib/python2.7/site-packages/tornado/web.py", line 1413, in _execute result = method(*self.path_args, **self.path_kwargs) File "webserver.py", line 41, in post r = results.json() File "/app/.heroku/python/lib/python2.7/site-packages/requests/models.py", line 819, in json return json.loads(self.text, **kwargs) File "/app/.heroku/python/lib/python2.7/json/__init__.py", line 338, in loads return _default_decoder.decode(s) File "/app/.heroku/python/lib/python2.7/json/decoder.py", line 366, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "/app/.heroku/python/lib/python2.7/json/decoder.py", line 384, in raw_decode raise ValueError("No JSON object could be decoded") ValueError: No JSON object could be decoded
скриншот:
urticazoku
17.07.2015 18:18+1Вот ведь, не распознает — знает, видимо, что это не кот =)
bachin
17.07.2015 18:40+21Это не кот! Три цвета — значит это кошка!
ilmirus
18.07.2015 01:37+5Не всё так просто:
«Обычно коты имеют одну X-хромосому и одну Y-хромосому, поэтому практически невозможно, чтобы у кота встречались одновременно два пигмента: оранжевый феомеланин и чёрный эумеланин. Существует единственное исключение: когда, в очень редких случаях, коты имеют набор половых хромосом XXY, они могут иметь черепаховый, или трёхцветный окрас. Большинство таких котов стерильны вследствие аномалии, связанной с наличием двух X-хромосом»
Источник: ru.wikipedia.org/wiki/Трёхцветная_кошка
IRainman
18.07.2015 10:50+1Это правда не кот! По сюжету лишь немного похож, Natsume’s Book of Friends (яп. ????? Нацумэ Ю: дзинтё:, рус. неоф. «Тетрадь друзей Нацумэ»), но 100% не кот и даже не кошка, к слову.
Lock_Stock Автор
17.07.2015 19:14+1Друзья, запросов очень много, поэтому вылетают ошибки)
Будет неплохо, если кто-то используя туториал развернет аналогичный сервис у себя и поделится в комментах, чтобы все могли распознать котиков и прочую живность :)
victor1234
17.07.2015 20:32Как работает сам сервис? Там каскадные классификаторы на все случаи жизни?
Seboreia
18.07.2015 01:16Странно, у меня почему-то висит на 98ми %. Причем и на catreco.eu-gb.mybluemix.net и на catreco.mybluemix.net
Скрины
Samber
18.07.2015 02:37daily-transaction-limit-exceededPerlPower
18.07.2015 11:42+2То что кот в маске бэтмена на 99% определяется как кот заставляет думать, что эту фотографию движку таки скармливали в процессе обучения сам ibm-овцы, а потом еще подгоняли под нее коэфициенты.
inwardik
18.07.2015 20:40Автору огромное спасибо. Интересно, доходчиво и познавательно.
Зарегистрировался, перенес Ваш шаблон — все равно «проблема 98%» имеет место. Кнопка «загрузить» на фотографии загружает полностью, но результаты не выводятся. «Загрузить» снизу — 98% и дальше не идет. Похоже, проблема не в бесплатном лимите.inwardik
19.07.2015 09:04Разобрался (спасибо Пётру). В AlchemyAPI ключ добавил, а в webserver.py он у меня не сохранился. Так что 98% — это ограничения AlchemyAPI.
Теперь работает.
rcat.mybluemix.net
Lock_Stock Автор
19.07.2015 11:35+1В конце поста добавил несколько аналогичных сервисов от сообщества! Спасибо что не остались в стороне в отношении столь важной темы :)
Jimilian
19.07.2015 13:32+2Моя кошка - личность!flycat
22.07.2015 13:01-таки это — конь!
Wedmer
22.07.2015 13:25+1<Error> <Code>AccessDenied</Code> <Message>Request has expired</Message> <Expires>2015-07-22T10:06:02Z</Expires> <ServerTime>2015-07-22T10:24:29Z</ServerTime> <RequestId>1A26B2605307079A</RequestId> <HostId>N3wdNuKIaywiZolQck+x+91bOg+2HiK3pmSGRWVcrp11U3YO0SGUqLQnbY7JGBtE70r45y2ZniE=</HostId> </Error>
не видно вашей картинки.
Flagman
Наконец-то первый полезный сервис!
AnemoN
Можно использовать для автоматического распознавания ASSIRA-капчи