生成模型经典网络之CGAN剖析

先要深刻理解GAN

CGAN(Conditional Generative Adversarial Nets, 条件生成-对抗网络)。借用原论文中的图如下:

想一想,再GAN中我们哪里使用了“类别”

在GAN中,我们求损失函数的时候用到了“类别”,因为二分类器输出的是正样本的几率值(或概率值),所以这里“类别”就用来作为判断用,如果是类别1,计算 l o g ( D ( x j ) ) log(D(x_j)) log(D(xj));如果是类别0,计算 l o g ( 1 − D ( x j ) ) log(1-D(x_j)) log(1D(xj))

在CGAN中,我们将样本的“类别”也作为特征输入。比如对于mnist数据集,其label的shape=(64,10),也就是有10类(0~9),在GAN中我们输入判别器的一个Batch是shape=(64,28,28,1),那么在CGAN中,我们输入的是shape=(64,28,28,11)。在GAN中我们输入生成器的一个Batch是shape=(64,62),那么在CGAN中,我们输入的是shape=(64,72)。—这一过程就是在生成模型 G G G和判别模型 D D D中均引入条件变量y(conditional variable y),这就是CGAN中"C"的含义所在,即一种带条件约束的GAN。

注意:在GAN我们说是的类别是二分类器分类的类别,只有0、1两类。而在CGAN中,添加到生成器和判别器中的是样本类别,可能会有很多类,而不再是2类。此外,CGAN中在计算损失函数的时候也同样用到二分类器分类的类别。

那么将样本标记考虑进去的好处是什么,或者会产生什么影响?

我们先来从直观上感受下:


对于mnist数据集中的1,在GAN的判别器中我们输入的是这样的:

在CGAN的判别器中我们输入的是这样的:

可以看到,CGAN中的输入比GAN中的输入更加有特点:第1阶后10个元素都是相同的。另外,对于数字1,即使是不同的图片,它们第1阶后10个元素都是相同的。那么我们可以这么说,在CGAN中让判别器学习数字1,就是在固定第1阶后10个元素的条件下学习第1阶第1个元素,这句话转成数学表达式就是: x ∣ y x|y xy;同理,生成器的输入可以表示为: z ∣ y z|y zy。于是,就有了原论文的损失函数表达式:

CGAN的损失函数:
V ( G m i n , D m a x ) = E x ∼ P d a t a ( x ) [ l o g ( D ( x ∣ y ) ) ] + E z ∼ P z ( z ) [ l o g ( 1 − D ( G ( z ∣ y ) ) ) ] V(G_{min},D_{max})=\Bbb E_{x\sim P_{data}(x)}[log(D(x|y))]+\Bbb E_{z\sim P_z(z)}[log(1-D(G(z|y)))] V(Gmin,Dmax)=ExPdata(x)[log(D(xy))]+EzPz(z)[log(1D(G(zy)))]

GAN的损失函数:
V ( G m i n , D m a x ) = E x ∼ P d a t a ( x ) [ l o g ( D ( x ) ) ] + E z ∼ P z ( z ) [ l o g ( 1 − D ( G ( z ) ) ) ] V(G_{min},D_{max})=\Bbb E_{x\sim P_{data}(x)}[log(D(x))]+\Bbb E_{z\sim P_z(z)}[log(1-D(G(z)))] V(Gmin,Dmax)=ExPdata(x)[log(D(x))]+EzPz(z)[log(1D(G(z)))]

对比GAN的损失函数,CGAN将输入变成基于样本类别条件下的 x x x z z z

# output of D for real images D_real((64,1),介于(0,1)),D_real_logits未经历过sigmoid,_临时存储net(64,1024)
D_real, D_real_logits, _ = self.discriminator(self.inputs, self.y, is_training=True, reuse=False)

# output of D for fake images G为由噪声z(64,62)生成的图片数据(64,28,28,1)
G = self.generator(self.z, self.y, is_training=True, reuse=False)
# D_fake((64,1),介于(0,1)),D_fake_logits未经历过sigmoid,_临时存储net(64,1024),送入鉴别器的是G生成的假的数据
D_fake, D_fake_logits, _ = self.discriminator(G, self.y, is_training=True, reuse=True)

# get loss for discriminator
# 它对于输入的logits先通过sigmoid函数计算,再计算它们的交叉熵,但是它对交叉熵的计算方式进行了优化,使得结果不至于溢出
# tf.ones_like的使用默认交叉商前面的系数为1数组
# d_loss_real=-log(sigmoid(D_real_logits))等价于d_loss_real=-log(D(x))
d_loss_real = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(logits=D_real_logits, labels=tf.ones_like(D_real)))
# d_loss_fake=-log(sigmoid(D_fake_logits))等价于d_loss_fake=-log(D(G(z))
d_loss_fake = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake_logits, labels=tf.zeros_like(D_fake)))
# d_loss为生成器和鉴别器传出的loss之和
self.d_loss = d_loss_real + d_loss_fake

# get loss for generator
# g_loss=-log(sigmoid(D_fake_logits))等价于g_loss=-log(D(G(z))
self.g_loss = tf.reduce_mean(
tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake_logits, labels=tf.ones_like(D_fake)))

如果我们参考代码实现,会发现原论文中CGAN的损失函数表达的并不准确,确切的说应该是这样的:
V ( G m i n , D m a x ) = E x ∼ P d a t a ( x ) [ l o g ( D ( x ∣ y ) ) ] + E z ∼ P z ( z ) [ l o g ( 1 − D ( G ( z ∣ y ) ∣ y ) ) ] V(G_{min},D_{max})=\Bbb E_{x\sim P_{data}(x)}[log(D(x|y))]+\Bbb E_{z\sim P_z(z)}[log(1-D(G(z|y)|y))] V(Gmin,Dmax)=ExPdata(x)[log(D(xy))]+EzPz(z)[log(1D(G(zy)y))]

其中, D ( x ∣ y ) D(x|y) D(xy) G ( z ∣ y ) G(z|y) G(zy) D ( G ( z ∣ y ) ∣ y ) ) D(G(z|y)|y)) D(G(zy)y))都是指在给定类别条件下的条件概率。

举个例子:
如果我说两只眼睛一张嘴的是什么?你肯定会想到很多。但是如果我说两只眼睛一张嘴的人,你的脑海里出现的就只是人了,而不会有牛头马面。所以加了类别,就是加了约束项,就是加了基本限定条件。

总结:
除了将样本类别作为作为生成器和判别器的输入为,CGAN与GAN在其他方面没有区别,代码实现上亦是。

,使用额外信息y对模型增加条件,可以指导数据生成过程。这些条件变量y可以基于多种信息,例如类别标签,用于图像修复的部分数据[2],来自不同模态(modality)的数据。如果条件变量y是类别标签,可以看做CGAN 是把纯无监督的 zGAN 变成有监督的模型的一种改进。这个简单直接的改进被证明非常有效,并广泛用于后续的相关工作中[3,4]。Mehdi Mirza et al. 的工作是在MNIST数据集上以类别标签为条件变量,生成指定类别的图像。作者还探索了CGAN在用于图像自动标注的多模态学习上的应用,在MIR Flickr25000数据集上,以图像特征为条件变量,生成该图像的tag的词向量。

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值