用TensorFlow写生成式对抗网络

keras是模仿别人写的,想真正自己去用tensorflow,下面是实现代码。代码仅搭建出了一个大的框架,没有加入一些关键的技巧,网络能跑通,但是精度不高。关键地方做了注释

import tensorflow as tf
import numpy as np
import keras
#获取数据和对数据的预处理
(x_train,y_train),(_,_)=keras.datasets.cifar10.load_data()
print("x_train.shape=",x_train.shape)       #x_train.shape= (50000, 32, 32, 3)
x_train = x_train[y_train.flatten() == 5]
print("x_train.shape=",x_train.shape)       #x_train.shape= (5000, 32, 32, 3)
x_train=x_train.reshape((x_train.shape[0],)+(32,32,3)).astype('float32')/255#数据标准化

#定义一个返回值为输入数据的函数
def get_inputs(noise_dim):
    inputs_real = tf.placeholder( tf.float32,[None, 32, 32, 3],name='inputs_real')  # input_real=[none,32,32,3]
    inputs_noise = tf.placeholder(tf.float32,[None, noise_dim],name='inputs_noise')  # inputs_noise=[none,100]
    print("input_real =", inputs_real)
    print("input_noise=", inputs_noise)
    return inputs_real, inputs_noise    #返回值为真实数据,和噪声数据

#定义一个生成器模型,参数为输入噪声
def get_generator(noise_img, is_train=True):
    with tf.variable_scope("generator", reuse=(not is_train)):
        layer1 = tf.layers.dense(noise_img, 4 * 4 * 512)
        layer1 = tf.reshape(layer1, [-1, 4, 4, 512])
        layer2 = tf.layers.conv2d_transpose(   inputs=layer1, filters =256, kernel_size=4, strides=2, padding='same')
        layer2 = tf.layers.batch_normalization(inputs=layer2, training=is_train)
        layer3 = tf.layers.conv2d_transpose(   inputs=layer2, filters =128, kernel_size=3, strides=2, padding='same')
        layer3 = tf.layers.batch_normalization(inputs=layer3, training=is_train)
        layer3 = tf.nn.dropout(x=layer3, keep_prob=0.8)
        logits = tf.layers.conv2d_transpose(   inputs=layer3, filters =3, kernel_size=3, strides=2, padding='same')
        outputs = tf.tanh(logits)
        return outputs      #输出为一张3通道的图片
def get_discriminator(inputs_img, reuse=False):
    with tf.variable_scope("discriminator", reuse=reuse):
        layer1 = tf.layers.conv2d(inputs=inputs_img,filters=128, kernel_size=3, strides=2, padding='same')
        layer2 = tf.layers.conv2d(inputs=layer1,    filters=256, kernel_size=3, strides=2, padding='same')
        layer2 = tf.layers.batch_normalization(inputs=layer2, training=True)
        layer3 = tf.layers.conv2d(inputs=layer2,    filters=512, kernel_size=3, strides=2, padding='same')
        layer3 = tf.layers.batch_normalization(inputs=layer3, training=True)
        layer3 = tf.nn.dropout( x=layer3, keep_prob=0.8)
        flatten = tf.reshape(   tensor=layer3, shape=(-1, 4 * 4 * 512))
        logits = tf.layers.dense(flatten, 1)
        outputs = tf.sigmoid(logits)
        return logits, outputs

#定义一个计算损失的函数
def get_loss(inputs_real, inputs_noise, image_depth):
    g_outputs = get_generator(inputs_noise,is_train=True)  # 输入的是inputs_noise=[none,100] image_depth=3
    d_logits_real, d_outputs_real = get_discriminator(inputs_real)  # 真实数据的loss input_real= [none,32,32,3]
    d_logits_fake, d_outputs_fake = get_discriminator(g_outputs, reuse=True)  # fake数据的loss   g_outputs=[32,32,3]
    print("d_outputs_fake",d_outputs_fake)
    print("tf.ones_like(d_outputs_fake)=", tf.ones_like(d_outputs_fake))
    g_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_fake, labels=tf.ones_like(d_outputs_fake)))
    d_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_real,labels=tf.ones_like(d_outputs_real)))
    d_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_fake,labels=tf.zeros_like(d_outputs_fake)))
    d_loss = tf.add(d_loss_real, d_loss_fake)#判别器的损失由两部分组成,真实图片和生成图片的损失之和
    print("type(d_loss{0} and  g_loss={1})".format(d_loss, g_loss))
    return g_loss, d_loss

#定义优化器的函数
def get_optimizer(g_loss, d_loss):
    with tf.control_dependencies(tf.get_collection(tf.GraphKeys.UPDATE_OPS)):
        d_opt = tf.train.AdamOptimizer(0.001).minimize(d_loss)
        g_opt = tf.train.AdamOptimizer(0.001).minimize(g_loss)
    return g_opt, d_opt
noise_dim=100       #噪声维度
batch_size = 64     #批数据大小
data_shape=[-1, 32, 32, 3]#数据维度

inputs_real, inputs_noise = get_inputs(noise_dim)  # input_real=[none,32,32,3]  inputs_noise=[none,100]
g_loss, d_loss = get_loss(inputs_real, inputs_noise, 3)  # input_real=[none,32,32,3]  inputs_noise=[none,100] data_shape[-1]=3
g_train_opt, d_train_opt = get_optimizer(g_loss, d_loss) #定义优化运算

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())#初始化全局变量
    for e in range(50):  # 迭代50个epoch
        steps = 0
        for steps in range(int(x_train.shape[0] / batch_size) - 1):
            batch_images = x_train[steps * batch_size: (steps + 1) * batch_size]
            batch_images = batch_images * 2 - 1
            batch_noise = np.random.uniform(-1, 1, size=(batch_size, noise_dim))
            _ = sess.run(g_train_opt, feed_dict={inputs_real: batch_images,inputs_noise: batch_noise})
            _ = sess.run(d_train_opt, feed_dict={inputs_real: batch_images,inputs_noise: batch_noise})
            steps+=1
            if steps % 10 == 0:
                train_loss_d = d_loss.eval({inputs_real: batch_images,inputs_noise: batch_noise})
                train_loss_g = g_loss.eval({inputs_real: batch_images,inputs_noise: batch_noise})
                print("Epoch {0}/{1}....".format(e + 1, 50),"Discriminator Loss: {:.4f}....".format(train_loss_d),
                      "Generator Loss: {:.4f}....".format(train_loss_g))

猜你喜欢

转载自blog.csdn.net/Dongjiuqing/article/details/84404921