很久之前做了C3D的视频分类,现在详细把整个项目的细节描述一下。
首先介绍一下C3D:对于一段视频来说,它是连续的帧图像叠加起来的,所以可以考虑在生成通道图像的时候,把多帧图像叠加的特性讨论进去。
一个视频段输入,其大小为 c∗l∗h∗w ,其中c为图像通道(一般为3),l为视频序列的长度,h和w分别为视频的宽与高。进行一次kernel size为3∗3∗3,stride为1,padding=True,滤波器个数为K的3D 卷积后,输出的大小为K∗l∗h∗w。池化同理。
作者对卷积核做了研究,发现3*3的卷积核最有效。基于3D卷积操作,共有8次卷积操作,4次池化操作。其中卷积核的大小均为3∗3∗3,步长为1∗1∗1。池化核的大小为2∗2∗2,步长为2∗2∗2,但第一层池化除外,其大小和步长均为1∗2∗2。这是为了不过早缩减时序上的长度。最终网络在经过两次全连接层和softmax层后就得到了最终的输出结果。网络的输入尺寸为3∗16∗112∗112,即一次输入16帧图像。
github地址:https://github.com/hx173149/C3D-tensorflow
训练过程:首先按照train.list,test.list将文件分类。然后使用ffmpeg,将视频分割,这里每5帧取一张图片。
模型代码:
def conv3d(name, l_input, w, b):
return tf.nn.bias_add(
tf.nn.conv3d(l_input, w, strides=[1, 1, 1, 1, 1], padding='SAME'), b )
def max_pool(name, l_input, k):
return tf.nn.max_pool3d(l_input, ksize=[1, k, 2, 2, 1], strides=[1, k, 2, 2, 1], padding='