首页 > 编程知识 正文

ai换脸教程,ai换脸算法

时间:2023-05-03 12:56:52 阅读:145116 作者:2829

各位,转载的话请注明出处。 http://blog.csdn.net/jiangjun show

还记得前言2018月3月热播的reddit的deepfake吗? 如果把视频中的头像换成别人的头像,可能会有点粗糙模糊,但分辨率不是很高也能达到假乱真的效果。

举个栗子,如下图所示,是将rzdds变成快乐鸡的演讲视频。

另外,也会和川普改变热情的太阳的脸。

当然这只是DeepFake冰山的一角,DeepFake当初火的原因可以说是很多有宅心的程序员们一起奋斗的结果。 那个,呃,可以把你想要的脸变成视听。 当然,这里不举行示威,禁止相关的reddit论坛。 所以这里不怎么讨论。

相关研究其实深度学习换脸的研究已经很普遍,有基于GAN的,也有基于Glow的,但本质上只是生成模型,改变了实现方式,这种DeepFake是机器学习中的http://www.ssw

技术解说人脸交换是计算机视觉领域中比较受欢迎的应用,人脸交换一般可用于视频合成、提供隐私服务、肖像画交换和其他创新应用。 以往,脸部的更换是通过分别分析两者脸部的类似信息来进行的。 也就是说,通过特征点的匹配,从一张脸上提取眉毛和眼睛等特征信息,匹配到另一张脸上。 这个实现不需要训练,也不需要数据集,但是实现不好,不能自己修正脸部表情。

在最近发展起来的深度学习技术中,通过深度神经网络提取输入图像的深层信息,读取其中内在的深层特征,可以实现新的任务。 例如,样式转换通过读取训练后的模型并提取图像中的深层信息来实现样式交换。

有时利用神经网络进行脸部置换(face-swap ),其中利用VGG网络进行特征提取,实现脸部置换。 在这里,通过特殊的自编码器结构实现了脸部置换,取得了良好的效果。

背景:自编码器类似于神经网络。 可以说是神经网络的一种。 接受训练后,可以尝试将输入复制到输出中。 自编码器和神经网络一样有隐含层

h能将输入解析为编码序列,再现输入。 来自编码器内部的函数

H=F(X )可以编码,还有一个称为r=g (h )的函数,如下图所示。

(自编码器结构是,输入x,将f作为编码函数,将x作为隐式特征变量h,g作为解码网络,通过重构隐式变量h获得输出结果r。 也可以看出,在编码器中输入数字2后,获得其隐含层的编码,即Compressed representation,然后在解码器中重新生成)

现代自编码器在宏观上也可以理解为随机映射

p_encoder(h/x )和p _ decoder (x/h )。 传统的自编码器通常用于数据降维和图像去噪。 但是,近年来随着神经网络的发展,研究了更多的潜在变量,自编码器也被带入了生成式建模的前沿,可以用于图像生成等。

网络框架应该如何通过自编码器实现我们的面部交换技术呢?

到目前为止,已知自编码器可以学习输入图像的信息以对输入图像信息进行编码,并将编码信息存储在隐含层中,并且解码器使用所学习的隐含层的信息重新产生先前输入的图像,但是如果两个不同的单独图像集的图像被存储在自编码器中

如上图所示,如果我们只是简单地把两个不同的脸部集合扔到自编码网络中,选择损耗函数进行训练,这样训练也一无所获,所以我们需要重新设计我们的网络。

怎么设计?

因为我们想交换两张脸,所以可以设计两个不同的解码网络。 也就是说,使用一个编码网络学习两个不同面部的共同特征,使用两个解码器分别生成。

如上图所示,即我们设计了一个输入端或一个编码器,分别输入了两个不同的脸,然后设计了两个输出端或两个解码器,从而我们通过抑制层来分别输入两个不同的脸

具体框架变成这样,我们的具体框架如下。

如上图所示,可以看到该自编码器有一个输入端和两个输出端,在输入端分别输入两个不同的脸部集(热情的太阳和川普),在输出端重新生成以前的脸部。 请注意,这里的每个解码器分别负责生成不同个体的面部。 因为在隐含层中学习了两个不同个体的公共信息,所以两个不同的解码器可以根据所学习的公共信息恢复以前输入的图像。

具体来说:

如上图所示,分别输入两个不同个体的图像集。 此时,Encoder是同一编码器,使用由同一Encoder生成的自编码器。 另外,用2个共同的隐含信息个体图像的解码器a、b再生成各个图像,用损失基准(criterion )进行比较(这里的损失使用L1损失函数),用Adam优化算法进行

梯度下降。

之后我们利用解码器A、B分别去重新生成由输入图像B、A后隐含层学习到的信息,如下公式:

网络结构

