Conditional Generative Adversarial Nets

Introduction

对抗生成网络通过迭代的方式训练生成模型,可以避免棘手的概率近似。它不需要用到马尔可夫链这么复杂的东西,仅仅需要通过反向传播学习梯度。Goodfellow2014年在《Generative adversarial nets》指出它可以产生最先进的对数似然估计和现实样本。

这篇文章提出一种带条件的生成对抗网络(判别器和生成器都带条件)。在不带条件的对抗网络中,数据生成的模式不太可控了。然而通过给模型的附加信息作为限制条件,可以指导数据生成。这些条件可以是:类标签、来自其他模型的数据等等。

    文章提出的几种应用:
     1. 生成MINIST数字
     2. 用来学习多模式模型
     3. 生成图像标签(不是训练标签的一部分)

多模式模型:
相同的信息往往可以用不同的方式进行表达或存储。例如,图像往往与其标签和文本说明表示一致; 不同的模式的特征在于非常不同的统计特性。例如,图像通常表示为像素强度或特征提取器的输出,而文本被表示为离散字计数向量。由于不同信息资源的不同统计特性,发现不同模式之间的关系是非常重要的。多模态学习是代表不同模式的联合表征的好模型。
本篇文章第二个实验主要是通过CGAN给图像贴标签

监督神经网络仍存在挑战:

  1. 对输出类别多的分类有困难。
    解决:利用其他的模型作为额外信息。比如说,对图像特征的分类,可以通过把图像特征空间转换成文字描述空间,再进行分类,这样性能能得到提升。【A deep visual-semantic embedding model】

  2. 很多方法是针对输入输出一对一映射,而实际问题更多是一对多的映射关系。(比如说给一张图片贴标签,一张图片就对应多个输出了)
    解决:比如CGAN,multi-modal Deep Boltzmann Machine

模型及实验

具体的GAN模型在这里就不做详细的描述啦,仅给出训练用到的方程及训练的流程伪代码供CGAN进行对比。

GAN minmax game方程:
这里写图片描述

GAN 训练流程:
引用块内容

CGAN流程:
y表示额外的限制条件

CGAN中生成器和判别器都加入了相同的约束条件y,这个额外的约束条件可以来自类标签、其他模型的数据等等。在生成模型中,先验噪声p(z)和条件y联合组成了联合隐层表征(我们的网络对如何去将x,y z,y进行隐藏没有特别的规定,文章中使用MLP进行映射),在判别模型中,真实分布x和条件y联合也组成了联合隐层表征(使用MLP进行映射)。将生成的隐藏层作为输入层的一部分,从而实现条件GAN。

MLP:每一层全连接下一层,除了输入节点外,每个节点都带一个非线性的激活函数(在本文使用Relu),使用反向监督的方式训练MLP。
MLP缺陷:
1.网络的隐含节点个数选取问题至今仍是一个 世界难题(Google,Elsevier, CNKI);
2.停止阈值、学习率、动量常数需要采用”trial-and-error”法,极其耗时(动手实验);
3.学习速度慢;
4.容易陷入局部极值,学习不够充分。

CGAN minmax game方程:与GAN的方程很相似,CGAN的目标函数是带有条件概率的二人极小极大值博弈。
这里写图片描述

Future Work

  1. 提出更复杂的方法,探索CGAN的细节和详细地分析它们的性能和特性。
  2. 当前生成的每个tag是相互独立的
  3. 构建一个联合训练的调度方法去学习语言模型

以下是从别人的文章里看来的代码,原博

def discriminator(self, image, y=None, reuse=False):
    # image is 256 x 256 x (input_c_dim + output_c_dim)
    with tf.variable_scope("discriminator") as scope:
        if reuse:
            tf.get_variable_scope().reuse_variables()
        else:
            assert tf.get_variable_scope().reuse == False

        h0 = lrelu(conv2d(image, self.df_dim, name='d_h0_conv')) # h0 is (128 x 128 x self.df_dim)
        h1 = lrelu(self.d_bn1(conv2d(h0, self.df_dim*2, name='d_h1_conv'))) # h1 is (64 x 64 x self.df_dim*2)
        h2 = lrelu(self.d_bn2(conv2d(h1, self.df_dim*4, name='d_h2_conv'))) # h2 is (32 x 32 x self.df_dim*4)
        h3 = lrelu(self.d_bn3(conv2d(h2, self.df_dim*8, d_h=1, d_w=1, name='d_h3_conv'))) # h3 is (16 x 16 x self.df_dim*8)
        h4 = linear(tf.reshape(h3, [self.batch_size, -1]), 1, 'd_h3_lin')
        return tf.nn.sigmoid(h4), h4

