Котики против нейросети. Или выбираем и запускаем нейросеть для распознавания объектов на Raspberry Zero +32


Добрый день всем.

Крохотный компьютер Raspberry — замечательная вещь. Я использовал Raspberry Zero W в паре проектов в течение последнего полугода. Подкупила простота протипирования и откатки различных идей. А теперь вот факультативно заинтересовал вопрос, потянет ли сей девайс полноценную сверточную сетку? [Спойлер — потянет, но есть забавые нюансы]. Кому интересна тема — добро пожаловать под кат. Осторожно, будет много котиков!

image


Зачем Raspberry нейросеть?


Как-то собрал на Raspbery Zero W простенькую видео-ловушку для наблюдения за ночной жизнью животных (в основном котов) на даче. Код отличался простотой и работал неплохо. Для видео-фото детекции использовалась камера с ИК-подсветкой вроде этой «Raspberry Pi Night Version Camera».

image

Суть кода в том, чтобы забирать два последовательных кадра, сравнивать попиксельно и если число изменившихся пикселей больше некого порогового значения, запускать запись 10-секундного видео. Текст кода в этом посте приводить не буду, если кого-то заинтересует, пишите в комментариях, могу выложить в следующем. Основная фишка, уложить получение двух сравниваемых кадров в 0,2 секунды хотя бы, чтобы отловить быстрые события. Ну и быстро сравнить эти кадры, конечно.

Далее возникла идея прикрутить к алгоритму простую нейросеть, чтобы можно было в пойманном кадре определять объект и запускать видеозапись, только если достоверно определился класс объекта. Это потенциально позволяет избавиться от ложных срабатываний видеоловушки. Таковые случаются от движущихся объектов (например, трава или ветки) или от резкой засветки сцены камеры (свет в окне включился или фонарь погас, например).

Какую сетку поставить на Raspberry?


К счастью, под предустановленный Питон (в моем случае это 3.5.3) и широко доступной OpenCV (я использую 3.4.3) можно поставить практически любую сетку. К несчастью, из-за ограниченных вычислительных возможностей девайса список вариантов невелик. По сути можно выбирать только из «лайтовых» вариантов:

1. SqueezeNet (пример кода здесь).
2. YOLO Tiny (здесь).
3. MobileNet-SSD (тут).
4. MobileNet_v1_224 (есть фантастическое видео работы детектора объектов на этой сетке).

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

У претендента №1 вдохновили заявленная высокая точность распознавания при скромных размерах весовых коэффициентов. Кроме того, недолгий поиск в Интернет вывел на великолепный блог Adrian Rosebrock, в котором подробнейшим образом прокомментирован код и расписаны несколько вариантов реализации deep learning на Raspberry.

Для тестирования возможностей SqueezeNet использовался код отсюда. Веса и текстовое представление модели автор кода присылает на емейл после заполнения формы на сайте. Кстати, если у Вас не установлен OpenCV, можете найти алгоритм действий в его же блоге. Плюс там же примеры «разгона» кода для ускорения времени работы моделей да и много чего еще. Респект Адриану, реально крутой ресурс.

Ну хорошо, запускаем код и на первой же картинке получаем сногсшибательный результат!

image

Кот на снимке определен как персидский с вероятностью 99%. На самом деле он не персидский, а британский длинношерстный или хайлендер. Но для модели с диапазоном в 1000 классов попадание, можно сказать, в яблочко. Для удобства я поместил основные результаты работы нейросети прямо на фото. Это 5 наиболее вероятных классов, первый — самый вероятный, второй — следующий по значимости, и так далее.

Кстати, модель считает классы объекта на моей Zero 6,5 секунд. Если верить данным Адриана, расчет на Raspberry Pi B+ на приведенных в его посте картинках (фото помещения парикмахерской, кобры и медузы) займет около 0,92 сек. Охотно верю, у полноценной версии Raspberry 4 ядра в процессоре как-никак. Полагаю, всем известно, что у Zero оно всего одно (((

Похоже, об определении класса объекта в реальном времени на Zero придётся забыть. Кстати, надо признаться, что и секунда времени на работу модели на «полноценной» Pi — тоже далеко не предел мечтаний.

Но продолжим тестирование модели.

image

Кот поменял положение тела и потерял целых 7% от своей былой «персидскости» ). Но это шутка, конечно, в целом работа модели очень даже на высоте. Вот на этом самом месте можно было и закончить, но захотелось слегка усложнить задачу модели. Продолжим упражняться на… кошках. Но наберем кадров, где кошка не сидит в классической позе, а спит, например. Итак, поехали.

image

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

image

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

image

Ого. Теперь она — сибирская хаски. Что-то мне подсказывает, что кошка пока ведет в счёте )

image

Похоже, кто-то из этих двоих явно в нокдауне и это явно не кошка. Теперь она определена нейросетью как веретено (правда, всего на 8,5%), есть еще варианты, что она бигль, косатка, каменистый питон или скунс. Не кошка, а женщина загадка!

image

Да ладно! Это всё таки косатка! Да, да, морское млекопитающее отряда китообразных. Мне почему-то вспомнились строки из далёкого детства:
«В этой сказке нет порядка,
Здесь ошибка, опечатка! Кто-то,
Против всяких правил,
В сказке буквы переставил,
Переправил
«КИТ» на «КОТ»,
«КОТ» на «КИТ», наоборот!».
Звон гонга, рефери останавливает бой )

image

Во втором раунде кошка, коварно надев очки, сошла за бостонского бульдога с вероятностью в 34%. Или за французского. Похоже, нейросеть не вполне оправилась от разгрома в первом раунде )

image

Ну вот наконец то! Кошка определена как сиамская с вероятностью аж 66%! Браво, SqueezeNet! Если серьезно, похоже, что в исходном датасете преобладали фото не лежащих, а сидящих кошек. Лежащие были в основном собаки )

image

Способность кошек принимать форму коробки сбивает с толку даже людей, чего уж говорить про нейросети. Погружение к коробку снизило точность распознавания аж на 40%.

image

Так, так… А это, похоже, вообще запрещенный приём. Лежащая рядом с кошкой компьютерная мышь окончательно сбивает нейросеть с толку. Теперь наша кошка — мышь! )

Итак, всего нейросети было предъявлено 11 фото котов, из которых правильно определены всего 5. При этом с вероятностью более 50% всего в трёх случаях. Ни в коей мере не умаляю работу авторов SqueezeNet. Это добротная сеть с очень широким классом объектов и относительно низкой требовательностью к ресурсам.

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

Что касается выбора оптимальной нейросети для Raspberry — вопрос пока остаётся открытым. Я продолжаю эксперименты, при наличии интереса аудитории к данной теме, буду делиться результатами дальнейших изысканий. Просто результаты первого шага оказались настолько забавными, что очень захотелось ими поделиться.

Спасибо, что дочитали до конца. Удачи и хорошей рабочей недели )




К сожалению, не доступен сервер mySQL