baseline发布 | OPPO 安全AI挑战赛,人脸识别对抗攻击赛题详解

百家 作者:OPPO安全应急响应中心 2021-07-30 19:39:15


baseline线上评测101.53分,文末附项目github地址。

今年6月,由OPPO发起,OPPO安全主办的“OPPO安全AI挑战赛”正式拉开序幕。比赛主要聚焦人脸识别场景中的对抗攻击。为了模拟真实的人脸识别场景并增加比赛的难度,主办方在后台使用了一组已经添加了防御措施的识别模型,要求参赛选手在不知道这些后台模型具体细节的前提下,对它们进行黑盒攻击。


扫描下方二维码

或点击阅读原文

前往大赛官网报名参赛


赛题介绍

比赛任务

本次比赛主要使用人脸识别数据集,具体的图片来自公开数据集 CASIA-FaceV5 和 CelebA 中的人脸图片。每个人都有2-5张不同图片,并被保存在一个文件夹中(如./images/0/,./images/1/…)。


参赛者需要修改这些图片,并保留原始图片尺寸和数据集目录结构。同时,对图片的修改必须足够微小。关于扰动的添加对于图像质量的影响,比赛组织者采用添加了扰动 Lp 范数和 Full Reference-IQA (FR-IQA) 来进行评价,其中 FR-IQA 部分将采用 MS-SSIM 图像结构相似性指标来进行量化。


除了自动判断外,在线下决赛环节,组织者还会对对抗样本的肉眼视觉差异进行更加严格的评判,即对抗样本和原始样本的视觉差异越小越好。


在把数据集提交到系统后,后台的防御模型会对上传数据集进行预测。攻击数据集要尽量让防御模型产生错误的结果。当攻击不成功时,得分为0,当攻击成功时,得分由扰动添加前后的图像差异大小来衡量,对原图的影响越小得分越高。最终得分由扰动大小和判断原图片和修改后图片的图像质量评分(multi-scale structural similarity)共同决定。


赛程与奖励

【大赛赛程】

06月18日-09月15日|组队报名

07月12日-09月15日|线上初赛

09月26日-10月21日|线上复赛

  11月|线下决赛


【奖金设置】

总奖金60万元

冠军:15万元

亚军(2支队伍):每支队伍9万元

季军(3支队伍):每支队伍5万元

优胜奖(4支队伍):每支队伍3万元

大赛地址:https://security.oppo.com/challenge/home.html


baseline

作者:孙裕道

北京邮电大学博士生,主要研究方向为人工智能安全中深度情绪识别模型的攻击和防御。



模型介绍

给定待攻击的干净样本和不同人名的的目标样本。将干净样本,对抗样本和目标样本一同输入到多个人脸识别模型中,经过多个模型整合后得到与之对应的人脸编码向量,和。计算和的相似度,并且我们希望的值越小越好。计算和的相似度,我们希望的值越大越好。通过优化的损失,得到对抗扰动,从而能够达到以上两个目的。利用正则化损失来限制对抗扰动扰动的范围。得到的对抗扰动经过高斯平滑后与人脸一起加在干净样中得到更新后的人脸对抗样本。




人脸Mask

本次比赛的任务是攻击人脸图像,考虑现有神经网络模型在训练人脸数据的时候对于重要的部位是比较敏感的。因此添加对抗扰动时只针对人脸的五官。使用  标定人脸的   ,选取了  个点连接组成一个待攻击的区域,对于很少的无法用  标定  的图片,手动框出人脸范围。最后将生成的人脸  转化成  j矩阵对对抗扰动  做矩阵乘法。



人脸识别模型

人脸识别模型的训练可以利用如下人脸识别网络结构在本地训练自己的人脸识别模型,也可以下载已经训练好的人脸识别模型参数。给定一张人脸图片,经过多个人脸识别模型生成多个人脸编码向量,最终整合成一个人脸编码向量。

人脸识别模型网络结构:

  •  链接:https://github.com/davidsandberg/facenet

  •  链接: https://github.com/luckycallor/InsightFace-tensorflow.git

  • 链接:https://github.com/sirius-ai/MobileFaceNet_TF.git

  •  链接:https://github.com/yule-li/CosFace.git



相似度计算

人脸编码向量之间的相似度计算可以分为和。表示的是对抗样本与干净样本人脸编码向量之间的相似度。表示的是为对抗样本与目标样本编码向量之间的相似度。给定向量和,向量的相似度计算公式可以被总结为:

  • 内积计算:


  • 余弦相似度:


  • 欧氏距离:


  • 皮尔逊相关系数:


  • 斯皮尔曼相关系数:



最常用的相似度计算公式是余弦相似度,时间允许的情况下其它的相似度计算公式可以尝试看看,是否也会对成绩有所提高。

在无目标攻击的视角下,对抗样本的人脸编码向量的与干净样本编码向量的相似度越小越好,关于样本的负梯度方向是我们想要的方向:


在有目标攻击的视角下,对抗样本的人脸编码向量的与目标样本编码向量的相似度越大越好,关于样本 的梯度方向是我们想要的方向:


综上所述总的相似度计算如下公式:



