Exemple #1
0
    def __init__(self):

        nn_template_fn = nets.OpenAITemplate(width=c.WIDTH_RESNET)

        layers, self.actnorm_layers = nets.create_simple_flow(
            num_steps=c.N_FLOW_STEPS,
            num_scales=c.N_FLOW_SCALES,
            template_fn=nn_template_fn)
        self.model_flow = fl.ChainLayer(layers)
        self.quantize_image_layer = layers[0]
    def test_create_simple_flow(self):
        np.random.seed(642201)

        images = tf.placeholder(tf.float32, [16, 32, 32, 1])
        layers, actnorm_layers = nets.create_simple_flow(num_steps=2,
                                                         num_scales=4,
                                                         num_bits=8)
        flow = fl.InputLayer(images)
        model_flow = fl.ChainLayer(layers)
        output_flow = model_flow(flow, forward=True)

        with self.test_session() as sess:
            sess.run(tf.global_variables_initializer())

            for actnorm_layer in actnorm_layers:
                init_op = actnorm_layer.get_ddi_init_ops(10)
                noise = np.random.rand(16, 32, 32, 1)
                # fit actnorms to certain noise
                for i in range(30):
                    sess.run(init_op, feed_dict={images: noise})

                actnorm_flow = actnorm_layer._forward_outputs[0]
                normed_x = sess.run(actnorm_flow[0], feed_dict={images: noise})
                nc = normed_x.shape[-1]

                self.assertAllClose(np.var(normed_x.reshape([-1, nc]), axis=0),
                                    [1.0] * nc,
                                    atol=0.1)
                self.assertAllClose(np.mean(normed_x.reshape([-1, nc]),
                                            axis=0), [0.0] * nc,
                                    atol=0.1)

            output_flow_np = sess.run(
                output_flow, feed_dict={images: np.random.rand(16, 32, 32, 1)})

            y, logdet, z = output_flow_np

            self.assertEqual(
                np.prod(y.shape) + np.prod(z.shape), np.prod([16, 32, 32, 1]))
            self.assertTrue(np.max(np.abs(y)) < 15.0)
            self.forward_inverse(
                sess,
                model_flow,
                flow,
                atol=0.01,
                feed_dict={images: np.random.rand(16, 32, 32, 1)},
            )
Exemple #3
0
def create_simple_flow(
    num_steps: int = 1,
    num_scales: int = 3,
    num_bits: int = 5,
    template_fn: Any = ResentTemplate()
) -> Tuple[List[fl.FlowLayer], List[fl.ActnormLayer]]:
    """Create Glow model. This implementation may slightly differ from the
    official one. For example the last layer here is the fl.FactorOutLayer

    Args:
        num_steps: number of steps per single scale, a K parameter from the paper
        num_scales: number of scales, a L parameter from the paper. Each scale
            reduces the tensor spatial dimension by 2.
        num_bits: input image quantization
        template_fn: a template function used in AffineCoupling layer

    Returns:
        layers: a list of layers which define normalizing flow
        actnorms: a list of actnorm layers which can be initialized using data
            dependent initialization. See: initialize_actnorms() function.
    """
    layers = [fl.QuantizeImage(num_bits=num_bits)]
    actnorm_layers = []
    for scale in range(num_scales):
        scale_name = f"Scale{scale+1}"
        scale_steps = []
        for s in range(num_steps):
            name = f"Step{s+1}"
            step_layer, actnorm_layer = step_flow(
                name=name,
                shift_and_log_scale_fn=template_fn.create_template_fn(name))
            scale_steps.append(step_layer)
            actnorm_layers.append(actnorm_layer)

        layers += [
            fl.SqueezingLayer(name=scale_name),
            fl.ChainLayer(scale_steps, name=scale_name),
            fl.FactorOutLayer(name=scale_name),
        ]

    return layers, actnorm_layers
