AI换脸新“邪术”?一文教你用FaceNet秒侦破

全文共4341字,预计学习时长12分钟

AI换脸新“邪术”?一文教你用FaceNet秒侦破

图片来源:CNN-business

某天,你谈了三个多月的网恋对象,在你要求面基的后三秒毫不犹豫地将你从朋友列表拉黑删除。

你心里咯噔一下,先不说平时一言不合就发的红包,光转账就好几笔巨款。你心想,完了,被骗了。

你慌忙拿着对方发给你的自拍照去警察局报了案。

结果警察告诉你,不好意思先生,这张照片是AI合成的,照片里的人根本不存在。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

AI换脸新“邪术”?一文教你用FaceNet秒侦破

AI换脸大行其道,直叫人真假难辨!

AI换脸术早在17年就在国外引发过热烈讨论和争议,各种换脸视频的背后,是一种叫做Deepfakes的技术。

这项技术进入大众视野最初是由于Reddit论坛上一个名叫“DeepFakes”的用户上传了一个成人电影片段,视频中该用户将《神奇女侠》女主角盖尔·加朵的脸换到了一名成人电影女演员的身上,竟看不出丝毫破绽。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

此后,Deepfakes用来指代使用AI来更换视频中人脸的技术。

AI换脸术让广大中国网友惊掉下巴的可能要数今年2月,一段B站某up主发布的“杨幂版1994年《射雕英雄传》”视频在网路上疯传。

这段视频被转发到微博上引发了网友们的广泛关注和热烈讨论,后由于涉嫌侵权被作者下架,在下架之前该条微博阅读量就已高达1.2亿,评论数多达2.8万条。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

事实上,不止杨幂,B站上的名场面几乎被up主们恶搞了个遍。比如让网友们惊呼“息影后再出国际巨作”大战灭霸的徐雷神,还有“忘记海王长什么样了”气势汹汹的江海王。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

当然,AI换脸界种子选手微博用户@慢三与偏见前不久又坐不住了,这不,当“傲娇小可爱”苏大强换上男神吴彦祖的脸,竟也是毫无违和感。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

因为换过后的脸实在太过自然,自然到让不熟悉他们的人在乍看这些视频时都不会觉得有什么异常。

虽然技术本身是很有趣,也让大家调侃道“未来演员都不用去现场录制了,直接后期处理换脸就行”,但也让不少网友感到担忧。当不法分子用爱豆的脸散播一些不当言论或者做出一些不当行为时,带来的负面影响将会非常可怕。

比如微博用户CareRoy_王源反黑组就曝光了最近有人利用AI换脸技术在微信冒充王源发表不实言论并在企鹅群内骗取粉丝刷礼物,让很多粉丝上当受骗多受困扰。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

此外,有很多女明星的脸被用在一些不可描述的视频上。比如前面讲到的盖尔·加朵,还有艾玛·沃特森、石原里美等等。

甚至,爱研究黑科技的英伟达公司在18年12月用计算机生成了一批人脸,然而这些人脸压根就不存在。也许就像开篇我们提到的,有一天你可能真的会“爱”上一个本就不存在的人。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

当AI换脸成为挤掉各大美颜软件的新一代“邪术”,我们该如何应对?

AI换脸新“邪术”?一文教你用FaceNet秒侦破

AI做的恶,让AI 来解决。

AI换脸术以假乱真的当下,其背后所引发的一系列网络和技术安全问题,必须予以高度重视。用AI做的恶,自然也要用AI来解决。

近日,由DEF CON和百度安全联合主办的2019第二届DCCB(DEF CON CHINA Baidu)安全行业国际峰会在北京正式开幕。DEF CON被誉为极客界的“奥斯卡”,是全球网络安全界顶级会议之一。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

图片来源:DCCB官网首页

“伪造视频有很严重的安全威胁,我们需要用技术去检测。”百度安全研究人员说。

会上,来自百度安全的专家们向参会者展示了识破换脸术的两种方法。据介绍,他们在探索换脸术危机的应对策略时,同样使用了基于深度神经网络的识别方法,他们发现用AI来解决AI,是一种行之有效的手段。

