| 41 | |
| 42 | |
| 43 | class Model(GANModelDesc): |
| 44 | def inputs(self): |
| 45 | return [tf.TensorSpec((None, SHAPE, SHAPE, 3), tf.float32, 'inputA'), |
| 46 | tf.TensorSpec((None, SHAPE, SHAPE, 3), tf.float32, 'inputB')] |
| 47 | |
| 48 | @staticmethod |
| 49 | def build_res_block(x, name, chan, first=False): |
| 50 | with tf.variable_scope(name): |
| 51 | input = x |
| 52 | return (LinearWrap(x) |
| 53 | .tf.pad([[0, 0], [0, 0], [1, 1], [1, 1]], mode='SYMMETRIC') |
| 54 | .Conv2D('conv0', chan, 3, padding='VALID') |
| 55 | .tf.pad([[0, 0], [0, 0], [1, 1], [1, 1]], mode='SYMMETRIC') |
| 56 | .Conv2D('conv1', chan, 3, padding='VALID', activation=tf.identity) |
| 57 | .InstanceNorm('inorm')()) + input |
| 58 | |
| 59 | @auto_reuse_variable_scope |
| 60 | def generator(self, img): |
| 61 | assert img is not None |
| 62 | with argscope([Conv2D, Conv2DTranspose], activation=INReLU): |
| 63 | l = (LinearWrap(img) |
| 64 | .tf.pad([[0, 0], [0, 0], [3, 3], [3, 3]], mode='SYMMETRIC') |
| 65 | .Conv2D('conv0', NF, 7, padding='VALID') |
| 66 | .Conv2D('conv1', NF * 2, 3, strides=2) |
| 67 | .Conv2D('conv2', NF * 4, 3, strides=2)()) |
| 68 | for k in range(9): |
| 69 | l = Model.build_res_block(l, 'res{}'.format(k), NF * 4, first=(k == 0)) |
| 70 | l = (LinearWrap(l) |
| 71 | .Conv2DTranspose('deconv0', NF * 2, 3, strides=2) |
| 72 | .Conv2DTranspose('deconv1', NF * 1, 3, strides=2) |
| 73 | .tf.pad([[0, 0], [0, 0], [3, 3], [3, 3]], mode='SYMMETRIC') |
| 74 | .Conv2D('convlast', 3, 7, padding='VALID', activation=tf.tanh, use_bias=True)()) |
| 75 | return l |
| 76 | |
| 77 | @auto_reuse_variable_scope |
| 78 | def discriminator(self, img): |
| 79 | with argscope(Conv2D, activation=INLReLU, kernel_size=4, strides=2): |
| 80 | l = (LinearWrap(img) |
| 81 | .Conv2D('conv0', NF, activation=tf.nn.leaky_relu) |
| 82 | .Conv2D('conv1', NF * 2) |
| 83 | .Conv2D('conv2', NF * 4) |
| 84 | .Conv2D('conv3', NF * 8, strides=1) |
| 85 | .Conv2D('conv4', 1, strides=1, activation=tf.identity, use_bias=True)()) |
| 86 | return l |
| 87 | |
| 88 | def build_graph(self, A, B): |
| 89 | with tf.name_scope('preprocess'): |
| 90 | A = tf.transpose(A / 128.0 - 1.0, [0, 3, 1, 2]) |
| 91 | B = tf.transpose(B / 128.0 - 1.0, [0, 3, 1, 2]) |
| 92 | |
| 93 | def viz3(name, a, b, c): |
| 94 | with tf.name_scope(name): |
| 95 | im = tf.concat([a, b, c], axis=3) |
| 96 | im = tf.transpose(im, [0, 2, 3, 1]) |
| 97 | im = (im + 1.0) * 128 |
| 98 | im = tf.clip_by_value(im, 0, 255) |
| 99 | im = tf.cast(im, tf.uint8, name='viz') |
| 100 | tf.summary.image(name, im, max_outputs=50) |
no outgoing calls
no test coverage detected
searching dependent graphs…