视频分类之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。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容