由于刚进入研究生阶段,熟悉新环境和新的生活节奏,加上业余杂事和自我懈怠,一直没有形成良好的学习习惯,因此趁着寒假这种纯自由支配时间,梳理一下上学期看过的文献,捞一捞当时可能因为其他事务耽误而浅尝辄止的知识点,用稍有长进的知识储备回顾之前的阅读任务,也起到温故知新的作用,顺便也规范一下以后的学习工作。
本人主攻的是GAN模型在人脸属性迁移方向,因此下面的文献梳理均为相关领域的内容,如有理解错误的地方,还望共同讨论,指正不足。
Fader Networks
文献全称:Fader Networks:Manipulating Images by Sliding Attributes
文献出处: neural information processing systems, : 5967-5976.
数据集:celebA
这篇论文做的是人脸属性迁移,通过输入目标图像和迁移标签来生成目标图像。
实验效果图
模型框架图
主要思想
这篇文章模型的主要架构是自编码器,自编码器分为编码器E和解码器D两部分,自编码器的机制是使输出尽可能地与输入相同。作者将GAN模型引入到该框架中,如框架图所示,将编码器E作为生成器,再引入一个简单的全连接层分类器作为判别器,通过引入GAN结构,来重塑编码器E生成的潜在特征(latent representation),使这个潜在特征具有特征不变性,通过在解码过程中引入目标标签来生成目标图像。
特征不变性:
编码器最后输出的特征图带有输入图像的特征,因而如果单纯地在解码器中添加标签,解码器便会忽略标签信息。这时引入GAN模型,目的是为了让编码器生成不带有特征的特征图,在GAN层面上就是判别器判别不出生成器的输出具有哪种特征。例如,给网络输入一张戴眼镜的照片,编码器输出的特征图中只蕴含其他信息,戴眼镜的信息被模糊掉了,即体现特征不变性,这样生成图像是否戴眼镜就完全取决于解码器赋予的标签。
训练:用输入图像对应的真实标签进行训练。
测试/应用:自由输入图像和目标标签。
损失函数
该模型的损失函数主要分为三部分:重构loss、判别器loss、整体对抗loss.
重构loss采用的是MSE,输入图像x和它所对应的真实标签y,通过均方误差来衡量生成图像和原图像的重构质量。
LAE(Θenc,Θdec)=1m∑(x,y)∈D∣∣Dθenc(Eθenc(x),y)−x∣∣22L_{AE}(\Theta_{enc},\Theta_{dec})=\frac{1}{m}\sum_{(x,y)\in D}||D_{\theta_{enc}}(E_{\theta_{enc}}(x),y)-x||_2^2 LAE(Θenc,Θdec)=m1(x,y)∈D∑∣∣Dθenc(Eθenc(x),y)−x∣∣22
判别器loss则与传统的GAN损失函数相同,公式如下:
Ldis(θdis∣θenc)=−1m∑(x,y)∈DlogPθdis(y∣Eθenc(x))L_{dis}(\theta_{dis}|\theta_{enc})=-\frac{1}{m}\sum_{(x,y)\in D}logP_{\theta_{dis}}(y|E_{\theta_{enc}}(x)) Ldis(θdis∣θenc)=−m1(x,y)∈D∑logPθdis(y∣Eθenc(x))
整体损失函数则引入了一个λE>0\lambda_E>0λE>0来权衡模型的重构质量和潜在特征不变性,公式如下:
LAE(Θenc,Θdec∣θenc)=1m∑(x,y)∈D∣∣Dθenc(Eθenc(x),y)−x∣∣22−λElogPθdis(1−y∣Eθenc(x))L_{AE}(\Theta_{enc},\Theta_{dec}|\theta_{enc})=\frac{1}{m}\sum_{(x,y)\in D}||D_{\theta_{enc}}(E_{\theta_{enc}}(x),y)-x||_2^2-\lambda_ElogP_{\theta_{dis}}(1-y|E_{\theta_{enc}}(x)) LAE(Θenc,Θdec∣θenc)=m1(x,y)∈D∑∣∣Dθenc(Eθenc(x),y)−x∣∣22−λElogPθdis(1−y∣Eθenc(x)) 其中λE\lambda_EλE在训练中的取值为:
起始值:λE=0\lambda_E=0λE=0经过第一个500k迭代后: λE=0.0001\lambda_E=0.0001λE=0.0001
初始状态相当于是训练一个自编码器,训练到一定程度之后,引入特征不变性的训练要求。
实现细节
卷积核:size:4×4 stride:2 padding:1
编码器和解码器均由7组 卷积+BN+ReLU模块 组成,编码器使用的是leaky-ReLU,解码器使用的是普通的ReLU.
优化算法:默认设置为Adam,学习率:0.0002
在解码器中加入条件标签信息,查阅代码后发现,因为CelebA数据集是二元标签,所以每个特征都使用one-hot形式来表示,将当前要添加的标签升维,使其和解码器每层输出一个尺寸,并在通道的维数上添加这些升维的标签(如上述框架图中绿色部分),与当前的特征图一并作为下一层的输入。
GeneGAN
文献全称:GeneGAN: Learning Object Transfiguration and Attribute Subspace from Unpaired Data
文献出处:Computer Vision and Pattern Recognition, .
数据集:Multi-PIE、CelebA
这篇论文做的是人脸属性迁移,测试效果为输入两张图像,可以通过互换特征部分获得两张不同特征的人脸照片。
实验效果图
模型框架图
主要思想
GeneGAN模型也是使用自编码器的结构,编码器将输入图像映射成两个部分(从代码中看,是在特征图的通道维度上将其三一分,即34\frac{3}{4}43为A,14\frac{1}{4}41为u),其中一部分表示人脸背景/标识AAA,另一部分表示脸部的属性特征uuu。模型一次需要输入两张图片IAI_AIA和IBI_BIB,IAI_AIA和IBI_BIB有一对不同的特征,模型把IAI_AIA的特征看作正常向量,把IBI_BIB的特征表示为0向量,从而形成鲜明地比较,交换后可以生成四张图片,其中两张是重构结果,两张是迁移结果。
损失函数
有若干表示如下:
该算法在GAN层面的实现就是:
让图片xA0′x'_{A0}xA0′在{xB0i}i=1M\lbrace x_{B0}^i {\rbrace}_{i=1}^M{xB0i}i=1M中不会被判别出来让图片xBu′x'_{Bu}xBu′在{xAui}i=1N\lbrace x_{Au}^i {\rbrace}_{i=1}^N{xAui}i=1N中不会被判别出来
生成器部分有四个类型的损失函数:
1.重构损失
LreconstructAu=∣∣xAu−xAu′∣∣1L_{reconstruct}^{Au}=||x_{Au}-x'_{Au}||_1LreconstructAu=∣∣xAu−xAu′∣∣1 LreconstructB0=∣∣xB0−xB0′∣∣1L_{reconstruct}^{B0}=||x_{B0}-x'_{B0}||_1LreconstructB0=∣∣xB0−xB0′∣∣1 重构损失可以衡量原图被重构的好坏程度,相当于自编码器X→XX→XX→X的一种监督手段,与下文中DiscoGAN中的重构损失有所不同。
2.标准的GAN损失
LGAN0=−Ez~P0[logD(xA0,z)]L_{GAN}^0=-E_{z~P_0}[logD(x_{A0},z)]LGAN0=−Ez~P0[logD(xA0,z)] LGAN≠0=−Ez~P≠0[logD(xBu,z)]L_{GAN}^{\neq0}=-E_{z~P_{\neq0}}[logD(x_{Bu},z)]LGAN=0=−Ez~P=0[logD(xBu,z)] 这里的两个损失函数是为了让互换特征后的生成结果更逼真,即让判别器认为生成图像为真的评分更高。
3.nulling loss
L0=∣∣ε∣∣1L_0=||\varepsilon||_1L0=∣∣ε∣∣1 nulling loss将IBI_BIB的第二个编码ε\varepsilonε加上了正则化,使其趋向于零,其目的是为了让IBI_BIB的第一个编码BBB获得除去当前属性后的人脸信息(identity),即模型训练成形后,BBB将只代表人脸信息,与要迁移的属性无关。这个损失函数也是GeneGAN能够通过互换部分通道来实现算法思想的关键。
4.平行四边形损失
Lparallelogram=∣∣xAu+xB0−xA0−xBu∣∣1L_{parallelogram}=||x_{Au}+x_{B0}-x_{A0}-x_{Bu}||_1Lparallelogram=∣∣xAu+xB0−xA0−xBu∣∣1 这个损失函数作为可选项,在生成样本和源图之间加一个约束,在给出的代码中作者也使用了这个函数,但是没有做消融实验。
生成器整体损失函数
LG=LreconstructAu+LreconstructB0+LGAN0+LGAN≠0+L0+LparallelogramL_G=L_{reconstruct}^{Au}+L_{reconstruct}^{B0}+L_{GAN}^0+L_{GAN}^{\neq0}+L_0+L_{parallelogram}LG=LreconstructAu+LreconstructB0+LGAN0+LGAN=0+L0+Lparallelogram
判别器部分采用的是标准的GAN损失:
LD0=−Ez~P0[logD(xAu,z)]−Ez~P0[log(1−D(xBu,z))]L_D^0=-E_{z~P_0}[logD(x_{Au},z)]-E_{z~P_0}[log(1-D(x_{Bu},z))]LD0=−Ez~P0[logD(xAu,z)]−Ez~P0[log(1−D(xBu,z))] LD≠0=−Ez~P≠0[logD(xA0,z)]−Ez~P≠0[log(1−D(xB0,z))]L_D^{\neq0}=-E_{z~P_{\neq0}}[logD(x_{A0},z)]-E_{z~P_{\neq0}}[log(1-D(x_{B0},z))]LD=0=−Ez~P=0[logD(xA0,z)]−Ez~P=0[log(1−D(xB0,z))] LD=LD0+LD≠0L_D=L_D^0+L_D^{\neq0}LD=LD0+LD=0
实现细节
卷积核尺寸:4*4,decoder实现使用的是fractional stride.
优化算法:RMSProp,学习率:5e-5, 冲量:0
弃子模型
文中借鉴了CycleGAN的思想,还提到了他们结合循环loss的一个模型,如下图所示:通过第一个GeneGAN网络得到两张互换特征的生成图,作为第二个GeneGAN网络的输入,再次互换得到和源图一样特征的图,在源图和孙子图之间搭建重构损失,但在他们的实验中,重构损失一直很高,也影响了对抗训练的效果,因而生成图的效果质量很差。
DiscoGAN / CycleGAN
discoGAN:
文献全称:Learning to Discover Cross-Domain Relations with Generative Adversarial Networks
文献出处:Computer Vision and Pattern Recognition, .
部分效果图
CycleGAN:
文献全称:Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks
文献出处:international conference on computer vision, : 2242-2251.
部分效果图
模型框架图
这两篇文章,加上一篇DualGAN的文章,三个作者在同一年相继提出这样的模型结构,但研究的内容和初衷稍有不同,但都是跨域迁移。
主要思想
加上DualGAN,这三篇的模型框架是相同的,即便具体实现时有些许不同。先来说一下模型的大概思路,因为是跨域问题,所以要从两个域(domain)下手,记两个域分别为AAA和BBB,模型中设计两种映射:A→BA→BA→B和B→AB→AB→A;这里使用的是CGAN,把域AAA的图片xAx_{_A}xA作为输入来生成迁移到域BBB的结果图xABx_{_{AB}}xAB,然后再使用B→AB→AB→A的映射网络将xABx_{_{AB}}xAB映射为属于域A的xABAx_{_{ABA}}xABA,然后构造一个重构损失来衡量xAx_{_A}xA和xABAx_{_{ABA}}xABA之间的差异,另一个域的映射流与此相似。
对于CycleGAN而言,作者的初衷是为了研究不配对的域间迁移问题,即只有两个域的数据集,相当于能得到的只有两个域的数据分布,两个域之间没有配对关系。
而对于DiscoGAN而言,尽管也是为了解决跨域问题,但其初衷是为了找到不同域之间的关联关系,因此起名为Discovery GAN.在这篇文章中,作者解释了设计该模型的理由,主要是为了克服mode collapse问题。
上图展示的是只添加了重构损失的GAN模型。理想情况下,迁移效果应该如下图(a)的情况一样,域AAA中的每个mode都对应指向域BBB中的每个mode。但因为传统GAN设计的固有缺陷,会有mode collapse问题,便会出现下图(b)所示的问题,域AAA中的多个mode迁移后成了域BBB中的同一个mode;在这种情况下,使用只带有重构损失的GAN模型(作者使用重构损失也是为了尝试解决mode collapse),便会使得Amode1A_{mode1}Amode1和Amode2A_{mode2}Amode2都映射到Bmode1B_{mode1}Bmode1,而Bmode1B_{mode1}Bmode1映射回域AAA时只可能映射到某一个mode上,假设映射成了Amode1A_{mode1}Amode1,那么对于作为源图输入的Amode2A_{mode2}Amode2而言,经过A→B→AA→B→AA→B→A的映射后,得到的结果图为Amode1A_{mode1}Amode1,也就是说重构出来的结果和源图并不是一个mode,如果使用重构损失,只会让模型对这两个状态的学习发生动荡,不能解决mode collapse问题。
为了解决上述问题,作者提出了搭建两个带有重构函数的GAN,即A→B→AA→B→AA→B→A和B→A→BB→A→BB→A→B,而两个映射流中的生成器GA→BG_{A→B}GA→B和GB→AG_{B→A}GB→A分别共享参数,所以这个模型有两个GAN损失和两个重构损失的约束,这样就相当于在两个域间建立起了一对一的对应关系。
在DiscoGAN验证mode collapse的toy experiment中,下图(d)也证实了该模型较好地克服了mode collapse问题;在CycleGAN对单向重构损失的消融实验中,也发现去除重构损失的映射方向(例如A→B→AA→B→AA→B→A)会明显存在mode collapse问题。
损失函数
从域AAA到域BBB的映射流公式表达如下:(B→A与此相似)
xAB=GAB(xA)x_{_{AB}}=G_{AB}(x_{_A})xAB=GAB(xA) xABA=GBA(xAB)=GBA∘GAB(xA)x_{_{ABA}}=G_{BA}(x_{_{AB}})=G_{BA} \circ G_{AB}(x_{_A})xABA=GBA(xAB)=GBA∘GAB(xA) 在GAN结构层面,两个映射流中要实现的是:
让生成图xABx_{_{AB}}xAB在域B中不会被判别出来让生成图xBAx_{_{BA}}xBA在域A中不会被判别出来
损失函数如下:
1.重构损失:
LCONSTA=d(GBA∘GAB(xA),xA)L_{CONST_A}=d(G_{BA} \circ G_{AB}(x_{_A}),x_{_A})LCONSTA=d(GBA∘GAB(xA),xA) LCONSTB=d(GAB∘GBA(xB),xB)L_{CONST_B}=d(G_{AB} \circ G_{BA}(x_{_B}),x_{_B})LCONSTB=d(GAB∘GBA(xB),xB) 这里的d可以用L1、L2等距离来实现。
2.生成器GAN部分:
LGANA=−ExB~PB[logDA(GBA(xB))]L_{GAN_A}=-E_{x_{_B}~P_{_B}}[logD_A(G_{BA}(x_{_B}))]LGANA=−ExB~PB[logDA(GBA(xB))] LGANB=−ExA~PA[logDB(GAB(xA))]L_{GAN_B}=-E_{x_{_A}~P_{_A}}[logD_B(G_{AB}(x_{_A}))]LGANB=−ExA~PA[logDB(GAB(xA))]
3.判别器GAN部分:
LDA=−ExA~PA[logDA(xA)]−ExB~PB[log(1−DA(GBA(xB)))]L_{D_A}=-E_{x_{_A}~P_{_A}}[logD_A(x_{_A})]-E_{x_{_B}~P_{_B}}[log(1-D_A(G_{BA}(x_{_B})))]LDA=−ExA~PA[logDA(xA)]−ExB~PB[log(1−DA(GBA(xB)))] LDB=−ExB~PB[logDB(xB)]−ExA~PA[log(1−DB(GAB(xA)))]L_{D_B}=-E_{x_{_B}~P_{_B}}[logD_B(x_{_B})]-E_{x_{_A}~P_{_A}}[log(1-D_B(G_{AB}(x_{_A})))]LDB=−ExB~PB[logDB(xB)]−ExA~PA[log(1−DB(GAB(xA)))]
模型整体损失函数:
LG=LGANA+LCONSTA+LGANB+LCONSTBL_G=L_{GAN_A}+L_{CONST_A}+L_{GAN_B}+L_{CONST_B}LG=LGANA+LCONSTA+LGANB+LCONSTB LD=LDA+LDBL_D=L_{D_A}+L_{D_B}LD=LDA+LDB
实现细节
DiscoGAN:
输入图片的大小:64×64×3
卷积核大小:4×4
优化算法:Adam,lr:0.0002,β1=0.5\beta_1=0.5β1=0.5,β2=0.999\beta_2=0.999β2=0.999
在除第一层和最后一层的卷积层和反卷积层加入批归一化(BN)
CycleGAN:
生成器的部分模块使用了微步卷积,也使用了几个残差模块;
batch size:1,所以使用的归一化为instance normalization.
在判别器部分,使用的是patchGAN的判别器结构,即判别器输出的不是一个标量,而是一个二维矩阵,每一个坐标值表示源图上与其对应的patch的真伪值。这种判别器相比于判断全图的网络结构而言,具有较少的参数。
在损失函数部分使用的是最小二乘损失:
LG=Ex~pdata(x)[(D(G(x))−1)2]L_G=E_{x~p_{data}(x)}[(D(G(x))-1)^2]LG=Ex~pdata(x)[(D(G(x))−1)2] LD=Ey~pdata(y)[(D(y)−1)2]+Ex~pdata(x)[D(G(x))2]L_D=E_{y~p_{data}(y)}[(D(y)-1)^2]+E_{x~p_{data}(x)}[D(G(x))^2]LD=Ey~pdata(y)[(D(y)−1)2]+Ex~pdata(x)[D(G(x))2] 这种损失更加稳定并且可以提高生成质量。
在训练策略上,使用先前迭代产生的生成图片更新判别器,而不是用最新的生成器产生的生成图片来更新判别器,这样可以减少模型的动荡。具体的代码实现如下所示(只截取了关键代码段):
'''tensorflow实现'''# 建立生成图片A和B的 history poolself.fake_pool_A = tf.placeholder(tf.float32, [None, img_width, img_height, img_layer], name="fake_pool_A")self.fake_pool_B = tf.placeholder(tf.float32, [None, img_width, img_height, img_layer], name="fake_pool_B")# 采样更新D的样本并更新history pooldef fake_image_pool(self, num_fakes, fake, fake_pool):if(num_fakes < pool_size):fake_pool[num_fakes] = fakereturn fakeelse :p = random.random()if p > 0.5:random_id = random.randint(0,pool_size-1)temp = fake_pool[random_id]fake_pool[random_id] = fakereturn tempelse :return fake# 把从history pool得到的样本丢进判别器得到的结果图 self.fake_pool_rec_A = build_gen_discriminator(self.fake_pool_A, "d_A")self.fake_pool_rec_B = build_gen_discriminator(self.fake_pool_B, "d_B")# 判别器损失函数d_loss_A = (tf.reduce_mean(tf.square(self.fake_pool_rec_A)) + tf.reduce_mean(tf.squared_difference(self.rec_A,1)))/2.0d_loss_B = (tf.reduce_mean(tf.square(self.fake_pool_rec_B)) + tf.reduce_mean(tf.squared_difference(self.rec_B,1)))/2.0
该策略出自Learning from Simulated and Unsupervised Images through Adversarial Training,作者认为判别器只关注于最新产生的生成图,相当于丧失了记忆功能,则将导致对抗训练的动荡,同时也会让生成器引入判别器已经遗忘的生成图。对于生成器在每一个时刻产生的每一张生成图,判别器都应该判定其为“假”,所以设计了如上述所示的history pool来存储过去产生的生成图。训练判别器的样本采样规则为:在每次迭代中,0.5*batch_size的样本来自于当前生成器的生成图,另外一半来自于history pool.消融实验的对比图如下图所示。
参考文献
Lample G, Zeghidour N, Usunier N, et al. Fader Networks: Manipulating Images by Sliding Attributes[C]. neural information processing systems, : 5967-5976Zhou S, Xiao T, Yang Y, et al. GeneGAN: Learning Object Transfiguration and Attribute Subspace from Unpaired Data[J]. arXiv: Computer Vision and Pattern Recognition, .Kim T, Cha M, Kim H, et al. Learning to Discover Cross-Domain Relations with Generative Adversarial Networks[J]. arXiv: Computer Vision and Pattern Recognition, .Zhu J, Park T, Isola P, et al. Unpaired Image-to-Image Translation Using Cycle-Consistent Adversarial Networks[C]. international conference on computer vision, : 2242-2251.Yi Z, Zhang H, Tan P, et al. DualGAN: Unsupervised Dual Learning for Image-to-Image Translation[J]. arXiv: Computer Vision and Pattern Recognition, .Shrivastava A, Pfister T, Tuzel O, et al. Learning from Simulated and Unsupervised Images through Adversarial Training[C]. computer vision and pattern recognition, : 2242-2251如果觉得《[研一上]人脸属性迁移文献梳理(1)》对你有帮助,请点赞、收藏,并留下你的观点哦!