Example #1
0
    def __init__(self, x_dim, y_dim, z_dim, gen_architecture, disc_architecture, aux_architecture, last_layer_activation,
                 folder="./CWGAN", image_shape=None
        ):
        super(InfoGAN, self).__init__(x_dim, y_dim, z_dim, [gen_architecture, disc_architecture, aux_architecture],
                                   last_layer_activation, folder, image_shape, None)

        self._gen_architecture = self._architectures[0]
        self._disc_architecture = self._architectures[1]
        self._aux_architecture = self._architectures[2]

        ################# Define architecture
        self._gen_architecture.append([logged_dense, {"units": x_dim, "activation": tf.nn.sigmoid, "name": "Output"}])
        self._generator = ConditionalGenerator(self._gen_architecture, name="Generator")

        self._disc_architecture.append([logged_dense, {"units": 1, "activation": tf.nn.sigmoid, "name": "Output"}])
        self._disc = Discriminator(self._disc_architecture, name="Discriminator")

        self._aux_architecture.append([logged_dense, {"units": y_dim, "activation": tf.nn.softmax, "name": "Output"}])
        self._aux = Encoder(self._aux_architecture, name="Auxiliary")

        self._nets = [self._generator, self._disc, self._aux]

        ################# Connect inputs and networks
        self._output_gen = self._generator.generate_net(self._mod_Z_input)
        self._output_disc_fake = self._disc.generate_net(self._output_gen)
        self._output_disc_real = self._disc.generate_net(self._X_input)
        self._output_aux = self._aux.generate_net(self._output_gen)

        ################# Finalize
        self._init_folders()
        self._verify_init()
Example #2
0
    def __init__(self, x_dim, z_dim, gen_architecture, disc_architecture, folder="./VanillaGan"
        ):
        super(VanillaGAN, self).__init__(x_dim, z_dim, [gen_architecture, disc_architecture], folder)

        self._gen_architecture = self._architectures[0]
        self._gen_architecture[-1][1]["name"] = "Output"
        self._disc_architecture = self._architectures[1]

        ################# Define architecture
        self._generator = Generator(self._gen_architecture, name="Generator")

        self._disc_architecture.append([logged_dense, {"units": 1, "activation": tf.nn.sigmoid, "name": "Output"}])
        self._discriminator = Discriminator(self._disc_architecture, name="Discriminator")

        self._nets = [self._generator, self._discriminator]

        ################# Connect inputs and networks
        self._output_gen = self._generator.generate_net(self._Z_input)
        self._output_disc_fake = self._discriminator.generate_net(self._output_gen)
        self._output_disc_real = self._discriminator.generate_net(self._X_input)

        ################# Finalize
        self._init_folders()
        self._verify_init()
Example #3
0
    def __init__(self, x_dim, y_dim, gen_xy_architecture, disc_xy_architecture,
                    gen_yx_architecture, disc_yx_architecture,
                    folder="./CycleGAN", PatchGAN=False, is_wasserstein=False
        ):
        super(CycleGAN, self).__init__(x_dim, y_dim,
                                [gen_xy_architecture, disc_xy_architecture, gen_yx_architecture, disc_yx_architecture],
                                folder, y_dim)

        self._gen_xy_architecture = self._architectures[0]
        self._disc_xy_architecture = self._architectures[1]
        self._gen_yx_architecture = self._architectures[2]
        self._disc_yx_architecture = self._architectures[3]
        self._is_patchgan = PatchGAN
        self._is_wasserstein = is_wasserstein

        ################# Define architecture

        if self._is_patchgan:
            f_xy = self._disc_xy_architecture[-1][-1]["filters"]
            assert f_xy == 1, "If is PatchGAN, last layer of Discriminator_XY needs 1 filter. Given: {}.".format(f_xy)
            f_yx = self._disc_yx_architecture[-1][-1]["filters"]
            assert f_yx == 1, "If is PatchGAN, last layer of Discriminator_YX needs 1 filter. Given: {}.".format(f_yx)

            a_xy = self._disc_xy_architecture[-1][-1]["activation"]
            assert a_xy == tf.nn.sigmoid, "If is PatchGAN, last layer of Discriminator_XY needs tf.nn.sigmoid. Given: {}.".format(a_xy)
            a_yx = self._disc_yx_architecture[-1][-1]["activation"]
            assert a_yx == tf.nn.sigmoid, "If is PatchGAN, last layer of Discriminator_YX needs tf.nn.sigmoid. Given: {}.".format(a_yx)
        else:
            self._disc_xy_architecture.append([tf.layers.flatten, {"name": "Flatten"}])
            if self._is_wasserstein:
                self._disc_xy_architecture.append([logged_dense, {"units": 1, "activation": tf.identity, "name": "Output"}])
            else:
                self._disc_xy_architecture.append([logged_dense, {"units": 1, "activation": tf.sigmoid, "name": "Output"}])

            self._disc_yx_architecture.append([tf.layers.flatten, {"name": "Flatten"}])
            if self._is_wasserstein:
                self._disc_yx_architecture.append([logged_dense, {"units": 1, "activation": tf.identity, "name": "Output"}])
            else:
                self._disc_yx_architecture.append([logged_dense, {"units": 1, "activation": tf.sigmoid, "name": "Output"}])


        self._gen_xy_architecture[-1][1]["name"] = "Output_XY"
        self._gen_yx_architecture[-1][1]["name"] = "Output_YX"


        self._generator_xy = Generator(self._gen_xy_architecture, name="Generator_XY")
        self._discriminator_xy = Discriminator(self._disc_xy_architecture, name="Discriminator_XY")
        self._generator_yx = Generator(self._gen_yx_architecture, name="Generator_YX")
        self._discriminator_yx = Discriminator(self._disc_yx_architecture, name="Discriminator_YX")

        self._nets = [self._generator_xy, self._discriminator_xy, self._generator_yx, self._discriminator_yx]

        ################# Connect inputs and networks
        self._output_gen_xy = self._generator_xy.generate_net(self._X_input, tf_trainflag=self._is_training)
        self._output_gen_yx = self._generator_yx.generate_net(self._Y_input, tf_trainflag=self._is_training)

        self._output_disc_xy_real = self._discriminator_xy.generate_net(self._Y_input, tf_trainflag=self._is_training)
        self._output_disc_xy_fake = self._discriminator_xy.generate_net(self._output_gen_xy, tf_trainflag=self._is_training)

        self._output_disc_yx_real = self._discriminator_yx.generate_net(self._X_input, tf_trainflag=self._is_training)
        self._output_disc_yx_fake = self._discriminator_yx.generate_net(self._output_gen_yx, tf_trainflag=self._is_training)

        self._output_gen_xyx = self._generator_yx.generate_net(self._output_gen_xy, tf_trainflag=self._is_training)
        self._output_gen_yxy = self._generator_xy.generate_net(self._output_gen_yx, tf_trainflag=self._is_training)

        if self._is_patchgan:
            print("PATCHGAN chosen with output: {}.".format(self._output_disc_xy_real.shape))

        ################# Finalize

        self._init_folders()
        self._verify_init()
