构造环境

创建一个新的conda环境fawkes

1
2
conda create -n fawkes python=3.7
conda activate fawkes

安装fawkes库:

1
pip install fawkes

构建测试样本

我们寻找一些名人图片用于测试该数据合成模型的效果,因为很多名人已经在网络上泄漏了大量的人脸信息,这些信息已经被识别模型建档

换句话说,这些测试样本需要满足能够被主流的人脸识别程序识别出身份

预期在经过fawkes模型的干扰之后,测试样本无法被识别

需要注意的是,人脸图像不能直接来源于搜索引擎的结果,因为这些图像很可能被用作训练数据集,我们可以在目标人物的演讲视频中截图这样这张图片就从来没有在网络上出现过

我选取了三位外国领导人的人脸图像作为测试样本,放在test_imgs文件夹下

识别测试样本

首先我们需要证明这些测试样本能够被主流人脸识别网站识别身份

这里我选择了一个具有高性能模型的人脸匹配网站

pictrievhttp://www.pictriev.com/?lang=zh#

可以看到,三种图片都被成功识别

安倍晋三和特朗普的识别准确率更是有惊人的90%以上

生成合成数据

接下来我们运行fawkes模型,生成三张测试样本的合成数据

1
fawkes -d ./test_imgs --mode low

由于是第一次运行模型,需要下载模型数据

当模式选为low时,每张图片生成的时间在20秒钟左右

合成数据与原测试样本生成在了同一目录下

我们将生成的合成数据移到另一个文件夹synthesis_imgs,然后再分别生成mid和high的合成数据

1
2
fawkes -d ./test_imgs --mode mid
fawkes -d ./test_imgs --mode high

中度干扰模式中,一张合成数据图需要140秒来生成。而到高干扰模式时,一张合成数据图则需要300秒来生成

最终得到三个测试样本在高中低模式下的合成数据

对比与分析

首先,我们从对同一张图片在不同模式下的扰动上着手分析

写一个python脚本,将同一张测试样本的原图和合成数据放在一起展示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from PIL import Image, ImageDraw, ImageFont
import os

test_img_folder = "test_imgs"
synthesis_img_folder = "synthesis_imgs"
file_names = ["test1", "test2", "test3"]

for file_name in file_names:

original_image_path = os.path.join(test_img_folder, f"{file_name}.jpg")
original_image = Image.open(original_image_path)
low_image = Image.open(os.path.join(synthesis_img_folder, f"{file_name}_low.png"))
mid_image = Image.open(os.path.join(synthesis_img_folder, f"{file_name}_mid.png"))
high_image = Image.open(os.path.join(synthesis_img_folder, f"{file_name}_high.png"))

fontsize = 60
font = ImageFont.truetype("arial.ttf", fontsize)
image_width = max(original_image.width, low_image.width, mid_image.width, high_image.width)
image_height = max(original_image.height, low_image.height, mid_image.height, high_image.height)

total_width = image_width * 2
total_height = (image_height + fontsize + 20) * 2
new_image = Image.new('RGB', (total_width, total_height), 'white') # 使用白色背景
# 将图像按顺序拼接在一起
images = [original_image, low_image, mid_image, high_image]
for i, img in enumerate(images):
x_offset = (i % 2) * image_width
y_offset = (i // 2) * (image_height + fontsize + 20)
new_image.paste(img.resize((image_width, image_height)), (x_offset, y_offset))

# 添加文本标注
draw = ImageDraw.Draw(new_image)
labels = ["Original", "Low", "Mid", "High"]
for i, label in enumerate(labels):
x_offset = (i % 2) * image_width + image_width // 2 - fontsize
y_offset = (i // 2) * (image_height + fontsize + 20) + image_height
draw.text((x_offset, y_offset), label, fill="black", font=font)

new_image.save(os.path.join(synthesis_img_folder, f"{file_name}_comparison.png"))

print("拼接完成")

下面是每个样本的对比图

可以看到,low级别的扰动肉眼基本无法分辨出来

但是high级别的扰动就非常明显了,许多人脸特征与原图有了很大区别

接下来我们测试合成样本的识别结果如何

编写类似的python脚本,将结果放在一账通中对比

首先是样本test1

可以看到,low和high模式下,奥巴马被成功识别为错误身份

接下来分析test2

这张测试样本的合成数据效果不太明显,即使是高级别的扰动也只让预测值从94%下降到77%

经过分析,我认为原因可能是原图的人脸部分不够清晰,导致合成数据时生成的扰动没有太大效果

最后一张test3

可以看到在low和mid模式下,对特朗普的预测值都有不同程度的下降

总的来说,fawkes的对人脸特征的攻击还是有部分效果

但是要达到较高扰动下预测值降低,必须保证原图的人脸足够清晰