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