本文是视频动作识别领域经典的C3D网络的简易实现,可以作为动作识别的入门。论文为<Learning Spatiotemporal Features with 3D Convolutional Networks>(ICCV 2015)。
框架:Tensorflow (=1.6)+python(2.7)+slim
数据集:UCF101. Center for Research in Computer Vision at the University of Central Florida
代码:2012013382/C3D-Tensorflow-slim
3D卷积的基本概念网上有很多,不再阐述。这里主要说一下输入帧(图片)通过网络之后的变化情况。
C3D的基本网络结构如图1所示:
图1 C3D网络结构示意图
细节:
1)输入clip(视频段)的shape为[batch_size, frame_length, crop_size, crop_size, channel_num],其中frame_length为16,表示输入为16帧一个样本;crop_size为112,channel_num为3,表示每帧的size统一为[112, 112, 3]。
2)每个卷积核的size都是[3, 3, 3],第一维表示时间维,后面两维表示帧(图片)上的kernel size;stride都是[1, 1, 1], padding='SAME'。
3)所有的pooling都是3D max pooling,只有第一层pooling的size和stride为[1, 2, 2],其他的均为[2, 2, 2],维数的含义与1)中一致,padding='SAME'。作者称第一层时间维用1是为了避免时间维度上过早缩小为1。
输入clip通过网络的shape变化如下:
设batch_size为10。
Input shape:[10, 16, 112, 112, 3]
After conv1:[10, 16, 112, 112, 64]
After pool1:[10, 16, 56, 56, 64]
After conv2a:[10, 16, 56, 56, 128]
After pool2:[10, 8, 28, 28, 128]
After conv3a:[10, 8, 28, 28, 256]
After conv3b:[10, 8, 28, 28, 256]
After pool3:[10, 4, 14, 14, 256]
After conv4a:[10, 4, 14, 14, 512]
After conv4b:[10, 4, 14, 14, 512]
After pool4:[10, 2, 7, 7, 512]
After conv5a:[10, 2, 7, 7, 512]
After conv5b:[10, 2, 7, 7, 512]
After pool5:[10, 1, 4, 4, 512]
After fc6:[10, 4096]
After fc7:[10, 4096]
out:[10, num_classes](UCF的num_classes为101)
数据预处理
做视频的工作,数据预处理相对会比较复杂,由于视频数据集通常较大,我们通常将其先转为图片的形式,再每次从硬盘上读一个batch的数据。下载UCF101数据集之后,将其解压到项目的根目录下。创建convert_video_to_images.sh文件,内容为
for folder in $1/*
do
for file in "$folder"/*.avi
do
if [[ ! -d "${file[@]%.avi}" ]]; then
mkdir -p "${file[@]%.avi}"
fi
ffmpeg -i "$file" -vf fps=$2 "${file[@]%.avi}"/%05d.jpg
rm "$file"
done
done
执行
sudo ./convert_video_to_images.sh UCF101/ 5
表示将视频每秒取5帧图片。
之后生成训练集与测试集。创建convert_images_to_list.sh文件,内容为
> train.list
> test.list
COUNT=-1
for folder in $1/*
do
COUNT=$[$COUNT + 1]
for imagesFolder in "$folder"/*
do
if (( $(jot -r 1 1 $2) > 1 )); then
echo "$imagesFolder" $COUNT >> train.list
else
echo "$imagesFolder" $COUNT >> test.list
fi
done
done
执行
./convert_images_to_list.sh UCF101/ 4
表示1/4的数据为测试集,其余为训练集。
每次为训练和测试从硬盘上读取batch_size大小的数据,具体如下。
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import PIL.Image as Image
import random
import numpy as np
import os
import tim