换脸技术已经火了好几年了,很是惭愧,之前都没有好好的研究过其背后的技术原理,最近在看人脸属性编辑相关的东西,无意中看到换脸技术(DeepFakes)能将人脸的表情、光照等变换的那么自然(虽然是有很多的前提条件),就想着认真学习一下,或许能从中得到些做人脸光照变换的灵感。
基础架构:自动编码器
自动编码器是一种无监督的神经网络模型,它可以学习到输入数据的隐含特征,称为编码(encode),同时用学习到的新特征可以重构出原始输入数据,称之为解码(decode)。从直观上来看,自动编码器可以用于特征降维,类似主成分分析PCA,但是其相比PCA其性能更强,这是由于神经网络模型可以提取更有效的新特征。除了进行特征降维,自动编码器学习到的特征可以送入有监督学习模型中,这样自动编码器可以起到特征提取器的作用。通过对隐向量施加约束,自动编码器还可以用于生成与训练样本不同的新数据,这就是变分自动编码器,也是一种很常见的生成模型。
以人脸为例,上图显示了将人脸进行编码以及解码的过程。编码器将人脸编码为较低维度的表示,称为潜在向量或隐向量。接着通过解码器重建出原本的人脸。自动编码器是有损的,因此重建的人脸很难具有与输入的人脸相同的细节。
DeepFakes模型架构
我们忽略人脸检测对齐等操作。仅仅考虑如何将一张脸A(甚至不包含轮廓)用另外一张脸B来进行替代,如下图所示。仔细想想不难发现,换脸任务要做的其实是保留脸A的表情与光照等共同属性(例如,每个人都可以做到咧嘴笑),而替换人脸固有属性如鼻子大小、嘴唇颜色等,这就是标题中的信息分离的说法。
不同的人脸使用不同的自动编码器训练显然是不行的,那样无法提取出共同特征。DeepFakes是让两个网络共享相同的编码器,但是解码器是使用各自不同的。如下图所示,注意图中的encoder是同一个。
在看到这个模型之前我就很清楚模型在做的一定是信息分离,但是这个模型是如何分离信息的呢?各部分的信息保存在哪里呢? 这都是一开始我想问的问题。
其实我一开始认为只有隐向量才能作为信息的载体,但是其实编码器解码器何尝不能作为信息的一种载体呢? 因此我的理解是共享编码器的做法使得隐向量只保留了人脸A和人脸B的一些共同属性(如表情与光照条件),而人脸的固有属性则保留在各自的编码器当中。例如人脸A是一个哭泣的表情,那么经过编码器编码成隐向量之后,该隐向量只保留了“哭泣”的表情信息,而解码器当中包含了人脸A的固有属性信息,因此它能做到“生成一个哭泣的A”。
信息分离的其他例子
FaderNet[2]是另外一个信息分离的典型例子,它同样是一种自动编码器架构,但是它没有用到多个解码器,而是将其整合成一个。以人脸光照变换任务为例,我们有很多不同光照条件的人脸图,我们希望能通过输入不同的“y”(见下图)来控制解码之后的人脸光照。从信息分离的角度来说我们需要编码之后的隐向量E(x)尽可能只包含除了光照以外的信息,而将光照的信息由“y”和“解码器”共同储存。
该模型确实也是这么做的,只是它做的方法比较新颖,它引入了对抗训练的思想,用一个判别器去判别隐向量E(x)的光照类别,判别器Dis和编码器E相互对抗。编码器E的目标是尽可能使得隐向量E(x)不被判别器分类成功,这样就表明E(x)中不包含光照的信息了;而判别器Dis的目标则是尽可能判别出E(x)所对应的光照类别。这样一来,E(x)中的光照信息就被分离出去了。
DeepFakes给我的思考
- 最直接的想法---能否用换脸技术做人脸光照变换?
我认为是可以的,但是可能成本和效果不成正比。我们希望用换脸技术对身份为A的人进行光照变换,那么由于在换脸技术中光照和表情等信息都是由另一个身份B的人脸提供的,因此我们需要身份B的人脸当中有各种表情、各种姿态、各种光照条件的充足人脸数据。当某张A的人脸图需要变换光照时,找出B中表情、姿态与该张图片相似但是光照不同的B人脸进行变换即可。该想法的要求是:
- 理想情况下B的数据集应该足够多以至于包含了全部的表情、姿态、光照,这一点就很难做到了
- 虽然不用和B一样严格,但是A也需要提供一定数量的不同表情、姿态、光照数据集,以供模型学习共性与特性的分离
- 若要对身份C的人脸进行光照变换,那么还需要再进行一次训练
这想法确实有点繁琐且前提条件较多,但是效果不知道会不会好。我认为工业界或许会进行这样的尝试,昨天在《vslam14讲》中看到一句话很有感触---“学术界总是追求‘大而干净’的问题,而工业界追求的是实用”。就像在slam问题中学术界总想单一用摄像头拍摄的图像进行定位与构图,但是工业界则会加入IMU,激光等多种传感器来简单的提升效果。
-
DeepFakes架构和FaderNet架构的信息分离性能比较
从共性的方面来说,两种架构都是将共性的信息保存在隐向量当中,不同的是DeepFakes将特性信息保存在不同的解码器当中(例如A的人脸特性保存在解码器A当中,而B的则保存在解码器B中),但是FaderNet就将特性全部保存在一个解码器当中,然后通过输入不同的“y”去控制激活哪部分的特性信息。直观上感觉的话一定是deepfakes的做法能更好的保存特性,因此我的第二个想法是扩展deepfake架构,编码器依然是一个,但是解码器可以扩充为多个,以光照为例,结构如下图所示
但是这样的问题是当需要变换的类别很多时(光照可不止左中右三种),就需要有很多的解码器,因此这个方法太占内存且训练也慢,但是可能效果会有些许提升。
引用:
[1]: https://www.alanzucconi.com/2018/03/14/understanding-the-technology-behind-deepfakes/
[2]: https://arxiv.org/pdf/1706.00409