基于深度学习的视频分析检测可疑活动


本文解释了视频分类的一种可能实现。我们的目标是解释我们是如何做到的,以及我们获得的结果,以便你们从中学习。

在这篇文章中,您将找到对解决方案体系结构的一般描述,我们遵循的方法,我们使用的数据集,我们如何实现它,以及我们取得的结果。

请随意使用这篇文章作为开发您自己的视频分类器的起点。

这里描述的系统能够将视频分类为三类:

  1. 犯罪或暴力活动
  2. 潜在可疑
  3. 安全

我们解决这个问题的建议是一个基于卷积和递归神经网络的架构。

解决方案体系结构的说明

第一个神经网络是卷积神经网络,目的是提取图像的高层特征,降低输入的复杂度。我们将使用一个预先训练的模型称为inception开发的谷歌。Inception-v3是在ImageNet大型视觉识别挑战数据集上训练的。这是计算机视觉中的一个标准任务,模型试图将整个图像分类为1000类,比如“斑马”,“斑点狗”和“洗碗机”。

我们用这个模型来应用迁移学习技术。现代的物体识别模型有数百万个参数,完全训练可能需要数周时间。迁移学习是一种技术,它通过对一组类别(如ImageNet)采用完全训练的模型,并从现有的权重对新类进行重新训练,从而优化了许多这方面的工作。

图1:初始模型

使用的第二个神经网络是一个递归神经网络,这个网络的目的是理解所描述的动作的顺序。这个网络在第一层有一个LSTM细胞,之后是两个隐藏层(一个有1024个神经元和relu激活,另一个有50个神经元和一个sigmoid激活),输出层是一个三神经元层,有softmax激活,这给了我们最终的分类。

图2:递归神经网络

方法学

第一步是提取视频的帧。我们每0.2秒提取一个帧,并使用这个帧,我们使用先兆模型进行预测。考虑到我们使用的是迁移学习技术,我们不打算提取初始模型的最终分类。取而代之的是,我们正在提取最后一个池化层的结果,这是一个2048个值的向量(高级特征图)。直到现在,我们有一个单一帧的特征图。然而,我们希望给我们的系统一个顺序的感觉。要这样做,我们并不是在考虑单帧来做我们的最终预测。我们取一组帧来进行分类,而不是对帧进行分类,而是对视频的一段进行分类。

我们认为每次分析三秒钟的视频就足以对当时正在发生的活动做出很好的预测。为此,我们存储了15个由初始模型预测生成的特征图,相当于3秒的视频。然后,我们将这组特征映射串接成一个单一模式,这将是我们的第二个神经网络的输入,即递归的一个,以获得我们系统的最终分类。

图3:视频分类架构

最后,我们在屏幕上看到的是视频的实时分类,每隔三秒钟,我们就会看到视频的那一部分的分类--安全,可疑或犯罪活动。

训练数据集

用于训练网络的数据集由150分钟的筛选组成,分为38个视频。这些视频大多记录在商店和仓库的安全摄像头上。获取每帧0.2秒长的数据集的结果是,训练用的数据集为45,000帧--相当于3000段视频,考虑到一段视频代表它的三秒(或15帧)。

整个数据集被我们贴上标签,分组:80%用于训练,20%用于测试。

如您所见,最终的数据集实际上相当小。然而,由于迁移学习技术,我们可以用较少的数据得到较好的结果。当然,为了使系统更精确,最好有更多的数据;这就是为什么我们一直在获取越来越多的数据来改进我们的系统。

图4:数据类示例

实施

整个系统用Python3.5实现。

我们使用OpenCV for 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

现在我们有了传递值和它们的标签,我们就可以用这些数据来训练我们的递归神经网络。这个网络的实现在Keras中,创建模型的代码如下:

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:视频分类的前端

我们可以用这个视频分类器做的事情之一是将它连接到一个安全摄像头,并持续实时分析视频,一旦系统检测到犯罪或可疑活动,它就可以启动警报或报警。

此外,您可以使用经过适当数据训练的类似系统来检测不同类型的活动;例如,在学校里安装一个摄像头,你的目标是检测欺凌行为。

参考文献