Paper link: https://arxiv.org/abs/2005.03922

Code link: https://github.com/VIS-VAR/LGSC-for-FAS

简介:

    最近读到了一篇百度在人脸活体领域的新作LGSC,感觉思路相当清奇,从异常检测的角度来解决活体问题,假设活体样本具有某种共同属性,属于一个closed-set,而攻击样本作为这个活体closed-set意外的异常,属于一个open-set(如图1所示)。定义了一个spoof cue map的概念,即攻击和活体之间的difference,并明确这种spoof cue只在攻击中存在,在活体没有(spoof cue map是all-zero map)。为了学习这种spoof cue map,作者通过显式的regression-loss、隐式的metric-learning和辅助分类器来做监督,有意思的是这篇文章里只对活体做了显式监督,只对活体做显式监督,通过隐式监督在特征空间里推开攻击,更神奇的是,这篇文章直接使用spoof cue map的magnitude做预测,而不是用分类器,也就是作者用分类器的作用是为了让整个网络学习到更合适的spoof cue map,而不是用分类器做决策,个人感觉这从一定程度上减轻了通过二分类解决活体模型的泛化性问题。文章在siw、oulu这些比较权威的活体数据集都SOTA了。更神奇的是,竟然在faceforensic++人脸伪造检测榜单上直接刷新了新纪录,并且直接开源了代码。感觉是挺靠谱的工作。

Residual-learning Framework

网络采用U-Net的结构作为spoof cue generator(图2),输入为人脸RGB图像(归一化-1到1),输出为原图大小的spoof cue map,编码器采用ResNet18(pre-trained on ImageNet),解码器D含四个ResNet Block其中每个结构如下图,上采样,2x2卷积,concatenation对称部分编码器的输出,第四个解码Block输出Tanh使器归一化-1到1。Decoder的五个block输出进行三元组度量学习,输出spoof cue map进行L1回归,最后spoof cue map加回到原始图像进行二分类(辅助分类器采用ResNet18)。文章中说这种overlay的方式是为了更好的学习spoof cue map,即采用分类器的目的不是为了做决策,而是为了让spoof cue map有更好的可区分性和泛化性。

Regression loss:

方法前提假设,只有攻击样本才具有欺骗线索,所以活体样本线索图应为全零图,而欺骗线索图应是非零图,回归网络只对活体样本进行全零图回归,而不对攻击样本做任何的显示监督,回归loss采用pixel-wise L1 loss:

Metric Learning:

使得网络特征在活体样本类间更紧凑,活体与攻击样本间更疏远,对于每个特征层输出,先进行全局平均池化(GAP)得到特征向量,每个训练,同个Batch在线收集合法三元组,其中anchor只属于活体样本:

Auxiliary Classifier:

将线索图加回到原图,构成重叠的图,作为分类模块输入进行分类,目的用于提取更好的 spoof cue map。

Test Phase

这篇文章和以往的大多数活体方法有一个明显的不同点,不再使用分类器结果做决策,而是直接简单粗暴的使用generator输出的spoof cue map来做预测,神奇的是,这种方式预测得到的结果竟然比分类器的效果更好。个人觉得这个原因在于使用分类器多少存在过拟合的问题。这篇文章的作者应该是想学习一个好的feature,而不是一个好的分类器,并且也确实通过联合监督学习到了一个足够robust的feature(spoof cue map),基于feature的magnitude就能得到一个足够好的决策边界。

Results:

论文实验SOTA结果这里就不贴出来了,详情见论文。下面介绍一下开源代码在人脸伪造检测(FaceForensics Benchmark)复现效果,先贴个结果图,轻轻松松达到0.818,因为用了人家的方法,也就没有再显示出来,不过能达到这个指标真心美滋滋。

下面介绍一下复现过程:

1.数据下载

登陆FaceForensics++官网,写个申请,就可以得到一个数据下载的脚本,配置好需要的数据,根据开源说明,下载了C23和C40两种压缩比的视频数据数据,视频数据不是很大,总共加起来4.67 GB,还要下载测试数据0.6GB,也就是榜单测试集数据。

2.数据预处理

原始数据为视频数据,所以需要进行拆帧和裁剪人脸,拆帧直接采用opencv,拆帧率大概每5帧保留一帧,人脸检测直接采用了MTCNN,差不多裁成下图那样。最后得到得到160G的拆帧数据,大概100万训练数据(建议边拆帧边裁剪保存,不然需要很大空间)。标签文件保存为txt文档,每行为图像路径+label(注意:0为活体样本,1为攻击样本,lgsc是基于spoof cue map的magnitue来做预测的,即数字越大越可能为攻击,越接近0越可能为活体,开源代码最后预测表示逻辑是反过来的),用空格间隔

数据路径:

3.训练

下载开源代码:https://github.com/VIS-VAR/LGSC-for-FAS, 单卡16Gv 100大概训练了15个epoch,训练大概5天。

  • 环境配置:

开源代码为paddle动态图代码,安装paddle 1.7.1, 这里需要注意cuda版本

pip install paddlepaddle-gpu==1.7.1.post97

由于需要用到resnet18 pytorch 版本的imagenet预训练模型,所以还需要pytorch

pip install torch

  • 转换与训练模型:

下载imagenet预训练模型resnet18, 放到新建pretrained文件夹下,

python convert.py

得到如下:

python train.py 

训练数据比较大,在平衡正负样本比例之后,一个epoch实际接近150万数据。

4.测试提交

指定测试模型的参数路径,

指定测试数据集路径,

最后直接运行测试脚本

python test.py

1000个测试样本(注意:有部分测试数据集图像包含两个人脸,可能一个是真样本,一个是假样本,按理解只要图像里面有攻击样本,图像就应该为攻击样本),下载测试提交样式,然后提交测试结果(注意提交的是json文件的压缩包,且压缩包不能包含文件夹)。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