Example #4
0
class CycleGAN(CyclicGenerativeModel):
    def __init__(self, x_dim, y_dim, gen_xy_architecture, disc_xy_architecture,
                    gen_yx_architecture, disc_yx_architecture,
                    folder="./CycleGAN", PatchGAN=False, is_wasserstein=False
        ):
        super(CycleGAN, self).__init__(x_dim, y_dim,
                                [gen_xy_architecture, disc_xy_architecture, gen_yx_architecture, disc_yx_architecture],
                                folder, y_dim)

        self._gen_xy_architecture = self._architectures[0]
        self._disc_xy_architecture = self._architectures[1]
        self._gen_yx_architecture = self._architectures[2]
        self._disc_yx_architecture = self._architectures[3]
        self._is_patchgan = PatchGAN
        self._is_wasserstein = is_wasserstein

        ################# Define architecture

        if self._is_patchgan:
            f_xy = self._disc_xy_architecture[-1][-1]["filters"]
            assert f_xy == 1, "If is PatchGAN, last layer of Discriminator_XY needs 1 filter. Given: {}.".format(f_xy)
            f_yx = self._disc_yx_architecture[-1][-1]["filters"]
            assert f_yx == 1, "If is PatchGAN, last layer of Discriminator_YX needs 1 filter. Given: {}.".format(f_yx)

            a_xy = self._disc_xy_architecture[-1][-1]["activation"]
            assert a_xy == tf.nn.sigmoid, "If is PatchGAN, last layer of Discriminator_XY needs tf.nn.sigmoid. Given: {}.".format(a_xy)
            a_yx = self._disc_yx_architecture[-1][-1]["activation"]
            assert a_yx == tf.nn.sigmoid, "If is PatchGAN, last layer of Discriminator_YX needs tf.nn.sigmoid. Given: {}.".format(a_yx)
        else:
            self._disc_xy_architecture.append([tf.layers.flatten, {"name": "Flatten"}])
            if self._is_wasserstein:
                self._disc_xy_architecture.append([logged_dense, {"units": 1, "activation": tf.identity, "name": "Output"}])
            else:
                self._disc_xy_architecture.append([logged_dense, {"units": 1, "activation": tf.sigmoid, "name": "Output"}])

            self._disc_yx_architecture.append([tf.layers.flatten, {"name": "Flatten"}])
            if self._is_wasserstein:
                self._disc_yx_architecture.append([logged_dense, {"units": 1, "activation": tf.identity, "name": "Output"}])
            else:
                self._disc_yx_architecture.append([logged_dense, {"units": 1, "activation": tf.sigmoid, "name": "Output"}])


        self._gen_xy_architecture[-1][1]["name"] = "Output_XY"
        self._gen_yx_architecture[-1][1]["name"] = "Output_YX"


        self._generator_xy = Generator(self._gen_xy_architecture, name="Generator_XY")
        self._discriminator_xy = Discriminator(self._disc_xy_architecture, name="Discriminator_XY")
        self._generator_yx = Generator(self._gen_yx_architecture, name="Generator_YX")
        self._discriminator_yx = Discriminator(self._disc_yx_architecture, name="Discriminator_YX")

        self._nets = [self._generator_xy, self._discriminator_xy, self._generator_yx, self._discriminator_yx]

        ################# Connect inputs and networks
        self._output_gen_xy = self._generator_xy.generate_net(self._X_input, tf_trainflag=self._is_training)
        self._output_gen_yx = self._generator_yx.generate_net(self._Y_input, tf_trainflag=self._is_training)

        self._output_disc_xy_real = self._discriminator_xy.generate_net(self._Y_input, tf_trainflag=self._is_training)
        self._output_disc_xy_fake = self._discriminator_xy.generate_net(self._output_gen_xy, tf_trainflag=self._is_training)

        self._output_disc_yx_real = self._discriminator_yx.generate_net(self._X_input, tf_trainflag=self._is_training)
        self._output_disc_yx_fake = self._discriminator_yx.generate_net(self._output_gen_yx, tf_trainflag=self._is_training)

        self._output_gen_xyx = self._generator_yx.generate_net(self._output_gen_xy, tf_trainflag=self._is_training)
        self._output_gen_yxy = self._generator_xy.generate_net(self._output_gen_yx, tf_trainflag=self._is_training)

        if self._is_patchgan:
            print("PATCHGAN chosen with output: {}.".format(self._output_disc_xy_real.shape))

        ################# Finalize

        self._init_folders()
        self._verify_init()


    def compile(self, learning_rate=0.00005, learning_rate_gen=None, learning_rate_disc=None,
                    optimizer=tf.train.AdamOptimizer, lmbda=10, loss="cross-entropy"):
        if self._is_wasserstein and loss != "wasserstein":
            raise ValueError("If is_wasserstein is true in Constructor, loss needs to be wasserstein.")
        if not self._is_wasserstein and loss == "wasserstein":
            raise ValueError("If loss is wasserstein, is_wasserstein needs to be true in constructor.")

        if learning_rate_gen is None:
            learning_rate_gen = learning_rate
        if learning_rate_disc is None:
            learning_rate_disc = learning_rate
        self._define_loss(lmbda, loss)
        with tf.name_scope("Optimizer"):
            gen_optimizer = optimizer(learning_rate=learning_rate_gen)
            self._gen_optimizer = gen_optimizer.minimize(self._gen_loss,
                                                         var_list=self._get_vars(scope="Generator_XY")+self._get_vars(scope="Generator_YX"),
                                                         name="Generator")
            disc_optimizer = optimizer(learning_rate=learning_rate_disc)
            self._disc_optimizer = disc_optimizer.minimize(self._disc_loss,
                                                            var_list=self._get_vars(scope="Discriminator_XY")+self._get_vars(scope="Discriminator_YX"),
                                                            name="Discriminator")
        self._summarise()


    def _define_loss(self, lmbda, loss):
        possible_losses = ["cross-entropy", "L1", "L2", "wasserstein"]
        if loss == "wasserstein":
            self._gen_loss_xy = -tf.reduce_mean(self._output_disc_xy_fake)
            self._gen_loss_yx = -tf.reduce_mean(self._output_disc_yx_fake)

            self._disc_loss_xy = (-(tf.reduce_mean(self._output_disc_xy_real) -
                                    tf.reduce_mean(self._output_disc_xy_fake)) +
                                    10*self._define_gradient_penalty_xy()
            )
            self._disc_loss_yx = (-(tf.reduce_mean(self._output_disc_yx_real) -
                                    tf.reduce_mean(self._output_disc_yx_fake)) +
                                    10*self._define_gradient_penalty_yx()
            )
        elif loss == "cross-entropy":
            logits_xy_real = tf.math.log(self._output_disc_xy_real / (1 - self._output_disc_xy_real))
            logits_yx_real = tf.math.log(self._output_disc_yx_real / (1 - self._output_disc_yx_real))
            logits_xy_fake = tf.math.log(self._output_disc_xy_fake / (1 - self._output_disc_xy_fake))
            logits_yx_fake = tf.math.log(self._output_disc_yx_fake / (1 - self._output_disc_yx_fake))

            self._gen_loss_xy = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
                                        labels=tf.ones_like(logits_xy_fake), logits=logits_xy_fake
            ))

            self._gen_loss_yx = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
                                        labels=tf.ones_like(logits_yx_fake), logits=logits_yx_fake
            ))

            self._disc_loss_xy = tf.reduce_mean(
                                    tf.nn.sigmoid_cross_entropy_with_logits(
                                        labels=tf.ones_like(logits_xy_real), logits=logits_xy_real
                                    ) +
                                    tf.nn.sigmoid_cross_entropy_with_logits(
                                        labels=tf.zeros_like(logits_xy_fake), logits=logits_xy_fake
                                    )
            )
            self._disc_loss_yx = tf.reduce_mean(
                                    tf.nn.sigmoid_cross_entropy_with_logits(
                                        labels=tf.ones_like(logits_yx_real), logits=logits_yx_real
                                    ) +
                                    tf.nn.sigmoid_cross_entropy_with_logits(
                                        labels=tf.zeros_like(logits_yx_fake), logits=logits_yx_fake
                                    )
            )

        elif loss == "L1":
            self._gen_loss_xy = tf.reduce_mean(tf.abs(self._output_disc_xy_fake - tf.ones_like(self._output_disc_xy_fake)))
            self._gen_loss_yx = tf.reduce_mean(tf.abs(self._output_disc_yx_fake - tf.ones_like(self._output_disc_yx_fake)))

            self._disc_loss_xy = (
                        tf.reduce_mean(
                                        tf.abs(self._output_disc_xy_real - tf.ones_like(self._output_disc_xy_real)) +
                                        tf.abs(self._output_disc_xy_fake)
                        )
            ) / 2.0
            self._disc_loss_yx = (
                        tf.reduce_mean(
                                        tf.abs(self._output_disc_yx_real - tf.ones_like(self._output_disc_yx_real)) +
                                        tf.abs(self._output_disc_yx_fake)
                        )
            ) / 2.0

        elif loss == "L2":
            self._gen_loss_xy = tf.reduce_mean(tf.square(self._output_disc_xy_fake - tf.ones_like(self._output_disc_xy_fake)))
            self._gen_loss_yx = tf.reduce_mean(tf.square(self._output_disc_yx_fake - tf.ones_like(self._output_disc_yx_fake)))

            self._disc_loss_xy = (
                        tf.reduce_mean(
                                        tf.square(self._output_disc_xy_real - tf.ones_like(self._output_disc_xy_real)) +
                                        tf.square(self._output_disc_xy_fake)
                        )
            ) / 2.0
            self._disc_loss_yx = (
                        tf.reduce_mean(
                                        tf.square(self._output_disc_yx_real - tf.ones_like(self._output_disc_yx_real)) +
                                        tf.square(self._output_disc_yx_fake)
                        )
            ) / 2.0

        else:
            raise ValueError("Loss not implemented. Choose from {}. Given: {}.".format(possible_losses, loss))

        with tf.name_scope("Loss") as scope:
            self._gen_loss_vanilla = self._gen_loss_xy + self._gen_loss_yx
            tf.summary.scalar("Generator_vanilla_loss_xy", self._gen_loss_xy)
            tf.summary.scalar("Generator_vanilla_loss_yx", self._gen_loss_yx)
            tf.summary.scalar("Generator_vanilla_loss", self._gen_loss_vanilla)

            self._recon_loss_xyx = lmbda*tf.reduce_mean(tf.abs(self._X_input - self._output_gen_xyx))
            self._recon_loss_yxy = lmbda*tf.reduce_mean(tf.abs(self._Y_input - self._output_gen_yxy))
            self._recon_loss = self._recon_loss_xyx + self._recon_loss_yxy
            tf.summary.scalar("Generator_recon_loss_xyx", self._recon_loss_xyx)
            tf.summary.scalar("Generator_recon_loss_yxy", self._recon_loss_yxy)
            tf.summary.scalar("Generator_recon_loss", self._recon_loss)

            self._gen_loss = self._gen_loss_vanilla + self._recon_loss
            tf.summary.scalar("Generator_total_loss", self._gen_loss)

            self._disc_loss = self._disc_loss_xy + self._disc_loss_yx
            tf.summary.scalar("Discriminator_loss_xy", self._disc_loss_xy)
            tf.summary.scalar("Discriminator_loss_yx", self._disc_loss_yx)
            tf.summary.scalar("Discriminator_loss", self._disc_loss)


        self._losses = {name: [] for name in ["Gen_XY", "Gen_YX", "Gen_Vanilla",
                                                "Gen_XYX", "Gen_YXY", "Gen_Recon", "Generator",
                                                "Disc_XY", "Disc_YX", "Discriminator"]}


    def _define_gradient_penalty_xy(self):
        alpha = tf.random_uniform(shape=tf.shape(self._Y_input), minval=0., maxval=1.)
        differences = self._output_gen_xy - self._Y_input
        interpolates = self._Y_input + (alpha * differences)
        gradients = tf.gradients(self._discriminator_xy.generate_net(interpolates, tf_trainflag=self._is_training), [interpolates])[0]
        slopes = tf.sqrt(tf.reduce_sum(tf.square(gradients)))
        with tf.name_scope("Loss") as scope:
            self._gradient_penalty_xy = tf.reduce_mean((slopes-1.)**2)
            tf.summary.scalar("Gradient_penalty_xy", self._gradient_penalty_xy)
        return self._gradient_penalty_xy


    def _define_gradient_penalty_yx(self):
        alpha = tf.random_uniform(shape=tf.shape(self._X_input), minval=0., maxval=1.)
        differences = self._output_gen_yx - self._X_input
        interpolates = self._X_input + (alpha * differences)
        gradients = tf.gradients(self._discriminator_yx.generate_net(interpolates, tf_trainflag=self._is_training), [interpolates])[0]
        slopes = tf.sqrt(tf.reduce_sum(tf.square(gradients)))
        with tf.name_scope("Loss") as scope:
            self._gradient_penalty_yx = tf.reduce_mean((slopes-1.)**2)
            tf.summary.scalar("Gradient_penalty_yx", self._gradient_penalty_yx)
        return self._gradient_penalty_yx


    def train(self, x_train, y_train, x_test=None, y_test=None, epochs=100, batch_size=64,
              gen_steps=1, disc_steps=5, steps=None, log_step=3, gpu_options=None, shuffle=True):
        if steps is not None:
            gen_steps = 1
            disc_steps = steps
        self._set_up_training(log_step=log_step, gpu_options=gpu_options)
        self._set_up_test_train_sample(x_train, y_train, x_test, y_test)
        self._log_results(epoch=0, epoch_time=0)
        nr_batches = np.floor(len(x_train) / batch_size)

        for epoch in range(epochs):
            batch_nr = 0
            disc_loss_epoch = 0
            gen_loss_epoch = 0
            start = time.clock()
            trained_examples = 0
            while trained_examples < len(x_train):
                disc_loss_batch, gen_loss_batch = self._optimize(self._trainset, batch_size, disc_steps, gen_steps, shuffle)
                trained_examples += batch_size

                disc_loss_epoch += disc_loss_batch
                gen_loss_epoch += gen_loss_batch

            disc_loss_epoch /= nr_batches
            gen_loss_epoch /= nr_batches
            print("D, D_XY, D_YX: ", self._sess.run([self._disc_loss, self._disc_loss_xy, self._disc_loss_yx],
                                                     feed_dict={self._X_input: x_test, self._Y_input: y_test, self._is_training: False}))
            print("G, G_XY, G_YX: ", self._sess.run([self._gen_loss_vanilla, self._gen_loss_xy, self._gen_loss_yx],
                                                     feed_dict={self._X_input: x_test, self._Y_input: y_test, self._is_training: False}))
            print("R, R_XYX, R_YXY: ", self._sess.run([self._recon_loss, self._recon_loss_xyx, self._recon_loss_yxy],
                                                     feed_dict={self._X_input: x_test, self._Y_input: y_test, self._is_training: False}))
            print("G Total: ", self._sess.run([self._gen_loss],
                                                     feed_dict={self._X_input: x_test, self._Y_input: y_test, self._is_training: False}))

            epoch_train_time = (time.clock() - start)/60
            disc_loss_epoch = np.round(disc_loss_epoch, 7)
            gen_loss_epoch = np.round(gen_loss_epoch, 7)

            print("Epoch {}: Discrimiantor: {} \n\t\t\tGenerator: {}.".format(epoch+1, disc_loss_epoch, gen_loss_epoch))

            if self._log_step is not None:
                self._log(epoch+1, epoch_train_time)


    def _optimize(self, dataset, batch_size, disc_steps, gen_steps, shuffle):
        d_loss = 0
        for i in range(disc_steps):
            if shuffle:
                current_batch_x, _ = dataset._sample_xy(n=batch_size)
                _, current_batch_y = dataset._sample_xy(n=batch_size)
            else:
                current_batch_x, current_batch_y = dataset.get_next_batch(batch_size)
            _, disc_loss_batch = self._sess.run([
                                            self._disc_optimizer, self._disc_loss
                                            ],
                                            feed_dict={self._X_input: current_batch_x, self._Y_input: current_batch_y,
                                            self._is_training: True})
            d_loss += disc_loss_batch
        d_loss /= disc_steps

        g_loss = 0
        for _ in range(gen_steps):
            if shuffle:
                current_batch_x, _ = dataset._sample_xy(n=batch_size)
                _, current_batch_y = dataset._sample_xy(n=batch_size)
            else:
                current_batch_x, current_batch_y = dataset.get_next_batch(batch_size)
            _, gen_loss_batch = self._sess.run([self._gen_optimizer, self._gen_loss],
                                               feed_dict={self._X_input: current_batch_x, self._Y_input: current_batch_y,
                                               self._is_training: True})
            g_loss += gen_loss_batch
        g_loss /= gen_steps
        return d_loss, g_loss
