StyleGAN-基于样式的生成对抗网络(论文阅读总结)
内容概要
- 1 文章相关信息
- 2 研究背景
- 3 本文的主要工作及贡献
- 4 模型和方法
- 4.1基于样式的生成器结构(Style based generator)
- 整体结构
- 细节
- 移除传统输入
- 映射网络(Mapping Network)
- 样式模块(style module,AdaIN)
- 随机变化(Stohastic variation,加入噪声)
- 4.2正则化技术-混合正则化(style mixing,样式混合)
- 4.3量化隐空间(latent code)的耦合程度的方法
- 5 实验及结果
- 生成器生成的图像的质量
- 随机变化效果
- 样式混合的正则化效果
- 不同层级的样式对生成图像特征的控制
- 对隐空间的解耦效果
- 6 结论
1 文章信息
- 发表时间: 2018年底2019年初
- 会议: CVPR 2019
- 引用量: 16(截至20190421)
- 机构 :NVIDIA
- 作者 :Tero Karras, Samuli Laine, Timo Aila
- 论文 :https://arxiv.org/abs/1812.04948
- 代码 :https://github.com/NVlabs/stylegan
2 研究背景
ProGAN(引用自Rani Horev)NVIDIA在2017年提出的ProGAN解决了生成高分辨率图像(如1024×1024)的问题。ProGAN的关键创新之处在于渐进式训练——从训练分辨率非常低的图像(如4×4)的生成器和判别器开始,每次都增加一个更高的分辨率层。
存在的问题:与多数GAN一样,ProGAN控制生成图像的特定特征的能力非常有限。这些属性相互纠缠,即使略微调整输入,会同时影响生成图像的多个属性。所以如何将ProGAN改为条件生成模型,或者增强其微调单个属性的能力,是一个可以研究的方向。
解决方法:StyleGAN是NVIDIA继ProGAN之后提出的新的生成网络,其主要通过分别修改每一层级的输入,在不影响其他层级的情况下,来控制该层级所表示的视觉特征。这些特征可以是粗的特征(如姿势、脸型等),也可以是一些细节特征(如瞳色、发色等)。
3 本文的工作及贡献
①借鉴风格迁移,提出基于样式的生成器(style-based generator)。
- 实现了无监督地分离高级属性(人脸姿势、身份)和随机变化(例如雀斑,头发)
- 实现对生成图像中特定尺度的属性的控制。
- 生成器从一个可学习的常量输入开始,隐码在每个卷积层调整图像的“样式”,从而直接控制不同尺度下图像特征的强度。
②实现了对隐空间(latent space)较好的解耦。
- 生成器将输入的隐码z嵌入一个中间的隐空间。因为输入的隐空间Z必须服从训练数据的概率密度,这在一定程度上导致了不可避免的纠缠,而嵌入的中间的隐空间W不受这个限制,因此可以被解耦。
③提出了两个新的量化隐空间解耦程度的方法
- 感知路径长度和线性可分性。与传统的生成器体系结构相比,新的生成器允许更线性、更解耦地表示不同的变化因素。
④提出了新的高质量的人脸数据集(FFHQ,7万张1024×1024的人脸图片)
4 模型和方法
4.1 基于样式的生成器结构
生成器结构(引用自Rani Horev,并加了标注)基于样式的生成器b)有18层,每个分辨率有两个卷积层(4,8,16...1024)。
- ①移除了传统的输入(remove traditional input)
- ②映射网络(Mapping Network)
- ③样式模块(style modules,AdaIN,自适应实例归一化)
- ④随机变化(Stohastic variation,通过加入噪声为生成器生成随机细节)
移除传统的输入
引用自Rani Horev传统的生成器a)使用latent code(随机输入)作为生成器的初始输入;StyleGAN抛弃了这种设计,将一个可学习的常数作为生成器的初始输入。一个假设是它减少了特征纠缠——对于网络来说,只使用w而不依赖于纠缠的输入向量更容易学习。
映射网络(Mapping Network)
引用自Rani Horev映射网络由8个全连接层组成,其输出w与输入z大小相同(512×1)。映射网络的目标是将输入向量编码为中间向量,中间向量W的不同元素控制不同的视觉特征。
使用输入向量z控制视觉特征的能力是有限的,它必须遵循训练数据的概率密度。例如,如果黑色头发的人的图像在数据集中更常见,那么更多的输入值将映射到该特性。因此该模型无法将输入向量z的一部分(向量中的元素)映射到特征,这种现象称为特征纠缠。
但是通过映射网络,该模型可以生成一个不需要跟随训练数据分布的向量w,并且可以减少特征之间的相关性(解耦,特征分离)。
样式模块(AdaIN)
引用自Rani HorevW通过每个卷积层的AdaIN输入到生成器的每一层中。图中的A代表一个可学习的仿射变换。
计算方法:
- ①首先每个特征图xi(feature map)独立进行归一化 。特征图中的每个值减去该特征图的均值然后除以方差
- ②一个可学习的仿射变换A(全连接层)将w转化为style中AdaIN的平移和缩放因子y =(ys,i,yb,i),
- ③然后对每个特征图分别使用style中学习到的的平移和缩放因子进行尺度和平移变换。
使用style来形容y,是因为类似结构已在风格迁移中使用(batch Normalization也有类似的结构),但是不同之处在于这里的缩放和平移因子是用隐码w计算得到,而不是用一个图像计算得到的。
随机变化(通过引入噪声为生成器生成随机细节)
引用自Rani Horev人的脸有很多可以看作是随机的,比如头发的精确位置,使图像更真实,增加了输出的多样性。将这些小特征插入GAN图像的常用方法是向输入向量添加随机噪声,然后通过输入层输入生成器。然而,在很多情况下,控制噪声效果是很棘手的,因为特征纠缠现象,略微改变噪声会导致图像的其他特征受到影响。
该架构通过在合成网络的每个分辨率级上增加尺度化的噪声来回避这些问题。噪声是由高斯噪声组成的单通道图像,将一个噪声图像提供给合成网络的一个特征图。在卷积之后、AdaIN之前将高斯噪声加入生成器网络中。B使用可学习的缩放参数对输入的高斯噪声进行变换,然后将噪声图像广播到所有的特征图中(分别加到每个特征图上,每个特征图对应一个可学习的scale参数)。
4.2 正则化-混合正则化(mixing regularization)
为了进一步鼓励styles的局部化(减小不同层之间样式的相关性),本文对生成器使用混合正则化。
方法:对给定比例的训练样本(随机选取)使用样式混合的方式生成图像。在训练过程中,使用两个随机隐码z(latent code)而不是一个,生成图像时,在合成网络中随机选择一个点(某层),从一个隐码切换到另一个隐码(称之为样式混合)。具体来说,通过映射网络运行两个潜码z1、z2,并让对应的w1、w2控制样式,使w1在交点前应用,w2在交点后应用。
这种正则化技术防止网络假设相邻样式是相关的,随机切换确保网络不会学习和依赖于级别之间的相关性。
4.3 两种新的量化隐空间(latent space)耦合度的方法
- 解耦的目标是使隐空间(latent space)由线性子空间组成,即每个子空间(每个维度)控制一个变异因子(特征)。
- 但是隐空间Z中的各个因子组合的采样概率需要与训练数据中响应的密度匹配,就会产生纠缠。而中间隐藏空间W不需要根据任何固定分布进行采样;它的采样密度是由可学习的映射网络f(z)得到的,使变化的因素变得更加线性。
- 本文假设,生成器基于解耦的表示比基于纠缠的表示应该更容易产生真实的图像(若在FID变小的同时,隐空间耦合度变小,则可以得证)。因此,我们期望训练在无监督的情况下(即,当不预先知道变异的因素时)产生较少纠缠的W
- 最近提出的用于量化解耦的指标需要一个将输入图像映射到隐码的编码器网络。但不适合本文,因为baseline GAN缺乏这样的编码器。
- 所以本文提出了两种新的量化解耦的方法,它们都不需要编码器,所以对于任何数据集和生成器都是可计算的。
- 感知路径长度(Perceptual path length)
- 线性可分性(linear separability)
感知路径长度
为什么这种量化纠缠的方法是可行的?
- 对隐空间向量进行插值会在图像中产生非线性变化。比如,在所有端点中缺失的特征可能会出现在线性插值路径的中间。这表明隐空间是耦合的,变化因子没有被恰当的分开。所以通过测量当在两个隐空间之间进行插值时图像的剧烈变化程度,可以反映隐空间的纠缠程度(特征分离程度)。
感知路径长度计算,使用10000个样本计算
- 将两个隐空间之间的插值路径细分为小段,感知总长度定义为每段感知差异的总和。感知路径长度的定义是这个和在无限细的细分下的极限,实际上用一个小的细分 来近似它。隐空间Z中所有可能端点(在路径中的位置)的平均感知路径长度,计算如下
- 其中 , 。 t服从0.1均匀分布,slerp表示球面插值操作,这是在归一化的输入隐空间中最合适的插值方式。
- G是生成器,d计算得到生成图像之间的感知距离。因为d是二次的,所以除以 而不是 来消除对细分粒度的依赖。
- d的具体计算方式:使用基于感知的成对图像距离,测量连续图像之间的差异(两个VGG16 embeddings之间的差异,利用VGG16提取出图像的特征,在特征层面上计算距离)
计算隐空间W的感知路径长度与z的唯一不同是采用lerp线性插值,因为w向量没有进行归一化
线性可分性(linear separability)
为什么这种量化纠缠的方法是可行的
如果一个隐空间是充分解耦的,应该能够找到与每个变化因子对应的方向向量。我们提出了另一种度量方法来量化这种效果,测量通过线性超平面将隐空间点分割成两个不同的集合的程度,使每个集合对应于图像的特定的二元属性(比如男、女)。
计算方法:
- ①训练40个辅助分类器,分别对40个二元属性进行区分(每个分类器区分一个属性,比如区分女性男性)。分类器与StyleGAN判别器结构相同,使用CelebA-HQ数据集训练得到(保留原始CelebA的40个属性,150000个训练样本),学习率10-3,批次大小8,Adam优化器。
- ②使用生成器生成200,000个图像,并使用辅助分类器进行分类,根据分类器的置信度对样本进行排序,去掉置信度最低的一半,得到100,000个已知类别的隐空间向量(latent code)
- ③对于每个属性,拟合一个线性SVM来预测标签-基于传统的隐空间点或基于样式的隐空间点w-并且根据这个超平面对这些隐空间点(512维,10000个点)进行分类。
- ④用条件熵H(Y |X)度量超平面将点划分为正确类别的能力,X是SVM预测的类别,Y是预先训练好的辅助分类器确定的类(作为真实类别);因此,根据SVM确定样本在超平面的哪一边,条件熵告诉我们需要多少额外的信息来确定样本的真实类别。直觉上,如果隐空间中的变化因子是耦合的(非线性的),那么用超平面来分离样本点将会更加困难(需要更多的额外信息),产生高的条件熵。较低的值表示易于分离(可分性好),因此解耦程度更大
可分性计算公式 ,其中i列举了40个属性。取幂是为了将值从对数域变换为线性域,便于进行比较
5 实验和结果
5.1 生成的图像的质量
评估指标:FID(Fréchet Inception Distance,越小越好)
测量不同的生成器结构产生的图像的质量。FID计算真实样本,生成样本在特征空间之间的距离。预训练的 Inception V3 来提取全连接层之前的 2048 维向量,作为图片的特征,然后根据均值和协方差来进行距离计算。具体公式如下:
公式中: 真实图片的特征的均值, 生成的图片的特征的均值, 真实图片的特征的协方差矩阵, 生成图片的特征的协方差矩阵
FID 只把 Inception V3 作为特征提取器,并不依赖它判断图片的具体类别,因此不必担心 Inception V3 的训练数据和生成模型的训练数据不同。
FID的tensorflow实现 https://github.com/bioinf-jku/TTUR
FID的测量结果
- 训练数据集:CelelbA-HQ和FFHQ
- FFHQ数据集(本文提出的)Flickr-Faces-HQ(FFHQ),包含7万张高分辨率的人脸图像(2014×1024)(https://github.com/NVlabs/ffhq-dataset)
- 加入映射网络、样式模块、移除传统输入、增加噪声,都提高了生成图像的质量,降低了FID
- 基于样式的生成器F相比于B,FID提升了20%,生成的图像质量更好
基于样式的生成器生成的图像
显示了使用生成器F从FFHQ数据集中生成的图片,平均的质量很高,帽子、眼睛等配饰也成功合成了。图中生成人脸时,对中间隐空间W采取了截断trick(0.7),该trick只在网络的低分辨率(4-32)使用(该trick只在这里使用,在计算FID时没有使用过),生成的图片的分辨率为1024。
- 截断技巧(截断中间隐空间W)
- 考虑到训练数据的分布,低密度区域很少被表示,因此生成器很难学习该区域。通过对隐空间进行截断可以提升生成影像的平均质量,虽然会损失一些变化。对中间隐码W进行截断,迫使W接近平均值
- 具体方法:在训练之后,通过多个输入z经过映射网络生成的中间向量W,得到均值 , ;
- 在生成新图像时,将输入z的映射w与中心的偏差按比例缩放
训练细节和超参数
- StyleGAN使用8个Tesla V100 gpu对CelebA-HQ和FFHQ数据集进行为期一周的训练。在TensorFlow中实现。
- B-F在两个数据集使用不同的损失函数
- CELEBA-HQ数据集使用WGAN-GP;
- FFHQ数据集,非线性饱和损失,WGAN-GP+R1正则化(γ=10),使用该损失的FID值比WGAN-GP减小的时间更长,所以使用更长的训练时间
- 基于样式的生成器使用leak ReLU,α=0.2,所有卷积层使用相同学习率;特征图(卷积核)数量与ProGAN相同;
- 映射网络的学习率每两层降低一次λ = 0.01λ(映射网络深度变大时,训练不稳定)。
- 权重使用高斯(0,1)随机初始化;除了样式计算ys的偏置初始化1,其余偏置和噪声的尺度因子初始化为0.
- 没有使用batch normalization、dropout
5.2 随机变化(Stochastic variation)效果
b使用相同latent code,不同噪声作为输入;整体特征是相似的,比如面部等,细节比如头发的形状有较大的不同;c是100个不同的随机噪声输入产生的图像的标准差,较亮部分是标准差较大的部分(受不同的噪声输入影响较大的部分,头发等部分),而面部姿势等高级特征不受随机变化的影响。显示了在相同底层图像输入不同的噪声实现的随机变化。噪声只影响随机方面,而保留了整体结构和身份、面部等高级特征。
上图说明了将随机变化应用于不同的层的效果(将噪声输入不同层)。a噪声加入了所有层;b没有噪声;c在精细层(fine layers,64-1024)加入噪声;d在粗糙层(coarse layer,4-32)加入噪声。粗糙的噪声导致头发大规模卷曲,背景特征更大,而细小的噪声则使头发卷曲更细,背景细节更细,皮肤毛孔更细。
5.3 混合正则化(样式混合)
- 用FFHQ数据集训练网络,对不同比例的训练样本使用混合正则化,得到FID值。
- 0-100%表示训练过程中混合正则化应用的样本的比例。
- 在训练过程中,通过随机化1-4个latent code和它们之间的交点对网络进行压力测试。
- 使用相同数目的隐码latent code,随着混合正则化应用的样本的比例的增加(同一列从上到下),得到的图像的质量得到了提高,FID值降低
5.4 不同层级样式对图像特征的控制
上图,可视化生成器中样式的效果—(使用训练好的生成器)在生成图像时用一个隐码(source)产生的样式覆盖另一个隐码(destination)产生的样式的子集。显示在3个不同的尺度下混合两个隐码得到的合成图像。结果表明样式的子集控制了图像的高级属性,不同尺度的样式控制了图像不同的高级属性的生成。
- 在粗糙分辨率(4-8)用source的样式覆盖目标的的样式,产生的图像的高级特征(姿势、头发样式、脸的形状和眼镜)从source图像中复制,而目标图像的颜色(眼睛、头发、光线)和更精细的面部特征被保留下来。说明该尺度的样式控制了生成图像的高级特征
- 在中间层(16-32)用source的样式覆盖目标的样式,合成的图像将会从source中继承较小尺度的面部特征(头发的样式、眼睛的闭合),而目标图像的姿势、脸的形状、眼镜等被保留。说明该尺度的样式控制了生成图像的较小尺度的面部特征
- 在精细分辨率(642 - 1024)用source的样式覆盖目标的样式,主要复制了source中的颜色。说明该尺度的样式控制了生成图像的更低尺度的特征-颜色
5.5 对隐空间的解耦效果(特征分离)
表3表4- 表3说明对于噪声输入的基于样式的生成器E/F(使用FFHQ数据集训练好的),感知路径长度比传统生成器短,这表明中间隐空间W比隐空间Z更线性,即W是Z的解耦映射(一定程度上)
- 表3和表4显示,中间隐空间W始终比输入隐空间Z更易于分离(Separability更小),这表明纠缠的表示更少。
- 此外,表4显示增加映射网络的深度可以同时提高W生成图像的质量(FID)和可分性,这与综合网络喜欢解耦输入表示的假设(可分性提高,生成图像质量提高)是一致的。
6 结论
- 基于样式的生成器,能生成更高质量的高分辨率图像。
- 实现了无监督地分离高级属性(人脸姿势、身份)和随机变化(例如雀斑,头发),实现对生成图像中特定尺度的属性的控制。通过style控制高级属性,通过不同层的style实现对不同尺度的特征的控制;通过噪声控制随机变化
- 降低了隐空间的耦合性。通过映射网络生成中间隐空间(intermediate latent space),中间隐空间降低了输入隐空间的纠缠
- 提出两种新的量化隐空间耦合性的指标-感知路径长度和线性可分性
- 对高级属性与随机效应的分离以及中间隐空间的线性的研究,提高了对GAN合成的理解和可控性
参考文章
https://www.yuthon.com/post/tutorials/from-progan-to-stylegan/
推荐阅读
ICCV 2019| Auto GAN 论文解读,神经网络结构搜索 + 生成对抗网络
生成对抗网络(GAN)可以用于生成、风格迁移、数据增强、超分辨率等任务。今天介绍一篇 ICCV 2019 的 paper: "AutoGAN: Neural Architecture Search for Generative Adversarial Networks…
数据增强(Data Augmentation)
论文阅读-CycleGAN:Unpaired_Image-to-Image_Translation
学习GAN必须阅读的10篇论文
更深入理解StyleGAN,究竟什么在控制人脸生成,我该如何控制?
Dec 9, 2019
原创:岐山凤鸣,转载请注明本站域名
理解可能有偏差,有错误请指出~
参考:
[1] Image2StyleGAN: How to Embed Images Into the StyleGAN Latent Space?
[2] A Style-Based Generator Architecture for Generative Adversarial Networks
前言:这篇StyleGAN的follow文章很有点意思,也是19年ICCV的Oral论文,是对StyleGAN进行的更多的理解和分析,而正是这些理解和分析,让StyleGAN有了超越仅仅生成高清图像的领域,进而对GAN有了更多的理解也有了更多的操作空间。什么是对GAN的理解?GAN本质是根据一个空间的分布(如512d向量空间),得到另一个空间的分布(如1024x1024x3的人脸空间),如果对这个有更多理解后,对原空间进行一些操作,从而让目标空间根据你想要的结果发生变化,这是非常awesome的。
理解StyleGAN
先放一张用烂的神图:
这图直接表明了StyleGAN的网络结构,很直观有两部分组成,一部分是左边的mapping网络和右边的Synthesis网络。
先明确输入,输入是一段随机分布latent,记为zz
,首先zz
经过Norm后,直接由多个串联的FC进行映射,映射到latent space omegaω
,关于这个的中文说法,有的说是"潜空间"或者"隐空间",总之我认为这个就是一个编码空间,每段编码经过仿射变换意味着一个 style,之后将style进行合成就能形成人脸。
那么原始输入latent映射到了latent space之后,假如原始latent的shape是[512],那当前映射后的shape还是是[ 512],再经过一些变换,得到n个[512]输入上图的A即仿射变换后得到n个style,其中每个style的编码是(2)的向量,即为(y_{s,i}, y_{b,i})(ys,i,yb,i)
,i表示第几层。这里在代码实现的时候,直接将向量经过多个个FC后,broadcast到n个layer后经过updating moving average + style mixing regularization + truncation trick后即可,可直接输入(n,512)的编码dlatent。
这里知道了A的输出是什么之后,再看最右边,是n个高斯噪音输入,这个是直接对特征图作用的,关于GAN中加噪音的原因可以参考别的资料,这里基本就是引入随机的细节。接下来是右边网络的细节部分,看下两图:
这是一个自顶向下的结构,最顶上的输入是一个const的比如4x4x512的矩阵,层层会进行传递,每层都包括style的输入和噪音的输入,输出是一个[res, res, channel]的矩阵,跨层的时候需要降采样,层内传递需要一个AdaIN模块和3x3的conv,最底层输出的是[1024,1024,3]的生成图像。AdaIN的模块公式上面给了,意思很简单,对特征图进行标准化后,和两个style值进行平移和缩放,然后一起经过conv。这个操作很像BN,但不同的是两个style值是根据编码来的,而不是特征图,这里对理解来说很重要,理解了BN也就能理解这个AdaIN模块的重要性。
简略的说,从代码层面考虑,整个过程很简单,就这样:
- 输入一个随机向量z,shape=(512,1)
- 多个FC对随机向量直接进行变换,得到
z_{latent}zlatent
,shape=(512,1) - 复制n层
z_{latent}zlatent
,n表示右边结构的层数,shape=(n,512),经过uodating moving average + style mixing regularization + truncation后,得到dlatent,shape=(n,512) - 先得到一个初始const图,往下进行输入
- 进行每层结构的计算,结构开始需要一个降采样,比如(4,4,512)降采样到(8,8,512),给feature_map加点高斯噪音,然后标准化。对输入的512的latent进行放射变换得到两个y,根据两个y对标准化的feature_map进行放缩和平移,之后输入conv进行channel变化
- 将n个结构都跑完,前几个结构都是4x4,8x8这种小的,主要是学的轮廓啊,头发在哪啊这些玩意,中间的几个结构比如32x32,64x64这种大一点的,主要是学的更多的人脸表情啊,眼睛啊什么的,最后几个更大的比如256x256,512x512,1024x1024学的就是超细节的比如毛发啊,颜色啊什么的。
- 输出最后的1024x1024x3
所以可以看到这个过程并不难,有兴趣的同学可以去读源码,读源码的话,一个完整的链是这样的:
- 302行的G_style是完整的生成器流程
- 334行定义synthesis网络,即440行的G_synthesis,同时了解总层数这些信息,dlatent的shape即是(n_layers,512)这种
- 338行定义mapping网络,即384行的G_mapping
- 根据随机的latent生成dlatent,四个步骤嘛,分别是345行的mapping,然后是348行的update,然后是356行的style mixing,然后是369行的truncation,最后得到dlatent
- 378行直接将dlatent输入syntheis网络即可,噪音均在中间生成。
只有上述过程全部了解,才能开始下面的内容,所以要理解如何进行嵌入和编辑,必须对StyleGAN有很完整的理解。
到底什么东西在控制人脸生成?
一句话,dlatent,其shape=(n_layers, 512)。
这到底是什么东西?
刚刚已经说了,它的前面几层在做什么?前面几层是4x4,8x8这种小图,前面几层的风格即是脑袋轮廓,头发位置这些显而易见的宏观风格。
所以它的中间几层,不断的一点点放大,去学的细节就会越来越多,n_layers越多,给的细节就越丰富,细节程度是自顶向下的那种,最顶部的细节是粗糙的,最底部的细节是最精细的。
每一个结构里,输入的dlatent 512编码,都仿射变换到了两个数y,然后带噪声的特征图通过标准化后用这两个y进行平移和放缩(AdaIN),所以实际控制风格的只有y,y来自于dlatent,这即表示输入当前层的dlatent即包含风格。
举个很简单的例子,比如你最后要输出256x256x3的清晰图像。那么整个res的变化是:
(4,4) -> (8,8) -> (16,16) -> (32,32) -> (64,64) -> (128,128) -> (256,256)
这一共是7个要变化的res,也就是需要7个结构,每个结构是包含两层的(一层欠采样,一层正常变换),所以一共14层,那么原始的z编码后是得到(14, 512)的编码,分别输入这14层。
第一层之前首先先init了一个(4,4,512)的东西,这时候还不是图像,然后加个噪音后标准化,将dlatent的第一个(512)提出来放射变换到y1,y2后对标准化后的图进行控制平移和放缩,然后一层层的输入。
所以就是这么简单,(14,512)的编码,一层层逐级的在控制人脸的生成。如果你改变(14,512)的前两三层,可能这个人的脑袋就变了,如果改了最后两三层,可能这个人的肤色什么的,毛孔什么的会发生变化。
如何控制人脸的特征生成?
既然了解了什么在控制人脸生成后,我们要进行控制,就变得很简单,只需要控制这个dlatent即可了。
那么到底如何控制?比如我现在有一张照片I,里面描述的是一个人严肃的表情,我想让他笑起来怎么办?
那么首先,先预训练上述的StyleGAN,得到了G,其中输入(14,512)的编码,会通过G得到一张256,256的图,这时候需要做一个类似AE结构的训练,训练什么?
我们得训练一个编码器,输入I后,得到人脸识别的emb前一层的feature_map,然后用这个feature_map经过一个编码结构,得到(14,512)的编码,然后输入参数冻结的G,得到了假图I',再通过一个预训练的人脸识别网络N(I, I')增加一个损失L给整个编码器,训练编码器。
这到底在干嘛?很简单,我们希望能够得到I这张照片的编码而已,也就是希望控制预训练且参数冻结的G生成出I这张照片。这样我们才能得到I的dlatent,得到dlatent后,通过控制dlatent才能编辑I这个人脸的特征,比如发色什么的。
到这步,我们手上得到了两个东西,生成器G,编码器E,要让I笑起来,怎么办?
这时候需要得到一组人脸数据对(I_1, I_2)(I1,I2)
,满足一个条件,前者是严肃不笑的照片,后者是笑的照片,都进入E后得到一组两个编码(E_1,E_2)(E1,E2)
,根据之前的理论,很明显啊,这一组从E_1 -> E_2E1−>E2
的方向向量,即是控制人脸笑起来的关键因素,当然这个方向向量也是(14,512)的shape。所以现在唯一要做的,就是求解出这个方向向量,然后作用到E(I)上,那么G(E(I) + vec{w})G(E(I)+w)
就是让I笑起来的图了。
其他的例如表情迁移(哭->笑)、特征迁移(白发->黑发)这些都用类似的操作就可以很容易的实现。关于求解这个向量,这个问题下节进行详述。
[闲谈]论被StyleGAN摧残的一天
Dec 9, 2019
原创:岐山凤鸣,转载请注明本站域名
这段时间做了很多GAN相关的研究,因为希望将之前投稿CVPR的文章结合GAN一起,做一点更强的工作,甚至是开创性的工作。
所以我兴冲冲的从DCGAN开始,复现了一个当前国内还没有的仅靠一段声纹生成人脸的应用,具体可以从Demo这里看到。当然,这个是从DCGAN出来的,人脸呢,很模糊,细节基本都不清晰,分辨率更是只有可怜的64x64,还不能改。
于是从DCGAN转战到17年传言巨强的WGAN,根据WGAN-GP的各种原理,对我的网络进行了从网络结构,到loss层面的大修改,这时候我还不能充分的理解WGAN带来的巨大的变革,只能从它论文中对DCGAN错误的推导,和大家纷纷惊叹的评论中知道,这个解决了很多原生GAN的问题,让调参变得更简单。
从这篇知乎文章中,了解到它的改进主要基于四点:
- D去掉了sigmoid
- D和G的loss,不再用以前的sigmoid交叉熵形式,而是直接对向量编码的输出取sum
- D的参数截断
- 采用不基于动量的优化算法
相比于具体的技术细节,我这里更想分享一下我个人的经历和感受。到这里为止,两年来所有的深度学习模型,机器学习模型,我都尽量的从头到尾,自己按照论文和相关的代码进行复现,自己调出一套最好的参数,从来不会直接把别人的代码弄下来,简单复现一下就再也不去探讨细了。而遇到WGAN的时候,出现了第一个问题,那就是明明计算图、输出均是按照正确的形式搭的,在进行了从DCGAN形式到WGAN形式的转变后,G竟然无法生成正常的图像,它的输出变成了一团糟的乱码。
我尝试把loss再改回去,发现就没有问题了。这仿佛在说DCGAN比WGAN的效果要好,于是回头进行了各种检查,发现了两个问题:
- 我的框架里除了D做判别外,还有一个分类器C做人脸的类别分类
- GAN的调参之路是比图像识别更难的,我还需要进一步的调整参数
所以就陷入了问题,上述两个总结一点便是经验不足,所以这里我陷入了迷茫,究竟要怎么改?要严格改为和已有代码仓库中一样的参数么?另外一条线里,我在研究GANimation的损失,这里同样遇到了问题,讲究太多了。这才深深明白深度学习被称为炼丹的原因,在之前图像识别的境界里没有遇到这么多和理论复杂的参数。
之后放弃了WGAN的调参,一边进行动画的分析,一边继续寻找更好的人脸GAN,直到我遇到了StyleGAN,这下可把我震撼到了,高分辨率的生成,举个刚出炉的生成的栗子:
很难相信这是用算法生成出的假脸,因为细节实在是太丰富了,用我自己的眼睛去看,我甚至相信这确实就是一张正常的照片,但可惜世界上不存在这样的人。有好事者之后做了一个很火的网站,https://thispersondoesnotexist.com/,每一次刷新都能得到一张不存在的人脸图,这非常的神奇,不得不说NVIDIA大法好。
于是我对着StyleGAN源码,准备进行重现和学习,先按照Guideline进行了test的尝试,这时候我还没意识到什么,只是感叹这个跨平台的性能做的太好了,直接下完代码后,就能够跑起来得到测试结果。直到看了看细节,再看了看train,我惊呆了,同样是TensorFlow,为什么他这么秀?TensorFlow的代码居然可以写成这样。
这里必须要原谅我的无知,在我早期进行图像识别时,一般是先参考TF官方的源代码的示例,进行搭建,从给出的各个经典模型里进行代码写法的归纳总结,但torch的代码看多了以后,我一度认为Python里torch的代码写的比TF优雅多了,而且更加的pythonic。我在使用TF进行计算图搭建,数据处理的时候,往往都写成流处理的模式,和写sh脚本一样,达到效果即可,很难实现其的封装性。
原本的TF流程大致是这样:
- 原始数据的索引构建
- 数据输入、预处理的离线或Tensor行为
- 计算图的搭建,从Placeholder到opt.minize
- 训练流程与测试流程的搭建
而这四步,都是顺序的,流处理形式的,通过这样的方法,我基本都能够很容易的进行他人代码的复现,并且能找到对应的bug,了解更多的细节,我一度认为我自己写代码的瓶颈,在于代码的优雅度,而不在其他方面。现在StyleGAN的源码给了我更多的思路,原来的方法虽然能实现功能,但并不高效,部署效果不好,提示信息不够,高层的逻辑难搞。NVIDIA给出的方案是:
- 预先定义好一套深度学习的内核系统,可以随便复制到其他的项目下进行使用。
- 训练的时候,采用字典驱动的方法,直接链接对象,无论是数据,方法等。
- 测试/部署的时候,无论计算图和预训练和参数,直接加载预训练好的二进制项目。
纸上得来终觉浅,看上去很简单,各位看官可以自行去研究上述的Style源码,会发现非常的头疼,封装性高到很难在里面进行一些修改,但即便如此,可读性又维护在一个很高的层次,这是非常的厉害,正符合去突破我当前存在的瓶颈:代码质量不高、工程化不足。今天被StyleGAN摧残了一整天,但我也成功跑起来了我自己收集的Chinese数据集和修改后的版本,看着训练数的跳动,从4x4到8x8到16x16最终回到1024x1024的过程也是非常的令人兴奋。之后会进一步的修改Demo中提供的展示,希望有一天自己做的东西,不管是功能、技术还是优雅的层面,也能得到如此的认可。
9 条评论
请问一下原文中Table 3中的Path length项的full和end分别指的是什么?
你好,文章4.1有提到,full代表t~U(0,1),end表示t∈{0,1}
看到了,谢谢
很详细,谢谢
写的很好很详细,感谢!
“一个可学习的仿射变换A(全连接层)将w转化为style中AdaIN的平移和缩放因子y =(ys,i,yb,i”这里不是很明白,为什么要将中间向量W转换为平移和缩放因子呢?合成网络的第一层输入也是一个4*4的平移和缩放因子吗?直接从平移和缩放因子开始合成一个图像好想说不大通啊。
其实这些在文章中都有提及
关于为什么将W转换为平移和缩放因子:个人理解,模仿风格迁移中的方法,对不同层次的图像特征进行控制;
关于第一层的输入:第一层的输入是4*4的常量,不是平移和缩放因子;
ganxie