|
| 1 | +from __future__ import division |
| 2 | +import tensorflow as tf |
| 3 | +import numpy as np |
| 4 | +from scipy.misc import imread, imresize, imsave |
| 5 | + |
| 6 | + |
| 7 | +class batch_norm(object): |
| 8 | + def __init__(self, epsilon=1e-5, momentum=0.9, name="batch_norm"): |
| 9 | + with tf.variable_scope(name): |
| 10 | + self.epsilon = epsilon |
| 11 | + self.momentum = momentum |
| 12 | + self.name = name |
| 13 | + |
| 14 | + def __call__(self, x, train=True): |
| 15 | + return tf.contrib.layers.batch_norm(x, decay=self.momentum, updates_collections=None, epsilon=self.epsilon, |
| 16 | + scale=True, scope=self.name) |
| 17 | + |
| 18 | + |
| 19 | +def conv2d(input_map, num_output_channels, size_kernel=5, stride=2, name='conv2d'): |
| 20 | + with tf.variable_scope(name): |
| 21 | + stddev = np.sqrt(2.0 / (np.sqrt(input_map.get_shape()[-1].value * num_output_channels) * size_kernel ** 2)) |
| 22 | + stddev = 0.02 |
| 23 | + kernel = tf.get_variable( |
| 24 | + name='w', |
| 25 | + shape=[size_kernel, size_kernel, input_map.get_shape()[-1], num_output_channels], |
| 26 | + dtype=tf.float32, |
| 27 | + initializer=tf.truncated_normal_initializer(stddev=stddev) |
| 28 | + ) |
| 29 | + biases = tf.get_variable( |
| 30 | + name='b', |
| 31 | + shape=[num_output_channels], |
| 32 | + dtype=tf.float32, |
| 33 | + initializer=tf.constant_initializer(0.0) |
| 34 | + ) |
| 35 | + conv = tf.nn.conv2d(input_map, kernel, strides=[1, stride, stride, 1], padding='SAME') |
| 36 | + return tf.nn.bias_add(conv, biases) |
| 37 | + |
| 38 | + |
| 39 | +def fc(input_vector, num_output_length, name='fc'): |
| 40 | + with tf.variable_scope(name): |
| 41 | + stddev = np.sqrt(1.0 / (np.sqrt(input_vector.get_shape()[-1].value * num_output_length))) |
| 42 | + stddev = 0.02 |
| 43 | + w = tf.get_variable( |
| 44 | + name='w', |
| 45 | + shape=[input_vector.get_shape()[1], num_output_length], |
| 46 | + dtype=tf.float32, |
| 47 | + initializer=tf.random_normal_initializer(stddev=stddev) |
| 48 | + ) |
| 49 | + b = tf.get_variable( |
| 50 | + name='b', |
| 51 | + shape=[num_output_length], |
| 52 | + dtype=tf.float32, |
| 53 | + initializer=tf.constant_initializer(0.0) |
| 54 | + ) |
| 55 | + return tf.matmul(input_vector, w) + b |
| 56 | + |
| 57 | + |
| 58 | +def deconv2d(input_map, output_shape, size_kernel=5, stride=2, stddev=0.02, name='deconv2d'): |
| 59 | + with tf.variable_scope(name): |
| 60 | + stddev = np.sqrt(1.0 / (np.sqrt(input_map.get_shape()[-1].value * output_shape[-1]) * size_kernel ** 2)) |
| 61 | + stddev = 0.02 |
| 62 | + # filter : [height, width, output_channels, in_channels] |
| 63 | + kernel = tf.get_variable( |
| 64 | + name='w', |
| 65 | + shape=[size_kernel, size_kernel, output_shape[-1], input_map.get_shape()[-1]], |
| 66 | + dtype=tf.float32, |
| 67 | + initializer=tf.random_normal_initializer(stddev=stddev) |
| 68 | + ) |
| 69 | + biases = tf.get_variable( |
| 70 | + name='b', |
| 71 | + shape=[output_shape[-1]], |
| 72 | + dtype=tf.float32, |
| 73 | + initializer=tf.constant_initializer(0.0) |
| 74 | + ) |
| 75 | + deconv = tf.nn.conv2d_transpose(input_map, kernel, strides=[1, stride, stride, 1], output_shape=output_shape) |
| 76 | + return tf.nn.bias_add(deconv, biases) |
| 77 | + |
| 78 | + |
| 79 | +def lrelu(logits, leak=0.2): |
| 80 | + return tf.maximum(logits, leak*logits) |
| 81 | + |
| 82 | + |
| 83 | +def concat_label(x, label, duplicate=1): |
| 84 | + x_shape = x.get_shape().as_list() |
| 85 | + if duplicate < 1: |
| 86 | + return x |
| 87 | + # duplicate the label to enhance its effect, does it really affect the result? |
| 88 | + label = tf.tile(label, [1, duplicate]) |
| 89 | + label_shape = label.get_shape().as_list() |
| 90 | + if len(x_shape) == 2: |
| 91 | + return tf.concat(1, [x, label]) |
| 92 | + elif len(x_shape) == 4: |
| 93 | + label = tf.reshape(label, [x_shape[0], 1, 1, label_shape[-1]]) |
| 94 | + return tf.concat(3, [x, label*tf.ones([x_shape[0], x_shape[1], x_shape[2], label_shape[-1]])]) |
| 95 | + |
| 96 | + |
| 97 | +def load_image( |
| 98 | + image_path, # path of a image |
| 99 | + image_size=64, # expected size of the image |
| 100 | + image_value_range=(-1, 1), # expected pixel value range of the image |
| 101 | + is_gray=False, # gray scale or color image |
| 102 | +): |
| 103 | + if is_gray: |
| 104 | + image = imread(image_path, flatten=True).astype(np.float32) |
| 105 | + else: |
| 106 | + image = imread(image_path).astype(np.float32) |
| 107 | + image = imresize(image, [image_size, image_size]) |
| 108 | + image = image.astype(np.float32) * (image_value_range[-1] - image_value_range[0]) / 255.0 + image_value_range[0] |
| 109 | + return image |
| 110 | + |
| 111 | + |
| 112 | +def save_batch_images( |
| 113 | + batch_images, # a batch of images |
| 114 | + save_path, # path to save the images |
| 115 | + image_value_range=(-1,1), # value range of the input batch images |
| 116 | + size_frame=None # size of the image matrix, number of images in each row and column |
| 117 | +): |
| 118 | + # transform the pixcel value to 0~1 |
| 119 | + images = (batch_images - image_value_range[0]) / (image_value_range[-1] - image_value_range[0]) |
| 120 | + if size_frame is None: |
| 121 | + auto_size = int(np.ceil(np.sqrt(images.shape[0]))) |
| 122 | + size_frame = [auto_size, auto_size] |
| 123 | + img_h, img_w = batch_images.shape[1], batch_images.shape[2] |
| 124 | + frame = np.zeros([img_h * size_frame[0], img_w * size_frame[1], 3]) |
| 125 | + for ind, image in enumerate(images): |
| 126 | + ind_col = ind % size_frame[1] |
| 127 | + ind_row = ind // size_frame[1] |
| 128 | + frame[(ind_row * img_h):(ind_row * img_h + img_h), (ind_col * img_w):(ind_col * img_w + img_w), :] = image |
| 129 | + imsave(save_path, np.clip(frame, 0.0, 1.0)) # imsave(save_path, frame) |
| 130 | + |
| 131 | + |
| 132 | + |
| 133 | + |
| 134 | + |
| 135 | + |
| 136 | + |
| 137 | + |
0 commit comments