Example #5
0
class VanillaGAN(GenerativeModel):
    def __init__(self, x_dim, z_dim, gen_architecture, disc_architecture, folder="./VanillaGan"
        ):
        super(VanillaGAN, self).__init__(x_dim, z_dim, [gen_architecture, disc_architecture], folder)

        self._gen_architecture = self._architectures[0]
        self._gen_architecture[-1][1]["name"] = "Output"
        self._disc_architecture = self._architectures[1]

        ################# Define architecture
        self._generator = Generator(self._gen_architecture, name="Generator")

        self._disc_architecture.append([logged_dense, {"units": 1, "activation": tf.nn.sigmoid, "name": "Output"}])
        self._discriminator = Discriminator(self._disc_architecture, name="Discriminator")

        self._nets = [self._generator, self._discriminator]

        ################# Connect inputs and networks
        self._output_gen = self._generator.generate_net(self._Z_input)
        self._output_disc_fake = self._discriminator.generate_net(self._output_gen)
        self._output_disc_real = self._discriminator.generate_net(self._X_input)

        ################# Finalize
        self._init_folders()
        self._verify_init()


    def compile(self, learning_rate_gen=0.0002, learning_rate_disc=0.0002, optimizer=tf.train.AdamOptimizer):
        self._define_loss()
        with tf.name_scope("Optimizer"):
            gen_optimizer = optimizer(learning_rate=learning_rate_gen)
            self._gen_optimizer = gen_optimizer.minimize(self._gen_loss, var_list=self._get_vars(scope="Generator"), name="Generator")
            disc_optimizer = optimizer(learning_rate=learning_rate_disc)
            self._disc_optimizer = disc_optimizer.minimize(self._disc_loss, var_list=self._get_vars(scope="Discriminator"), name="Discriminator")
        self._summarise()


    def _define_loss(self):
        with tf.name_scope("Loss") as scope:
            self._gen_loss = -tf.reduce_mean(tf.log(self._output_disc_fake+0.0001))
            tf.summary.scalar("Generator_loss", self._gen_loss)
            self._disc_loss = -tf.reduce_mean(tf.log(self._output_disc_real+0.0001) + tf.log(1.0-self._output_disc_fake+0.0001))
            tf.summary.scalar("Discriminator_loss", self._disc_loss)


    def train(self, x_train, x_test=None, epochs=100, batch_size=64, gen_steps=1, disc_steps=1, log_step=3):
        self._set_up_training(log_step=log_step)
        self._set_up_test_train_sample(x_train, x_test)
        for epoch in range(epochs):
            batch_nr = 0
            disc_loss_epoch = 0
            gen_loss_epoch = 0
            start = time.clock()
            trained_examples = 0
            while trained_examples < len(x_train):
                disc_loss_batch, gen_loss_batch = self._optimize(self._trainset, batch_size, disc_steps, gen_steps)
                trained_examples += batch_size

                disc_loss_epoch += disc_loss_batch
                gen_loss_epoch += gen_loss_batch

            epoch_train_time = (time.clock() - start)/60
            disc_loss_epoch = np.round(disc_loss_epoch, 2)
            gen_loss_epoch = np.round(gen_loss_epoch, 2)

            self._real_images_predicted_real = self.get_accuracy(self._x_test, np.ones(self._x_test.shape[0]), is_encoded=False)
            self._fake_images_predicted_real = self.get_accuracy(self._z_test, np.ones(self._x_test.shape[0]), is_encoded=True)
            print("Epoch {}: Discriminator: {} ({})\n\t\t\tGenerator: {} ({}).".format(epoch, disc_loss_epoch,
                                                                                       self._real_images_predicted_real, gen_loss_epoch,
                                                                                       self._fake_images_predicted_real))

            if log_step is not None:
                self._log(epoch, epoch_train_time)


    def _optimize(self, dataset, batch_size, disc_steps, gen_steps):
        for i in range(disc_steps):
            current_batch_x = dataset.get_next_batch(batch_size)
            Z_noise = self.sample_noise(n=len(current_batch_x))
            _, disc_loss_batch = self._sess.run([self._disc_optimizer, self._disc_loss], feed_dict={self._X_input: current_batch_x, self._Z_input: Z_noise})

        for _ in range(gen_steps):
            Z_noise = self.sample_noise(n=len(current_batch_x))
            _, gen_loss_batch = self._sess.run([self._gen_optimizer, self._gen_loss], feed_dict={self._Z_input: Z_noise})
        return disc_loss_batch, gen_loss_batch


    def get_accuracy(self, inpt_x, labels, is_encoded):
        if is_encoded:
            inpt_x = self.generate_samples(inpt=inpt_x)
        return self._discriminator.get_accuracy(inpt_x, labels, self._sess)


    def predict(self, inpt_x, is_encoded):
        if is_encoded:
            inpt_x = self.generate_samples(inpt=inpt_x)
        return self._discriminator.predict(inpt_x, self._sess)
