Repository: LeeDoYup/AnoGAN Branch: master Commit: 4c650b3ab606 Files: 8 Total size: 49.5 KB Directory structure: gitextract_m0d92t1m/ ├── .gitignore ├── LICENSE ├── README.md ├── download.py ├── main.py ├── model.py ├── ops.py └── utils.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # dotenv .env # virtualenv .venv venv/ ENV/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 Doyup Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # AnoGAN in tensorflow Tensorflow implementation of [Anomaly GAN (AnoGAN)](https://arxiv.org/abs/1703.05921). This model detect anomaly part in images, after training DCGAN with normal dataset. (In Korean, H. Kim's detail explanation is [here](https://www.slideshare.net/ssuser06e0c5/anomaly-detection-with-gans)) Basic model is DCGAN (Deep Convolutional Generative Adversarial Networks). * (Anomaly Detection of MNIST is not yet available) ## Model Description After learn DCGAN model with normal dataset (not contains anomalies), * Anomaly Detector calculates anomaly score of unseen images. ![Model Structure](./assets/model_structure.jpeg) When unseen data comes, the model tries to find latent variable z that generates input image using backpropagation. (similar with style transfer) Anomaly Score is based on residual and discrimination losses. - Residual loss: L1 distance between generated image by z and unseen test image. - Discrimination loss: L1 distacne between hidden representations of generated and test image, extracted by discriminators. ![Res_Loss](./assets/res_loss.jpeg) ![Discrimination Loss](./assets/dis_loss.jpeg) Total Loss for finding latent variable z is weighted sum of the two. (defualt lambda = 0.1) ![Total Loss](./assets/t_loss.jpeg) ## File Descriptions - main.py : Main function of implementations, contained argument parsers, model construction, and test. - model.py : DCGAN class (containing anomaly detection function. Imple core) - download.py : Files for downloading celebA, LSUN, and MNIST. - ops.py : Some operation functions with tensorflow. - utils.py : Some functions dealing with image preprocessing. ## Prerequisites (my environments) - Python 2.7 - Tensorflow > 0.14 - SciPy - pillow - (Optional) [Align&Cropped Images.zip](http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html) : Large-scale CelebFaces Dataset ## Usage First, you "must" have trained DCGAN model with normal dataset. If you have checkpoint file, the model tries to use it. ### Model Preparation (If you want to download and train the model) First, download dataset with: $ python download.py mnist celebA To train a model with downloaded dataset: $ python main.py --dataset mnist --input_height=28 --output_height=28 --train $ python main.py --dataset celebA --input_height=108 --train --crop Or, you can use your own dataset (without central crop) by: $ mkdir data/DATASET_NAME ... add images to data/DATASET_NAME ... $ python main.py --dataset DATASET_NAME --train $ python main.py --dataset DATASET_NAME $ # example $ python main.py --dataset=eyes --input_fname_pattern="*_cropped.png" --train ### Anomaly Detection After having trained DCGAN model, you have to prepare test images for anomaly detection. $ mkdir ./test_data ... add test images to ./test_data ... $ python main.py --dataset DATASET_NAME --input_height=108 --crop --anomaly_test ## Results To valid the model implementation, simple test was proceeded. Initial generated image by DCGAN in training is conisdered as anomaly. After learns DCGAN model, compared final and initial images on certain latent varaible z. Then, anomaly score of initial images was calculated. Eyes, mouth, and distorted parts in image were detected. ![result](./assets/result_example.jpeg) ## Related works - [Image Style Transfer](https://pdfs.semanticscholar.org/7568/d13a82f7afa4be79f09c295940e48ec6db89.pdf) - (Reconstruction-based AD) [Anomaly Detection in DBMSs](https://arxiv.org/abs/1708.02635) - (ICLR2018 under-review) [ADGAN](https://openreview.net/forum?id=S1EfylZ0Z) ## To Do ### You can always request pull requests with feeling free. - [ ] Threshold Setting Function (Manual/Automatic) - [ ] Add performance measures of anomaly detection with labels (ROC AUC) - [ ] Visaulization of anomaly detection results (t-SNE) ## Acknowledgement - Thanks for @carpedm20 's implementation of [DCGAN](https://github.com/carpedm20/DCGAN-tensorflow). I implemented AnoGAN based on his implementation. ================================================ FILE: download.py ================================================ ''' Downloads: Celeb-A, LSUN, or MNIST dataset ''' from __future__ import print_function import os import sys import gzip import json import shutil import zipfile import argparse import requests import subprocess from tqdm import tqdm from six.moves import urllib parser = argparse.ArgumentParser(description='Download dataset for DCGAN.') parser.add_argument('datasets', metavar='N', type=str, nargs='+', choices=['celebA', 'lsun', 'mnist'], help='name of dataset to download [celebA, lsun, mnist]') # Functions for Download CelebA Dataset def download_file_from_google_drive(id, destination): URL = "https://docs.google.com/uc?export=download" session = requests.Session() response = session.get(URL, params={ 'id': id }, stream=True) token = get_confirm_token(response) if token: params = { 'id' : id, 'confirm' : token } response = session.get(URL, params=params, stream=True) save_response_content(response, destination) def get_confirm_token(response): for key, value in response.cookies.items(): if key.startswith('download_warning'): return value return None def save_response_content(response, destination, chunk_size=32*1024): total_size = int(response.headers.get('content-length', 0)) with open(destination, "wb") as f: for chunk in tqdm(response.iter_content(chunk_size), total=total_size, unit='B', unit_scale=True, desc=destination): if chunk: # filter out keep-alive new chunks f.write(chunk) def unzip(filepath): print("Extracting: " + filepath) dirpath = os.path.dirname(filepath) with zipfile.ZipFile(filepath) as zf: zf.extractall(dirpath) os.remove(filepath) def download_celeb_a(dirpath): data_dir = 'celebA' if os.path.exists(os.path.join(dirpath, data_dir)): print('Found Celeb-A - skip') return filename, drive_id = "img_align_celeba.zip", "0B7EVK8r0v71pZjFTYXZWM3FlRnM" save_path = os.path.join(dirpath, filename) if os.path.exists(save_path): print('[*] {} already exists'.format(save_path)) else: download_file_from_google_drive(drive_id, save_path) zip_dir = '' with zipfile.ZipFile(save_path) as zf: zip_dir = zf.namelist()[0] zf.extractall(dirpath) os.remove(save_path) os.rename(os.path.join(dirpath, zip_dir), os.path.join(dirpath, data_dir)) # Functions for Download LSUN Dataset ## construct cagegory list from LSUN dataset def _list_categories(tag): url = 'http://lsun.cs.princeton.edu/htbin/list.cgi?tag=' + tag f = urllib.request.urlopen(url) return json.loads(f.read()) ## download LSUN dataset from url def _download_lsun(out_dir, category, set_name, tag): url = 'http://lsun.cs.princeton.edu/htbin/download.cgi?tag={tag}' \ '&category={category}&set={set_name}'.format(**locals()) print(url) if set_name == 'test': out_name = 'test_lmdb.zip' else: out_name = '{category}_{set_name}_lmdb.zip'.format(**locals()) out_path = os.path.join(out_dir, out_name) cmd = ['curl', url, '-o', out_path] print('Downloading', category, set_name, 'set') subprocess.call(cmd) ## run download def download_lsun(dirpath): data_dir = os.path.join(dirpath, 'lsun') if os.path.exists(data_dir): print('Found LSUN - skip') return else: os.mkdir(data_dir) tag = 'latest' #categories = _list_categories(tag) categories = ['bedroom'] for category in categories: _download_lsun(data_dir, category, 'train', tag) _download_lsun(data_dir, category, 'val', tag) _download_lsun(data_dir, '', 'test', tag) # Functions for Download MNIST Dataset def download_mnist(dirpath): data_dir = os.path.join(dirpath, 'mnist') if os.path.exists(data_dir): print('Found MNIST - skip') return else: os.mkdir(data_dir) url_base = 'http://yann.lecun.com/exdb/mnist/' file_names = ['train-images-idx3-ubyte.gz', 'train-labels-idx1-ubyte.gz', 't10k-images-idx3-ubyte.gz', 't10k-labels-idx1-ubyte.gz'] for file_name in file_names: url = (url_base+file_name).format(**locals()) print(url) out_path = os.path.join(data_dir,file_name) cmd = ['curl', url, '-o', out_path] print('Downloading ', file_name) subprocess.call(cmd) cmd = ['gzip', '-d', out_path] print('Decompressing ', file_name) subprocess.call(cmd) def prepare_data_dir(path = './data'): if not os.path.exists(path): os.mkdir(path) if __name__ == '__main__': args = parser.parse_args() prepare_data_dir() if any(name in args.datasets for name in ['CelebA', 'celebA', 'celebA']): download_celeb_a('./data') if 'lsun' in args.datasets: download_lsun('./data') if 'mnist' in args.datasets: download_mnist('./data') ================================================ FILE: main.py ================================================ import os import scipy.misc import numpy as np from model import DCGAN from utils import pp, visualize, show_all_variables import tensorflow as tf #arguments parsers flags = tf.app.flags #name, defulat value, description #below are for train and test flags.DEFINE_integer("epoch", 25, "Epoch to train [25]") flags.DEFINE_integer("test_epoch", 100, "Epoch for latent mapping in anomaly detection to train [100]") flags.DEFINE_float("learning_rate", 0.0002, "Learning rate of for adam [0.0002]") flags.DEFINE_float("beta1", 0.5, "Momentum term of adam [0.5]") flags.DEFINE_float("test_learning_rate", 0.001, "Learning rate for finding latent variable z [0.05]") flags.DEFINE_integer("train_size", np.inf, "The size of train images [np.inf]") flags.DEFINE_boolean("train", False, "True for training, False for testing [False]") flags.DEFINE_boolean("anomaly_test", False, "True for anomaly test in test directory, not anomaly test [False]") flags.DEFINE_boolean("visualize", False, "True for visualizing, False for nothing [False]") #below are for model construction flags.DEFINE_integer("batch_size", 64, "The size of batch images [64]") flags.DEFINE_integer("test_batch_size", 1, "The size of test batch images in anomaly detection to [1]") flags.DEFINE_integer("input_height", 108, "The size of image to use (will be center cropped). [108]") flags.DEFINE_integer("input_width", None, "The size of image to use (will be center cropped). If None, same value with input_height [None]") flags.DEFINE_integer("output_height", 64, "The size of the output images to produce [64]") flags.DEFINE_integer("output_width", None, "The size of the output images to produce. ") flags.DEFINE_string("dataset", "celebA", "The name of dataset [celebA, mnist, lsun]") flags.DEFINE_string("input_fname_pattern", "*.jpg", "Glob pattern of filename of input images [*]") flags.DEFINE_string("checkpoint_dir", "checkpoint", "Directory name to save the checkpoints [checkpoint]") flags.DEFINE_string("sample_dir", "samples", "Directory name to save the image samples [samples]") flags.DEFINE_string("test_dir", "test_data", "Directory name to load the anomaly detstion result [test_data]") flags.DEFINE_string("test_result_dir", "test_result", "Directory name to save the anomaly test result [test_data/test_result]") flags.DEFINE_boolean("crop", False, "True for training, False for testing [False]") flags.DEFINE_integer("generate_test_images", 100, "Number of images to generate during test. [100]") FLAGS = flags.FLAGS def main(_): pp.pprint(flags.FLAGS.__flags) if FLAGS.input_width is None: FLAGS.input_width = FLAGS.input_height if FLAGS.output_width is None: FLAGS.output_width = FLAGS.output_height if not os.path.exists(FLAGS.checkpoint_dir): os.makedirs(FLAGS.checkpoint_dir) if not os.path.exists(FLAGS.sample_dir): os.makedirs(FLAGS.sample_dir) run_config = tf.ConfigProto() run_config.gpu_options.allow_growth=True #run_config.gpu_options.per_process_gpu_memory_fraction = 0.4 with tf.Session(config=run_config) as sess: if FLAGS.dataset == 'mnist': dcgan = DCGAN( sess, input_width=FLAGS.input_width, input_height=FLAGS.input_height, output_width=FLAGS.output_width, output_height=FLAGS.output_height, batch_size=FLAGS.batch_size, test_batch_size=FLAGS.test_batch_size, sample_num=FLAGS.batch_size, y_dim=10, z_dim=FLAGS.generate_test_images, dataset_name=FLAGS.dataset, input_fname_pattern=FLAGS.input_fname_pattern, crop=FLAGS.crop, checkpoint_dir=FLAGS.checkpoint_dir, sample_dir=FLAGS.sample_dir, test_dir = FLAGS.test_dir) else: dcgan = DCGAN( sess, input_width=FLAGS.input_width, input_height=FLAGS.input_height, output_width=FLAGS.output_width, output_height=FLAGS.output_height, batch_size=FLAGS.batch_size, test_batch_size=FLAGS.test_batch_size, sample_num=FLAGS.batch_size, z_dim=FLAGS.generate_test_images, dataset_name=FLAGS.dataset, input_fname_pattern=FLAGS.input_fname_pattern, crop=FLAGS.crop, checkpoint_dir=FLAGS.checkpoint_dir, sample_dir=FLAGS.sample_dir, test_dir = FLAGS.test_dir) show_all_variables() if FLAGS.train: dcgan.train(FLAGS) else: if not dcgan.load(FLAGS.checkpoint_dir)[0]: raise Exception("[!] Train a model first, then run test mode") if FLAGS.anomaly_test: dcgan.anomaly_detector() assert len(dcgan.test_data_names) > 0 for idx in range(len(dcgan.test_data_names)): test_input = np.expand_dims(dcgan.test_data[idx],axis=0) test_name = dcgan.test_data_names[idx] dcgan.train_anomaly_detector(FLAGS, test_input, test_name) # Below is codes for visualization #OPTION = 1 #visualize(sess, dcgan, FLAGS, OPTION) if __name__ == '__main__': tf.app.run() ================================================ FILE: model.py ================================================ from __future__ import division import os import time import math from glob import glob import tensorflow as tf import numpy as np from six.moves import xrange from ops import * from utils import * def conv_out_size_same(size, stride): return int(math.ceil(float(size) / float(stride))) class DCGAN(object): def __init__(self, sess, input_height=108, input_width=108, crop=True, batch_size=64, sample_num = 64, output_height=64, output_width=64, y_dim=None, z_dim=100, gf_dim=64, df_dim=64, gfc_dim=1024, dfc_dim=1024, c_dim=3, dataset_name='default', input_fname_pattern='*.jpg', test_batch_size = 1, checkpoint_dir=None, sample_dir=None, test_dir = None): """ Args: sess: TensorFlow session batch_size: The size of batch. Should be specified before training. y_dim: (optional) Dimension of dim for y. [None] z_dim: (optional) Dimension of dim for Z. [100] gf_dim: (optional) Dimension of gen filters in first conv layer. [64] df_dim: (optional) Dimension of discrim filters in first conv layer. [64] gfc_dim: (optional) Dimension of gen units for for fully connected layer. [1024] dfc_dim: (optional) Dimension of discrim units for fully connected layer. [1024] c_dim: (optional) Dimension of image color. For grayscale input, set to 1. [3] """ self.sess = sess self.crop = crop self.batch_size = batch_size self.test_batch_size = test_batch_size self.sample_num = sample_num self.input_height = input_height self.input_width = input_width self.output_height = output_height self.output_width = output_width self.y_dim = y_dim self.z_dim = z_dim self.gf_dim = gf_dim self.df_dim = df_dim self.gfc_dim = gfc_dim self.dfc_dim = dfc_dim self.dataset_name = dataset_name self.input_fname_pattern = input_fname_pattern self.checkpoint_dir = checkpoint_dir self.test_dir = os.path.join('./',test_dir) if self.dataset_name == 'mnist': self.data_X, self.data_y = self.load_mnist() self.c_dim = self.data_X[0].shape[-1] else: self.data = glob(os.path.join("./data", self.dataset_name, self.input_fname_pattern)) #Check number of channels imreadImg = imread(self.data[0]) if len(imreadImg.shape) >= 3: #check if image is a non-grayscale image by checking channel number self.c_dim = imread(self.data[0]).shape[-1] else: self.c_dim = 1 self.grayscale = (self.c_dim == 1) self.build_model() def build_model(self): # batch normalization : deals with poor initialization helps gradient flow self.d_bn1 = batch_norm(name='d_bn1') self.d_bn2 = batch_norm(name='d_bn2') if not self.y_dim: self.d_bn3 = batch_norm(name='d_bn3') self.g_bn0 = batch_norm(name='g_bn0') self.g_bn1 = batch_norm(name='g_bn1') self.g_bn2 = batch_norm(name='g_bn2') if not self.y_dim: self.g_bn3 = batch_norm(name='g_bn3') #placeholders if self.y_dim: self.y = tf.placeholder(tf.float32, [self.batch_size, self.y_dim], name='y') else: self.y = None if self.crop: #for training image_dims = [self.output_height, self.output_width, self.c_dim] else: #for test image_dims = [self.input_height, self.input_width, self.c_dim] self.inputs = tf.placeholder( tf.float32, [self.batch_size] + image_dims, name='real_images') inputs = self.inputs self.z = tf.placeholder(tf.float32, [None, self.z_dim], name='z') self.z_sum = histogram_summary("z", self.z) #Construct Generator and Discriminators self.G = self.generator(self.z, self.y) self.D, self.D_logits = self.discriminator(inputs, self.y, reuse=False) self.sampler = self._sampler(self.z, self.y) self.D_, self.D_logits_ = self.discriminator(self.G, self.y, reuse=True) #summary op. self.d_sum = histogram_summary("d", self.D) self.d__sum = histogram_summary("d_", self.D_) self.G_sum = image_summary("G", self.G) #Create Loss Functions def sigmoid_cross_entropy_with_logits(x, y): return tf.nn.sigmoid_cross_entropy_with_logits(logits=x, labels=y) self.d_loss_real = tf.reduce_mean( sigmoid_cross_entropy_with_logits(self.D_logits, tf.ones_like(self.D))) self.d_loss_fake = tf.reduce_mean( sigmoid_cross_entropy_with_logits(self.D_logits_, tf.zeros_like(self.D_))) self.g_loss = tf.reduce_mean( sigmoid_cross_entropy_with_logits(self.D_logits_, tf.ones_like(self.D_))) #summary op. self.d_loss_real_sum = scalar_summary("d_loss_real", self.d_loss_real) self.d_loss_fake_sum = scalar_summary("d_loss_fake", self.d_loss_fake) #total loss self.d_loss = self.d_loss_real + self.d_loss_fake #summary op. self.g_loss_sum = scalar_summary("g_loss", self.g_loss) self.d_loss_sum = scalar_summary("d_loss", self.d_loss) t_vars = tf.trainable_variables() self.d_vars = [var for var in t_vars if 'd_' in var.name] self.g_vars = [var for var in t_vars if 'g_' in var.name] self.saver = tf.train.Saver() def train(self, config): d_optim = tf.train.AdamOptimizer(config.learning_rate, beta1=config.beta1) \ .minimize(self.d_loss, var_list=self.d_vars) g_optim = tf.train.AdamOptimizer(config.learning_rate, beta1=config.beta1) \ .minimize(self.g_loss, var_list=self.g_vars) tf.global_variables_initializer().run() #summary_op: merge summary self.g_sum = merge_summary([self.z_sum, self.d__sum, self.G_sum, self.d_loss_fake_sum, self.g_loss_sum]) self.d_sum = merge_summary( [self.z_sum, self.d_sum, self.d_loss_real_sum, self.d_loss_sum]) #Create Tensorboard self.writer = SummaryWriter("./logs", self.sess.graph) #Create Sample Benchmarks for monitoring of train results: use same random noises and real-images sample_z = np.random.uniform(-1, 1, size=(self.sample_num , self.z_dim)) if config.dataset == 'mnist': sample_inputs = self.data_X[0:self.sample_num] sample_labels = self.data_y[0:self.sample_num] else: sample_files = self.data[0:self.sample_num] #name_list sample = [ get_image(sample_file, input_height=self.input_height, input_width=self.input_width, resize_height=self.output_height, resize_width=self.output_width, crop=self.crop, grayscale=self.grayscale) for sample_file in sample_files] if (self.grayscale): sample_inputs = np.array(sample).astype(np.float32)[:, :, :, None] else: sample_inputs = np.array(sample).astype(np.float32) counter = 1 start_time = time.time() could_load, checkpoint_counter = self.load(self.checkpoint_dir) if could_load: counter = checkpoint_counter print(" [*] Load SUCCESS") else: print(" [!] Load failed...") if config.dataset == 'mnist': batch_idxs = min(len(self.data_X), config.train_size) // config.batch_size #config.train_size: default is np.inf sample_feed_dict = {self.z: sample_z, self.inputs: sample_inputs, self.y:sample_labels} else: batch_idxs = min(len(self.data), config.train_size) // config.batch_size sample_feed_dict = {self.z: sample_z, self.inputs: sample_inputs} for epoch in xrange(config.epoch): for idx in xrange(0, batch_idxs): #Prepare batch data for learning if config.dataset == 'mnist': batch_images = self.data_X[idx*config.batch_size:(idx+1)*config.batch_size] batch_labels = self.data_y[idx*config.batch_size:(idx+1)*config.batch_size] else: batch_files = self.data[idx*config.batch_size:(idx+1)*config.batch_size] batch = [ get_image(batch_file, input_height=self.input_height, input_width=self.input_width, resize_height=self.output_height, resize_width=self.output_width, crop=self.crop, grayscale=self.grayscale) for batch_file in batch_files] if self.grayscale: batch_images = np.array(batch).astype(np.float32)[:, :, :, None] else: batch_images = np.array(batch).astype(np.float32) #Prepare batch random noises for learning batch_z = np.random.uniform(-1, 1, [config.batch_size, self.z_dim]).astype(np.float32) #Make feed dictionary if config.dataset == 'mnist': d_feed_dict = {self.inputs: batch_images, self.z: batch_z, self.y: batch_labels} d_fake_feed_dict = {self.z: batch_z, self.y: batch_labels} d_real_feed_dict = {self.inputs: batch_images, self.y: batch_labels} g_feed_dict = {self.z: batch_z, self.y: batch_labels} else: d_feed_dict = {self.inputs: batch_images, self.z: batch_z} d_fake_feed_dict = {self.z: batch_z} d_real_feed_dict = {self.inputs: batch_images} g_feed_dict = {self.z:batch_z} #Run Optimization and Summary Operation of Discriminator _, summary_str = self.sess.run([d_optim, self.d_sum], feed_dict = d_feed_dict) self.writer.add_summary(summary_str, counter) #Run Optimization and Summary Operation of Generator _, summary_str = self.sess.run([g_optim, self.g_sum], feed_dict = g_feed_dict) self.writer.add_summary(summary_str, counter) # Run g_optim twice to make sure that d_loss does not go to zero (different from paper) _, summary_str = self.sess.run([g_optim, self.g_sum], feed_dict = g_feed_dict) self.writer.add_summary(summary_str, counter) # Calculate Loss Values of Discriminator and Generator errD_fake = self.d_loss_fake.eval(feed_dict = d_fake_feed_dict) errD_real = self.d_loss_real.eval(feed_dict = d_real_feed_dict) errG = self.g_loss.eval(feed_dict = g_feed_dict) counter += 1 print("Epoch: [%2d] [%4d/%4d] time: %4.4f, d_loss: %.8f, g_loss: %.8f" \ % (epoch, idx, batch_idxs, time.time() - start_time, errD_fake+errD_real, errG)) if np.mod(counter, 100) == 1: samples, d_loss, g_loss = self.sess.run([self.sampler, self.d_loss, self.g_loss], feed_dict = sample_feed_dict) save_images(samples, image_manifold_size(samples.shape[0]), './{}/train_{:02d}_{:04d}.png'.format(config.sample_dir, epoch, idx)) print("[Sample] d_loss: %.8f, g_loss: %.8f" % (d_loss, g_loss)) if np.mod(counter, 500) == 2: self.save(config.checkpoint_dir, counter) def discriminator(self, image, y=None, reuse=False, batch_size = None): if batch_size == None: batch_size = self.batch_size with tf.variable_scope("discriminator") as scope: if reuse: scope.reuse_variables() if not self.y_dim: h0 = leak_relu(conv2d(image, self.df_dim, name='d_h0_conv')) h1 = leak_relu(self.d_bn1(conv2d(h0, self.df_dim*2, name='d_h1_conv'))) h2 = leak_relu(self.d_bn2(conv2d(h1, self.df_dim*4, name='d_h2_conv'))) h3 = leak_relu(self.d_bn3(conv2d(h2, self.df_dim*8, name='d_h3_conv'))) #h4 = linear(tf.contrib.layers.flatten(h3),1,'d_h4_lin') h4 = linear(tf.reshape(h3, [batch_size, -1]), 1, 'd_h4_lin') return tf.nn.sigmoid(h4), h4 else: yb = tf.reshape(y, [batch_size, 1, 1, self.y_dim]) x = conv_cond_concat(image, yb) h0 = leak_relu(conv2d(x, self.c_dim + self.y_dim, name='d_h0_conv')) h0 = conv_cond_concat(h0, yb) h1 = leak_relu(self.d_bn1(conv2d(h0, self.df_dim + self.y_dim, name='d_h1_conv'))) h1 = tf.reshape(h1, [batch_size, -1]) #flatten h1 = concat([h1, y], 1) h2 = leak_relu(self.d_bn2(linear(h1, self.dfc_dim, 'd_h2_lin'))) h2 = concat([h2, y], 1) h3 = linear(h2, 1, 'd_h3_lin') return tf.nn.sigmoid(h3), h3 def feature_match_layer(self, image, y=None, reuse=False, batch_size = None): if batch_size == None: batch_size = self.batch_size with tf.variable_scope("discriminator") as scope: if reuse: scope.reuse_variables() if not self.y_dim: h0 = leak_relu(conv2d(image, self.df_dim, name='d_h0_conv')) h1 = leak_relu(self.d_bn1(conv2d(h0, self.df_dim*2, name='d_h1_conv'))) h2 = leak_relu(self.d_bn2(conv2d(h1, self.df_dim*4, name='d_h2_conv'))) h3 = leak_relu(self.d_bn3(conv2d(h2, self.df_dim*8, name='d_h3_conv'))) return h3 else: yb = tf.reshape(y, [-1, 1, 1, self.y_dim]) x = conv_cond_concat(image, yb) h0 = leak_relu(conv2d(x, self.c_dim + self.y_dim, name='d_h0_conv')) h0 = conv_cond_concat(h0, yb) h1 = leak_relu(self.d_bn1(conv2d(h0, self.df_dim + self.y_dim, name='d_h1_conv'))) h1 = tf.reshape(h1, [batch_size, -1]) #flatten h1 = concat([h1, y], 1) h2 = leak_relu(self.d_bn2(linear(h1, self.dfc_dim, 'd_h2_lin'))) return h2 def generator(self, z, y=None): with tf.variable_scope("generator") as scope: if not self.y_dim: s_h, s_w = self.output_height, self.output_width s_h2, s_w2 = conv_out_size_same(s_h, 2), conv_out_size_same(s_w, 2) s_h4, s_w4 = conv_out_size_same(s_h2, 2), conv_out_size_same(s_w2, 2) s_h8, s_w8 = conv_out_size_same(s_h4, 2), conv_out_size_same(s_w4, 2) s_h16, s_w16 = conv_out_size_same(s_h8, 2), conv_out_size_same(s_w8, 2) # project `z` and reshape self.z_, self.h0_w, self.h0_b = linear( z, self.gf_dim*8*s_h16*s_w16, 'g_h0_lin', with_w=True) self.h0 = tf.reshape( self.z_, [-1, s_h16, s_w16, self.gf_dim * 8]) h0 = tf.nn.relu(self.g_bn0(self.h0)) self.h1, self.h1_w, self.h1_b = deconv2d( h0, [self.batch_size, s_h8, s_w8, self.gf_dim*4], name='g_h1', with_w=True) h1 = tf.nn.relu(self.g_bn1(self.h1)) h2, self.h2_w, self.h2_b = deconv2d( h1, [self.batch_size, s_h4, s_w4, self.gf_dim*2], name='g_h2', with_w=True) h2 = tf.nn.relu(self.g_bn2(h2)) h3, self.h3_w, self.h3_b = deconv2d( h2, [self.batch_size, s_h2, s_w2, self.gf_dim*1], name='g_h3', with_w=True) h3 = tf.nn.relu(self.g_bn3(h3)) h4, self.h4_w, self.h4_b = deconv2d( h3, [self.batch_size, s_h, s_w, self.c_dim], name='g_h4', with_w=True) return tf.nn.tanh(h4) else: s_h, s_w = self.output_height, self.output_width s_h2, s_h4 = int(s_h/2), int(s_h/4) s_w2, s_w4 = int(s_w/2), int(s_w/4) # yb = tf.expand_dims(tf.expand_dims(y, 1),2) yb = tf.reshape(y, [self.batch_size, 1, 1, self.y_dim]) z = concat([z, y], 1) h0 = tf.nn.relu( self.g_bn0(linear(z, self.gfc_dim, 'g_h0_lin'))) h0 = concat([h0, y], 1) h1 = tf.nn.relu(self.g_bn1( linear(h0, self.gf_dim*2*s_h4*s_w4, 'g_h1_lin'))) h1 = tf.reshape(h1, [self.batch_size, s_h4, s_w4, self.gf_dim * 2]) h1 = conv_cond_concat(h1, yb) h2 = tf.nn.relu(self.g_bn2(deconv2d(h1, [self.batch_size, s_h2, s_w2, self.gf_dim * 2], name='g_h2'))) h2 = conv_cond_concat(h2, yb) return tf.nn.sigmoid( deconv2d(h2, [self.batch_size, s_h, s_w, self.c_dim], name='g_h3')) def _sampler(self, z, y=None, batch_size = None): if batch_size == None: batch_size = self.batch_size with tf.variable_scope("generator") as scope: scope.reuse_variables() if not self.y_dim: s_h, s_w = self.output_height, self.output_width s_h2, s_w2 = conv_out_size_same(s_h, 2), conv_out_size_same(s_w, 2) s_h4, s_w4 = conv_out_size_same(s_h2, 2), conv_out_size_same(s_w2, 2) s_h8, s_w8 = conv_out_size_same(s_h4, 2), conv_out_size_same(s_w4, 2) s_h16, s_w16 = conv_out_size_same(s_h8, 2), conv_out_size_same(s_w8, 2) # project `z` and reshape h0 = tf.reshape( linear(z, self.gf_dim*8*s_h16*s_w16, 'g_h0_lin'), [-1, s_h16, s_w16, self.gf_dim * 8]) h0 = tf.nn.relu(self.g_bn0(h0, train=False)) h1 = deconv2d(h0, [batch_size, s_h8, s_w8, self.gf_dim*4], name='g_h1') h1 = tf.nn.relu(self.g_bn1(h1, train=False)) h2 = deconv2d(h1, [batch_size, s_h4, s_w4, self.gf_dim*2], name='g_h2') h2 = tf.nn.relu(self.g_bn2(h2, train=False)) h3 = deconv2d(h2, [batch_size, s_h2, s_w2, self.gf_dim*1], name='g_h3') h3 = tf.nn.relu(self.g_bn3(h3, train=False)) h4 = deconv2d(h3, [batch_size, s_h, s_w, self.c_dim], name='g_h4') return tf.nn.tanh(h4) else: s_h, s_w = self.output_height, self.output_width s_h2, s_h4 = int(s_h/2), int(s_h/4) s_w2, s_w4 = int(s_w/2), int(s_w/4) # yb = tf.reshape(y, [-1, 1, 1, self.y_dim]) yb = tf.reshape(y, [self.batch_size, 1, 1, self.y_dim]) z = concat([z, y], 1) h0 = tf.nn.relu(self.g_bn0(linear(z, self.gfc_dim, 'g_h0_lin'), train=False)) h0 = concat([h0, y], 1) h1 = tf.nn.relu(self.g_bn1( linear(h0, self.gf_dim*2*s_h4*s_w4, 'g_h1_lin'), train=False)) h1 = tf.reshape(h1, [self.batch_size, s_h4, s_w4, self.gf_dim * 2]) h1 = conv_cond_concat(h1, yb) h2 = tf.nn.relu(self.g_bn2( deconv2d(h1, [self.batch_size, s_h2, s_w2, self.gf_dim * 2], name='g_h2'), train=False)) h2 = conv_cond_concat(h2, yb) return tf.nn.sigmoid(deconv2d(h2, [self.batch_size, s_h, s_w, self.c_dim], name='g_h3')) def get_test_data(self): self.test_data_names = glob(self.test_dir+'/*.*') batch = [get_image(name, input_height=self.input_height, input_width = self.input_width, resize_height = self.output_height, resize_width = self.output_width, crop = self.crop, grayscale=self.grayscale) for name in self.test_data_names] if self.grayscale: batch_images = np.array(batch).astype(np.float32)[:,:,:,None] else: batch_images = np.array(batch).astype(np.float32) #print np.shape(batch_images) self.test_data = batch_images print "[*] test data for anomaly detection is loaded" def anomaly_detector(self, ano_para=0.1, dis_loss='feature'): self.get_test_data() #with variable_scope("anomaly_detector"): if self.y_dim: self.ano_y = tf.placeholder(tf.float32, [self.test_batch_size, self.y_dim], name='y') else: self.y = None if self.crop: image_dims = [self.output_height, self.output_width, self.c_dim] else: #for test image_dims = [self.input_height, self.input_width, self.c_dim] self.test_inputs = tf.placeholder(tf.float32, [1] + image_dims, name='test_images') test_inputs = self.test_inputs self.ano_z = tf.get_variable('ano_z', shape = [1, self.z_dim], dtype = tf.float32, initializer = tf.random_uniform_initializer(minval=-1, maxval=1, dtype=tf.float32)) self.ano_y = None self.ano_G = self._sampler(self.ano_z, self.ano_y, batch_size=1) self.res_loss = tf.reduce_mean( tf.reduce_sum(tf.abs(tf.subtract(test_inputs, self.ano_G)))) #Create Anomaly Score if dis_loss == 'feature': # if discrimination loss with feature matching (same with paper) dis_f_z, dis_f_input = self.feature_match_layer(self.ano_G, self.ano_y, reuse=True,batch_size=1), self.feature_match_layer(test_inputs, self.ano_y, reuse=True, batch_size=1) self.dis_loss = tf.reduce_mean( tf.reduce_sum(tf.abs(tf.subtract(dis_f_z, dis_f_input)))) else: # if dis_loss with original generator's loss in DCGAN test_D, test_D_logits_ = self.discriminator(ano_G, ano_y, reuse=True, batch_size=1) self.dis_loss = tf.reduce_mean( sigmoid_cross_entropy_with_logits(test_D_logits_, tf.ones_like(test_D))) self.anomaly_score = (1. - ano_para)* self.res_loss + ano_para* self.dis_loss t_vars = tf.trainable_variables() self.z_vars = [var for var in t_vars if 'ano_z' in var.name] print test_inputs, self.ano_G, dis_f_z, dis_f_input def train_anomaly_detector(self, config, test_data, test_data_name): print "Filename: ", test_data_name, "Anomaly is detecting" print np.shape(test_data) #self.sess.run(self.ano_z.initializer) z_optim = tf.train.AdamOptimizer(config.test_learning_rate, beta1=config.beta1) \ .minimize(self.anomaly_score, var_list = self.z_vars) initialize_uninitialized(self.sess) for epoch in range(config.test_epoch): if not self.y_dim: feed_dict = {self.test_inputs: test_data} else: print "Not yet prepared anomaly detection model of MNIST dataset" feed_dict = {} _, ano_score, res_loss = self.sess.run([z_optim, self.anomaly_score, self.res_loss], feed_dict = feed_dict) print("Epoch: [{:02d}], anomaly score: {:.8f}, res loss: {:.8f}"\ .format(epoch, ano_score, res_loss)) save_epoch = [0, config.test_epoch/2, config.test_epoch-1] if epoch in save_epoch: samples = self.sess.run(self.ano_G) errors = samples-test_data print np.shape(samples) samples = np.squeeze(samples) samples = (np.array(samples)+1)*127.5 if not self.grayscale: errors = np.mean(np.squeeze(errors),axis=2) errors = (np.array(errors)+1)*127.5 _path = './test_data/' path = os.path.join(_path, config.test_result_dir) if not os.path.isdir(path): os.mkdir(path) filename = ['AD_'+str(epoch)+'_'+test_data_name.split('/')[-1], 'AD_error_'+str(epoch)+'_'+test_data_name.split('/')[-1]] scipy.misc.imsave(os.path.join(path,filename[0]),samples) scipy.misc.imsave(os.path.join(path,filename[1]),errors) #np.save('./{}/test_error_{}_{:02d}.png'.format(config.test_dir, test_data_name, epoch), errors) def load_mnist(self): data_dir = os.path.join("./data", self.dataset_name) fd = open(os.path.join(data_dir,'train-images-idx3-ubyte')) loaded = np.fromfile(file=fd,dtype=np.uint8) trX = loaded[16:].reshape((60000,28,28,1)).astype(np.float) fd = open(os.path.join(data_dir,'train-labels-idx1-ubyte')) loaded = np.fromfile(file=fd,dtype=np.uint8) trY = loaded[8:].reshape((60000)).astype(np.float) fd = open(os.path.join(data_dir,'t10k-images-idx3-ubyte')) loaded = np.fromfile(file=fd,dtype=np.uint8) teX = loaded[16:].reshape((10000,28,28,1)).astype(np.float) fd = open(os.path.join(data_dir,'t10k-labels-idx1-ubyte')) loaded = np.fromfile(file=fd,dtype=np.uint8) teY = loaded[8:].reshape((10000)).astype(np.float) 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) #Make one-hot y_vec = np.zeros((len(y), self.y_dim), dtype=np.float) index_offset = np.arange(len(y)) * self.y_dim y_vec.flat[index_offset + y.ravel()] = 1 return X/255.,y_vec @property def model_dir(self): return "{}_{}_{}_{}".format( self.dataset_name, self.batch_size, self.output_height, self.output_width) def save(self, checkpoint_dir, step): model_name = "DCGAN.model" checkpoint_dir = os.path.join(checkpoint_dir, self.model_dir) if not os.path.exists(checkpoint_dir): os.makedirs(checkpoint_dir) self.saver.save(self.sess, os.path.join(checkpoint_dir, model_name), global_step=step) def load(self, checkpoint_dir): import re print(" [*] Reading checkpoints...") checkpoint_dir = os.path.join(checkpoint_dir, self.model_dir) 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 ================================================ FILE: ops.py ================================================ import math import numpy as np import tensorflow as tf from tensorflow.python.framework import ops from utils import * image_summary = tf.summary.image scalar_summary = tf.summary.scalar histogram_summary = tf.summary.histogram merge_summary = tf.summary.merge SummaryWriter = tf.summary.FileWriter def concat(tensors, axis, *args, **kwargs): return tf.concat(tensors, axis, *args, **kwargs) #for efficient management of batch_norm layer's arguments class batch_norm(object): def __init__(self, epsilon=1e-5, momentum = 0.9, name="batch_norm"): with tf.variable_scope(name): self.epsilon = epsilon self.momentum = momentum self.name = name def __call__(self, x, train=True): 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 conv_cond_concat(x, y): """Concatenate conditioning vector on feature map axis.""" x_shapes = x.get_shape() y_shapes = y.get_shape() return concat([ x, y*tf.ones([x_shapes[0], x_shapes[1], x_shapes[2], y_shapes[3]])], 3) def conv2d(input_, output_dim, k_h=5, k_w=5, d_h=2, d_w=2, stddev=0.02, name="conv2d"): with tf.variable_scope(name): w = tf.get_variable('w', [k_h, k_w, input_.get_shape()[-1], output_dim], initializer=tf.truncated_normal_initializer(stddev=stddev)) conv = tf.nn.conv2d(input_, w, strides=[1, d_h, d_w, 1], padding='SAME') biases = tf.get_variable('biases', [output_dim], initializer=tf.constant_initializer(0.0)) conv = tf.reshape(tf.nn.bias_add(conv, biases), conv.get_shape()) return conv def deconv2d(input_, output_shape, k_h=5, k_w=5, d_h=2, d_w=2, stddev=0.02, name="deconv2d", with_w=False): with tf.variable_scope(name): # filter : [height, width, output_channels, in_channels] w = tf.get_variable('w', [k_h, k_w, output_shape[-1], input_.get_shape()[-1]], initializer=tf.random_normal_initializer(stddev=stddev)) deconv = tf.nn.conv2d_transpose(input_, w, output_shape=output_shape, strides=[1, d_h, d_w, 1]) biases = tf.get_variable('biases', [output_shape[-1]], initializer=tf.constant_initializer(0.0)) deconv = tf.reshape(tf.nn.bias_add(deconv, biases), deconv.get_shape()) if with_w: return deconv, w, biases else: return deconv def leak_relu(x, leak=0.2, name="leak_relu"): return tf.maximum(x, leak*x) def linear(input_, output_size, scope=None, stddev=0.02, bias_start=0.0, with_w=False): shape = input_.get_shape().as_list() with tf.variable_scope(scope or "Linear"): matrix = tf.get_variable("Matrix", [shape[1], output_size], tf.float32, tf.random_normal_initializer(stddev=stddev)) bias = tf.get_variable("bias", [output_size], initializer=tf.constant_initializer(bias_start)) if with_w: return tf.matmul(input_, matrix) + bias, matrix, bias else: return tf.matmul(input_, matrix) + bias ================================================ FILE: utils.py ================================================ """ Some codes from https://github.com/Newmu/dcgan_code """ from __future__ import division import math import json import random import pprint import scipy.misc import numpy as np from time import gmtime, strftime from six.moves import xrange import tensorflow as tf import tensorflow.contrib.slim as slim pp = pprint.PrettyPrinter() get_stddev = lambda x, k_h, k_w: 1/math.sqrt(k_w*k_h*x.get_shape()[-1]) def initialize_uninitialized(sess): global_vars = tf.global_variables() is_not_initialized = sess.run([tf.is_variable_initialized(var) for var in global_vars]) not_initialized_vars = [v for (v,f) in zip(global_vars, is_not_initialized) if not f] print [str(i.name) for i in not_initialized_vars] if len(not_initialized_vars): sess.run(tf.variables_initializer(not_initialized_vars)) 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 scipy.misc.imread(path, flatten = True).astype(np.float) else: return scipy.misc.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 scipy.misc.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 scipy.misc.imresize( 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 = scipy.misc.imresize(image, [resize_height, resize_width]) return np.array(cropped_image)/127.5 - 1. def inverse_transform(images): return (images+1.)/2. def make_gif(images, fname, duration=2, true_image=False): import moviepy.editor as mpy def make_frame(t): try: x = images[int(len(images)/duration*t)] except: x = images[-1] if true_image: return x.astype(np.uint8) else: return ((x+1)/2*255).astype(np.uint8) clip = mpy.VideoClip(make_frame, duration=duration) clip.write_gif(fname, fps = len(images) / duration) def visualize(sess, dcgan, config, option): image_frame_dim = int(math.ceil(config.batch_size**.5)) if option == 0: z_sample = np.random.uniform(-0.5, 0.5, size=(config.batch_size, dcgan.z_dim)) samples = sess.run(dcgan.sampler, feed_dict={dcgan.z: z_sample}) save_images(samples, [image_frame_dim, image_frame_dim], './samples/test_%s.png' % strftime("%Y-%m-%d-%H-%M-%S", gmtime())) elif option == 1: values = np.arange(0, 1, 1./config.batch_size) for idx in xrange(dcgan.z_dim): print(" [*] %d" % idx) z_sample = np.random.uniform(-1, 1, size=(config.batch_size , dcgan.z_dim)) for kdx, z in enumerate(z_sample): z[idx] = values[kdx] if config.dataset == "mnist": y = np.random.choice(10, config.batch_size) y_one_hot = np.zeros((config.batch_size, 10)) y_one_hot[np.arange(config.batch_size), y] = 1 samples = sess.run(dcgan.sampler, feed_dict={dcgan.z: z_sample, dcgan.y: y_one_hot}) else: samples = sess.run(dcgan.sampler, feed_dict={dcgan.z: z_sample}) save_images(samples, [image_frame_dim, image_frame_dim], './samples/test_arange_%s.png' % (idx)) elif option == 2: values = np.arange(0, 1, 1./config.batch_size) for idx in [random.randint(0, dcgan.z_dim - 1) for _ in xrange(dcgan.z_dim)]: print(" [*] %d" % idx) z = np.random.uniform(-0.2, 0.2, size=(dcgan.z_dim)) z_sample = np.tile(z, (config.batch_size, 1)) #z_sample = np.zeros([config.batch_size, dcgan.z_dim]) for kdx, z in enumerate(z_sample): z[idx] = values[kdx] if config.dataset == "mnist": y = np.random.choice(10, config.batch_size) y_one_hot = np.zeros((config.batch_size, 10)) y_one_hot[np.arange(config.batch_size), y] = 1 samples = sess.run(dcgan.sampler, feed_dict={dcgan.z: z_sample, dcgan.y: y_one_hot}) else: samples = sess.run(dcgan.sampler, feed_dict={dcgan.z: z_sample}) try: make_gif(samples, './samples/test_gif_%s.gif' % (idx)) except: save_images(samples, [image_frame_dim, image_frame_dim], './samples/test_%s.png' % strftime("%Y-%m-%d-%H-%M-%S", gmtime())) elif option == 3: values = np.arange(0, 1, 1./config.batch_size) for idx in xrange(dcgan.z_dim): print(" [*] %d" % idx) z_sample = np.zeros([config.batch_size, dcgan.z_dim]) for kdx, z in enumerate(z_sample): z[idx] = values[kdx] samples = sess.run(dcgan.sampler, feed_dict={dcgan.z: z_sample}) make_gif(samples, './samples/test_gif_%s.gif' % (idx)) elif option == 4: image_set = [] values = np.arange(0, 1, 1./config.batch_size) for idx in xrange(dcgan.z_dim): print(" [*] %d" % idx) z_sample = np.zeros([config.batch_size, dcgan.z_dim]) for kdx, z in enumerate(z_sample): z[idx] = values[kdx] image_set.append(sess.run(dcgan.sampler, feed_dict={dcgan.z: z_sample})) make_gif(image_set[-1], './samples/test_gif_%s.gif' % (idx)) new_image_set = [merge(np.array([images[idx] for images in image_set]), [10, 10]) \ for idx in range(64) + range(63, -1, -1)] make_gif(new_image_set, './samples/test_gif_merged.gif', duration=8) def image_manifold_size(num_images): manifold_h = int(np.floor(np.sqrt(num_images))) manifold_w = int(np.ceil(np.sqrt(num_images))) assert manifold_h * manifold_w == num_images return manifold_h, manifold_w