def define_ae(self): """ Builds an autoencoder with 3 encoding layers and 3 decoding layers. Layers are dense and use ReLu activation function. The optimizer is defined to be Adamax and loss as the MSE of visual features plus the MSE of semantic features. Inputs is the visual data and semantic data separately into two 2D array, where rows are different examples and columns the attributes definition, however, in this case, the semantic data is not part of reconstruction, it defines the code, so the task changes from reconstruction the semantic and visual data to projecting the visual space to the semantic space. @return: None """ input_vis = Input(shape=(self.input_length - self.encoding_length, ), name='ae_input_vis') input_sem = Input(shape=(self.encoding_length, ), name='ae_input_sem') lambda_ = self.input_length / self.encoding_length reduction_factor = (self.input_length - 2 * self.encoding_length) encoded = Dense(self.input_length - round(0.3 * reduction_factor), activation='relu', name='e_dense1')(input_vis) encoded = Dense(self.input_length - round(0.6 * reduction_factor), activation='relu', name='e_dense2')(encoded) encoded = Dense(self.input_length - round(0.9 * reduction_factor), activation='relu', name='e_dense3')(encoded) code = Dense(self.encoding_length, activation='relu', name='code')(encoded) decoded = Dense(self.input_length - round(0.9 * reduction_factor), activation='relu', name='d_dense4')(code) decoded = Dense(self.input_length - round(0.6 * reduction_factor), activation='relu', name='d_dense5')(decoded) decoded = Dense(self.input_length - round(0.3 * reduction_factor), activation='relu', name='d_dense6')(decoded) output_vis = Dense(self.output_length - self.encoding_length, activation='relu', name='ae_output_vis')(decoded) self.ae = Model(inputs=[input_vis, input_sem], outputs=output_vis) loss = 10000 * backend.mean( mse(input_vis, output_vis) + lambda_ * mse(input_sem, code)) self.ae.add_loss(loss) self.ae.compile(optimizer='adamax')
def detect_anomalies(self, train_data, train_oids, test_data, test_oids): ''' Function to detect anomalies from train and test data Keyword Args: train_data - training data train_oids - overflight ids for training data test_data - testing data test_oids - overflight ids for testing data Returns: two dictionaries of oid -> anomaly (-1 or 1) ''' reconstructed_train = self.Autoencoder(train_data) train_losses = mse(train_data, reconstructed_train).numpy() reconstructed_test = self.Autoencoder(test_data) test_losses = mse(test_data, reconstructed_test).numpy() train_anomalies = self.calculate_anomalies(train_losses) test_anomalies = self.calculate_anomalies(test_losses) train_dict = {} test_dict = {} for i in range(len(train_oids)): train_dict[train_oids[i]] = train_anomalies[i] for i in range(len(test_oids)): test_dict[test_oids[i]] = test_anomalies[i] return train_dict, test_dict
def bn_loss(target_feats, gen_feats): target_means = tf.reduce_mean(target_feats, axis=[1, 2]) gen_means = tf.reduce_mean(gen_feats, axis=[1, 2]) target_stds = tf.math.reduce_std(target_feats, axis=[1, 2]) gen_stds = tf.math.reduce_std(gen_feats, axis=[1, 2]) loss = losses.mse(target_means, gen_means) + losses.mse( target_stds, gen_stds) return loss
def define_ae(self): """ Builds an autoencoder with 3 encoding layers and 3 decoding layers. Layers are dense and use ReLu activation function. The optimizer is defined to be Adam and loss as the MSE of visual features plus the MSE of semantic features. Inputs is the visual data and semantic data separately into two 2D array, where rows are different examples and columns the attributes definition. @return: None """ input_vis = Input(shape=(self.input_length - self.encoding_length, ), name='ae_input_vis') input_sem = Input(shape=(self.encoding_length, ), name='ae_input_sem') concat = Concatenate(name='input_concat')([input_vis, input_sem]) lambda_ = self.input_length / self.encoding_length reduction_factor = (self.input_length - 2 * self.encoding_length) encoded = Dense(self.input_length - round(0.3 * reduction_factor), activation='relu', name='e_dense1')(concat) encoded = Dense(self.input_length - round(0.6 * reduction_factor), activation='relu', name='e_dense2')(encoded) encoded = Dense(self.input_length - round(0.9 * reduction_factor), activation='relu', name='e_dense3')(encoded) code = Dense(self.encoding_length, activation='relu', name='code')(encoded) decoded = Dense(self.input_length - round(0.9 * reduction_factor), activation='relu', name='d_dense4')(code) decoded = Dense(self.input_length - round(0.6 * reduction_factor), activation='relu', name='d_dense5')(decoded) decoded = Dense(self.input_length - round(0.3 * reduction_factor), activation='relu', name='d_dense6')(decoded) output_sem = Dense(self.encoding_length, activation='relu', name='ae_output_sem')(decoded) output_vis = Dense(self.output_length - self.encoding_length, activation='relu', name='ae_output_vis')(decoded) self.ae = Model(inputs=[input_vis, input_sem], outputs=[output_vis, output_sem]) loss = backend.mean( mse(output_vis, input_vis) + lambda_ * mse(output_sem, input_sem)) self.ae.add_loss(loss) self.ae.compile(optimizer='adam')
def loss(y_true, y_pred): mse_pointwise = K.mean(mse(y_true, y_pred), axis=(1, 2)) true_vol = K.conv2d(y_pred, kernel, strides=(scale, scale), padding='same') pred_vol = K.conv2d(y_pred, kernel, strides=(scale, scale), padding='same') mse_spatial = K.mean(mse(true_vol - input_lr, pred_vol - input_lr), axis=(1, 2)) return beta * mse_pointwise + (1. - beta) * mse_spatial
def train(self, train_data, val_data): reconstruction_loss = tf.reduce_mean(mse(self.__inputs, self.__outputs)) reconstruction_loss *= (self.sequence_length * self.number_of_vars) kl_loss = 1 + self.__z_log_var - K.square(self.__z_mean) - K.exp( self.__z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 vae_loss = K.mean(reconstruction_loss + kl_loss) self.vae.add_loss(vae_loss) lr_schedule = optimizers.schedules.ExponentialDecay( self.learning_rate, decay_steps=self.decay_step, decay_rate=self.decay_rate, staircase=True) opt = optimizers.Adam(learning_rate=lr_schedule) self.vae.compile(optimizer=opt) #logger.info('VAE_model. \n %s', self.__vae.summary()) #self.__vae.summary() time_start = time.time() self.vae.fit(train_data, batch_size=self.batch_size, epochs=self.epochs, shuffle=True, validation_data=(val_data, val_data)) logger.info('Training time. \n %s', time.time() - time_start)
def call(self, input): target, gen = input orig_gen = gen # Preprocess target = self.preprocess_input((target + 1) * 127.5) gen = self.preprocess_input((gen + 1) * 127.5) # Features target_feats = self.cnn(target) gen_feats = self.cnn(gen) # Style loss style_layer_losses = [ bn_loss(t, g) for t, g in zip(target_feats['style'], gen_feats['style']) ] style_loss = tf.reduce_mean(style_layer_losses) # Content loss content_loss = losses.mse(target_feats['content'], gen_feats['content']) content_loss = tf.reduce_mean(content_loss, axis=[1, 2]) content_loss = tf.reduce_mean(content_loss) self.add_loss(content_loss + 0.1 * style_loss) self.add_metric(style_loss, 'style-loss') self.add_metric(content_loss, 'content-loss') return orig_gen
def vae_loss(vae_out, dupout): print("x", vae_out.shape) print("x is", vae_out) print("x decoded mean", dupout.shape) print("x decoded mean is", dupout) print("mse is", mse(vae_out, dupout)) # mse_loss = K.mean(mse(vae_out, dupout), axis=(1, 2)) * height * width # print("mse_loss shape", mse_loss.shape) # print("z log sigma", K.exp(z_log_sigma)) # print("z mean", K.square(z_mean)) # print("hi", 1 + z_log_sigma - K.square(z_mean) - K.exp(z_log_sigma)) # kl_loss = - 0.5 * K.mean(1 + z_log_sigma - K.square(z_mean) - K.exp(z_log_sigma), axis=-1) # print("kl_loss shape", kl_loss.shape) # print("here", kl_loss) # print("whats up") return mse(vae_out, dupout)
def autoencoder_loss(self, depth_img, output): # Compute error in reconstruction reconstruction_loss = mse(K.flatten(depth_img), K.flatten(output)) im1 = tf.image.convert_image_dtype(depth_img, tf.float32) im2 = tf.image.convert_image_dtype(output, tf.float32) l_ssim = K.clip((1 - tf.image.ssim(im1, im2, max_val=1.0, filter_size=11, filter_sigma=1.5, k1=0.01, k2=0.03)) * 0.5, 0, 1) dy_true, dx_true = tf.image.image_gradients(depth_img) dy_pred, dx_pred = tf.image.image_gradients(output) term3 = K.mean(K.abs(dy_pred - dy_true) + K.abs(dx_pred - dx_true), axis=-1) tv = (1e-7) * tf.reduce_sum(tf.image.total_variation(output)) total_loss = 100 * reconstruction_loss + l_ssim + K.mean(term3) + tv # total_loss = tv return total_loss
def masked_loss(y_true, y_pred): inspectionArray = np.asarray([ 6 * 24 * 30 * 1, 6 * 24 * 30 * 2, 6 * 24 * 30 * 3, 6 * 24 * 30 * 4, 6 * 24 * 30 * 5, 6 * 24 * 30 * 6 - 1 ]) y_true_masked = y_true y_pred_masked = concat([[[ y_pred[0, inspectionArray[0], 0], y_pred[0, inspectionArray[1], 0], y_pred[0, inspectionArray[2], 0], y_pred[0, inspectionArray[3], 0], y_pred[0, inspectionArray[4], 0], y_pred[0, inspectionArray[5], 0] ]]], 1) for batch in range(1, y_pred.shape[0]): y_pred_masked = concat([ y_pred_masked, concat([[[ y_pred[batch, inspectionArray[0], 0], y_pred[batch, inspectionArray[1], 0], y_pred[batch, inspectionArray[2], 0], y_pred[batch, inspectionArray[3], 0], y_pred[batch, inspectionArray[4], 0], y_pred[batch, inspectionArray[5], 0] ]]], 1) ], 0) y_pred_masked = expand_dims(y_pred_masked, -1) return mse(y_true_masked, y_pred_masked)
def call(self, inputs): img, recon = inputs norm_img, norm_recon = self.normalize(img), self.normalize(recon) mse = losses.mse(norm_img, norm_recon) mse = tf.reduce_mean(mse) self.add_loss(mse) self.add_metric(mse, 'mse') return recon
def _build(self, n_features): h_1 = h_5 = self.layer_config[0] h_2 = h_4 = self.layer_config[1] h_3 = self.layer_config[2] # build layers of vae model encoder_in = Input(shape=(n_features, ), name='Input') layers = Dense(units=h_1, activation='relu')(encoder_in) layers = Dense(units=h_2, activation='relu')(layers) z_mean = Dense(units=h_3, name='Z_mean')(layers) z_log_var = Dense(units=h_3, name='Z_log_var')(layers) # use reparameterization trick to push the sampling out as input z = Lambda(self._sampling, output_shape=(50, ), name='Z')([z_mean, z_log_var]) #instantiate encoder model self.model_encoder_ = Model(encoder_in, [z_mean, z_log_var, z], name='Encoder') # build decoder model decoder_in = Input(shape=(h_3, ), name='Z_sampling') layers_2 = Dense(units=h_4, activation='relu')(decoder_in) layers_2 = Dense(units=h_5, activation='relu')(layers_2) decoder_out = Dense(units=n_features)(layers_2) # instantiate decoder model self.model_decoder_ = Model(decoder_in, decoder_out, name='Decoder') # instantiate VAE model model_output = self.model_decoder_(self.model_encoder_(encoder_in)[2]) self.model_ = Model(encoder_in, model_output, name='Vae') # make custom loss # reconstruction loss rec_loss = mse(encoder_in, model_output) rec_loss *= n_features # Kullback L loss kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 vae_loss = K.mean(rec_loss + kl_loss) # add custom loss self.model_.add_loss(vae_loss) # Compile self.model_.compile(optimizer=self.opt) self.test = 0
def autoencoder_loss(depth_img, output): # Compute error in reconstruction reconstruction_loss = mse(K.flatten(depth_img), K.flatten(output)) # total_loss = reconstruction_loss # total_variation_weight = 20 total_loss = 500 * reconstruction_loss + 0.5 * tf.image.total_variation( output) # total_loss =tf.image.total_variation(output) return total_loss
def contentLoss(y_true, y_pred): '''内容损失''' y_true = restoreImg(y_true) y_pred = restoreImg(y_pred) y_true = preprocess_input(y_true) y_pred = preprocess_input(y_pred) sr = vgg19(y_pred) hr = vgg19(y_true) return mse(y_true, y_pred)
def _vae_loss(): model_input = K.flatten(inputs) model_output = K.flatten(output) recon_loss= mse(model_input, model_output) # recon_loss *= self.input_shape[0] kl_loss = -5e-4 * K.mean(1 + z_log_var - K.square(z_mean) - K.exp(z_log_var), axis=-1) return K.mean(recon_loss + kl_loss)
def call(self, inputs): # print('\n'*5 + '*'*80, 'khi called', '\n'*5) joint_input = self.joint(inputs) latent = self.pipe(joint_input) outs = self.out(latent) for [i, o] in zip(inputs, outs): # print('='*80, mse(i, o),'\n'*5) self.add_loss(mse(i, o)) return outs
def __call__(self, y_true, y_pred): loss = self.alpha_mse * mse(y_true, y_pred) loss += self.alpha_mass * mass_res( self.inp_tensor, y_pred, self.inp_div, self.inp_sub, self.norm_q, self.noadiab) loss += self.alpha_ent * ent_res(self.inp_tensor, y_pred, self.inp_div, self.inp_sub, self.norm_q, self.noadiab) return loss
def get_loss(self, inputs, outputs): global beta reconstruction_loss = mse(inputs[:, :2049], outputs) kl_loss = 1 + self.z_log_var - K.square(self.z_mean) - K.exp( self.z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 * beta vae_loss = K.sum(reconstruction_loss + kl_loss) return vae_loss
def add_custom_loss_function(self, inputs, outputs, z_mean, z_log_var): # VAE loss = mse_loss or xent_loss + kl_loss reconstruction_loss = mse(K.flatten(inputs), K.flatten(outputs)) #reconstruction_loss = binary_crossentropy(K.flatten(inputs), K.flatten(outputs)) reconstruction_loss *= self.data.img_size * self.data.img_size kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 vae_loss = K.mean(reconstruction_loss + kl_loss) self.vae.add_loss(vae_loss)
def task_5_model(x_train, filters=16, n_latent=5, kernel_size=3): inputs = Input(shape=x_train.shape[1:]) x = inputs for i in range(2): filters *= 2 x = Conv2D(filters, kernel_size, activation="relu", strides=2, padding="same")(x) shape = K.int_shape(x) x = Flatten()(x) x = Dense(filters, activation="relu")(x) z_mean = Dense(n_latent)(x) z_log_var = Dense(n_latent)(x) z = Lambda(sampling)([z_mean, z_log_var]) encoder = Model(inputs, [z_mean, z_log_var, z], name="encoder") latent_inputs = Input(shape=(n_latent, )) x = Dense(shape[1] * shape[2] * shape[3], activation="relu")(latent_inputs) x = Reshape((shape[1], shape[2], shape[3]))(x) for i in range(2): x = Conv2DTranspose(filters, kernel_size, activation="relu", strides=2, padding="same")(x) filters //= 2 outputs = Conv2DTranspose(filters=1, kernel_size=kernel_size, activation="sigmoid", padding="same")(x) decoder = Model(latent_inputs, outputs, name="decoder") outputs = decoder(encoder(inputs)[2]) vae = Model(inputs, outputs) reconstruction_loss = mse(K.flatten(inputs), K.flatten(outputs)) reconstruction_loss *= np.prod(x_train.shape[1:3]) kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 vae_loss = K.mean(reconstruction_loss + kl_loss) vae.add_loss(vae_loss) return vae
def calc_loss(inputs, outputs, image_size, z_mean, z_sdv, mse=False, bce=True): if mse: reconstruction_loss = losses.mse(K.flatten(inputs), K.flatten(outputs)) else: reconstruction_loss = losses.binary_crossentropy( K.flatten(inputs), K.flatten(outputs)) reconstruction_loss *= image_size * image_size kl_loss = 1 + z_sdv - K.square(z_mean) - K.exp(z_sdv) kl_loss = -0.5 * K.sum(kl_loss, axis=-1) loss = K.mean(reconstruction_loss + kl_loss) return loss
def vae_loss(self, y_true, y_pred): """Compute VAE loss, using either mse or crossentropy.""" img_pixels = self.size * self.size use_mse = True if use_mse: match_loss = mse(K.flatten(y_true), K.flatten(y_pred)) * img_pixels else: match_loss = binary_crossentropy(K.flatten(y_true), K.flatten(y_pred)) * img_pixels kl_loss = -0.5 * K.sum( 1 + self.z_log_var - K.square(self.z_mean) - K.exp(self.z_log_var), axis=-1) return K.mean(match_loss + kl_loss)
def loss(y_true, y_pred): if self._mse_loss: reconstruction_loss = losses.mse(y_true, y_pred) else: reconstruction_loss = losses.binary_crossentropy( y_true, y_pred) reconstruction_loss *= self.embedding_size kl_loss = 1 + self.z_log_var - \ K.square(self.z_mean) - K.exp(self.z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 return K.mean(reconstruction_loss + kl_loss)
def build_loss(self, inputs, outputs, z_mean, z_log_var): reconstruction_loss = mse(inputs, outputs) # print(reconstruction_loss) reconstruction_loss *= self.input_dim # Might need to add axis=[1, 2] reconstruction_loss = K.sum(reconstruction_loss) kl_loss = (1 + z_log_var - K.square(z_mean) - K.exp(z_log_var)) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 print('recloss:', reconstruction_loss) print('klloss:', kl_loss) vae_loss = K.mean(reconstruction_loss + kl_loss) return vae_loss
def loss(in_, out_): x = in_[0] y = in_[1] x_ = out_[0] y_ = out_[1] if type is 'mix': return K.mean(mse(x, x_) + beta*binary_crossentropy(y, y_)) elif type is 'bin': return K.mean(binary_crossentropy(y, y_)) elif type is 'vae': return K.mean(mse(x, x_) + beta*binary_crossentropy(y, y_) + beta*K.sum(K.exp(z_log_var) + K.square(z_mu) - z_log_var)) else: return K.mean(mse(x, x_))
def compile_model(self, x_train): print("COMPILING MODEL") midi_file_size = x_train.shape[1] input_shape = (midi_file_size, ) # VAE model = encoder + decoder # build encoder model inputs = Input(shape=input_shape, name='encoder_input') x = Dense(self.intermediate_dim, activation='relu')(inputs) z_mean = Dense(self.latent_dim, name='z_mean')(x) z_log_var = Dense(self.latent_dim, name='z_log_var')(x) # use reparameterization trick to push the sampling out as input # note that "output_shape" isn't necessary with the TensorFlow backend z = Lambda(self.sampling, output_shape=(self.latent_dim, ), name='z')([z_mean, z_log_var]) # instantiate encoder model encoder = Model(inputs, [z_mean, z_log_var, z], name='encoder') # encoder.summary() plot_model(encoder, to_file='vae_mlp_encoder.png', show_shapes=True) # build decoder model latent_inputs = Input(shape=(self.latent_dim, ), name='z_sampling') x = Dense(self.intermediate_dim, activation='relu')(latent_inputs) outputs = Dense(midi_file_size, activation='sigmoid')(x) # instantiate decoder model decoder = Model(latent_inputs, outputs, name='decoder') # decoder.summary() plot_model(decoder, to_file='vae_mlp_decoder.png', show_shapes=True) # instantiate VAE model outputs = decoder(encoder(inputs)[2]) vae = Model(inputs, outputs, name='vae_mlp') reconstruction_loss = mse(inputs, outputs) reconstruction_loss *= midi_file_size kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) kl_loss = K.sum(kl_loss, axis=-1) kl_loss *= -0.5 vae_loss = K.mean(reconstruction_loss + kl_loss) # vae.add_loss(vae_loss) # loss = 'binary_crossentropy' loss = 'mean_squared_error' vae.compile(optimizer='adam', loss=loss) # vae.summary() plot_model(vae, to_file='vae_mlp.png', show_shapes=True) return vae, encoder, decoder
def __init__(self, input_dim, output_dim, batch_size, epochs): self.batch_size = batch_size self.input_dim = input_dim self.output_dim = output_dim self.epochs = epochs inputs = Input(shape=(self.input_dim,), name='encoder_input') x = Dense(1024, activation='relu')(inputs) x = BatchNormalization()(x) x = Dropout(0.3)(x) x = Dense(512, activation='relu')(x) x = BatchNormalization()(x) x = Dropout(0.3)(x) x = Dense(256, activation='relu')(x) x = BatchNormalization()(x) x = Dropout(0.3)(x) z_mean = Dense(128, name='z_mean')(x) z_log_var = Dense(128, name='z_log_var')(x) z = Lambda(sampling, output_shape=(128,), name='z')([z_mean, z_log_var]) self.encoder = Model(inputs, [z_mean, z_log_var, z], name='encoder') # print(self.encoder.summary()) latent_inputs = Input(shape=(128,), name='z_sampling') x = Dense(256, activation='relu')(latent_inputs) x = BatchNormalization()(x) x = Dropout(0.3)(x) x = Dense(512, activation='relu')(x) x = BatchNormalization()(x) x = Dropout(0.3)(x) x = Dense(1024, activation='relu')(x) outputs = Dense(self.input_dim, activation='sigmoid')(x) self.decoder = Model(latent_inputs, outputs, name='decoder') # print(self.decoder.summary()) outputs = self.decoder(self.encoder(inputs)[2]) self.vae = Model(inputs, outputs, name='vae_mlp') reconstruction_loss = mse(inputs, outputs) reconstruction_loss *= self.input_dim kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var) # kl_loss = K.sum(kl_loss, axis=-1) kl_loss = K.mean(kl_loss, axis=-1) # kl_loss *= -0.5 kl_loss *= -5e-4 vae_loss = K.mean(reconstruction_loss + kl_loss) self.vae.add_loss(vae_loss) self.vae.compile(optimizer='adam')
def autoencoder_loss(depth_img, output): # Compute error in reconstruction reconstruction_loss = mse(K.flatten(depth_img), K.flatten(output)) dy_true, dx_true = tf.image.image_gradients(depth_img) dy_pred, dx_pred = tf.image.image_gradients(output) term3 = K.mean(K.abs(dy_pred - dy_true) + K.abs(dx_pred - dx_true), axis=-1) tv = (1e-8) * tf.reduce_sum(tf.image.total_variation(output)) total_loss = 100 * reconstruction_loss + term3 + tv # total_loss = tv return total_loss
def recon_loss(y_true, y_pred): # dummy variables # VAE loss = mse_loss or xent_loss + kl_loss if args.loss == "MSE": reconstruction_loss = mse(K.flatten(inputs), K.flatten(outputs)) elif args.loss == "BCE": reconstruction_loss = binary_crossentropy(K.flatten(inputs), K.flatten(outputs)) else: raise ValueError # multiply by n data points, divide by batch size: # https://www.quora.com/How-do-you-fix-a-Variational-Autoencoder-VAE-that-suffers-from-mode-collapse reconstruction_loss *= (x_train.shape[0] / batch_size) return reconstruction_loss
def build_dense_model(num_features): """ Simple two layer MLP """ regression_target = layers.Input(shape=(1,), name='ground_truth') feature_input = layers.Input(shape=(num_features,), name='feature_input') encoder_output = layers.GaussianDropout(0.1)(feature_input) encoder_output = layers.Dense(64, activation='tanh', name='encoder_hidden')(encoder_output) encoder_output = layers.Dense(64, activation='tanh', name='encoder_hidden_2')(encoder_output) z_mean, z_log_var = layers.Dense(LATENT_DIM, name='z_mean')(encoder_output), \ layers.Dense(LATENT_DIM, name='z_log_var')(encoder_output) r_mean, r_log_var = layers.Dense(1, name='r_mean')(encoder_output), \ layers.Dense(1, name='r_log_var')(encoder_output) # Sample latent and regression target z = layers.Lambda(sampling, output_shape=(LATENT_DIM,), name='z')([z_mean, z_log_var]) r = layers.Lambda(sampling, output_shape=(1,), name='r')([r_mean, r_log_var]) # Latent generator pz_mean = layers.Dense(LATENT_DIM, kernel_constraint=constraints.unit_norm(), name='pz_mean')(r) encoder = Model([feature_input, regression_target], [z_mean, z_log_var, z, r_mean, r_log_var, r, pz_mean], name='encoder') latent_input = layers.Input(shape=(LATENT_DIM,), name='decoder_input') decoder_output = layers.Dense(64, activation='tanh', name='decoder_hidden')(latent_input) decoder_output = layers.Dense(64, activation='tanh', name='decoder_hidden_2')(decoder_output) decoder_output = layers.Dense(num_features, name='decoder_output')(decoder_output) decoder = Model(latent_input, decoder_output, name='decoder') encoder_decoder_output = decoder(encoder([feature_input, regression_target])[2]) vae = Model([feature_input, regression_target], encoder_decoder_output, name='vae') # Manually write up losses reconstruction_loss = mse(feature_input, encoder_decoder_output) kl_loss = 1 + z_log_var - K.square(z_mean - pz_mean) - K.exp(z_log_var) kl_loss = -0.5 * K.sum(kl_loss, axis=-1) label_loss = tf.divide(0.5 * K.square(r_mean - regression_target), K.exp(r_log_var)) + 0.5 * r_log_var vae_loss = K.mean(reconstruction_loss + kl_loss + label_loss) vae.add_loss(vae_loss) vae.compile(optimizer=Adam()) regressor = Model(feature_input, r_mean, name='regressor') return vae, regressor