Example #6
0
class InfoGAN(ConditionalGenerativeModel):
    def __init__(self, x_dim, y_dim, z_dim, gen_architecture, disc_architecture, aux_architecture, last_layer_activation,
                 folder="./CWGAN", image_shape=None
        ):
        super(InfoGAN, self).__init__(x_dim, y_dim, z_dim, [gen_architecture, disc_architecture, aux_architecture],
                                   last_layer_activation, folder, image_shape, None)

        self._gen_architecture = self._architectures[0]
        self._disc_architecture = self._architectures[1]
        self._aux_architecture = self._architectures[2]

        ################# Define architecture
        self._gen_architecture.append([logged_dense, {"units": x_dim, "activation": tf.nn.sigmoid, "name": "Output"}])
        self._generator = ConditionalGenerator(self._gen_architecture, name="Generator")

        self._disc_architecture.append([logged_dense, {"units": 1, "activation": tf.nn.sigmoid, "name": "Output"}])
        self._disc = Discriminator(self._disc_architecture, name="Discriminator")

        self._aux_architecture.append([logged_dense, {"units": y_dim, "activation": tf.nn.softmax, "name": "Output"}])
        self._aux = Encoder(self._aux_architecture, name="Auxiliary")

        self._nets = [self._generator, self._disc, self._aux]

        ################# Connect inputs and networks
        self._output_gen = self._generator.generate_net(self._mod_Z_input)
        self._output_disc_fake = self._disc.generate_net(self._output_gen)
        self._output_disc_real = self._disc.generate_net(self._X_input)
        self._output_aux = self._aux.generate_net(self._output_gen)

        ################# Finalize
        self._init_folders()
        self._verify_init()


    def compile(self, learning_rate=0.0003, learning_rate_gen=None, learning_rate_disc=None, learning_rate_aux=None, optimizer=tf.train.RMSPropOptimizer):
        self._define_loss()
        if learning_rate_gen is None:
            learning_rate_gen = learning_rate
        if learning_rate_disc is None:
            learning_rate_disc = learning_rate
        if learning_rate_aux is None:
            learning_rate_aux = learning_rate
        with tf.name_scope("Optimizer"):
            gen_optimizer = optimizer(learning_rate=learning_rate_gen)
            self._gen_optimizer = gen_optimizer.minimize(self._gen_loss, var_list=self._get_vars(scope="Generator"), name="Generator")
            disc_optimizer = optimizer(learning_rate=learning_rate_disc)
            self._disc_optimizer = disc_optimizer.minimize(self._disc_loss, var_list=self._get_vars(scope="Discriminator"), name="Discriminator")
            aux_optimizer = optimizer(learning_rate=learning_rate_aux)
            self._aux_optimizer = aux_optimizer.minimize(self._aux_loss, var_list=self._get_vars("Auxiliary")+self._get_vars("Generator"), name="Auxiliary")
        self._summarise(logged_labels=np.identity(self._y_dim))


    def _define_loss(self):
        with tf.name_scope("Loss") as scope:
            self._gen_loss = -tf.reduce_mean(tf.log(self._output_disc_fake+0.00001))
            tf.summary.scalar("Generator_loss", self._gen_loss)
            self._disc_loss  = -tf.reduce_mean(tf.log(self._output_disc_real+0.00001) + tf.log(1.0-self._output_disc_fake+0.00001))
            tf.summary.scalar("Discriminator_loss", self._disc_loss)
            self._aux_loss = -tf.reduce_mean(-tf.reduce_sum(tf.log(self._output_aux+0.00001)*self._Y_input, 1))
            tf.summary.scalar("Auxiliary_loss", self._aux_loss)


    def train(self, x_train, epochs=100, batch_size=64, gen_steps=1, disc_steps=1, log_step=3):
        self._set_up_training(log_step=log_step)
        self._trainset = Dataset(x_train)
        nr_test_samples = 5000 if len(x_train) >=5000 else len(x_train)
        self._x_test = self._trainset.sample(nr_test_samples)
        self._y_test = self.sample_condition(n=len(self._x_test))
        self._z_test = self._generator.sample_noise(n=nr_test_samples)
        for epoch in range(epochs):
            batch_nr = 0
            disc_loss_epoch = 0
            gen_loss_epoch = 0
            aux_loss_epoch = 0
            start = time.clock()
            trained_examples = 0
            while trained_examples < len(x_train):
                disc_loss_batch, gen_loss_batch, aux_loss_batch = self._optimize(self._trainset, batch_size, disc_steps, gen_steps)
                trained_examples += batch_size

                disc_loss_epoch += disc_loss_batch
                gen_loss_epoch += gen_loss_batch
                aux_loss_epoch += aux_loss_batch

            epoch_train_time = (time.clock() - start)/60
            disc_loss_epoch = np.round(disc_loss_epoch, 2)
            gen_loss_epoch = np.round(gen_loss_epoch, 2)
            aux_loss_epoch = np.round(aux_loss_epoch, 2)

            print("Epoch {}: Discriminator: {}\n\t\t\tGenerator: {}\n\t\t\tAuxiliary: {}.".format(epoch, disc_loss_epoch, gen_loss_epoch, aux_loss_epoch))

            if log_step is not None:
                self._log(epoch, epoch_train_time)


    def _optimize(self, dataset, batch_size, disc_steps, gen_steps):
        for i in range(disc_steps):
            current_batch_x = dataset.get_next_batch(batch_size)
            Z_noise = self.sample_noise(n=len(current_batch_x))
            C_noise = self.sample_condition(n=len(current_batch_x))
            latent_space = np.concatenate((Z_noise, C_noise), axis=1)
            _, disc_loss_batch = self._sess.run([self._disc_optimizer, self._disc_loss],
                                                feed_dict={self._X_input: current_batch_x, self._Y_input: C_noise, self._Z_input: Z_noise
            })

        for _ in range(gen_steps):
            Z_noise = self.sample_noise(n=len(current_batch_x))
            C_noise = self.sample_condition(n=len(current_batch_x))
            latent_space = np.concatenate((Z_noise, C_noise), axis=1)
            _, gen_loss_batch = self._sess.run([self._gen_optimizer, self._gen_loss], feed_dict={self._Y_input: C_noise, self._Z_input: Z_noise})
            _, aux_loss_batch = self._sess.run([self._aux_optimizer, self._aux_loss], feed_dict={self._Y_input: C_noise, self._Z_input: Z_noise})
        return disc_loss_batch, gen_loss_batch, aux_loss_batch


    def sample_condition(self, n):
        return np.random.multinomial(1, self._y_dim*[1/self._y_dim], size=n)


    def predict(self, inpt_x, is_encoded, inpt_c=None):
        if is_encoded:
            if inpt_c is None:
                raise ValueError("If input is encoded, the conditional input is also needed")
            else:
                input_x = np.concatenate((inpt_x, inpt_c), axis=1)
            inpt_x = self._generator.generate_samples(noise=inpt_x, sess=self._sess)
        return self._disc.predict(inpt_x, self._sess)
