上个月主要是基于TensorFlow使用4卡训练,用Kinetics400数据集预训练的I3D模型,对UCF101 split1进行finetune,从训练精度和效率上做了很多零碎的实验,稍微总结一下实验结果:
1、首先只使用RGB帧,基本上训几个epoch就能达到95.7%,这个问题不大,学习率合适即可。四卡大概两三小时就训出来了。
2、投了一些时间在TensorFlow的多机多卡的加速上,由于公司都是使用集群,所以真实的端口和IP尤其重要,注意区分容器的端口和IP。另外表示使用dataset API的话,速度比队列快,然后多进程,预取都要用上,尽可能把内存小的操作放在前面速度更快,速度太慢可以考虑cache。用htop观察CPU,同时watch nvidia-smi观察GPU实时占用率,看看是不是IO卡训练速度,当然也可以使用前面说的timeline。
3、tf.train.MonitoredTrainingSession()是个好东西啊,写代码更简洁了。
4、实现了快速的video IO(即读入video然后on the fly的做decoding)!!!!这个很重要!!!在大数据集下(如Kinetics400或者Kinetics600)on the fly decode比先把video转成frames再来处理会高效而且方便很多,不需要先解码视频存成帧在硬盘。Kinetics400视频大概130+G,处理成RGB帧估计要1T以上,不仅浪费存储而且预处理总是费时间的。我也在不断优化tf代码,现在on the fly的训练速度基本上和解码存帧差不多甚至更快。关键发现在于opencv > videoFileclip, nvvl>= ffmpeg ,经同事提醒才知道opencv解码真心快。虽然在后面三个也分别实现了,甚至考虑了cache,浪费了一点时间。
5、使用video IO 训UCF101,当然也是更快的复现了95.7%的精度咯~
至此,I3D与UCF101算是告一段落了。
总结完,想到今年在三星中国研究院打activitynet18的时候,当时使用的还是自己改的caffe,然后预取RGB和optical Flow存硬盘里,才能进行训练,而且需要SSD。现在想想,当时真的应该早点学TensorFlow写video IO,然后跑3D CONV,一劳永逸。不过话说回来,以当时的资源情况。也只能把2D玩到极限,caffe的速度还是挺快的,不过由于存图太多(大概一两亿图片,现在感觉是肯定卡了IO,实际速度应该更快),存储需要太大,三星买了两个4T硬盘,现在想想觉得其实如果实现了快速video IO,本是不需要买的。