374. Deepfake Detection Challenge | deepfake-detection-challenge
漫长的4个月过去了。向所有辛勤工作的参赛者致敬,也感谢主办方安排了这次数据集和比赛。
从社会角度来看,自动深度伪造检测算法在不久的将来将是必须的。从个人角度来看,这次比赛的举办时机对我来说非常好。所以在过去的4个月里,dfdc(深度伪造检测挑战赛)在我脑海中占据了首要位置。
幸运的是,我设法在公开排行榜上获得了第2名。在等待私有排行榜揭晓的同时,我将分享我的解决方案。
请注意,以下所有内容都是我为这次比赛所做的。(本帖不包括我的队友所做的工作)
出于好奇,我将首先分享我想出的主要方法,这些方法提高了公开榜分数。
广泛的数据增强显著提高了公开榜分数并减少了交叉验证(CV)与公开榜之间的差距。我想这使模型对变化的数据更加鲁棒。
我在裁剪人脸时设置了边距,即 new_face_width=face_width*(1+margin)(高度同理)。0.5~0.7 的边距比 0 效果显著更好,并进一步减少了 CV 与 LB 的差距。我猜想模型学会了检测被操纵区域与周围区域之间的不一致性。
调整增强和人脸边距是大幅提升公开榜分数的两个主要因素。
Efficientnet-b4 比 efficientnet-b0 好得多。在广泛的数据增强下,适当的模型大小提高了分数。
我使用了带有分类分支的 Unet 作为模型架构。我计算了伪造视频与对应原始视频之间的像素级差异,生成具有显著差异像素的掩码,并将其用作分割部分的目标。通过使用掩码信息,模型能够知道图像的哪一部分被修改了,我想这有助于提升性能。
正如 CV 与 LB 差异所见,训练数据和测试数据的分布截然不同。将常数(<1)乘以 logit 然后取 sigmoid 有助于改善这种情况下的对数损失。
集成总是有帮助的。
我使用简单的帧平均来获得概率,因此从视频中提取的帧越多越好,直到达到9小时的限制。
现在,我将详细介绍我的旅程。我将其分为10个阶段,每个阶段我都专注于某个特定主题。(标题括号内的数字是该阶段的大致公开榜分数)
这是我第一次接触视频类型的视觉任务和深度伪造检测。所以在比赛一开始,我就在谷歌上搜索文章和论文,Kaggle 讨论区也有一些介绍相关论文的好帖子。
起初,我尝试使用处理时间信息的网络架构,但我发现它们缺乏预训练权重且训练非常繁重,所以我决定基于 FaceForensics 论文介绍的 XceptionNet 建立基线。
在最初的实验中,我尝试通过使用频谱图作为第二输入将音频部分集成到图像模型中,但这并没有多大帮助,反而使过程复杂化,所以我放弃了音频部分。无论如何,我的队友想要音频信息,所以我建立了一个流程,使用 ffmpeg 和 subprocess 在训练和公开测试视频中稳定地提取音频。(我起初使用 PyAv,但它在公开测试视频中不稳定。)
读取视频是运行时的主要瓶颈,所以我努力优化这个过程。最后,我选择了讨论区提供的方法,这是我所尝试过的方法中最快的。我均匀提取了20帧。时长为10秒,所以我每0.5秒提取一帧。
下一步是选择快速但准确的人脸检测器。我搜索发现 retinaface 是在 WIDERFACE 数据集上评估的最佳可用的人脸检测器。此后,我使用了其 PyTorch 实现版本。
为了在训练网络时节省数据加载时间,我首先处理每个 原始 视频并将它们作为压缩的 joblib 文件保存到磁盘。我从每个视频中提取20帧,检测人脸,裁剪它们,并提取额外的元信息保存。保存的视频将是一个形状为 (n_people, n_detected_frames, height, width, 3) 的 numpy 数组。处理视频时有很多琐碎的问题和错误。我将介绍一些。