示例#1
0
 def _conv2d(scope, x, kernel_size, filters, padding='SAME'):
     return layers.custom_conv2d(
         x=x,
         filters=filters,
         kernel_size=kernel_size,
         padding=padding,
         activation=lambda x: layers.pixel_norm(tf.nn.leaky_relu(x)),
         he_initializer_slope=0.0,
         scope=scope)
示例#2
0
  def test_pixel_norm_4d_images_returns_channel_normalized_images(self):
    x = tf.constant([[[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]],
                     [[[0, 0, 0], [-1, -2, -3]], [[1, -2, 2], [2, 5, 3]]]],
                    dtype=tf.float32)
    with self.cached_session() as sess:
      output_np = sess.run(layers.pixel_norm(x))

    expected_np = [[[[0.46291006, 0.92582011, 1.38873017],
                     [0.78954202, 0.98692751, 1.18431306]],
                    [[0.87047803, 0.99483204, 1.11918604],
                     [0.90659684, 0.99725652, 1.08791625]]],
                   [[[0., 0., 0.], [-0.46291006, -0.92582011, -1.38873017]],
                    [[0.57735026, -1.15470052, 1.15470052],
                     [0.56195146, 1.40487862, 0.84292722]]]]
    self.assertAllClose(output_np, expected_np, 1.0e-5)
示例#3
0
def generator(z,
              progress,
              num_filters_fn,
              resolution_schedule,
              num_blocks=None,
              kernel_size=3,
              colors=3,
              to_rgb_activation=None,
              scope='progressive_gan_generator',
              reuse=None):
    """Generator network for the progressive GAN model.

  Args:
    z: A `Tensor` of latent vector. The first dimension must be batch size.
    progress: A scalar float `Tensor` of training progress.
    num_filters_fn: A function that maps `block_id` to # of filters for the
      block.
    resolution_schedule: An object of `ResolutionSchedule`.
    num_blocks: An integer of number of blocks. None means maximum number of
      blocks, i.e. `resolution.schedule.num_resolutions`. Defaults to None.
    kernel_size: An integer of convolution kernel size.
    colors: Number of output color channels. Defaults to 3.
    to_rgb_activation: Activation function applied when output rgb.
    scope: A string or variable scope.
    reuse: Whether to reuse `scope`. Defaults to None which means to inherit the
      reuse option of the parent scope.

  Returns:
    A `Tensor` of model output and a dictionary of model end points.
  """
    if num_blocks is None:
        num_blocks = resolution_schedule.num_resolutions

    start_h, start_w = resolution_schedule.start_resolutions
    final_h, final_w = resolution_schedule.final_resolutions

    def _conv2d(scope, x, kernel_size, filters, padding='SAME'):
        return layers.custom_conv2d(
            x=x,
            filters=filters,
            kernel_size=kernel_size,
            padding=padding,
            activation=lambda x: layers.pixel_norm(tf.nn.leaky_relu(x)),
            he_initializer_slope=0.0,
            scope=scope)

    def _to_rgb(x):
        return layers.custom_conv2d(x=x,
                                    filters=colors,
                                    kernel_size=1,
                                    padding='SAME',
                                    activation=to_rgb_activation,
                                    scope='to_rgb')

    end_points = {}

    with tf.compat.v1.variable_scope(scope, reuse=reuse):
        with tf.compat.v1.name_scope('input'):
            x = tf.compat.v1.layers.flatten(z)
            end_points['latent_vector'] = x

        with tf.compat.v1.variable_scope(block_name(1)):
            x = tf.expand_dims(tf.expand_dims(x, 1), 1)
            x = layers.pixel_norm(x)
            # Pad the 1 x 1 image to 2 * (start_h - 1) x 2 * (start_w - 1)
            # with zeros for the next conv.
            x = tf.pad(tensor=x,
                       paddings=[[0] * 2, [start_h - 1] * 2, [start_w - 1] * 2,
                                 [0] * 2])
            # The output is start_h x start_w x num_filters_fn(1).
            x = _conv2d('conv0', x, (start_h, start_w), num_filters_fn(1),
                        'VALID')
            x = _conv2d('conv1', x, kernel_size, num_filters_fn(1))
            lods = [x]

        for block_id in range(2, num_blocks + 1):
            with tf.compat.v1.variable_scope(block_name(block_id)):
                x = layers.upscale(x, resolution_schedule.scale_base)
                x = _conv2d('conv0', x, kernel_size, num_filters_fn(block_id))
                x = _conv2d('conv1', x, kernel_size, num_filters_fn(block_id))
                lods.append(x)

        outputs = []
        for block_id in range(1, num_blocks + 1):
            with tf.compat.v1.variable_scope(block_name(block_id)):
                lod = _to_rgb(lods[block_id - 1])
                scale = resolution_schedule.scale_factor(block_id)
                lod = layers.upscale(lod, scale)
                end_points['upscaled_rgb_{}'.format(block_id)] = lod

                # alpha_i is used to replace lod_select. Note sum(alpha_i) is
                # garanteed to be 1.
                alpha = _generator_alpha(block_id, progress)
                end_points['alpha_{}'.format(block_id)] = alpha

                outputs.append(lod * alpha)

        predictions = tf.add_n(outputs)
        batch_size = dimension_value(z.shape[0])
        predictions.set_shape([batch_size, final_h, final_w, colors])
        end_points['predictions'] = predictions

    return predictions, end_points