Exemple #4
0
def step_flow(
    name: str, shift_and_log_scale_fn: Callable[[tf.Tensor], tf.Tensor]
) -> Tuple[fl.ChainLayer, fl.ActnormLayer]:
    """Create single step of the Glow model:

        1. actnorm
        2. invertible conv
        3. affine coupling layer

    Returns:
        step_layer: a flow layer which perform 1-3 operations
        actnorm: a reference of actnorm layer from step 1. This reference can be
            used to initialize this layer using data dependent initialization
    """
    actnorm = fl.ActnormLayer()
    layers = [
        actnorm,
        fl.InvertibleConv1x1Layer(),
        fl.AffineCouplingLayer(shift_and_log_scale_fn=shift_and_log_scale_fn),
    ]
    return fl.ChainLayer(layers, name=name), actnorm
    def test_initialize_actnorms(self):

        np.random.seed(642201)
        images_ph = tf.placeholder(tf.float32, [16, 16, 16, 1])

        layers, actnorm_layers = nets.create_simple_flow(num_steps=1,
                                                         num_scales=3)
        flow = fl.InputLayer(images_ph)
        model_flow = fl.ChainLayer(layers)
        output_flow = model_flow(flow, forward=True)

        noise = np.random.rand(16, 16, 16, 1)

        def feed_dict_fn():
            return {images_ph: noise}

        with self.test_session() as sess:
            sess.run(tf.global_variables_initializer())

            nets.initialize_actnorms(
                sess,
                feed_dict_fn=feed_dict_fn,
                actnorm_layers=actnorm_layers,
                num_steps=50,
            )

            for actnorm_layer in actnorm_layers:

                actnorm_flow = actnorm_layer._forward_outputs[0]
                normed_x = sess.run(actnorm_flow[0],
                                    feed_dict={images_ph: noise})
                nc = normed_x.shape[-1]

                self.assertAllClose(np.var(normed_x.reshape([-1, nc]), axis=0),
                                    [1.0] * nc,
                                    atol=0.1)
                self.assertAllClose(np.mean(normed_x.reshape([-1, nc]),
                                            axis=0), [0.0] * nc,
                                    atol=0.1)
Exemple #6
0
    def test_combine_squeeze_and_factor_layers_conv(self):

        images_np = np.random.rand(8, 32, 32, 1)
        images = tf.to_float(images_np)

        flow = fl.InputLayer(images)
        # in comments are output shapes
        layers = [
            fl.SqueezingLayer(),  # x=[8, 16, 16, 4]
            fl.FactorOutLayer(),  # x=[8, 16, 16, 2]
            fl.SqueezingLayer(),  # x=[8, 8, 8, 8]
            fl.FactorOutLayer(),  # x=[8, 8, 8, 4] z=[8, 8, 8, 12]
        ]

        chain = fl.ChainLayer(layers=layers)
        print()
        with tf_framework.arg_scope([fl.FlowLayer.__call__], forward=True):
            new_flow = chain(flow)
            with self.test_session() as sess:
                x, logdet, z = sess.run(new_flow)
                self.assertEqual(x.shape, (8, 8, 8, 4))
                self.assertEqual(z.shape, (8, 8, 8, 12))

        self.forward_inverse(chain, flow)