def generator(self, img_in):
    with tf.variable_scope("generator") as scope:
        s = self.output_size
        s2, s4, s8, s16, s32, s64, s128 = int(s/2), int(s/4), int(s/8), int(s/16), int(s/32), int(s/64), int(s/128)
        # image is (256 x 256 x input_c_dim)
        e1 = conv2d(img_in, self.gf_dim, name='g_e1_conv') # e1 is (128 x 128 x self.gf_dim)
        e2 = bn(conv2d(lrelu(e1), self.gf_dim*2, name='g_e2_conv')) # e2 is (64 x 64 x self.gf_dim*2)
        e3 = bn(conv2d(lrelu(e2), self.gf_dim*4, name='g_e3_conv')) # e3 is (32 x 32 x self.gf_dim*4)
        e4 = bn(conv2d(lrelu(e3), self.gf_dim*8, name='g_e4_conv')) # e4 is (16 x 16 x self.gf_dim*8)
        e5 = bn(conv2d(lrelu(e4), self.gf_dim*8, name='g_e5_conv')) # e5 is (8 x 8 x self.gf_dim*8)


        self.d4, self.d4_w, self.d4_b = deconv2d(tf.nn.relu(e5), [self.batch_size, s16, s16, self.gf_dim*8], name='g_d4', with_w=True)
        d4 = bn(self.d4)
        d4 = tf.concat(axis=3, values=[d4, e4])
        # d4 is (16 x 16 x self.gf_dim*8*2)

        self.d5, self.d5_w, self.d5_b = deconv2d(tf.nn.relu(d4), [self.batch_size, s8, s8, self.gf_dim*4], name='g_d5', with_w=True)
        d5 = bn(self.d5)
        d5 = tf.concat(axis=3, values=[d5, e3])
        # d5 is (32 x 32 x self.gf_dim*4*2)

        self.d6, self.d6_w, self.d6_b = deconv2d(tf.nn.relu(d5), [self.batch_size, s4, s4, self.gf_dim*2], name='g_d6', with_w=True)
        d6 = bn(self.d6)
        d6 = tf.concat(axis=3, values=[d6, e2])
        # d6 is (64 x 64 x self.gf_dim*2*2)

        self.d7, self.d7_w, self.d7_b = deconv2d(tf.nn.relu(d6), [self.batch_size, s2, s2, self.gf_dim], name='g_d7', with_w=True)
        d7 = bn(self.d7)
        d7 = tf.concat(axis=3, values=[d7, e1])
        # d7 is (128 x 128 x self.gf_dim*1*2)

        self.d8, self.d8_w, self.d8_b = deconv2d(tf.nn.relu(d7), [self.batch_size, s, s, self.output_colors], name='g_d8', with_w=True)
        # d8 is (256 x 256 x output_c_dim)

    return tf.nn.tanh(self.d8)

生成器和判别器的损失函数:

combined_preimage = tf.concat(axis=3, values=[self.line_images, self.color_images])
self.generated_images = self.generator(combined_preimage)
self.real_AB = tf.concat(axis=3, values=[combined_preimage, self.real_images])
self.fake_AB = tf.concat(axis=3, values=[combined_preimage, self.generated_images])
self.disc_true, disc_true_logits = self.discriminator(self.real_AB, reuse=False)
self.disc_fake, disc_fake_logits = self.discriminator(self.fake_AB, reuse=True)
self.d_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=disc_true_logits, labels=tf.ones_like(disc_true_logits)))
self.d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=disc_fake_logits, labels=tf.zeros_like(disc_fake_logits)))
self.d_loss = self.d_loss_real + self.d_loss_fake
self.g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=disc_fake_logits, labels=tf.ones_like(disc_fake_logits))) \
                + self.l1_scaling * tf.reduce_mean(tf.abs(self.real_images - self.generated_images))
t_vars = tf.trainable_variables()
self.d_vars = [var for var in t_vars if 'd_' in var.name]
self.g_vars = [var for var in t_vars if 'g_' in var.name]
self.d_optim = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.d_loss, var_list=self.d_vars)
self.g_optim = tf.train.AdamOptimizer(0.0002, beta1=0.5).minimize(self.g_loss, var_list=self.g_vars)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值