Example #7
0
    def __init__(self,
                 x_dim,
                 y_dim,
                 z_dim,
                 gen_architecture,
                 disc_architecture,
                 enc_architecture,
                 last_layer_activation,
                 folder="./Results/CBiGAN_log",
                 image_shape=None,
                 append_y_at_every_layer=None):
        super(CBiGAN, self).__init__(
            x_dim, y_dim, z_dim,
            [gen_architecture, disc_architecture, enc_architecture],
            last_layer_activation, folder, image_shape,
            append_y_at_every_layer)

        self._gen_architecture = self._architectures[0]
        self._disc_architecture = self._architectures[1]
        self._enc_architecture = self._architectures[2]

        ################# Define architecture
        if len(self._x_dim) == 1:
            self._gen_architecture.append([
                logged_dense, {
                    "units": x_dim,
                    "activation": self._last_layer_activation,
                    "name": "Output"
                }
            ])
        else:
            self._disc_architecture.append(
                [tf.layers.flatten, {
                    "name": "Flatten"
                }])
            self._enc_architecture.append(
                [tf.layers.flatten, {
                    "name": "Flatten"
                }])
            self._gen_architecture[-1][1]["name"] = "Output"
        self._disc_architecture.append([
            logged_dense, {
                "units": 1,
                "activation": tf.sigmoid,
                "name": "Output"
            }
        ])
        self._enc_architecture.append([
            logged_dense, {
                "units": z_dim,
                "activation": tf.identity,
                "name": "Output"
            }
        ])

        self._generator = ConditionalGenerator(self._gen_architecture,
                                               name="Generator")
        self._discriminator = Discriminator(self._disc_architecture,
                                            name="Discriminator")
        self._encoder = Encoder(self._enc_architecture, name="Encoder")

        self._nets = [self._generator, self._discriminator, self._encoder]

        ################# Connect inputs and networks
        with tf.name_scope("InputsEncoder"):
            if len(self._x_dim) == 1:
                self._mod_X_input = tf.concat(
                    axis=1,
                    values=[self._X_input, self._Y_input],
                    name="modified_x")
            else:
                self._mod_X_input = image_condition_concat(
                    images=self._X_input, condition=self._Y_input, name="fake")

        self._output_gen = self._generator.generate_net(
            self._mod_Z_input,
            append_elements_at_every_layer=self._append_at_every_layer,
            tf_trainflag=self._is_training)
        self._output_enc = self._encoder.generate_net(
            self._mod_X_input,
            append_elements_at_every_layer=self._append_at_every_layer,
            tf_trainflag=self._is_training)

        with tf.name_scope("InputsCritic"):
            self._mod_output_enc = tf.concat(
                axis=1,
                values=[self._output_enc, self._Y_input],
                name="modified_encoder")
            if len(self._x_dim) == 1:
                self._disc_input_fake = tf.concat(
                    axis=1,
                    values=[self._output_gen, self._mod_Z_input],
                    name="fake")
                self._disc_input_real = tf.concat(
                    axis=1,
                    values=[self._X_input, self._mod_output_enc],
                    name="real")
            else:
                self._disc_input_fake = image_condition_concat(
                    inputs=self._output_gen,
                    condition=self._mod_Z_input,
                    name="fake")
                self._disc_input_real = image_condition_concat(
                    inputs=self._X_input,
                    condition=self._mod_output_enc,
                    name="real")

        self._output_disc_fake = self._discriminator.generate_net(
            self._disc_input_fake,
            append_elements_at_every_layer=self._append_at_every_layer,
            tf_trainflag=self._is_training)
        self._output_disc_real = self._discriminator.generate_net(
            self._disc_input_real,
            append_elements_at_every_layer=self._append_at_every_layer,
            tf_trainflag=self._is_training)

        ################# Finalize
        self._init_folders()
        self._verify_init()
