| 35 | |
| 36 | |
| 37 | class Model(GANModelDesc): |
| 38 | def __init__(self, shape, batch, z_dim): |
| 39 | self.shape = shape |
| 40 | self.batch = batch |
| 41 | self.zdim = z_dim |
| 42 | |
| 43 | def inputs(self): |
| 44 | return [tf.TensorSpec((None, self.shape, self.shape, 3), tf.float32, 'input')] |
| 45 | |
| 46 | def generator(self, z): |
| 47 | """ return an image generated from z""" |
| 48 | nf = 64 |
| 49 | l = FullyConnected('fc0', z, nf * 8 * 4 * 4, activation=tf.identity) |
| 50 | l = tf.reshape(l, [-1, 4, 4, nf * 8]) |
| 51 | l = BNReLU(l) |
| 52 | with argscope(Conv2DTranspose, activation=BNReLU, kernel_size=4, strides=2): |
| 53 | l = Conv2DTranspose('deconv1', l, nf * 4) |
| 54 | l = Conv2DTranspose('deconv2', l, nf * 2) |
| 55 | l = Conv2DTranspose('deconv3', l, nf) |
| 56 | l = Conv2DTranspose('deconv4', l, 3, activation=tf.identity) |
| 57 | l = tf.tanh(l, name='gen') |
| 58 | return l |
| 59 | |
| 60 | @auto_reuse_variable_scope |
| 61 | def discriminator(self, imgs): |
| 62 | """ return a (b, 1) logits""" |
| 63 | nf = 64 |
| 64 | with argscope(Conv2D, kernel_size=4, strides=2): |
| 65 | l = (LinearWrap(imgs) |
| 66 | .Conv2D('conv0', nf, activation=tf.nn.leaky_relu) |
| 67 | .Conv2D('conv1', nf * 2) |
| 68 | .BatchNorm('bn1') |
| 69 | .tf.nn.leaky_relu() |
| 70 | .Conv2D('conv2', nf * 4) |
| 71 | .BatchNorm('bn2') |
| 72 | .tf.nn.leaky_relu() |
| 73 | .Conv2D('conv3', nf * 8) |
| 74 | .BatchNorm('bn3') |
| 75 | .tf.nn.leaky_relu() |
| 76 | .FullyConnected('fct', 1)()) |
| 77 | return l |
| 78 | |
| 79 | def build_graph(self, image_pos): |
| 80 | image_pos = image_pos / 128.0 - 1 |
| 81 | |
| 82 | z = tf.random_uniform([self.batch, self.zdim], -1, 1, name='z_train') |
| 83 | z = tf.placeholder_with_default(z, [None, self.zdim], name='z') |
| 84 | |
| 85 | with argscope([Conv2D, Conv2DTranspose, FullyConnected], |
| 86 | kernel_initializer=tf.truncated_normal_initializer(stddev=0.02)): |
| 87 | with tf.variable_scope('gen'): |
| 88 | image_gen = self.generator(z) |
| 89 | tf.summary.image('generated-samples', image_gen, max_outputs=30) |
| 90 | with tf.variable_scope('discrim'): |
| 91 | vecpos = self.discriminator(image_pos) |
| 92 | vecneg = self.discriminator(image_gen) |
| 93 | |
| 94 | self.build_losses(vecpos, vecneg) |