视频分类之UCF-101上的CNN方法详解

Code at Github:https://github.com/sujiongming/UCF-101_video_classification

PDF版(排版更好)下载链接:链接:https://pan.baidu.com/s/1mjlZqjA密码:7ads

视频分类包括人类行为识别和通用的多标签视频分类等研究内容。用的多标签视频分类以2016年谷歌发布的youtube-8M数据集为代表,其中很多视频属于多个类别,并且在类别上不限于人类行为。人类行为识别主要研究分类视频中包含的人类行动,一般一个视频中只包含一类人类行为,UCF101数据集就是其中的典型代表。UCF-101(2012)包含13,320个视频(共27个小时),101个人类行为类别,如运动、乐器和人物交互等。[1] 国内外研究人员在UCF-101数据集上进行了深入研究,目前最好的准确率已经达到95%以上。

UCF-101上的CNN方法一般作为其他分类方法的比较基准,也是最简单和自然的视频分类方法[2]。CNN方法是将这些视频帧视为一张张静态图像,应用CNN识别每一帧,然后对预测结果进行平均处理来作为该视频的最终结果。然而,这个方法使用的是不完整的视频信息,因此使得分类器可能容易发生混乱而导致准确度不高。本文CNN方法在测试集上的最终准确度为top1:63.0%,top5:87.5%。

UCF-101中6类行为的样本图像帧


一、 基本过程和思想

基本思想是将数据集中视频及分类标签转换为图像(视频帧)和其对应的分类标签,再采用CNN网络对图像进行训练学习和测试,将视频分类问题转化为图形分类问题。具体步骤包括:

(1) 对每个视频(训练和测试视频)以一定的FPS截出视频帧(jpegs)保存为训练集和测试集,将对图像的分类性能作为所对应视频的分类性能:train set 有1, 788, 425帧图像,test set 有697, 865帧图像

(2) 选择一个预先训练好的CNN网络架构和初始权重,迁移学习至UCF-101,如inception v3 with pre-trained on ImageNet

(3) 用train set对CNN网络部分层进行重新训练,获得模型

(4) 训练完成后载入模型对test set内所有的视频帧进行检查验证,得出全测试集上的top1准确率和top5准确率输出

二、 运行环境简介

(1) 服务器硬件环境:40核至强cpu,GeForce GTX 1080 8G显存 X2,128G内存,512G

SSD,3TB机械硬盘

(2) 服务器软件环境:安装ubuntu16.04、conda(含python2.7),CUDA,cudnn、tensorflow GPU,keras等所需python包,SSH服务,screen包,vim工具,ffmpeg包

(3) 客户机:window7 64位,pycharm,xshell,xftp

(4) 使用模式:客户机远程SSH连接服务器进行操作

三、 运行过程和结果

(5) 准备数据(UCF提供了三种训练/测试划分方案,本实例采用1#划分方案)

i. 用xftp软件将开源项目程序和UCF101数据包上传至服务器谋和目录下

ii. 将UCF101数据包放在开源项目文件夹的data目录下,运行命令“unrar e UCF101.rar”

iii. 运行命令`python 1_move_files.py`

iv. 运行命令`python 2_extract_files.py`

6) 训练CNN,输出测试集性能

i. 运行python CNN_train_UCF101.py,命令行输出训练过程信息,在测试子集上的准确率和top5准确率,系统函数默认k=5。

ii.训练集:到41 epoch时训练自动停止,最好的结果在29 epoch时出现,val_loss 最小为1.19,采用该模型评价测试集。模型名称为:inception.0.29-1.19.hdf5,需要修改CNN_evaluate_testset.py文件加载该名称模型。

iii. 运行python CNN_evaluate_testset.py,命令行输出测试集结果 。

iv. 测试集:loss:1.33,accuracy:0.63,top5 accuracy:0.875

v. 运行python CNN_validate_images.py,命令行输出随机选择的5张图像的分类信息和结果。

需要注意的是,你的运行结果可能与本文有所差异,因此研究者可能需要不断修改调整模型超参,多次运行,找出最好的一组模型参数,取最好的准确度结果。

四、 将inception-v3网络迁移学习至UCF-101

假设有数据集D,不同于数据集ImageNet,D有1024个输入特征,200个输出类别。

from keras.applications.inception_v3 import InceptionV3

from keras.preprocessing import image

from keras.models import Model

from keras.layers import Dense,GlobalAveragePooling2D

from keras import backend as K

# create the base

pre-trained model

base_model=InceptionV3(weights='imagenet',include_top=False)

#

include_top=False因为我们想要重新在数据集D上训练top level,我们移除了最后三层,暴露的是mixed10层的输出。

#模型最后4层的 layer.name, layer.input_shape,

layer.output_shape

('mixed10',[(None,8,8,320),(None,8,8,768),(None,8,8,768),(None,8,8,192)

('avg_pool',(None,8,8,2048),(None,1,1,2048))

('flatten',(None,1,1,2048),(None,2048))

('predictions',(None,2048),(None,1000))

#因此,需要加三层

x=base_model.output

x=GlobalAveragePooling2D()(x)

x=Dense(1024,activation='relu')(x)#加入1024个特征层

predictions=Dense(200,activation='softmax')(x)#输出层,加入数据集类别

model=Model(input=base_model.input,output=predictions)

forlayerinbase_model.layers:#固定inceptionv3模型参数

layer.trainable=False

#编译模型

model.compile(optimizer='rmsprop',loss='categorical_crossentropy')

#模型训练新加的层

model.fit_generator(train_generator,steps_per_epoch=100,validation_data=validation_generator,validation_steps=10,epochs=nb_epoch,callbacks=callbacks)

#训练the top 2 inception blocks,因此固定前172层,训练后面的层

forlayerinmodel.layers[:172]:layer.trainable=False

forlayerinmodel.layers[172:]:layer.trainable=True

model.compile(

optimizer=SGD(lr=0.0001,momentum=0.9),

loss='categorical_crossentropy',

metrics=['accuracy','top_k_categorical_accuracy'])

model.fit_generator(

train_generator,

steps_per_epoch=100,

validation_data=validation_generator,

validation_steps=10,

epochs=nb_epoch,

callbacks=callbacks)

这样就在新的数据集上通过迁移学习训练好一个新的网络了。

需要注意的是

(1) InceptionV3模型的输入为299X299X3,因此数据集上的图片大小得修改为该大小格式:

train_generator = train_datagen.flow_from_directory(

'./data/train/',

target_size=(299, 299),  batch_size=32,

classes=data.classes,

class_mode='categorical')

validation_generator = test_datagen.flow_from_directory(

'./data/test/',

target_size=(299, 299),  batch_size=32,

classes=data.classes,

class_mode='categorical')

image_arr = process_image(image, (299, 299, 3)) #CNN_validate_images

(2) 验证测试数据集时

results=model.evaluate_generator(generator=test_generator,steps=test_data_num//batch_size)#参数steps为数据生成的批次,一般为数据总数除以每批产生的数据个数

(3) 参数设置

#每个epoch后存入val_loss最小的模型checkpointer=ModelCheckpoint(filepath='./data/checkpoints/inception.{epoch:03d}-{val_loss:.2f}.hdf5',verbose=1,save_best_only=True)# patience: number of epochs with no improvement after which training will be stopped. 10个epoch模型性能没有改进后训练停止early_stopper=EarlyStopping(patience=10)

其他代码和使用说明可以详见github项目 UCF-101_video_classification。

你可能感兴趣的:(视频分类之UCF-101上的CNN方法详解)