首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TensorFlow DCGAN模型的稳定性与收敛性问题

TensorFlow DCGAN模型的稳定性与收敛性问题
EN

Stack Overflow用户
提问于 2017-04-30 19:30:01
回答 1查看 772关注 0票数 1

我已经为DCGANTensorFlow上的米尼思培训中构建了自己的实现。

完整代码 (runnable)可在github:https://github.com/Daniel451/tfdcgan上获得

请随意提交拉请求:)

当该模型试图学习生成MNIST样本时,其稳定性很差,收敛速度较慢(即使在10年代以后,生成的样本仍显得非常人工)。

有趣的是,我首先在喀拉斯 (使用TensorFlow后端)中实现了相同的模型,这与预期的一样。它学习合理的滤波器和发电机返回良好的MNIST样本时,给标准正态分布。

我怀疑这是损失函数或模型配置的问题,但我无法找到确切的问题。

我注意到的另一件奇怪的事情是,TensorFlow实现需要鉴别器的输出才能具有(batch_size, 2)的形状。因此,我用[0, 1]对生成器/假图像进行编码以进行训练,并使用[1, 0]对真实的训练图像进行编码。

我的预期是,只有逻辑应该需要这个形状,因为它需要稀疏的work...but标签,即使是逻辑逻辑,当鉴别器的形状为(batch_size, 1)时,也不会返回有用的损失计算,其中,生成器/假图像的编码仅为0.0,而真正的训练图像为1.0。

在不同的损失函数和单个输出神经元的情况下,Keras实现工作良好。

这是生成器的(G)模型:

代码语言:javascript
复制
def model_generator(self, Z, reuse=True):

        init_op = tf.contrib.layers.xavier_initializer(uniform=True, dtype=tf.float32)

        with tf.variable_scope("g", initializer=init_op, reuse=reuse, dtype=tf.float32):

            with tf.variable_scope("reshape"):
                out = tf.layers.dense(Z, 7 * 7 * 256, activation=None)
                out = tf.reshape(out, [-1, 7, 7, 256])
                out = tf.layers.batch_normalization(out)
                out = tf.nn.tanh(out)

            with tf.variable_scope("deconv1"):
                out = tf.layers.conv2d_transpose(out, 128, [3, 3], strides=[2, 2], padding="same")
                out = tf.layers.batch_normalization(out)
                out = tf.nn.tanh(out)

            with tf.variable_scope("deconv2"):
                out = tf.layers.conv2d_transpose(out, 64, [3, 3], strides=[2, 2], padding="same")
                out = tf.layers.batch_normalization(out)
                out = tf.nn.tanh(out)

            with tf.variable_scope("output"):
                out = tf.layers.conv2d_transpose(out, 1, [5, 5], strides=[1, 1], padding="same")
                logits = out
                output = tf.nn.tanh(out)

        return output, logits

这是Discriminator's (D)模型:

代码语言:javascript
复制
def model_discriminator(self, X, reuse=True, trainable=True):

        init_op = tf.contrib.layers.xavier_initializer(uniform=False, dtype=tf.float32)

        with tf.variable_scope("d", initializer=init_op, reuse=reuse, dtype=tf.float32):

            with tf.variable_scope("conv1"):
                out = tf.layers.conv2d(X, 64, [5, 5], strides=[2, 2], padding="same",
                                       trainable=trainable)
                out = tf.nn.tanh(out)

            with tf.variable_scope("conv2"):
                out = tf.layers.conv2d(out, 128, [3, 3], strides=[2, 2], padding="same",
                                       trainable=trainable)
                out = tf.nn.tanh(out)

            with tf.variable_scope("output"):
                out = tf.reshape(out, [-1, 7 * 7 * 128])
                out = tf.layers.dense(out, 2, activation=None, trainable=trainable)
                logits = out
                output = tf.sigmoid(out)

        return output, logits

我试过这些损失函数中的每一个

代码语言:javascript
复制
self.d_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=self.D_logits, labels=self.Y))
self.dg_loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=self.DG_logits, labels=self.Y))

self.d_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=self.D_logits, labels=self.Y))
self.dg_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=self.DG_logits, labels=self.Y))

self.d_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=self.D_logits, labels=self.Y))
self.dg_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=self.DG_logits, labels=self.Y))

下面是相应的培训操作

代码语言:javascript
复制
self.d_train_op = tf.train.AdamOptimizer(learning_rate=2e-4, beta1=0.5, beta2=0.999, name="Adam_D")\
            .minimize(self.d_loss, var_list=tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope="d"))
self.g_train_op = tf.train.AdamOptimizer(learning_rate=2e-4, beta1=0.5, beta2=0.999, name="Adam_DG")\
            .minimize(self.dg_loss, var_list=tf.get_collection(tf.GraphKeys.GLOBAL_VARIABLES, scope="g"))

...beta1=0.5是由链接文件提出的,var_list=...确保DG都受过培训,但从来没有两者兼得。

我已经将规范化-- MNIST将图像输入到间隔[-1.0, 1.0],就像几个消息来源所建议的那样。

self.G (生成器;用于预测)、self.D (鉴别器;用于分类)和self.DG (为了训练生成器)的实例化如下所示:

代码语言:javascript
复制
# placeholder for noise Z, fed into G
self.Z = tf.placeholder(tf.float32, shape=[None, 100], name="Z")
# placeholder for X, image data fed into D
self.X = tf.placeholder(tf.float32, shape=[None, 28, 28, 1], name="X")
# placeholder for Y, labels for training
self.Y = tf.placeholder(tf.int32, shape=[None], name="Y")

self.G, self.G_logits = self.model_generator(self.Z, reuse=False)
self.D, self.D_logits = self.model_discriminator(self.X, reuse=False)
self.DG, self.DG_logits = self.model_discriminator(self.G, trainable=False)

我正在培训DCGAN,每批培训3个步骤:

  1. 用真实图像训练D
  2. 用生成器/假图像训练D
  3. 列车G

对于为什么这个网络表现不好,有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2019-05-13 13:12:11

我从你的问题中注意到一件事,那就是你提到你的训练分三个步骤。通常一列火车两步或一步。要么您分别训练鉴别器和生成器(两个步骤),要么一起训练(一个步骤)。

在训练鉴别器时,您使用获取鉴别器的输出,用于真实的和假的样本,并为两者生成损失并应用梯度。

如果您在一个步骤中进行培训,则需要确保以正确的顺序应用渐变。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43710471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档