Эта статья объясняет одну возможную реализацию классификации видео. Наша цель — объяснить, как мы это сделали и какие результаты мы получили, чтобы вы могли извлечь из этого уроки.
В этом посте вы найдете общее описание архитектуры решения, методологии, которой мы придерживаемся, набора данных, который мы использовали, как мы его реализовали и результатов, которых мы достигли.
Не стесняйтесь использовать этот пост в качестве отправной точки для разработки собственного классификатора видео.
Описанная здесь система способна классифицировать видео на три класса:
- Преступная или насильственная деятельность
- Потенциально подозрительно
- Сейф
Наше предложение решить эту проблему — это архитектура, основанная на сверточных и периодических нейронных сетях.
Описание архитектуры решения
Первая нейронная сеть представляет собой сверточную нейронную сеть с целью извлечения высокоуровневых особенностей изображений и уменьшения сложности ввода. Мы будем использовать предварительно обученную модель, названную Inception, разработанную Google. Inception-v3 обучается работе с набором данных для большого визуального распознавания ImageNet. Это стандартная задача в компьютерном зрении, где модели пытаются классифицировать целые изображения на 1000 классов, таких как «зебра», «далматин» и «посудомоечная машина».
Мы использовали эту модель для применения техники трансферного обучения. Современные модели распознавания объектов имеют миллионы параметров, и для их полного обучения могут потребоваться недели. Трансферное обучение — это метод, который оптимизирует большую часть этой работы, принимая полностью обученную модель для набора категорий, таких как ImageNet, и переобучает существующие веса для новых классов.
Рисунок 1: Начальная модель
Вторая используемая нейронная сеть была рекуррентной нейронной сетью, цель этой сети — понять последовательность изображаемых действий. Эта сеть имеет ячейку LSTM в первом слое, за которой следуют два скрытых слоя (один с 1024 нейронами и активацией relu, а другой — с 50 нейронами с сигмовидной активацией), а выходной слой представляет собой слой из трех нейронов с активацией softmax, что дает нам окончательную классификацию.
Рисунок 2: Рекуррентная нейронная сеть
методология
Первый шаг — извлечь кадры из видео. Мы извлекаем кадр каждые 0,2 секунды и, используя этот кадр, делаем прогноз, используя начальную модель. Учитывая, что мы используем технику трансферного обучения, мы не собираемся извлекать окончательную классификацию начальной модели. Вместо этого мы извлекаем результат последнего слоя пула, который представляет собой вектор из 2048 значений (карта объектов высокого уровня). До сих пор у нас была карта объектов из одного кадра. Тем не менее, мы хотим дать нашей системе ощущение последовательности. Для этого мы не рассматриваем отдельные кадры, чтобы сделать наш окончательный прогноз. Мы берем группу кадров, чтобы классифицировать не кадр, а сегмент видео.
Мы считаем, что анализа трех секунд видео достаточно для того, чтобы сделать хороший прогноз активности, которая происходит в этот момент. Для этого мы храним пятнадцать карт характеристик, сгенерированных с помощью предсказания начальной модели, что эквивалентно трем секундам видео. Затем мы объединяем эту группу карт характеристик в единый шаблон, который будет входом нашей второй нейронной сети, рекуррентной, для получения окончательной классификации нашей системы.
Рисунок 3: Архитектура классификации видео
В конце мы видим на экране классификацию видео в режиме реального времени, где каждые три секунды мы видим классификацию этой части видео — как безопасной, подозрительной, так и криминальной.
Набор обучающих данных
Набор данных, используемый для обучения сети, состоит из 150 минут просмотра, разделенного на 38 видео. Большая часть этих видео записывается на камеры видеонаблюдения магазинов и складов. В результате взятия кадра длительностью 0,2 секунды для обучения используется набор данных из 45 000 кадров, что эквивалентно 3000 сегментам видео, учитывая, что сегмент видео представляет три его секунды (или 15 кадров).
Весь набор данных был помечен нами и разделен на группы: 80% для обучения и 20% для тестирования.
Как видите, окончательный набор данных на самом деле довольно мал. Однако благодаря технике трансферного обучения мы можем получить хорошие результаты с меньшим количеством данных. Конечно, чтобы система была более точной, лучше иметь больше данных; Вот почему мы продолжаем получать все больше и больше данных для улучшения нашей системы.
Рисунок 4: Пример классов данных
Реализация
Вся система была реализована на Python 3.5.
Мы используем OpenCV для Python, чтобы сегментировать видео в кадрах и изменять их размер до 200x200px. Как только у нас есть все кадры, мы делаем прогноз на начальной модели, используя каждый из них. Результатом каждого предсказания является «значение передачи», представляющее карту объектов высокого уровня, извлеченную из этого конкретного кадра. Мы сохраняем это в transfer_values
переменной и соответствующие метки в label_train
переменной.
Когда у нас есть эти переменные, нам нужно разделить их на группы по 15 кадров. Мы сохраняем результат в joint_transfer
переменной.
frames_num=15
count = 0
joint_transfer=[]
for i in range(int(len(transfer_values)/frames_num)):
inc = count+frames_num
joint_transfer.append([transfer_values[count:inc],labels_train[count]])
count =inc
Теперь, когда у нас есть значения переноса и их метки, мы можем использовать эти данные для обучения нашей текущей нейронной сети. Реализация этой сети находится в Керасе, а код для создания модели выглядит следующим образом:
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.layers import LSTM
chunk_size = 2048
n_chunks = 15
rnn_size = 512
model = Sequential()
model.add(LSTM(rnn_size, input_shape=(n_chunks, chunk_size)))
model.add(Dense(1024))
model.add(Activation('relu'))
model.add(Dense(50))
model.add(Activation(sigmoid))
model.add(Dense(3))
model.add(Activation('softmax'))
model.compile(loss='mean_squared_error', optimizer='adam',metrics=['accuracy'])
Код выше описывает конструкцию модели. Следующий шаг — это тренировка:
data =[]
target=[]
epoch = 1500
batchS = 100
for i in joint_transfer:
data.append(i[0])
target.append(np.array(i[1]))
model.fit(data, target, epochs=epoch, batch_size=batchS, verbose=1)
После того, как мы обучим модель, нам нужно сохранить ее следующим образом:
model.save("rnn.h5", overwrite=True)
Теперь, когда модель полностью обучена, мы можем начать классифицировать видео.
Результаты и другие возможные применения
После экспериментов с различными сетевыми архитектурами и настройки гиперпараметров, лучший результат, которого мы смогли достичь, — точность 98%.
Мы разработали следующий интерфейс, где вы можете загрузить видео и начать его классификацию в режиме реального времени. Вы можете видеть, как классы постоянно меняются, а также соответствующую точность для этого класса. Эти значения постоянно обновляются каждые три секунды, пока видео не закончится.
Рисунок 5: Внешний вид видео классификации
Одна из вещей, которую мы можем сделать с этим классификатором видео, это подключить его к камере безопасности и продолжать анализировать видео в режиме реального времени, а в тот момент, когда система обнаружит преступную или подозрительную активность, она может активировать тревогу или предупредить полицию. ,
Кроме того, вы можете использовать аналогичную систему, обученную с соответствующими данными, для обнаружения различных видов деятельности; например, с камерой, расположенной в школе, где вашей целью может быть обнаружение издевательств.