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))