这一篇GAN文章只是让产生的结果尽量真实,还不能分类。
本次手写数字GAN的思想:
对于辨别器,利用真实的手写数字(真样本,对应的标签为真标签)和随机噪声经过生成器产生的样本(假样本,对应的标签为假标签)送入辨别器,分别得到两个损失值,最小化这两个损失值,这样的话就能保证辨别器能分清楚真假。
而对于生成器,用产生的随机噪声送入生成器,产生样本(假样本,对应的标签为真标签),得到损失值,最小化损失值,注意标签要改为真标签,因为这样才能以假乱真,正是辨别器和生成器博弈的过程,使得生成的数据能够以假乱真,为什么博弈到平衡的状态随机噪声能够以假乱真呢?看公式,论证了全局最优值,就是噪声和真实数据相等的时候。
下面看代码:test做测试用的,不用管。
路径:
util.py代码:
import tensorflow as tf
import numpy as np
"""
从正太分布输出随机值
"""
def xavier_init(size):
in_dim=size[0]
xavier_stddev=tf.sqrt(2./in_dim)
return tf.random_normal(shape=size,stddev=xavier_stddev)
#生成模型的输入和参数初始化
G_W1=tf.Variable(xavier_init(size=[100,128]))
G_b1=tf.Variable(tf.zeros(shape=[128]))
G_W2=tf.Variable(xavier_init(size=[128,784]))
G_b2=tf.Variable(tf.zeros(shape=[784]))
theta_G=[G_W1,G_W2,G_b1,G_b2]
#判别模型的输入和参数初始化
D_W1=tf.Variable(xavier_init(size=[784,128]))
D_b1=tf.Variable(tf.zeros(shape=[128]))
D_W2=tf.Variable(xavier_init(size=[128,1]))
D_b2=tf.Variable(tf.zeros(shape=[1]))
theta_D=[D_W1,D_W2,D_b1,D_b2]
"""
随机噪声产生
"""
def sample_z(m,n):
return np.random.uniform(-1.0,1.0,size=[m,n])
"""
生成模型:产生数据
"""
def generator(z):
G_h1=tf.nn.relu(tf.matmul(z,G_W1)+G_b1)
G_log_prob=tf.matmul(G_h1, G_W2) + G_b2
G_prob=tf.nn.sigmoid(G_log_prob)
return G_prob
"""
判别模型:真实值和概率值
"""
def discriminator(x):
D_h1=tf.nn.relu(tf.matmul(x,D_W1)+D_b1)
D_logit=tf.matmul(D_h1, D_W2) + D_b2
D_prob=tf.nn.sigmoid(D_logit)
return D_prob,D_logit
main.py代码:
import tensorflow as tf
import numpy as np
from GAN.TWO import util
import os
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
#读入数据
mnist=input_data.read_data_sets('./data',one_hot=True)
# print(mnist)
Z=tf.placeholder(tf.float32,shape=[None,100])
X=tf.placeholder(tf.float32,shape=[None,784])
#喂入数据
G_sample=util.generator(Z)
D_real,D_logit_real=util.discriminator(X)
D_fake,D_logit_fake=util.discriminator(G_sample)
#计算loss
D_real_loss=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_real,
labels=tf.ones_like(D_logit_real)))
D_fake_loss=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_fake,
labels=tf.zeros_like(D_logit_fake)))
D_loss=D_fake_loss+D_real_loss
G_loss=tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=D_logit_fake,
labels=tf.ones_like(D_logit_fake)))
D_optimizer=tf.train.AdamOptimizer().minimize(D_loss,var_list=util.theta_D)
G_optimizer=tf.train.AdamOptimizer().minimize(G_loss,var_list=util.theta_G)
if not os.path.exists('out/'):
os.makedirs('out/')
"""
画图
"""
def plot(samples):
gs=gridspec.GridSpec(4,4)
gs.update(wspace=0.05,hspace=.05)
for i,sample in enumerate(samples):
ax = plt.subplot(gs[i])
plt.axis('off')
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.set_aspect('equal')
plt.imshow(sample.reshape(28,28),cmap='Greys_r')
print("=====================开始训练============================")
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for it in range(100000):
X_mb,_=mnist.train.next_batch(batch_size=128)
# print(X_mb)
_,D_loss_curr=sess.run([D_optimizer,D_loss],
feed_dict={X:X_mb,Z:util.sample_z(128,100)})
_, G_loss_curr = sess.run([G_optimizer, G_loss],
feed_dict={Z: util.sample_z(128, 100)})
if it%1000==0:
print('====================打印出生成的数据============================')
samples=sess.run(G_sample,feed_dict={Z: util.sample_z(16, 100)})
plot(samples)
plt.show()
if it%1000==0:
print('iter={}'.format(it))
print('D_loss={}'.format(D_loss_curr))
print('G_loss={}'.format(G_loss_curr))
打印结果:
迭代0次。
迭代50000次。