此时对的梯度方向能够同时获得有无目标攻击和有目标攻击的这两个梯度方向:





正则化损失

正则化损失可以分为损失函数和损失函数,它们的作用是限制对抗扰动的大小并对图像进行平滑处理。


范数损失

给定干净人脸图像和对抗图像

  • 形式:

  • 形式2:


损失

全称Total Variation Loss,其作用主要是降噪,图像中相邻像素值的差异可以通过降低TV Loss来一定程度上进行解决 ,从而保持图像的光滑性。

  • 连续的定义为:


其中是定义域。


  • 离散的定义为:



在比赛中,采用的是离散的,并且阶数取为



动量迭代

本次比赛主要利用的是基于梯度的迭代攻击,在迭代的攻击过程中加入动量项之后可以稳定更新方向并在迭代期间从较差的局部最大值中离开,从而产生更多迁移性更强的的对抗样本。为了进一步提高黑盒攻击的成功率。具体的计算公式如下所示:




图像去噪平滑

生成的对抗扰动通过高斯滤波进行去噪平滑。考虑到OPPO人脸对抗样本线上测试可能会有高斯滤波这种防御机制因而在算法生成噪声的时候加入高斯滤波一定程度上也能使防御机制失效从而提高样本攻击率。使用高斯核函数进行卷积就能完成上述操作,高斯核如下:




核心代码

如下代码为人脸对抗样本生成的过程,对照上面的模型流程图以及各个模块的细节讲解在代码中都有所显示,主要的核心代码提供了详细的解释和注释。

def adv_attack(tmp_noise, origin_img, target_img, mask, gaussian_blur, model_pool, index, loss1_v, momentum=0, lr=1):
    tmp_noise.requires_grad = True
 # 对对抗扰动进行高斯平滑处理
    noise = gaussian_blur(tmp_noise)
 # 对人脸图像的扰动范围进行限制
    noise *= mask
    loss1 = 0
 # 整合多个人脸识别模型的人脸编码向量
    for model_dict in model_pool:
        model = model_dict['model']
        proportion = model_dict['proportion']
        # 对抗样本的人脸编码向量
        v1 = l2_norm(model(origin_img + noise)) 
        # 干净样本的人脸编码向量
        v2_1 = l2_norm(model(origin_img)).detach_()  
        # 目标样本的人脸编码向量
        v2_2 = l2_norm(model(target_img)).detach_() 
        # 对抗样本和干净样本之间的内积相似度,越小越好
        tmp1 = (v1*v2_1).sum() 
  # 对抗样本和目标样本的内积相似度,越大越好
        tmp2 = (v1*v2_2).sum()  
        r1 = 1
        r2 = 1
        if tmp1 < 0.2:  
            r1 = 0
        if tmp2 > 0.8
            r2 = 0 
        # 将两个相似度进行整合成总的相似度函数
        loss1 += (r1 * tmp1 - r2 * tmp2) * proportion  # Cos Loss
 # 求解相似度关于样本的梯度
    loss1.backward(retain_graph=True)  
    loss1_v = tmp_noise.grad.detach() * (1 - momentum) + loss1_v * momentum  
    tmp_noise.grad.data.zero_()
    # L2范数损失和TV损失的量级比较大需要将它们适当的缩小
    r3 = 1
    if index > 100:
        r3 *= 0.1
    if index > 200:
        r3 *= 0.1
 # L2范数的损失
    loss2 = (noise**2).sum().sqrt() 
 # TV损失
    loss3 = tv_loss(noise)  # TV loss
    # 求解正则化L2和TV损失函数关于样本的梯度
    loss = r3 * 0.025 * loss2 + r3 * 0.004 * loss3
    loss.backward()
 # 将相似度损失的梯度与正则化损失的梯度进行整合得到对抗扰动
    tmp_noise = tmp_noise.detach() - lr * (tmp_noise.grad.detach() + loss1_v)
 # 将对抗扰动的像素进行适当的截断
    tmp_noise = (tmp_noise + origin_img).clamp_(-11) - origin_im g
    tmp_noise = tmp_noise.clamp_(-0.20.2)
    return tmp_noise, loss1_v

(滑动查看完整代码)



github代码及其成绩


项目的  代码链接为:https://github.com/guidao20/OPPO_ADVERSARIAL_ATTACK


相关的细节已经在  中有所介绍。因为前期需要处理生成人脸 之类的操作需要耗费一定的时间,在中程序共耗时一天多,前面的铺垫工作完成后,生成人脸对抗样本的时间大约只有不到个小时。

最终初赛的评测成绩为



点击“阅读原文”进入官网报名参赛~

最新动态

60万奖金花落谁家?OPPO安全AI挑战赛初赛正式开战
OPPO智能护盾助力软件商店,全力守护APP使用安全
红蓝对抗之ATT&CK框架入门和解读
揭秘QUIC的性能与安全
OPPO互联网DevSecOps实践


关注公众号:拾黑(shiheibook)了解更多

[广告]赞助链接:

四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/

公众号 关注网络尖刀微信公众号
随时掌握互联网精彩
赞助链接