在GAN的鉴别器中重塑的问题(Tensorflow)

时间:2017-06-21 09:55:10

标签: tensorflow neural-network deep-learning

我试图在Tensorflow中实现各种GAN(在PyTorch中成功完成之后),并且在编写鉴别器部分时遇到了一些问题。

鉴别器的代码(非常类似于MNIST CNN教程)是:

def discriminator(x):
    """Compute discriminator score for a batch of input images.

    Inputs:
    - x: TensorFlow Tensor of flattened input images, shape [batch_size, 784]

    Returns:
    TensorFlow Tensor with shape [batch_size, 1], containing the score 
    for an image being real for each input image.
    """
    with tf.variable_scope("discriminator"):
        x = tf.reshape(x, [tf.shape(x)[0], 28, 28, 1])
        h_1 = leaky_relu(tf.layers.conv2d(x, 32, 5))
        m_1 = tf.layers.max_pooling2d(h_1, 2, 2)
        h_2 = leaky_relu(tf.layers.conv2d(m_1, 64, 5))
        m_2 = tf.layers.max_pooling2d(h_2, 2, 2)
        m_2 = tf.contrib.layers.flatten(m_2)
        h_3 = leaky_relu(tf.layers.dense(m_2, 4*4*64))   
        logits = tf.layers.dense(h_3, 1)
        return logits

而生成器的代码(InfoGAN论文的架构)是:

def generator(z):
    """Generate images from a random noise vector.

    Inputs:
    - z: TensorFlow Tensor of random noise with shape [batch_size, noise_dim]

    Returns:
    TensorFlow Tensor of generated images, with shape [batch_size, 784].
    """
    with tf.variable_scope("generator"):
        batch_size = tf.shape(z)[0]
        fc = tf.nn.relu(tf.layers.dense(z, 1024))
        bn_1 = tf.layers.batch_normalization(fc)
        fc_2 = tf.nn.relu(tf.layers.dense(bn_1, 7*7*128))
        bn_2 = tf.layers.batch_normalization(fc_2)
        bn_2 = tf.reshape(bn_2, [batch_size, 7, 7, 128])
        c_1 = tf.nn.relu(tf.contrib.layers.convolution2d_transpose(bn_2, 64, 4, 2, padding='valid'))
        bn_3 = tf.layers.batch_normalization(c_1)
        c_2 = tf.tanh(tf.contrib.layers.convolution2d_transpose(bn_3, 1, 4, 2, padding='valid'))

到目前为止,这么好。参数数量是正确的(选中它)。但是,我在下一段代码中遇到了一些问题:

tf.reset_default_graph()

# number of images for each batch
batch_size = 128
# our noise dimension
noise_dim = 96

# placeholder for images from the training dataset
x = tf.placeholder(tf.float32, [None, 784])
# random noise fed into our generator
z = sample_noise(batch_size, noise_dim)
# generated images
G_sample = generator(z)

with tf.variable_scope("") as scope:
    #scale images to be -1 to 1
    logits_real = discriminator(preprocess_img(x))
    # Re-use discriminator weights on new inputs
    scope.reuse_variables()
    logits_fake = discriminator(G_sample)

# Get the list of variables for the discriminator and generator
D_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'discriminator')
G_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'generator') 

# get our solver
D_solver, G_solver = get_solvers()

# get our loss
D_loss, G_loss = gan_loss(logits_real, logits_fake)

# setup training steps
D_train_step = D_solver.minimize(D_loss, var_list=D_vars)
G_train_step = G_solver.minimize(G_loss, var_list=G_vars)
D_extra_step = tf.get_collection(tf.GraphKeys.UPDATE_OPS, 'discriminator')
G_extra_step = tf.get_collection(tf.GraphKeys.UPDATE_OPS, 'generator')

我遇到的问题是我在鉴别器中进行重塑,错误说:

ValueError: None values not supported.

当然,batch_size的值是None(顺便说一下,即使我将其更改为某个数字,我得到的错误相同),但是形状函数(据我所知)应该得到动态形状,而不是静态的。我想我在这里有点失落。

值得一提的是,我在这里给出了我正在工作的整个笔记本的链接:https://github.com/TheRevanchist/GANs/blob/master/GANs-TensorFlow.ipynb如果有人想看一下。

注意:这里的代码是斯坦福CS231n任务的一部分。我与斯坦福没有任何关系,所以它不是作业作弊(证明:课程在几个月前完成)。

2 个答案:

答案 0 :(得分:2)

发电机似乎是问题所在。输出大小应与鉴别器匹配。而其他问题是批量规范应该在激活单元之前应用。我修改了代码:

    with tf.variable_scope("generator"):

        fc = tf.layers.dense(z, 4*4*128)
        bn_1 = leaky_relu(tf.layers.batch_normalization(fc))
        bn_1 = tf.reshape(bn_1, [-1, 4, 4, 128])

        c_1 = tf.layers.conv2d_transpose(bn_1, 64, 5, strides=2, padding='same')
        bn_2 = leaky_relu(tf.layers.batch_normalization(c_1))

        c_2 = tf.layers.conv2d_transpose(bn_2, 32, 5, strides=2, padding='same')
        bn_3 = leaky_relu(tf.layers.batch_normalization(c_2))
        c_3 = tf.layers.conv2d_transpose(bn_3, 1, 5, strides=2, padding='same')

        c_3 = tf.layers.batch_normalization(c_3)
        c_3 = tf.image.resize_images(c_3, (28, 28))
        c_3 = tf.contrib.layers.flatten(c_3)
        c_3 = tf.tanh(c_3)
        return c_3

使用上述更改运行时,您的代码会提供以下输出

enter image description here

答案 1 :(得分:-1)

不是传递None来重塑,而是必须传递-1。

所以这个:

x = tf.reshape(x, [tf.shape(x)[0], 28, 28, 1])

变为

x = tf.reshape(x, [-1, 28, 28, 1])

和此:

bn_2 = tf.reshape(bn_2, [batch_size, 7, 7, 128])

变为:

bn_2 = tf.reshape(bn_2, [-1, 7, 7, 128])

它将从您提供的其余形状推断批量大小。