返回列表

Public 2nd (Private 30th) Place Solution

374. Deepfake Detection Challenge | deepfake-detection-challenge

开始: 2019-12-11 结束: 2020-04-23 AI安全与对抗 数据算法赛
Public 2nd (Private 30th) Place Solution

公开榜第2名(私有榜第30名)解决方案

作者:YoonSoo
发布时间:2020-04-01

漫长的4个月过去了。向所有辛勤工作的参赛者致敬,也感谢主办方安排了这次数据集和比赛。

从社会角度来看,自动深度伪造检测算法在不久的将来将是必须的。从个人角度来看,这次比赛的举办时机对我来说非常好。所以在过去的4个月里,dfdc(深度伪造检测挑战赛)在我脑海中占据了首要位置。

幸运的是,我设法在公开排行榜上获得了第2名。在等待私有排行榜揭晓的同时,我将分享我的解决方案。

请注意,以下所有内容都是为这次比赛所做的。(本帖不包括我的队友所做的工作)

出于好奇,我将首先分享我想出的主要方法,这些方法提高了公开榜分数。

公开榜的要素

1. 数据增强

广泛的数据增强显著提高了公开榜分数并减少了交叉验证(CV)与公开榜之间的差距。我想这使模型对变化的数据更加鲁棒。

2. 人脸边距

我在裁剪人脸时设置了边距,即 new_face_width=face_width*(1+margin)(高度同理)。0.5~0.7 的边距比 0 效果显著更好,并进一步减少了 CV 与 LB 的差距。我猜想模型学会了检测被操纵区域与周围区域之间的不一致性。

调整增强和人脸边距是大幅提升公开榜分数的两个主要因素。

3. 模型容量

Efficientnet-b4 比 efficientnet-b0 好得多。在广泛的数据增强下,适当的模型大小提高了分数。

4. 多任务学习

我使用了带有分类分支的 Unet 作为模型架构。我计算了伪造视频与对应原始视频之间的像素级差异,生成具有显著差异像素的掩码,并将其用作分割部分的目标。通过使用掩码信息,模型能够知道图像的哪一部分被修改了,我想这有助于提升性能。

5. 保守修正

正如 CV 与 LB 差异所见,训练数据和测试数据的分布截然不同。将常数(<1)乘以 logit 然后取 sigmoid 有助于改善这种情况下的对数损失。

6. 集成

集成总是有帮助的。

7. 推理时的帧数

我使用简单的帧平均来获得概率,因此从视频中提取的帧越多越好,直到达到9小时的限制。



现在,我将详细介绍我的旅程。我将其分为10个阶段,每个阶段我都专注于某个特定主题。(标题括号内的数字是该阶段的大致公开榜分数)

阶段 1. 搭建流程 (0.69)

这是我第一次接触视频类型的视觉任务和深度伪造检测。所以在比赛一开始,我就在谷歌上搜索文章和论文,Kaggle 讨论区也有一些介绍相关论文的好帖子。

起初,我尝试使用处理时间信息的网络架构,但我发现它们缺乏预训练权重且训练非常繁重,所以我决定基于 FaceForensics 论文介绍的 XceptionNet 建立基线。

在最初的实验中,我尝试通过使用频谱图作为第二输入将音频部分集成到图像模型中,但这并没有多大帮助,反而使过程复杂化,所以我放弃了音频部分。无论如何,我的队友想要音频信息,所以我建立了一个流程,使用 ffmpeg 和 subprocess 在训练和公开测试视频中稳定地提取音频。(我起初使用 PyAv,但它在公开测试视频中不稳定。)

读取视频是运行时的主要瓶颈,所以我努力优化这个过程。最后,我选择了讨论区提供的方法,这是我所尝试过的方法中最快的。我均匀提取了20帧。时长为10秒,所以我每0.5秒提取一帧。

下一步是选择快速但准确的人脸检测器。我搜索发现 retinaface 是在 WIDERFACE 数据集上评估的最佳可用的人脸检测器。此后,我使用了其 PyTorch 实现版本。

为了在训练网络时节省数据加载时间,我首先处理每个 原始 视频并将它们作为压缩的 joblib 文件保存到磁盘。我从每个视频中提取20帧,检测人脸,裁剪它们,并提取额外的元信息保存。保存的视频将是一个形状为 (n_people, n_detected_frames, height, width, 3) 的 numpy 数组。处理视频时有很多琐碎的问题和错误。我将介绍一些。

  • 裁剪的帧大小不相等 -> 直接调整大小以匹配一个视频内的最大尺寸
  • 有些视频有2个人 -> 设置置信度分数阈值,如果检测到的第二置信度人脸的置信度分数大于阈值,则确认有2个人
  • 检测器在一个视频的某些帧中找到人脸,但在其他帧中找不到 -> 直接忽略未检测到的帧
同比赛其他方案