Pas encore de compte ?
main.py
Testé sous Anaconda et Python 3.7
import os ## GAN Variants from GAN import GAN from CGAN import CGAN from infoGAN import infoGAN from ACGAN import ACGAN from EBGAN import EBGAN from WGAN import WGAN from WGAN_GP import WGAN_GP from DRAGAN import DRAGAN from LSGAN import LSGAN from BEGAN import BEGAN ## VAE Variants from VAE import VAE from CVAE import CVAE from utils import show_all_variables from utils import check_folder import tensorflow as tf import argparse """parsing and configuration""" def parse_args(): desc = "Tensorflow implementation of GAN collections" parser = argparse.ArgumentParser(description=desc) parser.add_argument('--gan_type', type=str, default='GAN', choices=['GAN', 'CGAN', 'infoGAN', 'ACGAN', 'EBGAN', 'BEGAN', 'WGAN', 'WGAN_GP', 'DRAGAN', 'LSGAN', 'VAE', 'CVAE'], help='The type of GAN', required=True) parser.add_argument('--dataset', type=str, default='mnist', choices=['mnist', 'fashion-mnist', 'celebA'], help='The name of dataset') parser.add_argument('--epoch', type=int, default=20, help='The number of epochs to run') parser.add_argument('--batch_size', type=int, default=64, help='The size of batch') parser.add_argument('--z_dim', type=int, default=62, help='Dimension of noise vector') parser.add_argument('--checkpoint_dir', type=str, default='checkpoint', help='Directory name to save the checkpoints') parser.add_argument('--result_dir', type=str, default='results', help='Directory name to save the generated images') parser.add_argument('--log_dir', type=str, default='logs', help='Directory name to save training logs') return check_args(parser.parse_args()) """checking arguments""" def check_args(args): # --checkpoint_dir check_folder(args.checkpoint_dir) # --result_dir check_folder(args.result_dir) # --result_dir check_folder(args.log_dir) # --epoch assert args.epoch >= 1, 'number of epochs must be larger than or equal to one' # --batch_size assert args.batch_size >= 1, 'batch size must be larger than or equal to one' # --z_dim assert args.z_dim >= 1, 'dimension of noise vector must be larger than or equal to one' return args """main""" def main(): # parse arguments args = parse_args() if args is None: exit() # open session models = [GAN, CGAN, infoGAN, ACGAN, EBGAN, WGAN, WGAN_GP, DRAGAN, LSGAN, BEGAN, VAE, CVAE] with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)) as sess: # declare instance for GAN gan = None for model in models: if args.gan_type == model.model_name: gan = model(sess, epoch=args.epoch, batch_size=args.batch_size, z_dim=args.z_dim, dataset_name=args.dataset, checkpoint_dir=args.checkpoint_dir, result_dir=args.result_dir, log_dir=args.log_dir) if gan is None: raise Exception("[!] There is no option for " + args.gan_type) # build graph gan.build_model() # show network architecture show_all_variables() # launch the graph in a session gan.train() print(" [*] Training finished!") # visualize learned generator gan.visualize_results(args.epoch-1) print(" [*] Testing finished!") if __name__ == '__main__': main()
DRAGAN.py
Testé sous Anaconda et Python 3.7
#-*- coding: utf-8 -*- from __future__ import division import os import time import tensorflow as tf import numpy as np from ops import * from utils import * class DRAGAN(object): model_name = "DRAGAN" # name for checkpoint def __init__(self, sess, epoch, batch_size, z_dim, dataset_name, checkpoint_dir, result_dir, log_dir): self.sess = sess self.dataset_name = dataset_name self.checkpoint_dir = checkpoint_dir self.result_dir = result_dir self.log_dir = log_dir self.epoch = epoch self.batch_size = batch_size if dataset_name == 'mnist' or dataset_name == 'fashion-mnist': # parameters self.input_height = 28 self.input_width = 28 self.output_height = 28 self.output_width = 28 self.z_dim = z_dim # dimension of noise-vector self.c_dim = 1 # DRAGAN parameter self.lambd = 0.25 # The higher value, the more stable, but the slower convergence # train self.learning_rate = 0.0002 self.beta1 = 0.5 # test self.sample_num = 64 # number of generated images to be saved # load mnist self.data_X, self.data_y = load_mnist(self.dataset_name) # get number of batches for a single epoch self.num_batches = len(self.data_X) // self.batch_size else: raise NotImplementedError def discriminator(self, x, is_training=True, reuse=False): # Network Architecture is exactly same as in infoGAN (https://arxiv.org/abs/1606.03657) # Architecture : (64)4c2s-(128)4c2s_BL-FC1024_BL-FC1_S with tf.variable_scope("discriminator", reuse=reuse): net = lrelu(conv2d(x, 64, 4, 4, 2, 2, name='d_conv1')) net = lrelu(bn(conv2d(net, 128, 4, 4, 2, 2, name='d_conv2'), is_training=is_training, scope='d_bn2')) net = tf.reshape(net, [self.batch_size, -1]) net = lrelu(bn(linear(net, 1024, scope='d_fc3'), is_training=is_training, scope='d_bn3')) out_logit = linear(net, 1, scope='d_fc4') out = tf.nn.sigmoid(out_logit) return out, out_logit, net def generator(self, z, is_training=True, reuse=False): # Network Architecture is exactly same as in infoGAN (https://arxiv.org/abs/1606.03657) # Architecture : FC1024_BR-FC7x7x128_BR-(64)4dc2s_BR-(1)4dc2s_S with tf.variable_scope("generator", reuse=reuse): net = tf.nn.relu(bn(linear(z, 1024, scope='g_fc1'), is_training=is_training, scope='g_bn1')) net = tf.nn.relu(bn(linear(net, 128 * 7 * 7, scope='g_fc2'), is_training=is_training, scope='g_bn2')) net = tf.reshape(net, [self.batch_size, 7, 7, 128]) net = tf.nn.relu( bn(deconv2d(net, [self.batch_size, 14, 14, 64], 4, 4, 2, 2, name='g_dc3'), is_training=is_training, scope='g_bn3')) out = tf.nn.sigmoid(deconv2d(net, [self.batch_size, 28, 28, 1], 4, 4, 2, 2, name='g_dc4')) return out def get_perturbed_batch(self, minibatch): return minibatch + 0.5 * minibatch.std() * np.random.random(minibatch.shape) def build_model(self): # some parameters image_dims = [self.input_height, self.input_width, self.c_dim] bs = self.batch_size """ Graph Input """ # images self.inputs = tf.placeholder(tf.float32, [bs] + image_dims, name='real_images') self.inputs_p = tf.placeholder(tf.float32, [bs] + image_dims, name='real_perturbed_images') # noises self.z = tf.placeholder(tf.float32, [bs, self.z_dim], name='z') """ Loss Function """ # output of D for real images D_real, D_real_logits, _ = self.discriminator(self.inputs, is_training=True, reuse=False) # output of D for fake images G = self.generator(self.z, is_training=True, reuse=False) D_fake, D_fake_logits, _ = self.discriminator(G, is_training=True, reuse=True) # get loss for discriminator d_loss_real = tf.reduce_mean( tf.nn.sigmoid_cross_entropy_with_logits(logits=D_real_logits, labels=tf.ones_like(D_real))) d_loss_fake = tf.reduce_mean( tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake_logits, labels=tf.zeros_like(D_fake))) self.d_loss = d_loss_real + d_loss_fake # get loss for generator self.g_loss = tf.reduce_mean( tf.nn.sigmoid_cross_entropy_with_logits(logits=D_fake_logits, labels=tf.ones_like(D_fake))) """ DRAGAN Loss (Gradient penalty) """ # This is borrowed from https://github.com/kodalinaveen3/DRAGAN/blob/master/DRAGAN.ipynb alpha = tf.random_uniform(shape=self.inputs.get_shape(), minval=0.,maxval=1.) differences = self.inputs_p - self.inputs # This is different from WGAN-GP interpolates = self.inputs + (alpha * differences) _,D_inter,_=self.discriminator(interpolates, is_training=True, reuse=True) gradients = tf.gradients(D_inter, [interpolates])[0] slopes = tf.sqrt(tf.reduce_sum(tf.square(gradients), reduction_indices=[1])) gradient_penalty = tf.reduce_mean((slopes - 1.) ** 2) self.d_loss += self.lambd * gradient_penalty """ Training """ # divide trainable variables into a group for D and a group for G t_vars = tf.trainable_variables() d_vars = [var for var in t_vars if 'd_' in var.name] g_vars = [var for var in t_vars if 'g_' in var.name] # optimizers with tf.control_dependencies(tf.get_collection(tf.GraphKeys.UPDATE_OPS)): self.d_optim = tf.train.AdamOptimizer(self.learning_rate*5, beta1=self.beta1) \ .minimize(self.d_loss, var_list=d_vars) self.g_optim = tf.train.AdamOptimizer(self.learning_rate*5, beta1=self.beta1) \ .minimize(self.g_loss, var_list=g_vars) """" Testing """ # for test self.fake_images = self.generator(self.z, is_training=False, reuse=True) """ Summary """ d_loss_real_sum = tf.summary.scalar("d_loss_real", d_loss_real) d_loss_fake_sum = tf.summary.scalar("d_loss_fake", d_loss_fake) d_loss_sum = tf.summary.scalar("d_loss", self.d_loss) g_loss_sum = tf.summary.scalar("g_loss", self.g_loss) # final summary operations self.g_sum = tf.summary.merge([d_loss_fake_sum, g_loss_sum]) self.d_sum = tf.summary.merge([d_loss_real_sum, d_loss_sum]) def train(self): # initialize all variables tf.global_variables_initializer().run() # graph inputs for visualize training results self.sample_z = np.random.uniform(-1, 1, size=(self.batch_size , self.z_dim)) # saver to save model self.saver = tf.train.Saver() # summary writer self.writer = tf.summary.FileWriter(self.log_dir + '/' + self.model_name, self.sess.graph) # restore check-point if it exits could_load, checkpoint_counter = self.load(self.checkpoint_dir) if could_load: start_epoch = (int)(checkpoint_counter / self.num_batches) start_batch_id = checkpoint_counter - start_epoch * self.num_batches counter = checkpoint_counter print(" [*] Load SUCCESS") else: start_epoch = 0 start_batch_id = 0 counter = 1 print(" [!] Load failed...") # loop for epoch start_time = time.time() for epoch in range(start_epoch, self.epoch): # get batch data for idx in range(start_batch_id, self.num_batches): batch_images = self.data_X[idx*self.batch_size:(idx+1)*self.batch_size] batch_images_p = self.get_perturbed_batch(batch_images) batch_z = np.random.uniform(-1, 1, [self.batch_size, self.z_dim]).astype(np.float32) # update D network _, summary_str, d_loss = self.sess.run([self.d_optim, self.d_sum, self.d_loss], feed_dict={self.inputs: batch_images, self.inputs_p: batch_images_p, self.z: batch_z}) self.writer.add_summary(summary_str, counter) # update G network _, summary_str, g_loss = self.sess.run([self.g_optim, self.g_sum, self.g_loss], feed_dict={self.z: batch_z}) self.writer.add_summary(summary_str, counter) # display training status counter += 1 print("Epoch: [%2d] [%4d/%4d] time: %4.4f, d_loss: %.8f, g_loss: %.8f" \ % (epoch, idx, self.num_batches, time.time() - start_time, d_loss, g_loss)) # save training results for every 300 steps if np.mod(counter, 300) == 0: samples = self.sess.run(self.fake_images, feed_dict={self.z: self.sample_z}) tot_num_samples = min(self.sample_num, self.batch_size) manifold_h = int(np.floor(np.sqrt(tot_num_samples))) manifold_w = int(np.floor(np.sqrt(tot_num_samples))) save_images(samples[:manifold_h * manifold_w, :, :, :], [manifold_h, manifold_w], './' + check_folder(self.result_dir + '/' + self.model_dir) + '/' + self.model_name + '_train_{:02d}_{:04d}.png'.format( epoch, idx)) # After an epoch, start_batch_id is set to zero # non-zero value is only for the first epoch after loading pre-trained model start_batch_id = 0 # save model self.save(self.checkpoint_dir, counter) # show temporal results self.visualize_results(epoch) # save model for final step self.save(self.checkpoint_dir, counter) def visualize_results(self, epoch): tot_num_samples = min(self.sample_num, self.batch_size) image_frame_dim = int(np.floor(np.sqrt(tot_num_samples))) """ random condition, random noise """ z_sample = np.random.uniform(-1, 1, size=(self.batch_size, self.z_dim)) samples = self.sess.run(self.fake_images, feed_dict={self.z: z_sample}) save_images(samples[:image_frame_dim * image_frame_dim, :, :, :], [image_frame_dim, image_frame_dim], check_folder(self.result_dir + '/' + self.model_dir) + '/' + self.model_name + '_epoch%03d' % epoch + '_test_all_classes.png') @property def model_dir(self): return "{}_{}_{}_{}".format( self.model_name, self.dataset_name, self.batch_size, self.z_dim) def save(self, checkpoint_dir, step): checkpoint_dir = os.path.join(checkpoint_dir, self.model_dir, self.model_name) if not os.path.exists(checkpoint_dir): os.makedirs(checkpoint_dir) self.saver.save(self.sess,os.path.join(checkpoint_dir, self.model_name+'.model'), global_step=step) def load(self, checkpoint_dir): import re print(" [*] Reading checkpoints...") checkpoint_dir = os.path.join(checkpoint_dir, self.model_dir, self.model_name) ckpt = tf.train.get_checkpoint_state(checkpoint_dir) if ckpt and ckpt.model_checkpoint_path: ckpt_name = os.path.basename(ckpt.model_checkpoint_path) self.saver.restore(self.sess, os.path.join(checkpoint_dir, ckpt_name)) counter = int(next(re.finditer("(\d+)(?!.*\d)",ckpt_name)).group(0)) print(" [*] Success to read {}".format(ckpt_name)) return True, counter else: print(" [*] Failed to find a checkpoint") return False, 0
utils.py
Testé sous Anaconda et Python 3.7
""" Most codes from https://github.com/carpedm20/DCGAN-tensorflow """ from __future__ import division import math import random import pprint import cv2 import imageio import numpy as np from time import gmtime, strftime from six.moves import xrange import matplotlib.pyplot as plt import os, gzip import tensorflow as tf import tensorflow.contrib.slim as slim def load_mnist(dataset_name): data_dir = os.path.join("./data", dataset_name) def extract_data(filename, num_data, head_size, data_size): with gzip.open(filename) as bytestream: bytestream.read(head_size) buf = bytestream.read(data_size * num_data) data = np.frombuffer(buf, dtype=np.uint8).astype(np.float) return data data = extract_data(data_dir + '/train-images-idx3-ubyte.gz', 60000, 16, 28 * 28) trX = data.reshape((60000, 28, 28, 1)) data = extract_data(data_dir + '/train-labels-idx1-ubyte.gz', 60000, 8, 1) trY = data.reshape((60000)) data = extract_data(data_dir + '/t10k-images-idx3-ubyte.gz', 10000, 16, 28 * 28) teX = data.reshape((10000, 28, 28, 1)) data = extract_data(data_dir + '/t10k-labels-idx1-ubyte.gz', 10000, 8, 1) teY = data.reshape((10000)) trY = np.asarray(trY) teY = np.asarray(teY) X = np.concatenate((trX, teX), axis=0) y = np.concatenate((trY, teY), axis=0).astype(np.int) seed = 547 np.random.seed(seed) np.random.shuffle(X) np.random.seed(seed) np.random.shuffle(y) y_vec = np.zeros((len(y), 10), dtype=np.float) for i, label in enumerate(y): y_vec[i, y[i]] = 1.0 return X / 255., y_vec def check_folder(log_dir): if not os.path.exists(log_dir): os.makedirs(log_dir) return log_dir def show_all_variables(): model_vars = tf.trainable_variables() slim.model_analyzer.analyze_vars(model_vars, print_info=True) def get_image(image_path, input_height, input_width, resize_height=64, resize_width=64, crop=True, grayscale=False): image = imread(image_path, grayscale) return transform(image, input_height, input_width, resize_height, resize_width, crop) def save_images(images, size, image_path): return imsave(inverse_transform(images), size, image_path) def imread(path, grayscale = False): if (grayscale): return imageio.imread(path, flatten = True).astype(np.float) else: return imageio.imread(path).astype(np.float) def merge_images(images, size): return inverse_transform(images) def merge(images, size): h, w = images.shape[1], images.shape[2] if (images.shape[3] in (3,4)): c = images.shape[3] img = np.zeros((h * size[0], w * size[1], c)) for idx, image in enumerate(images): i = idx % size[1] j = idx // size[1] img[j * h:j * h + h, i * w:i * w + w, :] = image return img elif images.shape[3]==1: img = np.zeros((h * size[0], w * size[1])) for idx, image in enumerate(images): i = idx % size[1] j = idx // size[1] img[j * h:j * h + h, i * w:i * w + w] = image[:,:,0] return img else: raise ValueError('in merge(images,size) images parameter ''must have dimensions: HxW or HxWx3 or HxWx4') def imsave(images, size, path): image = np.squeeze(merge(images, size)) return imageio.imsave(path, image) def center_crop(x, crop_h, crop_w, resize_h=64, resize_w=64): if crop_w is None: crop_w = crop_h h, w = x.shape[:2] j = int(round((h - crop_h)/2.)) i = int(round((w - crop_w)/2.)) return cv2.resize(x[j:j+crop_h, i:i+crop_w], [resize_h, resize_w]) def transform(image, input_height, input_width, resize_height=64, resize_width=64, crop=True): if crop: cropped_image = center_crop(image, input_height, input_width, resize_height, resize_width) else: cropped_image = cv2.resize(image, [resize_height, resize_width]) return np.array(cropped_image)/127.5 - 1. def inverse_transform(images): return (images+1.)/2. """ Drawing Tools """ # borrowed from https://github.com/ykwon0407/variational_autoencoder/blob/master/variational_bayes.ipynb def save_scattered_image(z, id, z_range_x, z_range_y, name='scattered_image.jpg'): N = 10 plt.figure(figsize=(8, 6)) plt.scatter(z[:, 0], z[:, 1], c=np.argmax(id, 1), marker='o', edgecolor='none', cmap=discrete_cmap(N, 'jet')) plt.colorbar(ticks=range(N)) axes = plt.gca() axes.set_xlim([-z_range_x, z_range_x]) axes.set_ylim([-z_range_y, z_range_y]) plt.grid(True) plt.savefig(name) # borrowed from https://gist.github.com/jakevdp/91077b0cae40f8f8244a def discrete_cmap(N, base_cmap=None): """Create an N-bin discrete colormap from the specified input map""" # Note that if base_cmap is a string or None, you can simply do # return plt.cm.get_cmap(base_cmap, N) # The following works for string, None, or a colormap instance: base = plt.cm.get_cmap(base_cmap) color_list = base(np.linspace(0, 1, N)) cmap_name = base.name + str(N) return base.from_list(cmap_name, color_list, N)
tensorflow-generative-model-collections
Copyright (c) Apache.
python main.py --dataset mnist --gan_type DRAGAN --epoch 25 --batch_size 64
python main.py --dataset fashion-mnist --gan_type DRAGAN --epoch 40 --batch_size 64
Bienvenu, je m’appelle Eric Soupet et je suis l'administrateur du site elodees.com. elodees.com est un état de l'art de l'Intelligence Artificielle et se veut collaboratif, vous pouvez dès à présent proposer du contenu tels que des articles, des événements, des tutoriels, ... alors n'hésitez pas !
Crédit des images de la plate-forme : Pixabay - Pixabay License | Pexels - Pexels License