从零带你入门stylegan~stylegan3的技术细节
入门级文章,讲解stylegan ~ stylegan3的模型发展
部分地方融入个人理解,所以专业性略有不足,希望谅解。
但更方便新手的入门理解,愿能够帮助大家进行理解。
如果您已对此十分了解,欢迎指教~
from : Ericam_
前言
近段时间,stylegan3模型开源,于是便想开始认真了解学习一下stylegan的模型架构与原理,所以本文会从stylegan逐步介绍到stylegan3,大家可以选择自己感兴趣的部分阅读,如果想要了解模型项目如何使用,那建议直接在github阅读readme啦。
基本介绍
stylegan是什么?讲再多也不如用效果展示来的明显:
1.利用stylegan2生成的网红人脸(现实中不存在的假脸)
2.性别转换
3.人脸融合并作表情编辑
以上只是利用stylegan完成应用的一小部分尝试,但是相信看完这些效果你也能理解stylegan的大概用途啦~。
StyleGAN中的“**Style”**是指数据集中人脸的主要属性,比如人物的姿态等信息,而不是风格转换中的图像风格,这里Style是指人脸的风格,包括了脸型上面的表情、人脸朝向、发型等等,还包括纹理细节上的人脸肤色、人脸光照等方方面面。
StyleGAN 用风格(style)来影响人脸的姿态、身份特征等,用噪声 ( noise ) 来影响头发丝、皱纹、肤色等细节部分。
大概知道了这些,那我们接下来便继续深一步了解吧~
stylegan
按照我的习惯,我习惯从模型图开始入手理解,所以先来看一看stylegan的模型架构:
乍一看这图,可能会十分晕,但其实在generator部分主要被分为两个子网络:
- Mapping network : 用于将latent code z 转换成为 w
- Synthesis network : 用于生成图像
在开头我们便讲了,stylegan通过style来影响人脸的姿态、身份特征等,那在模型里,其实是通过w来完成的,也就是说可以理解为,我们通过转换得到的w是用来影响图像的style的。
(一)Mapping Network
作用:为输入向量z的特征解耦提供一条学习通道
为啥需要将latent code z变成w呢?
由于z是符合均匀分布或者高斯分布的随机变量,所以变量之间的耦合性比较大。举个例子,比如特征:头发长度和男子气概,如果按照z的分布来说,那么这两个特征之间就会存在交缠紧密的联系,头发短了你的男子气概会降低或者增加,但其实现实情况来说,短发男子、长发男子都可以有很强的男子气概。所以我们需要将latent code z进行解耦,才能更好的后续操作,来改变其不同特征。
Mapping network需要做的事情就是对latent code进行解耦
将latent code转换得到w后,然后经过仿射变换生成A,分别送入Synthesis network的每一层网络,进行控制特征,因为Synthesis network的网络层有18层,所以我们才会说通过w生成得到了18个控制向量,用于控制不同的视觉特征。
Mapping network详细结构图
其是由8个全连接层(fc)组成,同时输出向量w和输入的z维度相同(512*1)
为何Mapping network能够学习到特征解耦呢?
因为如果仅通过z来控制视觉特征,那么其能力十分有限,因为它必须遵循训练数据的概率密度。比如数据集中长头发的人很常见,那么更多的输入值便会映射到该特征上,那么z中其他变量也会向着该值靠近、无法更好地映射其他特征。 所以通过Mapping network,该模型可以生成一个不必遵循训练数据分布地向量w,减少了特征之间的相关性,完成解耦。
(二)Synthesis network
作用:用于生成图像
在Synthesis network中,最初的输入向量shape为 512 * 4 * 4,最后输出为 3 * 1024 * 1024。
从4 * 4 到 8 * 8 ….( 4,8,16,32…1024),其中每一个又包含两个卷积层(一个用于upsample,一个用于特征学习),所以一共包含18层。
关于层数这一块,补充说明,可以配合着图理解: 18 = 1(初始进入的conv层)+8 * 2(每一个块包含的两个卷积层,将vector从44变到10241024)+1(to_rgb层,将通道变成3)。 p.s : 其实每个模块都有to_rgb上采样后实现跨层链接
删除了传统输入
利用512 * 4 * 4的输入代替传统初始输入。
- 避免初始输入值取值不当而生成不正常图片。
- 有助于减少特征纠缠
随机变化(添加噪声noise)
在文章开头,我们便讲了stylegan通过用噪声 ( noise ) 来影响头发丝、皱纹、肤色等细节部分。 人们脸上有很多小特征,比如雀斑、发髻线的准确位置,这些都可以是随机的。将这些小特征插入GAN图像的常用方法是 在输入向量中添加noise。 为了控制噪声仅影响图片样式上细微的变化, StyleGAN 采用类似于 AdaIN 机制的方式添加噪声(噪声输入是由不相关的高斯噪声组成的单通道数据,它们被馈送到生成网络的每一层)。 即在 AdaIN 模块之前向每个通道添加一个缩放过的噪声,并稍微改变其操作的分辨率级别特征的视觉表达方式。 加入噪声后的生成人脸往往更 加逼真与多样。
自适应实例归一化(AdaIN)
此前的风格迁移方法,一种网络只对应一种风格,速度很慢。基于AdaIN可以“self modulate” the generator快速实现任意图像风格的转换。
特征图的均值和方差中带有图像的风格信息。所以在这一层中,特征图减去自己的均值除以方差,去掉自己的风格。再乘上新风格的方差加上均值,以实现转换的目的。StyleGAN的风格不是由图像的得到的,而是w生成的。
(三)其他细节
(1)样式混合(通过混合正则化)
目的:进一步明确风格控制(训练过程中使用)
在训练过程中,stylegan采用混合正则化的手段,即在训练过程中使用两个latent code w (不是1个)。通过Mapping network输入两个latent code z,得到对应的w1和w2(代表两个风格),接下来为它们生成中间变量w’。然后利用第一个w1映射转换后来训练一些网络级别,用另一个w2来训练其余的级别,于是便能生成混合了A和B的样式特征的新人脸。
第一部分是 Coarse styles from source B,分辨率(4x4 - 8x8)的网络部分使用B的style,其余使用A的style, 可以看到图像的身份特征随souce B,但是肤色等细节随source A; 第二部分是 Middle styles from source B,分辨率(16x16 - 32x32)的网络部分使用B的style,这个时候生成图像不再具有B的身份特性,发型、姿态等都发生改变,但是肤色依然随A; 第三部分 Fine from B,分辨率(64x64 - 1024x1024)的网络部分使用B的style,此时身份特征随A,肤色随B。
大致结论:低分辨率的style 控制姿态、脸型、配件 比如眼镜、发型等style,高分辨率的style控制肤色、头发颜色、背景色等style。
Truncation Trick
Truncation Trick,截断技巧。从数据分布来说,低概率密度的数据在网络中的表达能力很弱,直观理解就是,低概率密度的数据出现次数少,能影响网络梯度的机会也少,网络学习到其图像特征的能力就会减弱。如何解决该问题呢,truncation trick大致做法如下:
首先找到数据中的一个平均点,然后计算其他所有点到这个平均点的距离,对每个距离按照统一标准进行压缩,这样就能将数据点都聚拢了(相当于截断了中间向量𝑊′,迫使它保持接近“平均”的中间向量𝑊′ 𝑎𝑣𝑔),但是又不会改变点与点之间的距离关系。
当生成新的图像时,不用直接使用映射网络(Mapping NetWork)的输出,而是将值𝑊′转换为𝑊′ 𝑛𝑒𝑤 = 𝑊′ 𝑎𝑣𝑔 +𝞧(𝑊′ − 𝑊′ 𝑎𝑣𝑔) ,其中 𝞧 的值定义了图像与“平均”图像的差异量(以及输出的多样性)。有趣的是,在仿射转换块之前,通过对每个级别使用不同的𝞧 ,模型可以控制每个级别上的特征值与平均特征值的差异量。
(2)微调超参数
StyleGAN 的另外一个改进措施是更新几个网络超参数,例如训练持续时间和损失函数, 并将图片最接近尺度的缩放方式替换为双线性采样。
(四)如何量化解耦?
stylegan提出的新方法,不需要解码器,对于任何数据集和生成器都是可计算的。
- 感知路径长度(Perceptual path length)
- 线性可分性(linear separability)
感知路径长度(Perceptual path length)
图像生成其实是学习从一个分布到目标分布的迁移过程,如下图,已知input latent code 是z1,或者说白色的狗所表示的latent code是z1,目标图像是黑色的狗,黑狗图像的latent code 是 z2。图中紫色的虚线是z1 到 z2 最快的路径,绿色的曲线是我们不希望的路径。
Perceptual path length 是一个指标,用于判断生成器是否选择了最近的路线(比如上图紫色虚线)
测量在潜在空间中执行插值时图像的变化程度,来了解隐空间到图像特征之间的纠缠度。
具体做法如下:
(1) 使用两个VGG16提取特征的加权差异来表示一对图像间的感知距离。 (2) 将潜在空间插值路径细分为线性段,每个段上的感知差异的总和就是感知路径长度。 (3)使用多份样本,分别计算z和w的PPL(感知距离长度)。由于z已经归一化,所以对z使用球面插值 slerp,而对w使用线性插值 lerp。评估为裁剪后仅包含面部的图像。
线性可分性(linear separability)
训练特征,方便之后面部编辑,操纵图像特征,比如将男性图片变为女性
如果隐空间与图像特征足够解耦,那么隐空间中存在线性超平面,可以二分类两种特征。在stylegan的文章中,基于CelebA-HQ数据集,训练40种特征的分类器。然后用生成器生成200000张图像,用训练的分类器分类,去掉置信度最低的一半,得到隐变量和标签已知的100000张图像。对每个属性,用线性SVM拟合预测z的类别,判断z是否足够线性。线性关系用X和Y的分布差异衡量。
结论:增加mapping network的深度确实有助于提高w的线性可分性。映射网络对传统生成器有同样的提升,具备通用性。
(五)总结
创新点:
- 加入了可通用的Mapping network
- 样式混合,使用两个中层latent code w生成一张图像,扩大了w的训练空间
- 感知路径长度
- 线性可分性
stylegan2
stylegan2主要是为了解决stylegan的不足之处,最重要的一点就是stylegan生成的图像上容易出现“水滴”。
导致水滴的原因是Adain操作,Adain对每个feature map进行归一化,因此有可能破坏掉feature之间的信息,产生上述现象。而去除了Adain后,该问题便解决了。
(一)Adain问题解决 (水滴问题)
- 移除最开始的数据处理
- 在标准化特征时取消均值 (可以对照上文Adain查看)
- 将noise模块在外部style模块添加
(二) weight demodulation
在样式混合(style mixing)中,容易将某个特征放大一个数量级或更多,而在去除了Adain后,便无法有效控制这个问题(因为移除了mean),但style mixing又是stylegan的亮点,如何能够在保留style mixing的同时有效地解决特征放大问题呢?这便是weight demodulation设计的原因。
(三) Lazy regularization
loss 是由损失函数和正则项组成,优化的时候也是同时优化这两项的。
lazy regularization就是正则项可以减少优化的次数,比如每16个minibatch才优化一次正则项,这样可以减少计算量,同时对效果也没什么影响。
(四) Path length regularization
在生成人脸的同时,我们希望能够控制人脸的属性,不同的latent code能得到不同的人脸,当确定latent code变化的具体方向时,该方向上不同的大小应该对应了图像上某一个具体变化的不同幅度。为了达到这个目的,设计了 Path length regularization。
stylegan3
首先通过论文摘要,我们来看看stylegan3试图解决了什么问题:
在GAN的合成过程中,某些特征依赖于绝对像素坐标,这会导致:【细节似乎粘在图像坐标上,而不是所要生成对象的表面】
而stylegan3从根本上解决了stylegan2图像坐标与特征粘连的问题,实现了真正的图像平移、旋转等不变性,大幅度提高了图像合成质量。
以一些动态图可以清晰地解释:
通过上图可以看出来stylegan2生成的毛发等细节会粘在屏幕上,和人物的形态变化不一致。
这个问题的出现其实是GAN模型存在的一个普遍问题:
生成的过程并不是一个自然的层次化生成。
粗糙特征(GAN的浅层网络的输出特征)主要控制了精细特征(GAN的深层网络的输出特征)的存在与否,并没有精细控制它们的出现的精确位置。
简单来讲:如果训练集中大多数图片的眼睛出现在图片居中位置,那么哪怕你的浅层网络输出中图片的眼睛在其他位置,最终整个网络输出的图片眼睛还是基本会处于图片居中位置。
为什么会产生这种问题?
作者们认为产生这个现象的根本问题是:目前的生成器网络架构是卷积+非线性+上采样等结构,而这样的架构无法做到很好的Equivariance(等变性)
这种糟糕的 “纹理粘附”在latent值变换的时候会更加明显:
在人脸平移时,对于某个固定的坐标切片,stylegan3可以随人脸移动变化纹理(比如右图那一块固定区域,在左图人脸平移时,也是在不断移动的),而stylegan2则是倾向于生成固定的纹理。
同时stylegan2也无法满足旋转一致性问题:
通过实验表明,这些问题出现原因在哪里呢?
(1)使用图像边界参考(例如padding的使用实际上提示了图像的边界位置信息)
(2)像素的噪声输入(防止头发丝粘一起)
(3)位置编码和混叠(加入一些额外的位置信息)。
如何消除这些不需要的辅助信息,从而防止网络去组合、使用这些错误信息呢?
针对边界问题,可以在稍大一点的图像边缘上进行操作。
针对像素的噪声输入,可以直接取消掉该操作。
而关于生成图像中的混叠,作者认为有两个可能的来源:
- 非理想上采样(如最近邻、双线性或空洞卷积)产生的像素网格的微弱的印记。
- 应用pointwise的非线性激活,如
ReLU
或者Swish
。
网络会去放大哪怕是最轻微的混叠,并在多个尺度上进行组合,这就成为了固定在图像坐标中的那些混叠状网格的基础(解释了为何特征会依赖于坐标)。
而实验表明,在stylegan2时,当前的上采样滤波器在抑制混叠方面根本不够积极,而且需要具有超过100dB衰减的高质量滤波器。
而针对这个问题,stylegan3根据它们在连续域的影响,提出了一种解决点态非线性引起的混叠的原理,并对结果进行了适当的低通滤波。
stylegan3的生成器主要进行了哪些改进?
傅里叶特征以及基线模型简化
(1) 利用Fourier特征(傅里叶特征)代替了stylegan2生成器的常数输入
(2) 删除了noise输入(特征的位置信息要完全来自前层粗糙特征)
(3) 降低了网络深度(14层,之前是18层),禁用mixing regularization和path length regularization,并且在每次卷积前都使用简单的归一化 (这里有点直接推翻了stylegan2的一些思想)
边界及上采样问题优化
(4) 理论上特征映射有一个无限的空间范围(就是特征不能局限固定在某些坐标域),引入了一个固定大小的boundaries来近似,每一层操作后再crop到这个扩展的空间。
用理想低通滤波器来代替双线性采样。
改进后的boundaries和upsampling得到了更好的平移性,但是fid变差了。
非线性滤波改进
(5) 工程化的操作,改进了非线性滤波,并将整个upsample-LReLU-downsample过程写到一个自定义的CUDA内核中
非临界采样改进
(6) 为了抑制 aliasing(混淆对于生成器的Equivariance很有害),可以简单地将截止频率降低,从而确保所有混叠频率都在阻带。【丢掉了浅层的高频细节,因为作者认为浅层中高频细节并不重要】
傅里叶特征改进
(7) 为了应对每层的全局变换能力有限的问题,加入了一个仿射层,通过输出全局平移和旋转参数输入傅里叶特征,稍微改善了FID
平移不变性
(8) 虽然提高了平移不变性,但是一些可见的伪影仍然存在。这是因为滤波器的衰减对于最低分辨率的层来说仍然是不够的,而这些层往往在其带宽限制附近有丰富的频率信息,这就需要有非常强的衰减来完全消除混叠。提出:跳频在最低分辨率层中较高,以最大化提高阻带的衰减;在最高分辨率层中较低,以匹配高层细节
旋转不变性
(9) 为了得到旋转不变性网络,做出来两个改进:
-
将所有层的卷积核大小从3 * 3替换为1 * 1
-
通过将feature map的数量增加一倍,用来弥补减少的特征容量
实验表明,一个基于 1 * 1的卷积操作能够产生强旋转的等变生成器,一旦适当地抑制了混叠,便可以迫使模型实现更自然的层次细化。
尾言
这篇文章只是个人学习过程中的一些思考与记录,太多的细节部分没有过多涉及。
如果大家对该项技术感兴趣的话可以去仔细调研一下,并阅读论文细节。
如果对您有所帮助的话,请记得给一个点赞和收藏~
参考资料
-
stylegan官方论文