以前写的GAN神经网络,但是训练过程并不收敛。放在这里,慢慢改!
#_*_encoding:UTF-8_*_
import tensorflow as tf
import numpy as np
import scipy.misc
from glob import glob
import PIL
sample_size = 100
flags = tf.app.flags
flags.DEFINE_integer("batch_size", 100, "The number of sample in a training process")
flags.DEFINE_float("learning_rate", 0.0001, "Learning rate of for adam")
flags.DEFINE_integer("input_height", 96, "The size of input image")
flags.DEFINE_integer("input_width", 96, "The size of input image")
flags.DEFINE_integer("output_height", 64, "The size of output image")
flags.DEFINE_integer("output_width", 64, "The size of output image")
flags.DEFINE_integer("c_dim", 3, "Dimension of image color")
flags.DEFINE_integer("z_dim", 100, "Dimension of dim for z")
flags.DEFINE_string("input_fname_pattern", "*.jpg", "Glob pattern of filename of input images")
flags.DEFINE_float("beta1", 0.5, "Momentum term of adam[0.5]")
flags.DEFINE_float("beta2", 0.5, "Momentum term of adam[0.5]")
flags.DEFINE_integer("epoch", 2, "the num of training")
FLAGS = flags.FLAGS
def get_image(path, input_height=96, input_width=96, resize_height=64, resize_width=64):
image = imread(path)
return transform(image, input_height, input_width, resize_height, resize_width)
def imread(path):
return scipy.misc.imread(path).astype(np.float)
def transform(image, input_height, input_width, resize_height, resize_width):
transform_image = scipy.misc.imresize(image, [resize_height, resize_width])
return np.array(transform_image)/127.5 - 1
def get_weights(name, shape, initializer):
return tf.get_variable(name, shape, initializer)
def lrelu(input_, leak=0.2):
return tf.maximum(input_, leak * input_)
def full_conn(z_, output_size, name):
z_shape = z_.get_shape().as_list()
with tf.variable_scope(name):
weights = tf.get_variable(name="fullconn_weights", shape=[z_shape[-1], output_size], initializer=tf.random_normal_initializer(stddev=0.001))
biases = tf.get_variable(name="fullconn_biases", shape=[output_size], initializer=tf.random_normal_initializer(stddev=0.001))
return tf.matmul(z_, weights) + biases, weights, biases
def conv2d(input_, output_dim=64, k_h=5, k_w=5, stddev=0.01, name="conv2d"):
with tf.variable_scope(name):
weights = tf.get_variable(name="conv2d_weights", shape=[k_h, k_w, input_.get_shape()[-1], output_dim], initializer=tf.truncated_normal_initializer(stddev=stddev))
biases = tf.get_variable(name="conv2d_biases", shape=[output_dim], initializer=tf.constant_initializer(0.0))
conv = tf.nn.conv2d(input_, weights, [1, 2, 2, 1], padding="SAME")
conv = tf.reshape(tf.nn.bias_add(conv, biases), conv.get_shape())
return conv, weights, biases
def deconv2d(input_, output_shape, k_h=5, k_w=5, name="deconv2d"):
with tf.variable_scope(name):
filter = tf.get_variable(name="deconv2d_weights", shape=[k_h, k_w, output_shape[-1], input_.get_shape()[-1]], initializer=tf.random_normal_initializer(stddev=0.001))
biases = tf.get_variable(name="deconv2d_biases", shape=[output_shape[-1]], initializer=tf.random_normal_initializer(stddev=0.001))
deconv = tf.nn.conv2d_transpose(input_, filter, output_shape, strides=[1, 2, 2, 1])
deconv = tf.reshape(tf.nn.bias_add(deconv, biases), deconv.get_shape())
return deconv, filter, biases
class DcGan():
def __init__(self, config):
self.config = config
def build_model(self):
def sigmoid_cross_entropy_with_logits(x, y):
return tf.nn.sigmoid_cross_entropy_with_logits(labels=x, logits=y)
self.inputs = tf.placeholder(tf.float32, [self.config.batch_size, self.config.output_height, self.config.output_width, self.config.c_dim], name="real_image")
self.z = tf.placeholder(tf.float32, [self.config.batch_size, self.config.z_dim], name="z")
z = self.z
inputs = self.inputs
self.gen = Generator(z, "generator").get_layer5()
print("-------------------self.gen---------------:", self.gen.get_shape().as_list())
self.dis, self.dis_logits = Discriminator(inputs).get_layer5()
self.sampler = Sampler(z).get_layer5()
print("----------------warning:79----------------")
self.dis_, self.dis_logits_ = Discriminator(self.gen, reuse=True).get_layer5()
print("----------------warning:81----------------")
self.dis_loss_real = tf.reduce_mean(sigmoid_cross_entropy_with_logits(self.dis_logits, tf.ones_like(self.dis)))
self.dis_loss_fake = tf.reduce_mean(sigmoid_cross_entropy_with_logits(self.dis_logits_, tf.ones_like(self.dis_)))
self.gen_loss = tf.reduce_mean(sigmoid_cross_entropy_with_logits(self.dis_logits_, tf.ones_like(self.dis_)))
self.dis_loss = self.dis_loss_fake + self.dis_loss_real
t_vars = tf.trainable_variables()
self.dis_vars = [var for var in t_vars if 'd_' in var.name]
self.gen_vars = [var for var in t_vars if 'g_' in var.name]
def optimize(self):
dis_optim = tf.train.AdamOptimizer(self.config.learning_rate, beta1=self.config.beta1).minimize(self.dis_loss, var_list=self.dis_vars)
gen_optim = tf.train.AdamOptimizer(self.config.learning_rate, beta1=self.config.beta2).minimize(self.gen_loss, var_list=self.gen_vars)
data = glob(r"E:\pythoncode\DcGan\data\anime\*.jpg")
sample_z = np.random.uniform(-1, 1, size=(sample_size, self.config.z_dim))
sample_files = data[0:sample_size]
sample = [get_image(sample_file, input_height=96, input_width=96, resize_height=64, resize_width=64) for sample_file in sample_files]
counter = 1
with tf.Session() as sess:
tf.global_variables_initializer().run()
for epoch in range(self.config.epoch):
print(epoch)
print(int(len(data)/self.config.batch_size))
for idx in range(int(len(data) / self.config.batch_size)):
print("---------------", idx)
batch_files = data[idx*self.config.batch_size: (idx+1)*self.config.batch_size]
batch = [get_image(batch_file, input_height=96, input_width=96, resize_height=64, resize_width=64) for batch_file in batch_files]
batch_z = np.random.uniform(-1, 1, [self.config.batch_size, self.config.z_dim]).astype(np.float32)
batch_images = np.array(batch).astype(np.float32)
_ = sess.run([dis_optim], feed_dict={self.inputs: batch_images, self.z:batch_z})
_ = sess.run([gen_optim], feed_dict={self.z: batch_z})
_ = sess.run([gen_optim], feed_dict={self.z:batch_z})
counter += 1
if idx % 3 == 0:
sample_z_1 = np.random.uniform(-1, 1, [self.config.batch_size, self.config.z_dim]).astype(np.float32)
sample_result = sess.run([self.gen], feed_dict={self.z:sample_z_1})
print(len(sample_result))
sample_result = (sample_result[0][0] + 1) * 255
im = PIL.Image.fromarray(np.array(sample_result) + 1, mode='RGB')
im.save(str(idx) + "out.jpeg")
class Sampler:
def __init__(self, z):
self.s_bn0 = Batch_norm(name="g_bn0")
self.s_bn1 = Batch_norm(name="g_bn1")
self.s_bn2 = Batch_norm(name="g_bn2")
self.s_bn3 = Batch_norm(name="g_bn3")
with tf.variable_scope("generator") as scope:
scope.reuse_variables()
self.z = z
self.layer1, self.layer1_weights, self.layer1_biases = full_conn(z, 4 * 4 * 1024, "generator_layer1_fullconn")
self.layer1 = tf.reshape(self.layer1, [sample_size, 4, 4, 1024])
layer1 = tf.nn.relu(self.s_bn0(self.layer1))
self.layer2, self.layer2_weights, self.layer2_biases = deconv2d(layer1, [sample_size, 8, 8, 512], name="generator_layer2_deconv2d")
layer2 = tf.nn.relu(self.s_bn1(self.layer2))
self.layer3, self.layer3_weights, self.layer3_biases = deconv2d(layer2, [sample_size, 16, 16, 256], name="generator_layer3_deconv2d")
layer3 = tf.nn.relu(self.s_bn2(self.layer3))
self.layer4, self.layer4_weights, self.layer4_biases = deconv2d(layer3, [sample_size, 32, 32, 128], name="generator_layer4_deconv2d")
layer4 = tf.nn.relu(self.s_bn3(self.layer4))
self.layer5, self.layer5_weights, self.layer5_biases = deconv2d(layer4, [sample_size, 64, 64, 3], name="generator_layer5_deconv2d")
def get_layer5(self):
return tf.nn.tanh(self.layer5)
class Discriminator:
def __init__(self, image, reuse=False):
self.d_bn1 = Batch_norm(name="d_bn1")
self.d_bn2 = Batch_norm(name="d_bn2")
self.d_bn3 = Batch_norm(name="d_bn3")
with tf.variable_scope("discriminator") as scope:
if reuse:
print("++++++++++++++in++++++++++++++")
scope.reuse_variables()
#print("-----------------------+---------------------",image.get_shape().as_list())
self.image = image
#print("-----------------------+---------------------",self.image.get_shape().as_list())
self.layer1, self.layer1_weights, layer1_biases = conv2d(self.image, 64*2, name="discriminator_layer1_conv")
layer1 = lrelu(self.layer1)
self.layer2, self.layer2_weights, layer2_biases = conv2d(layer1, 64*4, name="discriminator_layer2_conv")
layer2 = lrelu(self.d_bn1(self.layer2))
self.layer3, self.layer3_weights, layer3_biases = conv2d(layer2, 64*8, name="discriminator_layer3_conv")
layer3 = lrelu(self.d_bn2(self.layer3))
self.layer4, self.layer4_weights, layer4_biases = conv2d(layer3, 64*16, name="discriminator_layer4_conv")
layer4 = lrelu(self.d_bn3(self.layer4))
self.layer5, self.layer5_weights, self.layer5_biases = full_conn(tf.reshape(layer4, [FLAGS.batch_size, -1]), 1, "discriminator_layer5_fullconn")
#print("discriminator.layer5.shape", self.layer5)
def get_layer5(self):
return tf.nn.sigmoid(self.layer5), self.layer5
#return f(10) error, 无法调用f(a)
#def f(a):
#return a
class Generator:
def __init__(self, z, name="generator"):
self.g_bn0 = Batch_norm(name="g_bn0")
self.g_bn1 = Batch_norm(name="g_bn1")
self.g_bn2 = Batch_norm(name="g_bn2")
self.g_bn3 = Batch_norm(name="g_bn3")
with tf.variable_scope(name) as scope:
self.z = z
self.layer1, self.layer1_weights, self.layer1_biases = full_conn(self.z, 4 * 4 * 1024, "generator_layer1_fullconn")
self.layer1 = tf.reshape(self.layer1, [sample_size, 4, 4, 1024])
layer1 = tf.nn.relu(self.g_bn0(self.layer1))
self.layer2, self.layer2_weights, self.layer2_biases = deconv2d(layer1, [sample_size, 8, 8, 512], name="generator_layer2_deconv2d")
layer2 = tf.nn.relu(self.g_bn1(self.layer2))
self.layer3, self.layer3_weights, self.layer3_biases = deconv2d(layer2, [sample_size, 16, 16, 256], name="generator_layer3_deconv2d")
layer3 = tf.nn.relu(self.g_bn2(self.layer3))
self.layer4, self.layer4_weights, self.layer4_biases = deconv2d(layer3, [sample_size, 32, 32, 128], name="generator_layer4_deconv2d")
layer4 = tf.nn.relu(self.g_bn3(self.layer4))
self.layer5, self.layer5_weights, self.layer5_biases = deconv2d(layer4, [sample_size, 64, 64, 3], name="generator_layer5_deconv2d")
def get_layer5(self):
return tf.nn.tanh(self.layer5)
class Batch_norm(object):
def __init__(self, name="batch_norm", epsilon=1e-5, momentum=0.9):
with tf.variable_scope(name):
self.epsilon = epsilon
self.momentum = momentum
self.name = name
def __call__(self, x , train=False):
return tf.contrib.layers.batch_norm(x, decay=self.momentum, updates_collections=None, epsilon=self.epsilon, scale=True, is_training=train, scope=self.name)
def train():
dcgan = DcGan(FLAGS)
dcgan.build_model()
dcgan.optimize()
def main(argv=None):
train()
if __name__ == "__main__":
tf.app.run()
"""
a = tf.get_variable("main", shape=[10, 100], initializer=tf.random_normal_initializer(stddev=0.001))
b = tf.constant([[1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 4.0, 4.0, 5.0, 5.0]])
c = tf.matmul(b, a)
with tf.Session() as sess:
tf.global_variables_initializer().run()
print(sess.run(c))
"""