Example #8
0
class CBiGAN(ConditionalGenerativeModel):
    def __init__(self,
                 x_dim,
                 y_dim,
                 z_dim,
                 gen_architecture,
                 disc_architecture,
                 enc_architecture,
                 last_layer_activation,
                 folder="./Results/CBiGAN_log",
                 image_shape=None,
                 append_y_at_every_layer=None):
        super(CBiGAN, self).__init__(
            x_dim, y_dim, z_dim,
            [gen_architecture, disc_architecture, enc_architecture],
            last_layer_activation, folder, image_shape,
            append_y_at_every_layer)

        self._gen_architecture = self._architectures[0]
        self._disc_architecture = self._architectures[1]
        self._enc_architecture = self._architectures[2]

        ################# Define architecture
        if len(self._x_dim) == 1:
            self._gen_architecture.append([
                logged_dense, {
                    "units": x_dim,
                    "activation": self._last_layer_activation,
                    "name": "Output"
                }
            ])
        else:
            self._disc_architecture.append(
                [tf.layers.flatten, {
                    "name": "Flatten"
                }])
            self._enc_architecture.append(
                [tf.layers.flatten, {
                    "name": "Flatten"
                }])
            self._gen_architecture[-1][1]["name"] = "Output"
        self._disc_architecture.append([
            logged_dense, {
                "units": 1,
                "activation": tf.sigmoid,
                "name": "Output"
            }
        ])
        self._enc_architecture.append([
            logged_dense, {
                "units": z_dim,
                "activation": tf.identity,
                "name": "Output"
            }
        ])

        self._generator = ConditionalGenerator(self._gen_architecture,
                                               name="Generator")
        self._discriminator = Discriminator(self._disc_architecture,
                                            name="Discriminator")
        self._encoder = Encoder(self._enc_architecture, name="Encoder")

        self._nets = [self._generator, self._discriminator, self._encoder]

        ################# Connect inputs and networks
        with tf.name_scope("InputsEncoder"):
            if len(self._x_dim) == 1:
                self._mod_X_input = tf.concat(
                    axis=1,
                    values=[self._X_input, self._Y_input],
                    name="modified_x")
            else:
                self._mod_X_input = image_condition_concat(
                    images=self._X_input, condition=self._Y_input, name="fake")

        self._output_gen = self._generator.generate_net(
            self._mod_Z_input,
            append_elements_at_every_layer=self._append_at_every_layer,
            tf_trainflag=self._is_training)
        self._output_enc = self._encoder.generate_net(
            self._mod_X_input,
            append_elements_at_every_layer=self._append_at_every_layer,
            tf_trainflag=self._is_training)

        with tf.name_scope("InputsCritic"):
            self._mod_output_enc = tf.concat(
                axis=1,
                values=[self._output_enc, self._Y_input],
                name="modified_encoder")
            if len(self._x_dim) == 1:
                self._disc_input_fake = tf.concat(
                    axis=1,
                    values=[self._output_gen, self._mod_Z_input],
                    name="fake")
                self._disc_input_real = tf.concat(
                    axis=1,
                    values=[self._X_input, self._mod_output_enc],
                    name="real")
            else:
                self._disc_input_fake = image_condition_concat(
                    inputs=self._output_gen,
                    condition=self._mod_Z_input,
                    name="fake")
                self._disc_input_real = image_condition_concat(
                    inputs=self._X_input,
                    condition=self._mod_output_enc,
                    name="real")

        self._output_disc_fake = self._discriminator.generate_net(
            self._disc_input_fake,
            append_elements_at_every_layer=self._append_at_every_layer,
            tf_trainflag=self._is_training)
        self._output_disc_real = self._discriminator.generate_net(
            self._disc_input_real,
            append_elements_at_every_layer=self._append_at_every_layer,
            tf_trainflag=self._is_training)

        ################# Finalize
        self._init_folders()
        self._verify_init()

    def compile(self,
                logged_images=None,
                logged_labels=None,
                learning_rate=0.0003,
                learning_rate_gen=None,
                learning_rate_disc=None,
                optimizer=tf.train.AdamOptimizer):
        self._define_loss()
        if learning_rate_gen is None:
            learning_rate_gen = learning_rate
        if learning_rate_disc is None:
            learning_rate_disc = learning_rate
        with tf.name_scope("Optimizer"):
            gen_optimizer = optimizer(learning_rate=learning_rate_gen)
            self._gen_optimizer = gen_optimizer.minimize(
                self._gen_loss,
                var_list=self._get_vars(scope="Generator") +
                self._get_vars(scope="Encoder"),
                name="Generator")
            disc_optimizer = optimizer(learning_rate=learning_rate_disc)
            self._disc_optimizer = disc_optimizer.minimize(
                self._disc_loss,
                var_list=self._get_vars(scope="Discriminator"),
                name="Discriminator")
        self._summarise(logged_images=logged_images,
                        logged_labels=logged_labels)

    def _define_loss(self):
        with tf.name_scope("Loss") as scope:
            self._gen_loss = -tf.reduce_mean(
                tf.log(self._output_disc_fake + 0.00001) +
                tf.log(1.0 - self._output_disc_real + 0.00001))
            tf.summary.scalar("Generator_loss", self._gen_loss)
            self._disc_loss = -tf.reduce_mean(
                tf.log(self._output_disc_real + 0.00001) +
                tf.log(1.0 - self._output_disc_fake + 0.00001))
            tf.summary.scalar("Discriminator_loss", self._disc_loss)

    def train(self,
              x_train,
              y_train,
              x_test=None,
              y_test=None,
              epochs=100,
              batch_size=64,
              gen_steps=1,
              disc_steps=1,
              steps=None,
              log_step=3,
              gpu_options=None):
        if steps is not None:
            gen_steps = 1
            disc_steps = steps
        self._set_up_training(log_step=log_step, gpu_options=gpu_options)
        self._set_up_test_train_sample(x_train, y_train, x_test, y_test)
        self._log_results(epoch=0, epoch_time=0)
        for epoch in range(epochs):
            batch_nr = 0
            disc_loss_epoch = 0
            gen_loss_epoch = 0
            start = time.clock()
            trained_examples = 0
            while trained_examples < len(x_train):
                disc_loss_batch, gen_loss_batch = self._optimize(
                    self._trainset, batch_size, disc_steps, gen_steps)
                trained_examples += batch_size

                disc_loss_epoch += disc_loss_batch
                gen_loss_epoch += gen_loss_batch

            epoch_train_time = (time.clock() - start) / 60
            disc_loss_epoch = np.round(disc_loss_epoch, 2)
            gen_loss_epoch = np.round(gen_loss_epoch, 2)

            acc_real = self.get_accuracy(inpt=self._x_test,
                                         inpt_y=self._y_test,
                                         labels=np.ones(len(self._x_test)),
                                         is_encoded=False)
            acc_fake = self.get_accuracy(inpt=self._z_test,
                                         inpt_y=self._y_test,
                                         labels=np.zeros(len(self._z_test)),
                                         is_encoded=True)
            print(
                "Epoch {}: Discriminator: {} ({})\n\t\t\tGenerator: {} ({}).".
                format(epoch, disc_loss_epoch, acc_real, gen_loss_epoch,
                       acc_fake))

            if log_step is not None:
                self._log(epoch + 1, epoch_train_time)

    def _optimize(self, dataset, batch_size, disc_steps, gen_steps):
        for i in range(disc_steps):
            current_batch_x, current_batch_y = dataset.get_next_batch(
                batch_size)
            Z_noise = self.sample_noise(n=len(current_batch_x))
            _, disc_loss_batch = self._sess.run(
                [self._disc_optimizer, self._disc_loss],
                feed_dict={
                    self._X_input: current_batch_x,
                    self._Y_input: current_batch_y,
                    self._Z_input: Z_noise,
                    self._is_training: True
                })

        for _ in range(gen_steps):
            Z_noise = self.sample_noise(n=len(current_batch_x))
            _, gen_loss_batch = self._sess.run(
                [self._gen_optimizer, self._gen_loss],
                feed_dict={
                    self._X_input: current_batch_x,
                    self._Y_input: current_batch_y,
                    self._Z_input: Z_noise,
                    self._is_training: True
                })
        return disc_loss_batch, gen_loss_batch

    def get_accuracy(self, inpt, inpt_y, labels, is_encoded):
        if not is_encoded:
            inpt = self._sess.run(self._disc_input_real,
                                  feed_dict={
                                      self._X_input: inpt,
                                      self._Y_input: inpt_y,
                                      self._is_training: False
                                  })
        else:
            inpt = self._sess.run(self._disc_input_fake,
                                  feed_dict={
                                      self._Z_input: inpt,
                                      self._Y_input: inpt_y,
                                      self._is_training: False
                                  })
        return self._discriminator.get_accuracy(inpt, labels, self._sess)

    def predict(self, inpt_x, inpt_y, is_encoded):
        if not is_encoded:
            inpt_x = self._encoder.encode(inpt=inpt_x, sess=self._sess)
        inpt_x = self._sess.run(self._mod_X_input,
                                feed_dict={
                                    self._X_input: inpt_x,
                                    self._Y_input: inpt_y,
                                    self._is_training: False
                                })
        return self._discriminator.predict(inpt_x, self._sess)

    def generate_image_from_noise(self, n):
        noise = self.sample_noise(n=n)
        return self.generate_samples(noise, self._sess)
