class CVAE(ConditionalGenerativeModel): def __init__(self, x_dim, y_dim, z_dim, dec_architecture, enc_architecture, last_layer_activation, folder="./VAE", image_shape=None, append_y_at_every_layer=None): super(CVAE, self).__init__(x_dim, y_dim, z_dim, [dec_architecture, enc_architecture], last_layer_activation, folder, image_shape, append_y_at_every_layer) self._gen_architecture = self._architectures[0] self._enc_architecture = self._architectures[1] ################# 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._enc_architecture.append( [tf.layers.flatten, { "name": "Flatten" }]) self._gen_architecture[-1][1]["name"] = "Output" last_layer_mean = [ logged_dense, { "units": z_dim, "activation": tf.identity, "name": "Mean" } ] last_layer_std = [ logged_dense, { "units": z_dim, "activation": tf.identity, "name": "Std" } ] self._encoder_mean = Encoder(self._enc_architecture + [last_layer_mean], name="Encoder") self._encoder_std = Encoder(self._enc_architecture + [last_layer_std], name="Encoder") self._generator = ConditionalDecoder(self._gen_architecture, name="Generator") self._nets = [self._generator, self._encoder_mean] ################# 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="real") else: self._mod_X_input = image_condition_concat( inputs=self._X_input, condition=self._Y_input, name="real") self._mean_layer = self._encoder_mean.generate_net( self._mod_X_input, append_elements_at_every_layer=self._append_at_every_layer, tf_trainflag=self._is_training) self._std_layer = self._encoder_std.generate_net( self._mod_X_input, append_elements_at_every_layer=self._append_at_every_layer, tf_trainflag=self._is_training) self._output_enc = self._mean_layer + tf.exp( 0.5 * self._std_layer) * self._Z_input with tf.name_scope("InputsGenerator"): self._dec_input = tf.concat( axis=1, values=[self._output_enc, self._Y_input], name="latent") self._output_dec = self._generator.generate_net( self._dec_input, append_elements_at_every_layer=self._append_at_every_layer, tf_trainflag=self._is_training) self._output_dec_from_encoding = self._generator.generate_net( self._mod_Z_input, 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.0001, optimizer=tf.train.AdamOptimizer): self._define_loss() with tf.name_scope("Optimizer"): vae_optimizer = optimizer(learning_rate=learning_rate) self._vae_optimizer = vae_optimizer.minimize(self._vae_loss, name="VAE") self._summarise(logged_images=logged_images, logged_labels=logged_labels) def _define_loss(self): with tf.name_scope("Loss") as scope: self._data_fidelity_loss = self._X_input * tf.log( 1e-10 + self._output_dec) + ( 1 - self._X_input) * tf.log(1e-10 + 1 - self._output_dec) self._data_fidelity_loss = -tf.reduce_sum(self._data_fidelity_loss, 1) self._KLdiv = 1 + self._std_layer - tf.square( self._mean_layer) - tf.exp(self._std_layer) self._KLdiv = -0.5 * tf.reduce_sum(self._KLdiv, 1) self._vae_loss = tf.reduce_mean(self._data_fidelity_loss + self._KLdiv) tf.summary.scalar("Loss", self._vae_loss) def train(self, x_train, y_train, x_test=None, y_test=None, epochs=100, batch_size=64, steps=5, log_step=3, gpu_options=None): 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 loss_epoch = 0 start = time.clock() trained_examples = 0 while trained_examples < len(x_train): loss_batch = self._optimize(self._trainset, batch_size, steps) trained_examples += batch_size loss_epoch += loss_batch epoch_train_time = (time.clock() - start) / 60 loss_epoch = np.round(loss_epoch, 2) print("Epoch {}: Loss: {}.".format(epoch, loss_epoch)) if log_step is not None: self._log(epoch + 1, epoch_train_time) def _optimize(self, dataset, batch_size, steps): for i in range(steps): current_batch_x, current_batch_y = dataset.get_next_batch( batch_size) Z_noise = self.sample_noise(n=len(current_batch_x)) _, loss_batch = self._sess.run( [self._vae_optimizer, self._vae_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 loss_batch def decode(self, inpt_x, is_encoded): if not is_encoded: inpt_x = self._encoder_mean.encode(noise=inpt_x, sess=self._sess) return self._generator.decode(inpt_x, self._sess)
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)
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)
class VAE(GenerativeModel): def __init__(self, x_dim, z_dim, dec_architecture, enc_architecture, last_layer_activation, folder="./VAE", image_shape=None): super(VAE, self).__init__(x_dim, z_dim, [dec_architecture, enc_architecture], last_layer_activation, folder, image_shape) self._gen_architecture = self._architectures[0] self._enc_architecture = self._architectures[1] ################# Define architecture last_layer_mean = [ logged_dense, { "units": z_dim, "activation": tf.identity, "name": "Mean" } ] self._encoder_mean = Encoder(self._enc_architecture + [last_layer_mean], name="Encoder") last_layer_std = [ logged_dense, { "units": z_dim, "activation": tf.identity, "name": "Std" } ] self._encoder_std = Encoder(self._enc_architecture + [last_layer_std], name="Encoder") self._gen_architecture.append([ logged_dense, { "units": x_dim, "activation": self._last_layer_activation, "name": "Output" } ]) self._decoder = Decoder(self._gen_architecture, name="Generator") self._nets = [self._decoder, self._encoder_mean] ################# Connect inputs and networks self._mean_layer = self._encoder_mean.generate_net(self._X_input) self._std_layer = self._encoder_std.generate_net(self._X_input) self._output_enc_with_noise = self._mean_layer + tf.exp( 0.5 * self._std_layer) * self._Z_input self._output_dec = self._decoder.generate_net( self._output_enc_with_noise) self._output_dec_from_encoding = self._decoder.generate_net( self._Z_input) ################# Finalize self._init_folders() self._verify_init() def compile(self, learning_rate=0.0001, optimizer=tf.train.AdamOptimizer): self._define_loss() with tf.name_scope("Optimizer"): vae_optimizer = optimizer(learning_rate=learning_rate) self._vae_optimizer = vae_optimizer.minimize(self._vae_loss, name="VAE") self._summarise() def _define_loss(self): with tf.name_scope("Loss") as scope: self._data_fidelity_loss = self._X_input * tf.log( 1e-10 + self._output_dec) + ( 1 - self._X_input) * tf.log(1e-10 + 1 - self._output_dec) self._data_fidelity_loss = -tf.reduce_sum(self._data_fidelity_loss, 1) self._KLdiv = 0.5 * (tf.square(self._mean_layer) + tf.exp(self._std_layer) - self._std_layer - 1) self._KLdiv = tf.reduce_sum(self._KLdiv, 1) self._vae_loss = tf.reduce_mean(self._data_fidelity_loss + self._KLdiv) tf.summary.scalar("Loss", self._vae_loss) def train(self, x_train, x_test, epochs=100, batch_size=64, steps=5, 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 loss_epoch = 0 start = time.clock() trained_examples = 0 while trained_examples < len(x_train): loss_batch = self._optimize(self._trainset, batch_size, steps) trained_examples += batch_size loss_epoch += loss_batch epoch_train_time = (time.clock() - start) / 60 loss_epoch = np.round(loss_epoch, 2) print("Epoch {}: Loss: {}.".format(epoch, loss_epoch)) if log_step is not None: self._log(epoch, epoch_train_time) def _optimize(self, dataset, batch_size, steps): for i in range(steps): current_batch_x = dataset.get_next_batch(batch_size) Z_noise = self._decoder.sample_noise(n=len(current_batch_x)) _, loss_batch = self._sess.run( [self._vae_optimizer, self._vae_loss], feed_dict={ self._X_input: current_batch_x, self._Z_input: Z_noise }) return loss_batch def decode(self, inpt_x, is_encoded): if not is_encoded: inpt_x = self._encoder_mean.encode(noise=inpt_x, sess=self._sess) return self._decoder.decode(inpt_x, self._sess) def generate_image_from_noise(self, n): noise = self.sample_noise(n=n) return self._decoder.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._decoder.generate_samples(encoding, self._sess)