Exemple #7
0
    def model_fn(features, labels, mode, params):

        nn_template_fn = nets.OpenAITemplate(
            width=args.width
        )

        layers, actnorm_layers = nets.create_simple_flow(
            num_steps=args.num_steps,
            num_scales=args.num_scales,
            num_bits=args.num_bits,
            template_fn=nn_template_fn
        )

        images = features["images"]
        flow = fl.InputLayer(images)
        model_flow = fl.ChainLayer(layers)
        output_flow = model_flow(flow, forward=True)
        y, logdet, z = output_flow

        for layer in actnorm_layers:
            init_op = layer.get_ddi_init_ops(30)
            tf.add_to_collection(ACTNORM_INIT_OPS, init_op)

        total_params = 0
        trainable_variables = tf.trainable_variables()
        for k, v in enumerate(trainable_variables):
            num_params = np.prod(v.shape.as_list())
            total_params += num_params

        print(f"TOTAL PARAMS: {total_params/1e6} [M]")

        if mode == tf.estimator.ModeKeys.PREDICT:
            raise NotImplementedError()

        tfd = tf.contrib.distributions
        y_flatten = tf.reshape(y, [batch_size, -1])
        z_flatten = tf.reshape(z, [batch_size, -1])

        prior_y = tfd.MultivariateNormalDiag(loc=tf.zeros_like(y_flatten),
                                             scale_diag=tf.ones_like(y_flatten))
        prior_z = tfd.MultivariateNormalDiag(loc=tf.zeros_like(z_flatten),
                                             scale_diag=tf.ones_like(z_flatten))

        log_prob_y = prior_y.log_prob(y_flatten)
        log_prob_z = prior_z.log_prob(z_flatten)

        loss = log_prob_y + log_prob_z + logdet
        # compute loss per pixel, the final loss should be same
        # for different input sizes
        loss = - tf.reduce_mean(loss) / image_size / image_size

        trainable_variables = tf.trainable_variables()
        l2_loss = l2_reg * tf.add_n(
            [tf.nn.l2_loss(v) for v in trainable_variables])

        total_loss = l2_loss + loss

        tf.summary.scalar('total_loss', total_loss)
        tf.summary.scalar('loss', loss)
        tf.summary.scalar('l2_loss', l2_loss)

        # Sampling during training and evaluation
        prior_y = tfd.MultivariateNormalDiag(loc=tf.zeros_like(y_flatten),
                                             scale_diag=sample_beta * tf.ones_like(y_flatten))
        prior_z = tfd.MultivariateNormalDiag(loc=tf.zeros_like(z_flatten),
                                             scale_diag=sample_beta * tf.ones_like(z_flatten))

        sample_y_flatten = prior_y.sample()
        sample_y = tf.reshape(sample_y_flatten, y.shape.as_list())
        sample_z = tf.reshape(prior_z.sample(), z.shape.as_list())
        sampled_logdet = prior_y.log_prob(sample_y_flatten)

        inverse_flow = sample_y, sampled_logdet, sample_z
        sampled_flow = model_flow(inverse_flow, forward=False)
        x_flow_sampled, _, _ = sampled_flow
        # convert to uint8
        quantize_image_layer = layers[0]
        x_flow_sampled_uint = quantize_image_layer.to_uint8(x_flow_sampled)

        grid_image = tf.contrib.gan.eval.image_grid(
            x_flow_sampled_uint,
            grid_shape=[4, batch_size // 4],
            image_shape=(image_size, image_size),
            num_channels=3
        )

        grid_summary = tf.summary.image(
            f'samples{sample_beta}', grid_image, max_outputs=10
        )

        if mode == tf.estimator.ModeKeys.EVAL:
            eval_summary_hook = tf.train.SummarySaverHook(
                save_steps=1,
                output_dir=args.model_dir + "/eval",
                summary_op=grid_summary
            )

            return tf.estimator.EstimatorSpec(
                mode,
                loss=total_loss,
                evaluation_hooks=[eval_summary_hook]
            )

        # Create training op.
        assert mode == tf.estimator.ModeKeys.TRAIN

        train_summary_hook = tf.train.SummarySaverHook(
            save_secs=args.save_secs,
            output_dir=args.model_dir,
            summary_op=grid_summary
        )

        global_step = tf.train.get_global_step()
        learning_rate = tf.train.inverse_time_decay(
            args.lr, global_step, args.decay_steps, args.decay_rate,
            staircase=True
        )

        tf.summary.scalar('learning_rate', learning_rate)

        optimizer = tf.train.AdagradOptimizer(learning_rate=learning_rate)
        if args.clip > 0.0:
            gvs = optimizer.compute_gradients(total_loss)
            capped_gvs = [
                (tf.clip_by_value(grad, -args.clip, args.clip), var) for grad, var in gvs
            ]
            train_op = optimizer.apply_gradients(capped_gvs, global_step=global_step)
        else:
            train_op = optimizer.minimize(total_loss, global_step=global_step)

        return tf.estimator.EstimatorSpec(
            mode, loss=total_loss,
            train_op=train_op, training_hooks=[train_summary_hook]
        )