Example #9
0
    def __init__(self,
                 x_dim,
                 z_dim,
                 gen_architecture,
                 disc_architecture,
                 enc_architecture,
                 last_layer_activation,
                 folder="./WGAN",
                 image_shape=None):
        super(BiGAN, self).__init__(
            x_dim, z_dim,
            [gen_architecture, disc_architecture, enc_architecture],
            last_layer_activation, folder, image_shape)

        self._gen_architecture = self._architectures[0]
        self._disc_architecture = self._architectures[1]
        self._enc_architecture = self._architectures[2]

        ################# Define architecture
        self._gen_architecture.append([
            logged_dense, {
                "units": x_dim,
                "activation": self._last_layer_activation,
                "name": "Output"
            }
        ])
        self._generator = Generator(self._gen_architecture, name="Generator")

        self._disc_architecture.append([
            logged_dense, {
                "units": 1,
                "activation": tf.nn.sigmoid,
                "name": "Output"
            }
        ])
        self._discriminator = Discriminator(self._disc_architecture,
                                            name="Discriminator")

        self._enc_architecture.append([
            logged_dense, {
                "units": z_dim,
                "activation": tf.identity,
                "name": "Output"
            }
        ])
        self._encoder = Encoder(self._enc_architecture, name="Encoder")

        self._nets = [self._generator, self._discriminator, self._encoder]

        ################# Connect inputs and networks
        self._output_gen = self._generator.generate_net(self._Z_input)
        self._output_enc = self._encoder.generate_net(self._X_input)

        with tf.name_scope("InputsDiscriminator"):
            self._disc_input_fake = tf.concat(
                axis=1, values=[self._output_gen, self._Z_input])
            self._disc_input_real = tf.concat(
                axis=1, values=[self._X_input, self._output_enc])

        self._output_disc_fake = self._discriminator.generate_net(
            self._disc_input_fake)
        self._output_disc_real = self._discriminator.generate_net(
            self._disc_input_real)

        ################# Finalize
        self._init_folders()
        self._verify_init()
