专栏首页GiantPandaCV基于Kaggle DeepFake比赛的代码实战

基于Kaggle DeepFake比赛的代码实战

1. 介绍

本文使用Kaggle的Deepfake比赛数据集,使用CNN+LSTM架构,对视频帧做二分类,该项目部署在百度的aistudio上进行训练。

2. 确定整体架构

  • 首先是对视频进行「抽帧」,并将抽帧图片保存至文件夹内。
  • 其次是对视频帧截取人脸,这里我直接使用了「paddlehub的预训练人脸检测模型」
  • 删除图片数量过少的文件夹,一开始我们保存了15帧图片,我们最后模型是使用10帧,而经过人脸检测模型,有些图片检测不到人脸,因此就不会截取出来。我们会写一个代码「删除掉人脸图片少于10的文件夹」
  • 数据装载器,不同于以往的CNN数据装载器,由于我们要输入到RNN,是以一个序列输入,因此这里我们要「额外增加一个维度」,形如(batch, timestep, channel, height, width),也就是将一个文件夹里的10张图片作为一个batch。
  • CNN卷积网络,这里使用的是EfficientNet,我是针对pytorch版本改写得到的
  • LSTM网络,这里我用的是卷积版本的LSTM,同样也是由pytorch版本改写得来(https://github.com/ndrplz/ConvLSTM_pytorch)
  • 网络训练代码
  • 网络验证代码

3. 生成数据

第一步是解压我们的数据集,然后是针对视频进行抽帧,这里我们的策略是从0到中间位置「随机选取起始帧」,每隔2帧进行帧的抽取。这里我们使用的是cv2库里的VideoCapture函数,参数是视频位置,返回一个视频流对象,然后我们调用set方法获取指定视频帧,最后以 「视频文件名_标签_帧数」的格式保存截图文件。并且由于样本极度不平均(真:假=4:1),我加入了一个下采样,进行样本平衡,使得真假视频比例维持在1比1,具体代码位于SaveFrameImage.py。

你可以在代码里面修改你想保存图片至指定的文件夹路径

我们需要生成训练集和验证集,因此我们后续修改文件夹名字为validate_frame_image。验证集所需图片数量不需要太多,我们运行一段时间可以通过上面的中断按钮,终止验证集图片生成。

接着是安装paddlehub的人脸检测模型

创建文件夹face_image和validate_face_image,通过指定SaveFaceImage.py里面的文件夹名字,分别对视频帧进行人脸检测,并截取人脸图片保存至刚刚我们创建的文件夹中

4. 图片筛选

由于存在人脸漏检的情况,我们这里运行testScript.py 将少于10张图片的文件夹删除掉

这里使用的是shutil.rmtree模块

5. 数据装载器

5.1 数据增强

我们使用了之前论文里面提到的JPEG+Blur的图像预处理方法,resize图片至224x224分辨率,最后做归一化

5.2 数据生成器

我们通过文件名,将文件夹的人脸帧,按照帧位置进行排序

然后装进10x3x224x224的nparray当中

同理把标签装进nparray当中,大小为1

最后将人脸图片以及标签添加至列表,组合成一个batch,通过yield关键字转化成生成器,减少内存占用

最后我们测试一下数据生成器以及图像增广是否正确

6. 网络架构

6.1 EfficientNet

这里我采用的是EfficientNetB0结构,网络主体是EfficientNet.py,网络相关参数和其他操作是在model_utils.py文件里

6.2 LSTM

这里使用的是卷积版本的LSTM,相关代码在convlstm.py当中

7. 组合模型

这里采用的是CNN+全连接层+LSTM+两层全连接层的架构

具体代码在CNNRNNModel2.py当中

在CNNEncoder这个类中,我们的前向传播函数与传统CNN的有些区别

输入形如(batch, timestep, channel, height, width)

我们先根据「时间步维度」,对每一批做卷积,卷积的结果再「调用stack函数堆叠到batch维度」,由于使用了flatten函数,我们卷积结果会损失两个维度,为了输入进后续的RNN中,我们使用unsqueeze函数增加两个维度

我们这里设置LSTM隐层数为256,由于将视频抽取10帧,因此最后输出为10x256=2560

最后通过两次全连接层

这里使用shape为2x10x3x224x224的nparray进行测试

8. 训练

这里以batch=8,优化器为Adam(学习率=0.0001),采用交叉熵损失函数训练200轮

可以看到loss还是下降的很快的,如果发现准确率不变可能是初始化问题,重新启动一下训练程序即可

9. 验证

我们调用eval.py文件,后面跟网络权重名字,对模型进行测试

在20多条数据中,准确率接近83%,我们的模型还有很大的改进空间

10. 总结

这是我第一次做Kaggle的比赛,比赛期间提交失败,后续这几个月才弄出来。期间也踩了许多坑,改了很多Bug,以下几点是我的经验

  • 通过「可视化」查看图像预处理是否正确
  • 搭建好CNN,最好先「放到一个简单的分类任务」上,观察网络是否运行正确
  • 搭建好整个模型,可以先在一个「比较小的数据集」上,调节学习率,batchsize等参数,「以防后续训练不收敛无法定位问题」
  • 当代码没问题,模型运行结果不正确,比如每次运行eval.py所得的结果不一样,那么最好是查查是不是「某些API被框架废弃不使用」
  • 结构越复杂效果不一定越好,为了更好泛化需要一定程度上「减小模型复杂度」
  • 如果模型收敛不明显,可以对各个神经层「进行参数初始化」,初始化不同收敛快慢也不同

最后是项目地址

https://aistudio.baidu.com/aistudio/projectdetail/316583

本文分享自微信公众号 - GiantPandaCV(BBuf233),作者:zzk

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 利用渐进校准网络(PCN)的实时角度无关人脸检测

    然后现在的很多人脸检测器比如我们介绍过的MTCNN,FaceBoxes,RetinaFace等等都实现了高精度的实时人脸检测,但这些算法往往都是在直立的人脸上表...

    BBuf
  • 基于RNN网络的Deepfake检测

    大部分检测假脸工作是在图片上进行的,而针对deepfake视频往往有很少检测方法。这个工作里我们提出了一种基于时间序列的处理方法,用于检测Deepfake视频。...

    BBuf
  • 人脸识别系列二 | FisherFace,LBPH算法及Dlib人脸检测

    前面介绍了使用特征脸法进行人脸识别,这里介绍一下OpenCV人脸识别的另外两种算法,一种是FisherFace算法,一种是LBPH算法。

    BBuf
  • 云计算类型介绍

    高德纳公司(Gartner)所提出的“炒作周期”(hype cycle)着实了不起。这个周期包括“期望膨胀期”以及“幻觉破灭期”。所以,这本身就带有非常浓厚的娱...

    PALIN
  • 云存储安全问题首当其冲 三个步骤不可少

    目前市场上仍然存在大量的中小型企业由于缺少投入,管理水平较低,而在数据资源的管理上缺乏有效的管理机制,迫切需要实现基本的文档集中存储、传递与共享,云存储应运而生...

    静一
  • 【DB笔试面试659】在Oracle中,SELECT ... FOR UPDATE加的是什么锁?

    其中,这个OF子句在涉及到多个表时,具有较大作用。若不使用OF指定锁定的表的列,则所有表的相关行均被锁定。若在OF中指定了需修改的列,则只有与这些列相关的表的行...

    小麦苗DBA宝典
  • 人脸识别系列三 | MTCNN算法详解上篇

    我们前面分享了PCA,Fisher Face,LBPH三种传统的人脸识别算法,Dlib人脸检测算法。今天我们开始分享一下MTCNN算法,这个算法可以将人脸检测和...

    BBuf
  • 通俗易懂讲一下:QOS 概念及术语

    TOS、DSCP、PHB、COS、EXP(MPLS的)、ipv6TC(ipv6 Traffic Class)

    网络技术联盟站
  • climits

    <climits>头文件定义的符号常量 CHAR_MIN       char的最小值 SCHAR_MAX      signed char 最大值 SCHAR...

    lpxxn
  • “历史遗留”漏洞:浅析新型SSL/TLS漏洞FREAK

    最近安全研究人员发现一种新型SSL/TLS漏洞。预计在十年内,数以百万计的苹果、安卓用户访问HTTPS网站时将可能遭受中间人进而被窃取账号和密码,即使这些网站使...

    FB客服

扫码关注云+社区

领取腾讯云代金券