GAN Discriminator. A network to differentiate between generated and real handwritten digits.
| 36 | |
| 37 | |
| 38 | class Discriminator(tf.keras.Model): |
| 39 | """GAN Discriminator. |
| 40 | |
| 41 | A network to differentiate between generated and real handwritten digits. |
| 42 | """ |
| 43 | |
| 44 | def __init__(self, data_format): |
| 45 | """Creates a model for discriminating between real and generated digits. |
| 46 | |
| 47 | Args: |
| 48 | data_format: Either 'channels_first' or 'channels_last'. |
| 49 | 'channels_first' is typically faster on GPUs while 'channels_last' is |
| 50 | typically faster on CPUs. See |
| 51 | https://www.tensorflow.org/performance/performance_guide#data_formats |
| 52 | """ |
| 53 | super(Discriminator, self).__init__(name='') |
| 54 | if data_format == 'channels_first': |
| 55 | self._input_shape = [-1, 1, 28, 28] |
| 56 | else: |
| 57 | assert data_format == 'channels_last' |
| 58 | self._input_shape = [-1, 28, 28, 1] |
| 59 | self.conv1 = layers.Conv2D( |
| 60 | 64, 5, padding='SAME', data_format=data_format, activation=tf.tanh) |
| 61 | self.pool1 = layers.AveragePooling2D(2, 2, data_format=data_format) |
| 62 | self.conv2 = layers.Conv2D( |
| 63 | 128, 5, data_format=data_format, activation=tf.tanh) |
| 64 | self.pool2 = layers.AveragePooling2D(2, 2, data_format=data_format) |
| 65 | self.flatten = layers.Flatten() |
| 66 | self.fc1 = layers.Dense(1024, activation=tf.tanh) |
| 67 | self.fc2 = layers.Dense(1, activation=None) |
| 68 | |
| 69 | def call(self, inputs): |
| 70 | """Return two logits per image estimating input authenticity. |
| 71 | |
| 72 | Users should invoke __call__ to run the network, which delegates to this |
| 73 | method (and not call this method directly). |
| 74 | |
| 75 | Args: |
| 76 | inputs: A batch of images as a Tensor with shape [batch_size, 28, 28, 1] |
| 77 | or [batch_size, 1, 28, 28] |
| 78 | |
| 79 | Returns: |
| 80 | A Tensor with shape [batch_size] containing logits estimating |
| 81 | the probability that corresponding digit is real. |
| 82 | """ |
| 83 | x = tf.reshape(inputs, self._input_shape) |
| 84 | x = self.conv1(x) |
| 85 | x = self.pool1(x) |
| 86 | x = self.conv2(x) |
| 87 | x = self.pool2(x) |
| 88 | x = self.flatten(x) |
| 89 | x = self.fc1(x) |
| 90 | x = self.fc2(x) |
| 91 | return x |
| 92 | |
| 93 | |
| 94 | class Generator(tf.keras.Model): |