Example #10
0
class BiGAN(GenerativeModel):
    def __init__(self,
                 x_dim,
                 z_dim,
                 gen_architecture,
                 disc_architecture,
                 enc_architecture,
                 last_layer_activation,
                 folder="./WGAN",
                 image_shape=None):
        super(BiGAN, self).__init__(
            x_dim, z_dim,
            [gen_architecture, disc_architecture, enc_architecture],
            last_layer_activation, folder, image_shape)

        self._gen_architecture = self._architectures[0]
        self._disc_architecture = self._architectures[1]
        self._enc_architecture = self._architectures[2]

        ################# Define architecture
        self._gen_architecture.append([
            logged_dense, {
                "units": x_dim,
                "activation": self._last_layer_activation,
                "name": "Output"
            }
        ])
        self._generator = Generator(self._gen_architecture, name="Generator")

        self._disc_architecture.append([
            logged_dense, {
                "units": 1,
                "activation": tf.nn.sigmoid,
                "name": "Output"
            }
        ])
        self._discriminator = Discriminator(self._disc_architecture,
                                            name="Discriminator")

        self._enc_architecture.append([
            logged_dense, {
                "units": z_dim,
                "activation": tf.identity,
                "name": "Output"
            }
        ])
        self._encoder = Encoder(self._enc_architecture, name="Encoder")

        self._nets = [self._generator, self._discriminator, self._encoder]

        ################# Connect inputs and networks
        self._output_gen = self._generator.generate_net(self._Z_input)
        self._output_enc = self._encoder.generate_net(self._X_input)

        with tf.name_scope("InputsDiscriminator"):
            self._disc_input_fake = tf.concat(
                axis=1, values=[self._output_gen, self._Z_input])
            self._disc_input_real = tf.concat(
                axis=1, values=[self._X_input, self._output_enc])

        self._output_disc_fake = self._discriminator.generate_net(
            self._disc_input_fake)
        self._output_disc_real = self._discriminator.generate_net(
            self._disc_input_real)

        ################# Finalize
        self._init_folders()
        self._verify_init()

    def compile(self,
                learning_rate=0.0003,
                learning_rate_gen=None,
                learning_rate_disc=None,
                optimizer=tf.train.AdamOptimizer):
        self._define_loss()
        if learning_rate_gen is None:
            learning_rate_gen = learning_rate
        if learning_rate_disc is None:
            learning_rate_disc = learning_rate
        with tf.name_scope("Optimizer"):
            gen_optimizer = optimizer(learning_rate=learning_rate_gen)
            self._gen_optimizer = gen_optimizer.minimize(
                self._gen_loss,
                var_list=self._get_vars(scope="Generator") +
                self._get_vars(scope="Encoder"),
                name="Generator")
            disc_optimizer = optimizer(learning_rate=learning_rate_disc)
            self._disc_optimizer = disc_optimizer.minimize(
                self._disc_loss,
                var_list=self._get_vars(scope="Discriminator"),
                name="Discriminator")
        self._summarise()

    def _define_loss(self):
        with tf.name_scope("Loss") as scope:
            self._gen_loss = -tf.reduce_mean(
                tf.log(self._output_disc_fake + 0.00001) +
                tf.log(1.0 - self._output_disc_real + 0.00001))
            tf.summary.scalar("Generator_loss", self._gen_loss)
            self._disc_loss = -tf.reduce_mean(
                tf.log(self._output_disc_real + 0.00001) +
                tf.log(1.0 - self._output_disc_fake + 0.00001))
            tf.summary.scalar("Discriminator_loss", self._disc_loss)

    def train(self,
              x_train,
              x_test=None,
              epochs=100,
              batch_size=64,
              gen_steps=1,
              disc_steps=1,
              log_step=3):
        self._set_up_training(log_step=log_step)
        self._set_up_test_train_sample(x_train, x_test)
        for epoch in range(epochs):
            batch_nr = 0
            disc_loss_epoch = 0
            gen_loss_epoch = 0
            start = time.clock()
            trained_examples = 0
            while trained_examples < len(x_train):
                disc_loss_batch, gen_loss_batch = self._optimize(
                    self._trainset, batch_size, disc_steps, gen_steps)
                trained_examples += batch_size

                disc_loss_epoch += disc_loss_batch
                gen_loss_epoch += gen_loss_batch

            epoch_train_time = (time.clock() - start) / 60
            disc_loss_epoch = np.round(disc_loss_epoch, 2)
            gen_loss_epoch = np.round(gen_loss_epoch, 2)

            acc_real = self.get_accuracy(inpt_x=self._x_test,
                                         labels=np.ones(len(self._x_test)))
            acc_fake = np.round(
                100 - self.get_accuracy(inpt_x=self._z_test,
                                        labels=np.zeros(len(self._z_test))), 2)
            print(
                "Epoch {}: Discriminator: {} ({})\n\t\t\tGenerator: {} ({}).".
                format(epoch, disc_loss_epoch, acc_real, gen_loss_epoch,
                       acc_fake))

            if log_step is not None:
                self._log(epoch, epoch_train_time)

    def _optimize(self, dataset, batch_size, disc_steps, gen_steps):
        for i in range(disc_steps):
            current_batch_x = dataset.get_next_batch(batch_size)
            Z_noise = self.sample_noise(n=len(current_batch_x))
            _, disc_loss_batch = self._sess.run(
                [self._disc_optimizer, self._disc_loss],
                feed_dict={
                    self._X_input: current_batch_x,
                    self._Z_input: Z_noise
                })

        for _ in range(gen_steps):
            Z_noise = self.sample_noise(n=len(current_batch_x))
            _, gen_loss_batch = self._sess.run(
                [self._gen_optimizer, self._gen_loss],
                feed_dict={
                    self._X_input: current_batch_x,
                    self._Z_input: Z_noise
                })
        return disc_loss_batch, gen_loss_batch

    def get_accuracy(self, inpt_x, labels):
        if labels[0] == 0:
            inpt_image = self._sess.run(self._output_gen,
                                        feed_dict={self._Z_input: inpt_x})
            inpt_x = np.concatenate((inpt_image, inpt_x), axis=1)
        else:
            inpt_encoding = self._encoder.encode(inpt=inpt_x, sess=self._sess)
            inpt_x = np.concatenate((inpt_x, inpt_encoding), axis=1)
        return self._discriminator.get_accuracy(inpt_x, labels, self._sess)

    def predict(self, inpt_x, is_encoded):
        if is_encoded:
            inpt_image = self._generator.generate_samples(noise=inpt_x,
                                                          sess=self._sess)
            inpt_x = np.concatenate((inpt_image, inpt_x), axis=1)
        else:
            inpt_encoding = self._generator.generate_samples(noise=inpt_x,
                                                             sess=self._sess)
            inpt_x = np.concatenate((inpt_x, inpt_encoding), axis=1)
        return self._discriminator.predict(inpt_x, self._sess)

    def generate_image_from_noise(self, n):
        noise = self.sample_noise(n=n)
        return self.generate_samples(noise, self._sess)

    def generate_image_from_image(self, inpt_x):
        encoding = self._encoder.encode(inpt=inpt_x, sess=self._sess)
        return self._generator.generate_samples(encoding, self._sess)