方法之一实际还是“看”。但这个“看”,跟人类用肉眼看有所不同,它是用计算机去识别视频画面中肉眼观察不出的一些低级特征,比如每一帧视频的分辨率、色度等。毕竟Deepfakes生成的换脸视频多少都有些“造”的痕迹,比如画面不清晰、脸部轮廓不流畅不自然等等。通过AI来识别这些人眼不可察的“瑕疵”,就能一秒勘破换脸术。

方法之二是基于谷歌提出的FaceNet算法模型,这个模型原本是用来做人脸检测的。简单来说,其实就是将输入的人脸图片映射成一个向量,通过计算向量在欧式空间的距离,如果距离非常相近,就说明是同一个人。反之,则不是。通过该技术来比对人脸信息特征,算法就能找出处理后的换脸视频。具体针对FaceNet的技术解读,可以看下一部分介绍。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

图片来源:DCCB官网首页

当然,除了百度安全专家们提出的这俩勘破换脸术的手段,国外也有不少在此方面的研究,具体不再一一介绍。

此外,据媒体报道,达特茅斯学院的一位教授正在开发一款可以识别假的政治视频的软件,目的是防止公众因为受到假的政治演讲视频误导而对美国接下来的大选投票产生不良影响。

美国一位研究员Siwei Lyu目前也正在与美国国防高级研究计划局(DARPA)开展深度合作,致力于开发可以检测并过滤掉Deepfakes视频的软件,以防止被操纵的虚假内容被上传到互联网上。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

正式动手前,再来了解一下FaceNet

本文最后一部分将会教你怎么在移动端(Android 或者IOS系统均可)用代码实现你自己FaceNet,但在此之前,我们再来简单介绍一下FaceNet。

FaceNet是一种高性能的人脸识别、验证和聚类神经网络。它具有22层深度神经网络,可直接训练其输出维度为128维。FaceNet的结构如下图

AI换脸新“邪术”?一文教你用FaceNet秒侦破

Deep Architecture就是传统的CNN,论文中只提到使用的是GoogleNet,但没具体说用的是GoogleNet的哪个版本,不过这不是关键。

通过 CNN 将人脸映射到欧式空间的特征向量上,在FaceNet训练期间,深层网络提取并学习各种面部特征,然后计算不同图片人脸特征的欧式距离。训练原则是基于相同个体的人脸距离总是小于不同个体的人脸距离这一先验知识。

测试时只需要计算人脸特征,然后通过事先设定好的阈值即可判定两张人脸照片是否属于同一个人。

FaceNet一文中的最大亮点,就是作者提出的Triplet Loss损失函数。以往的损失函数都是一个或者两个,而本文作者开创性地提出了三元组损失函数。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

举例来说,我们想要比较埃隆·马斯克的照片(Anchor),如果我们输入了另一张埃隆·马斯克的照片,那么我们得到了一个Positive;但如果我们输入的是约翰·特拉沃尔塔的照片,那就是一个Negative。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

因此,在欧式空间中,经过神经网络学习后,Anchor图像会更接近Positive样本图同时远离Negative样本图。这样就达到了我们鉴别是否属于同一个人的人脸的目的。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

勘破换脸术?你的手机就可以

在移动设备上运行AI模型时,需要考虑内存和解析开销的问题,而Tensorflow提供的.tflite文件格式就是为了解决深度学习模型在移动设备上运行时的资源受限问题。

下面我们一步一步来看

第一步,克隆FaceNet存储库

$ git clone

我们将量化大小为512维的预训练FaceNet模型,你也可以选择使用具有128维大小的模型。在量化之前,该模型的大小约为95MB。

wget模型到 ../facenet/models/目录

$ ls -l models/
total 461248
-rw-rw-r — @ 1 milinddeore staff 95745767 Apr 9 2018 20180402–114759.pb

在你的机器上安装Tensorflow

$ pip3 install tensorflow

注意你的python版本需要大于等于3.4

第二步,划分阶段

这里我们将模型实现分为几个分支,这样将减少操作总数,同时考虑到在移动端,我们就不训练了,直接进入图像推断分支。

如果你尝试将FaceNet模型.pb文件转换为.tflite,你将会收到BatchNorm的错误提示:

ERROR: mean, multiplier and offset needs tobe constant.

如何解决呢?在代码中,我们设置is_training = False以便BatchNorm按照推理模式来工作。下面这段代码设置了arg_scope,因此在全局的BatchNorm中都适用。

