最近gan异常的火,应老师要求写一个gan。网上有很多gan的实例,比如下面这个链接里的:https://blog.csdn.net/jiongnima/article/details/80033169?tdsourcetag=s_pctim_aiomsg写的很详细,解释很到位。
运行上述文件可以看出训练到后面多样性消失,生成的图片都是1
我写的代码和上面的不大一样,大家可以参考看看
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.examples.tutorials.mnist import input_data
mnist=input_data.read_data_sets("H:/iangpan/gan/data",one_hot=True)
#定义网络初始化参数
#迭代次数
num_step=10000
#批次大小
batch_size=128
#学习率
learning_rate=0.0002
img_dim=784
gen_hidden_dim=256
disc_hidden_dim=256
noise_dim=100
# 初始化参数时使用的glorot_init函数
def glorot_init(shape):
return tf.random_normal(shape=shape,stddev=1./tf.sqrt(shape[0]/2.))
#权重与偏置
weights={
'gen_hidden1':tf.Variable(glorot_init([noise_dim,gen_hidden_dim])),
'gen_out':tf.Variable(glorot_init([gen_hidden_dim,img_dim])),
'disc_hidden1':tf.Variable(glorot_init([img_dim,disc_hidden_dim])),
'disc_out':tf.Variable(glorot_init([disc_hidden_dim,1])),
}
biases={
'gen_hidden1':tf.Variable(tf.zeros([gen_hidden_dim])),
'gen_out':tf.Variable(tf.zeros(img_dim)),
'disc_hidden1':tf.Variable(tf.zeros([disc_hidden_dim])),
'disc_out':tf.Variable(tf.zeros([1])),
}
#生成器
def generate(x):
hidden_layer=tf.matmul(x,weights['gen_hidden1'])
hidden_layer=tf.add(hidden_layer,biases['gen_hidden1'])
hidden_layer=tf.nn.relu(hidden_layer)
out_layer=tf.matmul(hidden_layer,weights['gen_out'])
out_layer=tf.add(out_layer,biases['gen_out'])
out_layer=tf.nn.sigmoid(out_layer)
return out_layer
#判别器
def discrimibator(x):
hidden_layer=tf.matmul(x,weights['disc_hidden1'])
hidden_layer=tf.add(hidden_layer,biases['disc_hidden1'])
hidden_layer=tf.nn.relu(hidden_layer)
out_layer=tf.matmul(hidden_layer,weights['disc_out'])
out_layer=tf.add(out_layer,biases['disc_out'])
out_layer=tf.nn.sigmoid(out_layer)
return out_layer
#网络的输入
gen_input=tf.placeholder(tf.float32,shape=[None,noise_dim],name='input_noise')
disc_input=tf.placeholder(tf.float32,shape=[None,img_dim],name='disc_input')
#建立generator网络
gen_sample=generate(gen_input)
#建立两个判别器网络
disc_real=discrimibator(disc_input)
disc_fake=discrimibator(gen_sample)
#loss函数
gen_loss=-tf.reduce_mean(tf.log(disc_fake))
disc_loss=-tf.reduce_mean(tf.log(disc_real)+tf.log(1.-disc_fake))
# 手动设置梯度下降时所需要更新的参数
# tensorflow运行时会更新所有参数,但是我们是分开训练生成器与判别器,所以不能全部的参数都更新
gen_vars=[weights['gen_hidden1'],weights['gen_out'],
biases['gen_hidden1'],biases['gen_out']]
disc_vars=[weights['disc_hidden1'],weights['disc_out'],
biases['disc_hidden1'],biases['disc_out']]
# 创建优化器
optimizer_gen=tf.train.AdamOptimizer(learning_rate=learning_rate)
optimizer_disc=tf.train.AdamOptimizer(learning_rate=learning_rate)
# 创建梯度下降
train_gen=optimizer_gen.minimize(gen_loss,var_list=gen_vars)
train_disc=optimizer_disc.minimize(disc_loss,var_list=disc_vars)
#初始化所有参数
init=tf.global_variables_initializer()
#训练模型
sess=tf.Session()
sess.run(init)
for i in range(1,num_step+1):
batch_x,_=mnist.train.next_batch(batch_size)
# 随机生成-1到1的浮点数
z=np.random.uniform(-1.,1.,size=[batch_size,noise_dim])
# 训练数据为样本数据和随机初始化数据(用于生成网络)
feed_dict={disc_input:batch_x,gen_input:z}
_,_,gl,dl=sess.run([train_gen,train_disc,gen_loss,disc_loss],
feed_dict=feed_dict)
if i%2000==0 or i==1:
print('Step %i: Generator Loss: %f, Discriminator Loss: %f' % (i, gl, dl))
#设置随机输入,反转颜色,生成测试图
n=28
canvas=np.empty((28*n,28*n))#创建空的数组
for i in range(n):
z=np.random.uniform(-1., 1., size=[n, noise_dim])#
g=sess.run(gen_sample,feed_dict={gen_input:z})
#反转颜色显示
g=-1*(g-1)
for j in range(n):
# 在 matplotlib 中画出结果
canvas[i * 28:(i + 1) * 28, j * 28:(j + 1) * 28] = g[j].reshape([28, 28])
plt.figure(figsize=(n, n))
plt.imshow(canvas, origin="upper", cmap="gray")
plt.show()