雷锋网 AI 研习社按 :本文为知乎主兔子老大 为雷锋网 AI 研习社撰写的独家稿件。
前一段时间用于人物换脸的deepfake火爆了朋友圈,早些时候Cycle GAN就可以轻松完成换脸任务,其实换脸是计算机视觉常见的领域,比如Cycle GAN ,3dmm,以及下文引用的论文均可以使用算法实现换脸(一定程度上能模仿表情),而不需要使用PS等软件手工换脸(表情僵硬,不符合视频上下文),只能说deepfake用一个博取眼球的角度切入了换脸算法,所以一开始我并没有太过关注这方面,以为是Cycle GAN干的,后来隐约觉得不对劲,因为GAN系列确实在image to image领域有着非凡的成绩,但GAN的训练是出了名的不稳定,而且收敛时间长,某些特定的数据集时不时需要有些trick,才能保证效果。但deepfake似乎可以无痛的在各个数据集里跑,深入阅读开源代码后(https://github.com/deepfakes/faceswap),发现这东西很多值得一说的地方和优化的空间才有了这一篇文章。
本文主要包括以下几方面:
解读deepfake的model和预处理与后处理的算法以引用论文。(目前大多文章只是介绍了其中的神经网络,然而这个项目并不是单纯的end2end的输出,所以本文还会涉及其他CV的算法以及deepfake的介绍);
引入肤色检测算法,提升换脸的视觉效果。
干货和口水齐飞,各位客官可安心食用。
虽然原作者没有指出,但从模型和整体方法设计来说,该模型应该是参考了论文https://arxiv.org/abs/1611.09577,其网络结构总体仍是encoder - decoder的形式,但与我们所熟知autoencoder不同的是,他由一个Encoder和两个Decoder组成,两个Decoder分别对应imageA和imageB的解码。
Encoder部分用了简单的堆叠5x5卷积核,采用aplha=0.1的LeakRelu作为激活函数。Decoder部分使用了卷积和PixelShuffer来做上采样,结构上采用了4x4,8x8……64x64这样逐分辨率增加的重建方式(网络整体是类U-net的结构)。
(图为u-net)
如果你想要复现和改进模型的话,需要主要一点的是,虽然我们期望输入A脸然后输出B脸,输入B脸输出A脸,但训练却不把AB脸作为pair输进神经网络(输入A脸,期望在另一端获得B脸),仍然是像训练普通autoencoder的一样,我给出A脸,你要复原A脸,B脸亦然。(用不同的decoder),这样训练的结果是decoderA能学会用A的信息复原A,decoderB用B的信息复原B,而他们共用的Encoder呢?则学会了提取A,B的共有特征,比如眼睛的大小,皮肤的纹理,而解码器根据得到的编码,分别找对应的信息复原,这样就能起到换脸的效果了。
而Encoder获取到共同的特征,比单独学习A的特征,信息要损失得更为严重,故会产生模糊的效果,另一个照片模糊得原因是autoencoder使用得是均方误差(mse)这一点已经是不可置否的了,后文提及的使用GAN来优化,可以一定程度上缓解模糊的问题。
在文处,我就强调了这个不是end2end的东西,接下来就着找介绍deepfake里的预处理和后处理。
我们都知道在CV里用深度学习解决问题前,需要用进行数据增强,然而涉及人脸的数据增强的算法和平时的有一点点不一样。
在开源代码中,作者分别使用了random_transform,random_warp 两个函数来做数据增强。但这个两个函数只是做一些有关比例之类的参数的封装,真正做了转换的是opencv的warpAffine、rmap两个函数。下面分别解读这两个函数做了些什么。
首先解读rmap其直译过来就是重映射,其所做的就是将原图的某一个像素以某种规则映射到新的图中。利用该函数,可以完成图像的平移,反转等功能。
在数据增强中,我们不希望改动数据会影响label的分布,在常见的有监督任务中,数据的标签由人工打上,如类别,位置等,图像的扭曲,反转不会影响到label的分布,但在deepfake中,我们做的是生成任务,作为无监督任务中的一种,其反向转播的误差由图像自己的提供,而要使得数据增强后(代码中的warped_image)有对应的样本(代码中的target_image),作者使用了rmap构造除warped_image,而使用umeyama和warpAffine构造出target_image。
Umeyama是一种点云匹配算法,简单点来理解就是将源点云(source cloud)变换到目标点云(target cloud)相同的坐标系下,包含了常见的矩阵变换和SVD的分解过程,(碍于篇幅本文不作详解)。调用umeyama后获取变换所需的矩阵,最后将原图和所求得矩阵放进warpAffine即可获的增强后对应的target_image。其中warpAffine的功能就是根据变换矩阵对源矩阵进行变换。
上图是经过变型处理的warped_image ,下图是target_image。
说完了数据增强部分后,我们来分解后处理。
在deepfake(上述链接中)的命令行版本中,有一个-P参数,选中后可以实时演示图片的变化过程。在通过预览这个演变过程中,不难发现进入神经网络的不是整张图片,也不是使用extract出来的整个256x256的部分(头像),而是仅仅只有脸部的小区域(64x64)。因此在预测阶段,首先就是截取人脸,然后送进网络,再根据网络的输出覆盖原图部分。
至于将头像部分传进网络,也并非不行,脸部还是会可以进行转换,但背景部分也会变得模糊,且很难修复,因此我们只选择脸部替换。
在脸部替换后,会出现如下问题:
肤色差异,即使是同种人,也会有细微的差异。
光照差异,每张照片的光照环境不同
假脸边界明显
前两者的造成原因一是客观差异,二是和数据集的大小相关,作为想给普通的用户用,数据集太大了,用户承受不起,数据集太小,神经网络学习不多。
至于最后一点则是前两者造成的,但这一点可以通过降低分辨率缓解。这也是很多网上小视频假脸边界不明显的原因,因为很少会有一张脸占屏幕80%的画面。但如果你直接用在256x256的头像图上则边界效果明显,如下图:
(原图,下文所有图片的原图都是这个,由官方提供)
该图使用的是官方提供的预训练权重和数据。接下来在试试低尺寸下的视觉效果:
相对来说,边界效果没那明显了。
至于另外的两个问题,官方给出了下面的几种后处理方法缓减:
smooth_mask
这个方法解释其实起来很简单,你神经网络输出的图像不是很模糊吗?要模糊变清晰很难,但清晰变糊还不简单吗?直接用高斯模糊将边界进行处理,从而让过渡看起来自然。
adjust_avg_color
这个方法背后的理论同样很简单,假设A图要换成B图,那么做法就是A图加上自身和B图的每一个像素的均值的差值,算是作为一种色彩的调和。
(左图未经处理,右图经过上述两种方法处理)
以上两种便是deepfake默认的处理方式。下面介绍另外一种图像编辑常用的算法,这种算法作为deepfake的后备选项,由参数-S控制。
此外,deepfake给出了基于泊松融合算法的来进行后处理,泊松融合的大致思想提供一个一个mask矩阵,背景区域为0,ROI区域(region of insteresing 这里就是指脸部,下文同一简称ROI)的区域为255,算法通过该矩阵得知拿一步分是融合的部分,然后通过计算梯度,用梯度场作为指示,修改ROI的像素值,使得边界与原图更为贴切。
( 图片源于网络)
Deepfake中的泊松融合可以选择两种模式。一种以人脸矩形框为边界,另一种以人的特征点(即人脸边界和眼睛边界)为边界。
(左图未经处理,右图在整个替换区域进行泊松融合)
事实上,这里得补充一点,人脸检测和定位如果不想自己实现,一般有两种实现方法(在本地实现),一种是使用dlib库提供的api,另一种是使用opencv。dlib,face_recongize的模型比opencv的精度要高的,但要自己下载模型(模型比较大),且这个库的编译在windows上比较麻烦,但对于特征点检测,opencv没有现成的特征点检测的接口。如果有同学不想依赖dlib,这里提供一种方法来代替在泊松融合时的特征点定位问题。(人脸检测可以使用opencv即可)
显然,我们选择人脸的特征点的位置信息,目的时为了只替换人脸,这样可以尽量将信息损失(模糊)局限于人脸部分,而其他部分则保留原图的清晰度,而我们刚才说过了,deepfake并不将全图放进神经网络,而是将人脸部分(由人脸检测算法确定),定位后的ROI是以人脸为主的矩形,这时唯一的肤色就只有人脸部分了,不用太过担心其余噪音干扰。
如果再人脸定位这一步出错,那么使用肤色检测还是人脸特征点两种方法,都不会有太大差别。因此,使用肤色检测在这种场景上,在效果上一定程度能代替人脸特征点检测这种方法。
下面解释肤色检测如何使用。总的来说,肤色检测一般常见RGB,HSV和YCrCb空间的检测,所谓的YCrCb空间,Y代表的是亮度,Cr与Cb代表的都是色度,而HSV空间H代表色调,S饱和度,V亮度,RGB则是常见的红绿蓝空间。
下面只介绍RGB空间下的肤色检测,无需依赖其他库,手写即可,亦可以达到不错的效果。
检测规则如下:
R>G and R>B and |R - G| > 15
在(1)满足下,(R > 95) and (G > 40) and (B > 20) and (max(R, G, B) - min(R, G, B) > 15)
在(1)满足,(2)不满足下,(R > 220) and (G > 210) and (B > 170),则可认为该像素是肤色。
(左图未经处理,右图经过肤色模型构造mask矩阵,再进行泊松融合)
最后说说deepfake可以优化的空间。
Deepfake出现后也有很多工作对deepfake进行优化,包括使用GAN的,这些优化的针对生成图像的质量,但目前看质量没有太大的提升,同时几乎没有工作是针对模型的训练速度和图像的后处理。
本文最后提出的肤色检测代替原来人脸特征点检测的,算是一种补充。
我也曾经尝试过一些模型压缩的算法,虽然在原始数据下可以恢复精度,但迁移的能力差(因为参数少了)。而deepfake的目的是做成一款app,(已经有了,叫fakeapp,在deepfake的基础上添加了图形界面),那么就不能不考虑软件的体积,fakeapp共1.8G,以及没有GPU的普通用户在自己数据集上迁移的时间。
在Reddit上,作者是指出,在GPU上模型训练要几小时,而CPU要近3天,这已经超出很多人的忍受范围了。
深度学习走入寻常百姓家,尤其是有自定制需求的深度学习,仍然任重道远。
二十年前我还是一名本科生的时候,就对计算机算法很感兴趣。当时深蓝战胜了卡斯帕罗夫,大家都普遍会议论到围棋,并且基本的观点都一致,就是计算机虽然在国际象棋上战胜了人类,但是离在围棋上战胜人类还有相当遥远的距离。没想到二十年后,我已经可以借助先进的4G通讯技术,实时收看AlphaGo在围棋上击败人类的全过程,真的是感慨万千。
虽然我不做科研很多年,但出于兴趣还是将DeepMind团队发表在Nature上的论文阅读了一遍。之后发现,很多围棋爱好者、很多对AI感兴趣的人虽然在网上发表了诸多议论,但是很少有真正了解AlphaGo是怎样“思考”和下棋的。考虑到很多AI领域、深度学习领域的专家不屑于科普AlphaGo的“算法”,而更多的人又不愿意去啃那篇论文,干脆我就来抛砖引玉,将AlphaGo的“思考过程”和大家做个普及性分享,并谈谈自己针对未来AI和深度学习领域的认识。
一、AlphaGo“思考”的过程
考虑到我们人类认识问题都愿意自顶向下,先看到全局再看局部。所以我先介绍一下AlphaGo“思考”的全过程。
形象地说,AlphaGo有四个思考用的“大脑”,也就是DeepMind团队训练出来的四个神经网络,用论文中的符号表示,就是Pπ、Pσ、Pρ和Vθ,为了方便起见,给它们起名为“快速走子网络”、“专家训练网络”、“自我提升网络”和“价值判断网络”。前三个神经网络都以当前围棋对弈局面为输入,经过计算后输出可能的走子选择和对应的概率,概率越大的点意味着神经网络更倾向于在那一点走子,这个概率是针对输入局面下所有可能的走子方法而计算的,也就是每个可能的落子点都有一个概率,当然会有不少的点概率为0。第四个神经网络是进行价值判断的,输入一个对弈局面,它会计算得出这个局面下黑棋和白棋的胜率。
简单的解释一下前三个网络的区别:“快速走子网络”是一个比较低水平但是计算量也很小的神经网络;“专家训练网络”的参数都是通过职业棋手对弈的棋局训练出来的,它的激活函数和具体的卷积核数量以及相应神经元数量会与“快速走子网络”有所不同,表现为计算量不同,水平也不同;“自我提升网络”是在“专家训练网络”的基础上,通过电脑自我对弈的大量棋局进行提升训练后的网络,理论上讲水平更高,计算量与“专家训练网络”是一样的,只是训练出来的参数不同。
训练好这四个神经网络之后,AlphaGo就可以开始与人对弈了。对弈过程中,AlphaGo的“思考”是通过蒙特卡洛博弈树搜索和模拟来实现的。大致步骤如下:
(1)假设当前棋局状态为St,对于每一种可选择的走法a,选择走a之后的棋局价值Q(St,a)与“专家训练网络”计算出的走a的概率P(St,a)之和最大的那种a,记为at。注意,这里面的Q(St,a)不是简单的靠“价值判断网络”计算出来的,而是“价值判断网络”计算结果与蒙特卡洛模拟结果的加权平均;这里的P(St,a)也不是直接用“专家训练网络”计算出来的,而是正比于Pσ(St,a)/(1+N(St,a)),N(St,a)是(St,a)这个节点所经过的搜索次数,为了鼓励搜索模拟,“专家训练网络”所得到的走子概率用搜索次数进行了衰减。
(2)按照(1)中的方法继续搜索选择下一级节点,直到搜索下去碰上一个叶子节点,也就是原来没有再继续展开的、没有评估过的节点。
(3)将这个叶子节点SL展开,并用“价值判断网络”计算其价值Vθ(SL),然后用“快速走子网络”在这个节点的基础上进行多局自我对弈,根据多局对弈的胜负比率来估算胜率Z(SL)。最后使用Vθ(SL)和Z(SL)的加权平均来估算此节点的胜率。
(4)将估算结果反向更新到这次搜索途经的全部节点,反向更新公式稍复杂,就不再列了,本来目的就是普及性介绍嘛。
(5)之后再从St开始,仍然按照(1)的规则重新搜索。
至于蒙卡搜索模拟到什么时候,取决于给AlphaGo多长的时间走一步棋,时间快到的时候,AlphaGo就停止搜索模拟,并以跟节点St下搜索途经次数最多的节点(因为每次都是选最佳节点搜索模拟,所以搜索结束后就以途经次数最多作为标准了)作为自己本步的着法。
以上就是AlphaGo思考的全过程,其实和人类很类似,有思考下一步着法的“大脑”,有判断局面价值的“大脑”,然后再向后推断若干步,确定自己的“走法”。
二、卷积神经网络(CNN)的极简介绍
下面简单介绍一下卷积神经网络。先说神经网络,就是模拟人类或者动物大脑,用若干个神经元共同计算逼近某种复杂计算(函数)的方法。其实任何一种价值判断都可以理解为某种多元函数,输入若干数据(信息),输出结论。数学上可以证明,使用神经网络(多层)可以无限逼近这些多元函数。
拿围棋来讲,假设每种局面下会有一种或几种最理想的走法,那么就可以将局面作为输入,理想走法作为输出形成一类多元函数。理论上,神经网络可以无限逼近这个函数。由于围棋局面可以看成一个19*19的图像,而卷积神经网络(CNN)又是处理图像比较理想的方法,所以DeepMind团队就使用了CNN。
当然CNN为什么设置为13层的神经网络,每层的卷积核有几个,激活函数是什么,使用什么样的误差传递函数来反向训练这个神经网络,这些都需要尝试,这才是DeepMind团队最主要的成果,当然论文里面也不会详细说了。
一个问题是,训练最基础的“专家训练网络”所使用的数据是大量职业棋手的棋局,但是没有理由认为职业棋手的走法就是最佳走法,所以这种训练实际上是用一种有误差的数据进行的,当然训练出来的神经网络也不会绝对理想。但是,如果AlphaGo真的在这种训练下达到高水平,以后可以考虑使用高水平AlphaGo自我对弈的棋局重新训练形成“专家训练网络”,也许效果会更好。
三、关于论文中的几个有趣事实
(1)“快速走子网络”计算一次需要2微秒,“专家训练网络”计算一次需要3毫秒。
(2)“快速走子网络”与专家走法的匹配准确度为24.2%,“专家训练网络”则为57%。
(3)“自我提升网络”和“专家训练网络”对弈胜率为80%。
(4)“价值判断网络”在使用职业棋手对局数据进行训练时,发生了过度拟合的情况,训练组偏差0.19而测试组达到0.37,说明泛化效果不好。为了解决这个问题,改用了“自我提升网络”自我对弈3000万局作为“价值判断网络”的训练数据,基本解决了过度拟合的问题。
(5)DeepMind团队发现,在蒙特卡洛树搜索时,计算下一步走子概率使用“专家训练网络”效果要优于使用“自我提升网络”,虽然“自我提升网络”与“专家训练网络”对弈时胜率高达80%。但是在训练“价值判断网络”时,使用“自我提升网络”自我对弈的棋局效果好于使用“专家训练网络”。
(6)计算上,多线程搜索使用CPU处理,策略和价值并行计算使用GPU处理。单机版的AlphaGo使用了40个线程、48个CPU和8个GPU。分布式版的AlphaGo使用了40个线程、1202个CPU和176个GPU。
(7)分布式版本对单机版的胜率为77%。
四、澄清一些观点及个人思考
(1)AlphaGo有自己的“棋风”么?
从人类的角度看,某个固定版本的AlphaGo肯定会有自己的“棋风”,因为训练好的神经网络参数就决定了它会如何“判断”,蒙卡搜索算法又决定了它的“思考”过程,这些综合在一起就形成了它的走棋风格。但是这种风格是在大量数据训练后形成的,肯定与人类的风格很不一样。它未必有系统的、前后一致的特点,它的风格更多体现在某种局面下会有怎样的判断倾向。当然,是否能够被人类准确抓住不好说。
(2)AlphaGo在第四局“抽风”的bug好解决么?
个人认为不好解决。训练形成的神经网络里面有大量的参数,这些参数都不是程序员设定的,而是软件自己学习形成的。如果这些参数不尽合理,在某些局面下会误判,那么可能的解决办法就是重新训练或者加强训练,绝不可能由哪个人直接修改某些参数来消除bug。严格的说,没有哪个人敢随意修改神经网络参数,所以在与李世石这五局对局过程中,AlphaGo版本是没有任何变化的。
(3)关于人工智能在深度学习技术下的可能发展?
首先,个人认为那种能够威胁人类的AI还远远看不到希望,目前的AlphaGo是在“监督”下学习,还算不上完全自我学习。即使不久的将来能自我学习了,也不过是针对围棋,并不是万能的“学者”。我觉得人类还没必要担心AI会威胁人类。
其次,AI这次在围棋上战胜人类顶尖高手,基本证明了所谓的“棋感”、“棋风”、“大局观”等围棋高手所谈论的虚的能力,并不是人类独有的,经过训练的神经网络也会有。所以,随着技术的进步,我相信电脑也会能够欣赏艺术(音乐、画作、小说、笑话),能够创作文学、艺术作品,能够针对不同的情况形成自己的“情绪”。但是这些都不是人类害怕AI的理由,因为这些始终都是通过计算实现的,其实是我们人类可控的。
未来的AI可以帮助人类搞科研、分析数据、协助医疗、创作诗歌、写新闻报道等等,我相信这些都会是人类科技的进步,都会让生活更美好。当然在享受这些美好的同时,也需要记住,世界上所有的事情都是双刃剑,AI也可以用来骗人、作恶,这就需要善良的人类通过有效的管理措施和监督措施,通过法律,禁止人们开展“坏”AI的研究。
相关问答
在学术论文查重中,固定算法是否被查重取决于论文检测系统的具体算法。一些查重系统会将固定算法作为一种特殊模式进行识别,并将其计入重复率计算。这意味着,...
自然科学,主要是数学和算法。数学建模,总的来说,就是把遇到的问题,用数学的方法来建立模型,以计算机辅助求得优化结果.正式的数学建模比赛中,问题的本身是...
知网论文查重由于是采用了最先进的模糊算法,如果整体结构和大纲被打乱,可能会引起同一处的文章检测第一次和第二次标红不一致或者第一次检测没有标...
查重检测是全选,2113所以摘要、5261目录、结语、后记、附录4102,只要十三个字一样就算重复,那是机器1653检所以很机械的。知网检测,就是用一定的算...
[最佳回答]ThispaperfirstintroducesthebasicknowledgeofDFTandspectrumanalysis,introducesthe"f...
算法工程化是一个涉及将算法理论转化为实际应用的过程。这个过程涵盖了从简单的算法模型调用,如基于算法开发服务或封装接口对外服务,到部署算法到具体硬件上...
博士都不容易毕业。毕业看论文是否达标、boss是否同意。到达一定年限不毕业学校就会劝退。博士都不容易毕业。毕业看论文是否达标、boss是否同意。到达一定年...
目前我国的研究算法、的论文较多,与我国的教学工作的纲要有很大的关系,本科生的课程要求写论文,要经过专家的评审才能过关。研究生、博士生需要在国内、国外主...
论文的查重率是通过比较论文中的文本与已有文献或互联网上的其他文献的相似度来确定的。查重率通常以百分比表示,表示论文中的多少内容与其他来源相似。以下...
以下是一些关于计算机病毒的论文题目供您参考:计算机病毒的防范与控制方法研究计算机病毒的特征与识别算法研究计算机病毒对网络安全的威胁及应对策略计算...