下面则是之前提到的结构的具体的网络设计,我们可以看到网络结构有一个输入端和两个输出端,输入端由卷积层和全连接层构成,而输出端则同样由卷积层构成,但是需要注意这里的输入端是下采样卷积,而输出端则是上采样卷积,也就是图像的分辨率是先变低再慢慢升高。

可以看下Pytorch中网络设计的代码:

class Autoencoder(nn.Module): def __init__(self): super(Autoencoder, self).__init__() self.encoder = nn.Sequential( # 编码网络 _ConvLayer(3, 128), # 3 64 64 _ConvLayer(128, 256), # 32/2=16 _ConvLayer(256, 512), # 16/2=8 _ConvLayer(512, 1024), # 8/2=4 Flatten(), nn.Linear(1024 * 4 * 4, 1024), nn.Linear(1024, 1024 * 4 * 4), Reshape(), _UpScale(1024, 512), ) self.decoder_A = nn.Sequential( # 解码网络 _UpScale(512, 256), _UpScale(256, 128), _UpScale(128, 64), Conv2d(64, 3, kernel_size=5, padding=1), nn.Sigmoid(), ) self.decoder_B = nn.Sequential( _UpScale(512, 256), _UpScale(256, 128), _UpScale(128, 64), Conv2d(64, 3, kernel_size=5, padding=1), nn.Sigmoid(), ) def forward(self, x, select='A'): if select == 'A': out = self.encoder(x) out = self.decoder_A(out) else: out = self.encoder(x) out = self.decoder_B(out) return out复制代码

上述代码网络可以由下图的图例所表示:

但是这些结构都是可以变化的,其中卷积核的大小可以按照需求调整,而全连接这种可以打乱空间结构的网络我们也可以寻找类似的结构去代替。另外,在解码器阶段的最后一层还采用了Sub-pixel的上采样卷积技术可以快速并且较好地生成图像的细节。

总之,我们想实现换脸的操作,在整体结构不变的基础上,需要满足以下几点:

如上图,也就是类似于VGG的编码网络、还要可以打乱空间结构结构的全连接网络、以及可以快速且较好地上采样图像的Sub-Pixel网络。我们进行了额外的测试,发现作为编码网络的话,传统的VGG形式的网络结构的效果最好,可以使损失函数降到最低。但是如果采用其他较为先进的网络,其效果并没有传统的VGG构架好,这也是为什么风格迁移和图像生成使用VGG网络格式更多一些。

同样,如果我们将全连接网络从编码器中去掉或者使用卷积网络代替,那么图像是无法正常生成的,也就是编码器学习不到任何有用的知识,但是我们可以使用1x1的卷积网络去代替全连接网络,1x1网络如:

nn.Conv2d(1024, 128, 1, 1, 0, bias=False),nn.Conv2d(128, 1024, 1, 1, 0, bias=False),复制代码

同样也拥有打乱空间结构的特性,优点是比全连接网络运行更快,但是效果并没有全连接网络好。

至此,我们简单说明了基本构架以及网络层的选择。

图像预处理

当然训练的时候是有很多小技巧的,因为我们需要隐含层学习到两个不同个体的共同特征,我们可以采取一些小Tricks来让我们的训练过程更快更平滑:

如上图,我们可以将图像A(川普)集加上两者图像集的平均差值(RGB三通道差值)来使两个输入图像图像的分布尽可以相近,这样我们的损失函数曲线下降会更快些。

拿代码表示则为:

images_A += images_B.mean(axis=(0, 1, 2)) - images_A.mean(axis=(0, 1, 2))复制代码 图像增强

当然还有图像增强技术,这个技术就不必多说了,基本是万能的神器了。我们可以旋转、缩放、翻转训练图像从而使图像的数量翻倍进而增加训练的效果。

如上图,对于人脸来说,使用扭曲的增强技术可以有效地降低训练过程中的损失值,当然增强也是有限度的,不要太过,物极必反。哦对了,还忘了说,我们训练的时候使用的脸部图像只从原图截取了包含脸部的部分,比如上图右上角的aligned image,我们使用OpenCV库截图脸部图像作为训练素材。

图像后处理

至于图像后处理,当然是将我们生成的脸部图像重新拼回去了:

这里使用了泊松融合以及Mask边缘融合的方法,我们可以很容易地看出融合的效果。

总结

总得来说,这个换脸技术是一个结构简单但是知识点丰富的一个小项目,其结构简单易于使用以及修改,并且可以生成不错的效果,但是因为其拥有较多的参数,其运行速度并不是很快(当然我们可以通过改变编码层和解码层结构加快训练生成的速度),并且对于脸部有异物的图像可能会生成不真实的效果。

这是因为自编码器网络并没有针对图像中需要学习的部位进行学习而是全部进行了学习,当然会有很多杂质,这可以通过注意力的机制适当改善。

就说这些吧~

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。