
导 语
学习如何构建可以将视频分为三类的AI系统:犯罪或暴力活动视频,潜在可疑的活动视频、安全活动视频。
本文介绍了一种视频分类技术的实现方法。我们的目标是解释我们如何实现的以及我们获得的结果,以便大家从中学习。
通过本文,您将了解到这类问题的解决方案的架构、遵循的一套方法、使用的数据集、如何实现以及实现后的结果。
您可以使用该文章作为开发自己的视频分类器的起点。
本文中描述的系统能够将视频分为三类:
1、犯罪或暴力活动;
2、可能是可疑的;
3、安全;
我们解决这个问题是基于卷积神经网络和递归神经网络架构。
解决方案架构描述
第一个神经网络——卷积神经网络,目的是提取图像的高级特征,并降低输入的复杂性。我们将使用由Google开发的Inception层预训练模型。Inception v3在ImageNet大型视觉识别挑战数据集上进行了训练。这是计算机视觉中的标准任务,模型试图将整个图像分为1000个类,如“斑马”、“达尔马提亚狗”和“洗碗机”。
我们利用这个模型来使用迁移学习技术。现代物体识别模型具有数百万个参数,并且可能需要数周才能完全训练。转移学习是把类似于ImageNet这样公共的数据集的知识迁移到自己的问题上,即将已经训练好的模型的一部分知识(网络结构)直接应用到另一个新的类似模型中。

第二个神经网络——递归神经网络,它的目的是理解所描绘动作的顺序。该网络在第一层有一个LSTM单元,随后是两个隐藏层(一个有11024个神经元和ReLU激活;另一个有50个神经元,一个sigmoid激活),输出层是一个带有softmax激活的三神经元层,它给出了最后的分类。

方法
第一步,提取视频的帧。每隔0.2秒提取一帧,使用Inception 模型对提取的该帧进行预测。由于使用的是迁移学习技术,因此,将不提取Inception 模型的最终分类。我们最终提取最后一个池化层的结果,该层是2048个值的向量(高级特征映射)。到目前为止,我们拥有了一个单帧的特征图。然而,我们希望该系统了解序列。为此,我们不考虑用单帧进行最终预测。我们采用一组帧对一段视屏进行分类,而不是对帧进行分类。
我们认为一次分析3秒钟的视频就足以对当时正在发生的活动做出很好的预测。为此,我们存储了由Inception 模型预测生成的15个特征映射,相当于3秒的视频。然后,将这组特征映射连接成一个单独的模式,这将是第二个神经网络的输入,即递归,以便获得系统的最终分类。

最后,在屏幕上看到的是视频的实时分类,每3秒钟会看到视频的分类:安全、可疑或犯罪活动。
训练数据集
用于训练网络的数据集包括150分钟,分为38个视频。这些视频大多数都记录在商店和仓库的安全摄像机里。采用每0.2秒长的帧,用于训练的数据集共有45000帧——相当于3000段视频,考虑到视频的一段代表3秒钟(或15帧)。
我们对整个数据集标记并分组:80%用于训练,20%用于测试。
如您所见,最终数据集实际上非常小。由于使用了迁移学习技术,可以用更少的数据获得良好的结果。当然,为了使系统更准确,最好使用更多的数据;这就是为什么我们不断努力获取越来越多的数据来改进我们的系统。

执行
整个系统是用Python 3.5实现的。
使用OpenCV for Python来分割帧中的视频,并将它们调整成为200*200像素。当拥有了所有帧,就可以使用它们中的每一个对Inception 模型进行预测。每个预测结果表示从该特定帧提取的高级特征映射的“传输值”。将变量保存在transfer_value变量中,将其各自的标签保存在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%的准确性。
我们设计了以下前端页面,可以在其中上传视频并开始实时分类。可以看到类是如何不断变化的,以及该类对应的准确性。这些值每3秒更新,直到视频结束。

我们可以用这个视频分类器做的事情之一是:将它连接到安全摄像机,对视频进行实时分析,当系统检测到犯罪或可疑活动时,可以激活报警或是提醒警察。
此外,还可以使用经过适当数据训练的类似系统来检测不同类型的活动,例如:使用位于学校的摄像头,检测目标(可能是学生等,待检测对象)是否受到欺凌。
参考资料
1,TensorFlow图像识别教程:
tensorflow.org/tutorials/image_recognition
2,TensorFlow图像再培训教程:
tensorflow.org/tutorials/image_retraining
3,Python网站:https://www.python.org
4,OpenCV和Python:
https://pypi.python.org/pypi/opencv-python
5,Keras网站:https://keras.io

长按二维码 ▲
订阅「架构师小秘圈」公众号
如有启发,帮我点个在看,谢谢↓