inception_resnet_v1.inference(data_input, keep_probability=0.8, phase_train=False, bottleneck_layer_size=512)
Here: 
is_training = phase_train = False

要创建一个仅用来推理结果的模型,请将以下代码粘贴到inference_graph.py目录下的文件中 ../facenet/

import tensorflow as tf
from src.models import inception_resnet_v1
import sys
def main():
 
 traning_checkpoint = “models/model-20180402-114759.ckpt-275”
 eval_checkpoint = “model_inference/imagenet_facenet.ckpt”
 
 data_input = tf.placeholder(name=’input’, dtype=tf.float32, shape=[None, 160, 160, 3])
 output, _ = inception_resnet_v1.inference(data_input, keep_probability=0.8, phase_train=False, bottleneck_layer_size=512)
 label_batch= tf.identity(output, name=’label_batch’)
 embeddings = tf.identity(output, name=’embeddings’)
 
 init = tf.global_variables_initializer()
 with tf.Session() as sess:
 sess.run(init)
 saver = tf.train.Saver()
 saver.restore(sess, traning_checkpoint)
 save_path = saver.save(sess, eval_checkpoint)
 print(“Model saved in file: %s” % save_path)
if __name__ == “__main__”:
main()

运行脚本创建仅推理模型,将其保存在../facenet/model_inference/目录下

$ python3 inference_graph.py models/ model_inference/

Facenet提供freeze_graph.py文件,我们将使用它来冻结推理模型。

$ cd ./facenet 
$ python3 src / freeze_graph.py model_inference / facenet_frozen.pb

生成冻结模型后,将其转换为.tflite文件

$ tflite_convert --output_file model_mobile/my_facenet.tflite --graph_def_file facenet_frozen.pb --input_arrays “input” --input_shapes “1,160,160,3” --output_arrays "embeddings" --output_format TFLITE — mean_values 128 --std_dev_values 128 --default_ranges_min 0 --default_ranges_max 6 --inference_type QUANTIZED_UINT8 --inference_input_type QUANTIZED_UINT8

我们已经将float32与quint8进行了比较,并将尺寸缩小了三倍。让我们检查量化的模型大小:

$ ls -l model_mobile/
total 47232
-rw-r — r — @ 1 milinddeore staff 23667888 Feb 25 13:39 my_facenet.tflite

要验证 .tflite模型性能,我们需要如下代码:

import numpy as np
import tensorflow as tf
# Load TFLite model and allocate tensors.
interpreter = tf.lite.Interpreter(model_path=”/Users/milinddeore/facenet/model_mobile/my_facenet.tflite”)
interpreter.allocate_tensors()
# Get input and output tensors.
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
# Test model on random input data.
input_shape = input_details[0][‘shape’]
input_data = np.array(np.random.random_sample(input_shape), dtype=np.uint8)
interpreter.set_tensor(input_details[0][‘index’], input_data)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0][‘index’])
print(‘INPUTS: ‘)
print(input_details)
print(‘OUTPUTS: ‘)
print(output_details)

输出如下:

$ python inout.py
INPUTS:
[{‘index’: 451, ‘shape’: array([ 1, 160, 160, 3], dtype=int32), ‘quantization’: (0.0078125, 128L), ‘name’: ‘input’, ‘dtype’: <type ‘numpy.uint8’>}]
OUTPUTS:
[{‘index’: 450, ‘shape’: array([ 1, 512], dtype=int32), ‘quantization’: (0.0235294122248888, 0L), ‘name’: ‘embeddings’, ‘dtype’: <type ‘numpy.uint8’>}]

看起来输出正如我们所期待的那样。这下,轮到你动手了。

尽管,Deepfakes就像是计算机病毒一样,只要有人找到了杀毒的方法,它就会变异成另一种更强大的病毒。它和侦破它的技术不停地捉迷藏、缠斗,就像一个巨大的GAN一样。但不管怎样,邪不压正,总是没错的。

真撕破脸,难看的总是作恶的那一方。

AI换脸新“邪术”?一文教你用FaceNet秒侦破

留言 点赞 关注

我们一起分享AI学习与发展的干货

欢迎关注全平台AI垂类自媒体 “读芯术”