暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kaggle DFDC 大型翻车现场

Techdemic 2020-04-29
582

前段时间跟大家分享了我们在KaggleDFDC比赛中用的解决方案。先解释一下,那个Top2%是Public LB的Top2%。就在上周三,Private LB放榜了,放榜现场跟05原油价格跌到负数一样让人大跌眼镜。很多Public LB的前排队伍都消失在了Private LB上。

这个是Public LB的金牌区:

这是Private LB的金牌区:

最后的金牌区14支队伍有10支都是从银牌区升上来的,也就是说10支Public LB金牌队伍都翻车了,也算是一次大地震了。后台也有朋友关心我们的成绩如何,实不相瞒,我们也从2%掉到了6%。

01
复盘Top solutions

说不失落那是不可能的,不过还是决定复盘一下,查查原因。在Discussion里面我们看到了两篇金牌区的分享帖[1][2],分别是第三名和第八名的解决方案,也刚好一个是是没翻车的队伍,一个是逆袭的队伍。

第三名的方案是一个纯2D-CNN方案,也确实如作者所说:"Keep it simple"。

  • MTCNN提取人脸。

  • 人脸检测框扩大30%。

  • 1:1采样正负样本。

  • EfficientNet

模型层面足够简洁,干货都在预处理和后处理上。

训练的时候,采用了一系列常规augmentation:

Compression, Noise, Blur, Resize, Color jittering

  1. def create_train_transforms(size=380):

  2.    return Compose([

  3.        ImageCompression(quality_lower=60, quality_upper=100, p=0.5),

  4.        GaussNoise(p=0.1),

  5.        GaussianBlur(blur_limit=3, p=0.05),

  6.        HorizontalFlip(),

  7.        IsotropicResize(max_side=size)

  8.        PadIfNeeded(min_height=size, min_width=size, border_mode=cv2.BORDER_CONSTANT),

  9.        OneOf([RandomBrightnessContrast(), FancyPCA(), HueSaturationValue()], p=0.7),

  10.        ToGray(p=0.2),

  11.        ShiftScaleRotate(shift_limit=0.1, scale_limit=0.2, rotate_limit=10, border_mode=cv2.BORDER_CONSTANT, p=0.5),

  12.    ]

  13.    )

为了防止过拟合,提高模型泛化能力,他们使用了domain specific augmentations,根据MTCNN的面部关键点删除人脸的部分区域(半边脸,嘴巴,眼睛或者鼻子)。除此之外,还针对真脸和假脸做了SSIM,把不同区域作为关键特征,确保在删除区域的时候不会删除关键特征。这一步应该是整个pipeline的点睛之笔,既提高了泛化能力,也变相的将模型注意力放在了真脸假脸的区别上,需要很强的数据处理能力。他们做的结果如下(结合了参考资料[3]和[4]):

预测时,每个视频取32帧。这里还有个sao操作,人为设置了一个规则来做average predict:

  1. def confident_strategy(pred, t=0.87):

  2.    pred = np.array(pred)

  3.    size = len(pred)

  4.    fakes = np.count_nonzero(pred > t)

  5.    if fakes > size // 3 and fakes > 11:

  6.        return np.mean(pred[pred > t])

  7.    elif np.count_nonzero(pred < 0.2) > 0.6 * size:

  8.        return np.mean(pred[pred < 0.2])

  9.    else:

  10.        return np.mean(pred)

也就是说只选择一些非常确信的预测结果来获得平均预测结果,这就解决了我们之前在做average predict时遇到的得分普遍在0.3-0.8之间的问题。当时我们想到用中位数或者其他分位数来代替均值,但也没想到还能这样处理,确实学到了。

第八名的方案,则是一个纯Video解决方案,他们用了3D CNN(I3D, 3D ResNet等)融合了一个2DCNN模型,一共8个模型。

原贴没有说太多关于数据处理的细节,所以我们也没法很好的去对比和评价。因为这个比赛最大的难度现在来看是如何有效提高泛化能力,抛开数据单纯谈论模型,没有太大意义。

02
总结

这个比赛给我带来的最大感触是,不要尝试一味地拟合Public LB。回想当时我们在刷分的时候,唯一的目标就是提高Public LB的分数,忽视了泛化能力的提升。当时的想法还是Public LB的分布理应是跟Private LB分布差不多的。现在看来趋势就是要让model能在现实世界中使用,而不是只活在数据集中,因此分布一致的假设还是不应该再有了,尽力提高泛化能力才是王道。某种程度上来说,这是一件好事,一个好的趋势,可以让未来比赛的产出更加直接,甚至可以直接被工业界使用。

另一个感触就是,Data Science的比赛,终究还是数据为王,在整个比赛过程中,我见过前排队伍说LSTM有用,也见过说LSTM没用的;见过说3D CNN有用,也见过说3D CNN没用的;当然,也见过说average predict有用和没用的。但是仔细想来,这些方法在正确的数据下,应该都是可行且有用的,产生这些不一致结果的根本原因是不同的输入数据。在我看到的这些高分开源方案中,基本都对数据做了细致的分析和处理,这部分应该是我以后的比赛中最需要提升的。

03
参考资料

[1] https://www.kaggle.com/c/deepfake-detection-challenge/discussion/145721

[2] https://www.kaggle.com/c/deepfake-detection-challenge/discussion/140364

[3] Chen, Pengguang. "GridMask Data Augmentation." arXiv preprint arXiv:2001.04086 (2020).

[4] Li, Lingzhi, et al. "Face X-ray for More General Face Forgery Detection." arXiv preprint arXiv:1912.13458 (2019).

往期精彩回顾
Kaggle DFDC挑战赛(附Top2% 解决方案)
【Go语言专题】实战CSP并发编程
【Python专题(三)】Python模块导入与路径管理
我就知道你“在看”


文章转载自Techdemic,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论