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

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

Сегодня мы собираемся изучить способ непрерывной классификации видео по мере его снятия в онлайн-системе. Непрерывная классификация позволяет нам решать всевозможные интересные задачи в режиме реального времени, от понимания того, что находится перед автомобилем, для приложений автономного вождения, до понимания того, что транслируется по телевизору. Мы постараемся сделать последнее, используя только программное обеспечение с открытым исходным кодом и сверхдешевое оборудование. В частности, TensorFlow на Raspberry Pi с PiCamera.

В этом посте мы воспользуемся «наивным» классификационным подходом (см. Следующий раздел), который даст нам относительно простой путь к решению нашей проблемы и сформирует основу для более сложных систем, которые мы будем исследовать позже.

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

Поехали!

Интуиция

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

Мы предполагаем, что для многих приложений использование только пространственных функций достаточно для достижения высокой точности. Преимущество этого подхода в том, что он относительно прост или, по крайней мере, минимален. Это наивно, потому что игнорирует информацию, закодированную между несколькими кадрами видео.

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

Метод

Мы собираемся собирать данные для автономного обучения с помощью Raspberry Pi и PiCamera. Мы направим камеру на телевизор и будем записывать 10 кадров в секунду, а точнее, сохранять 10 jpeg каждую секунду, которые и будут составлять наше «видео».

Вот код для захвата наших изображений:

Получив данные, мы воспользуемся сверточной нейронной сетью (CNN), чтобы классифицировать каждый кадр по одному из наших ярлыков: реклама или футбол.

Автономное обучение и исследование

TensorFlow и начало

CNN - это самые современные системы классификации изображений. А в 2016 году это по сути решенная проблема. Было бы безумием говорить это, но это действительно так: в значительной степени благодаря Google → TensorFlow → Inception и многим исследователям, работавшим до этого, нам очень мало требуется низкоуровневого кодирования, когда дело доходит до обучения CNN для наших проблема непрерывной классификации видео.

Пит Уорден из Google написал потрясающее сообщение в блоге под названием TensorFlow for Poets, в котором показано, как переобучить последний уровень Inception с новыми изображениями и классами. Это называется трансферным обучением, и оно позволяет нам воспользоваться неделями предыдущего обучения без необходимости обучать сложную CNN с нуля. Другими словами, это позволяет нам обучать классификатор изображений с относительно небольшим обучающим набором.

Наши данные обучения

Мы собрали 20 минут видеоматериала со скоростью 10 JPEG в секунду, что составило 4 146 рекламных кадров и 7 899 футбольных кадров. Следующим шагом будет сортировка каждого кадра по двум папкам: футбол и реклама. Имена папок представляют собой метки каждого кадра, которые будут классами, которые наша сеть научится предсказывать, когда мы переобучаем верхний уровень CNN Inception v3.

По сути, здесь используется метод цветов, описанный в TensorFlow для поэтов, применяемый к видеокадрам.

Чтобы переобучить последний уровень CNN на наших новых данных, мы извлекаем тег r0.11 из репозитория TensorFlow и запускаем следующую команду:

python3 tensorflow/examples/image_retraining/retrain.py \     
    --bottleneck_dir=/home/harvitronix/blog/inception/bottlenecks \
    --model_dir=/home/harvitronix/blog/inception/ \
    --output_graph=/home/harvitronix/blog/retrained_graph.pb \
    --output_labels=/home/harvitronix/blog/retrained_labels.txt \
    --image_dir /home/harvitronix/blog/images/classifications/

Переобучение последнего уровня сети на этих данных занимает около 30 минут на моем ноутбуке с графическим процессором GeForce GTX 960m. По завершении 4000 шагов обучения наша модель сообщает о невероятной точности 98,8% на проведенном валидационном наборе! Я не уверен, что смог бы добиться большего, используя те же данные. Для сравнения: если бы сеть классифицировала каждый кадр как футбол, точность составила бы около 66%. Так вроде работает!

Выборочная проверка

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

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

А вот результаты выборочной проверки отдельных кадров:

Смоделированная онлайн-классификация

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

Чтобы получить этот набор данных и убедиться, что у нас нет утечки данных в наш тренировочный набор, мы отдельно записываем еще 19 минут футбольной трансляции. Этот набор данных составил 2639 рекламных фреймов и 8 524 футбольных фрейма.

Мы пропускаем каждый кадр этого набора через наш классификатор и достигаем истинной точности удержания 93,3%. Потрясающие!

Похоже, мы подтвердили нашу гипотезу о том, что мы можем достичь высокого уровня точности, учитывая только пространственные особенности. Впечатляющие результаты, учитывая, что мы использовали только 20 минут тренировочных данных! Спасибо, Google, Пит, TensorFlow и всем людям, которые создавали CNN на протяжении многих лет, за вашу невероятную работу и вклад.

Онлайн-классификация

Отлично, теперь у нас есть обученная CNN, и мы знаем, что можем классифицировать каждый кадр нашего видео с относительно высокой точностью. Как это происходит в прямом эфире с постоянно меняющимся контекстом?

Для этого мы загружаем в Raspberry Pi 3 наши недавно обученные веса модели, включаем PiCamera на скорости 10 кадров в секунду и вместо сохранения изображения отправляем его через нашу CNN для классификации.

Мы должны внести некоторые изменения в код для классификации в реальном времени. Окончательный результат выглядит так:

Мы также должны запустить TensorFlow на Pi. Сэм Абрахамс написал для этого отличные инструкции, поэтому я не буду их здесь снова описывать.

После установки наших зависимостей запускаем программу и… лажа! Inception на Raspberry Pi 3 может классифицировать только одно изображение каждые четыре секунды.

Хорошо, у нас пока нет оборудования, чтобы делать 10 кадров в секунду, но это все равно похоже на волшебство, так что давайте посмотрим, как мы это сделаем.

Если щелкнуть по экрану Sunday Night Football и направить камеру на телевизор, это показывает замечательную работу по классификации каждого момента как футбола или рекламы каждые несколько секунд. В подавляющем большинстве трансляций мы видим, как наши предсказания сбываются. Так круто.

Следующие шаги

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

Для этого нам придется погрузиться глубже. Итак, в следующем посте мы исследуем подачу выходных данных нашей CNN (как финального слоя softmax, так и уровня пула, который дает нам 2048-дневный вектор признаков каждого изображения) в LSTM RNN, чтобы увидеть, если мы может повысить нашу точность.

Спойлер: мы можем!

Обновление: Часть 2 уже доступна!

Код, который сопровождает этот пост, доступен на GitHub.

дальнейшее чтение