diff --git a/auto_encoder.py b/auto_encoder.py new file mode 100644 index 0000000..54e58cb --- /dev/null +++ b/auto_encoder.py @@ -0,0 +1,174 @@ +import os +import time +import argparse +import wandb +from cv2 import drawFrameAxes +import numpy as np +import tensorflow as tf +from custom_utils.custom_utils import UV2Mesh, maskFacesBatch +from tensorboardX import SummaryWriter + +from utils import str_to_bool +from tf_utils import check_tf_version, allow_memory_growth, split_gpu_for_testing +from load_models import load_generator, load_discriminator +from dataset import DatasetSimple +from losses import d_logistic, d_logistic_r1_reg, g_logistic_non_saturating, g_logistic_ns_pathreg, edge_loss, uv_mask_loss +# from losses import collision_penalty as collision_penalty +from losses import collision_loss as collision_penalty +from convnext.models.convnext_tf import ConvNeXt +from stylegan2_ae.generator import Generator + + +os.environ["CUDA_VISIBLE_DEVICES"] = "3" +run = wandb.init(config=tf.compat.v1.flags.FLAGS, sync_tensorboard=True, project='stylegan', name='ae_1_2', notes='convnext + stylegan generator') +artifact = wandb.Artifact('code', type='code') +artifact.add_file('auto_encoder.py') +artifact.add_file('stylegan2_ae/layers/mapping_block.py') +run.log_artifact(artifact) + +uv2mesh = UV2Mesh(res=256) + + + +def filter_resolutions_featuremaps(resolutions, featuremaps, res): + index = resolutions.index(res) + filtered_resolutions = resolutions[:index + 1] + filtered_featuremaps = featuremaps[:index + 1] + return filtered_resolutions, filtered_featuremaps + + +class AutoEncoder(tf.keras.Model): + + def __init__(self): + super(AutoEncoder, self).__init__() + + resolutions = [4, 8, 16, 32, 64, 128, 256, 512, 1024] + g_featuremaps = [256, 256, 256, 256, 256, 128, 64, 32, 16] + train_resolutions, train_g_featuremaps = filter_resolutions_featuremaps(resolutions, g_featuremaps, 512) + g_params = { + 'z_dim': 256, + 'w_dim': 256, + 'labels_dim': -1, + 'n_mapping': 8, + 'resolutions': train_resolutions, + 'featuremaps': train_g_featuremaps, + } + + # test_latent = tf.ones((1, g_params['z_dim']), dtype=tf.float32) + self.decoder = Generator(g_params) + # _ = generator(test_latent) + + + self.encoder = ConvNeXt(depths=[3, 3, 27, 3], dims=[96, 192, 256, g_params['z_dim']], include_top=False) + self.pooling = tf.keras.layers.GlobalAveragePooling2D() + + + def call(self, inputs, training=None): + x, uv_mask = inputs + + x = tf.transpose(x, [0,2,3,1]) + x = self.encoder(x, training=training) + x = self.pooling(x) + + x = self.decoder(x, training=training) + x = x * uv_mask[:,tf.newaxis,:,:] + + return x + + +@tf.function +def train_step(batch): + posed_uv, conditions,_, mesh_body_posed, mesh_mask = batch + uv_mask = conditions[3] + + with tf.GradientTape() as tape: + + pred = model([posed_uv, uv_mask]) + + mesh_pred = uv2mesh(pred) + mesh_orig = uv2mesh(posed_uv) + + e_loss = 0.0#edge_loss(mesh_pred, mesh_orig, mesh_mask) + c_loss = 0.0#collision_penalty(mesh_pred, mesh_body_posed, mesh_mask) + l1_loss = tf.reduce_mean(tf.reduce_sum((tf.math.abs(posed_uv - pred)), axis=1) * uv_mask) + loss = l1_loss + e_loss + c_loss + + metric = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(mesh_mask[:,:,tf.newaxis] * (mesh_orig - mesh_pred) ** 2, axis=-1))) / tf.reduce_sum(mesh_mask) + gradients = tape.gradient(loss, model.trainable_variables) + optimizer.apply_gradients(zip(gradients, model.trainable_variables)) + return { 'loss': loss, 'edge_loss': e_loss, 'collision_loss': c_loss, 'l1_loss': l1_loss, 'euclid_error': metric } + + + +@tf.function +def valid_step(batch): + posed_uv, conditions,_, mesh_body_posed, mesh_mask = batch + uv_mask = conditions[3] + + pred = model([posed_uv, uv_mask]) + mesh_pred = uv2mesh(pred) + mesh_orig = uv2mesh(posed_uv) + + e_loss = 0.0#edge_loss(mesh_pred, mesh_orig, mesh_mask) + c_loss = 0.0#collision_penalty(mesh_pred, mesh_body_posed, mesh_mask) + l1_loss = tf.reduce_mean(tf.reduce_sum((tf.math.abs(posed_uv - pred)), axis=1) * uv_mask) + loss = l1_loss + e_loss + c_loss + + metric = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(mesh_mask[:,:,tf.newaxis] * (mesh_orig - mesh_pred) ** 2, axis=-1))) / tf.reduce_sum(mesh_mask) + return { 'loss': loss, 'edge_loss': e_loss, 'collision_loss': c_loss, 'l1_loss': l1_loss, 'euclid_error': metric } + + +if __name__ == '__main__': + allow_memory_growth() + + + name = 'test-9' + dataset_train = DatasetSimple('/home/workspace/data/dataset/stylegan_new/train').cache().batch(8).repeat() + dataset_valid = DatasetSimple('/home/workspace/data/dataset/stylegan_new/valid').cache().batch(8).repeat() + + model = AutoEncoder() + # optimizer = tf.optimizers.Adam(learning_rate=0.002, beta_1=0.0, beta_2=0.99, epsilon=1e-8) + optimizer = tf.optimizers.Adam() + folder = 'models/ae_logs/' + train_summary_writer = tf.summary.create_file_writer(folder + name + '/train') + valid_summary_writer = tf.summary.create_file_writer(folder + name + '/valid') + mesh_writer = SummaryWriter(folder + name + '/mesh') + + step = 0 + for batch in dataset_train: + train_loss = train_step(batch) + + for key in train_loss.keys(): + with train_summary_writer.as_default(): + tf.summary.scalar(key, train_loss[key], step=step) + + data_valid = iter(dataset_valid).get_next() + valid_loss = valid_step(data_valid) + + for key in valid_loss.keys(): + with valid_summary_writer.as_default(): + tf.summary.scalar(key, valid_loss[key], step=step) + + if step % 250 == 0: + pred = model([data_valid[0], data_valid[1][3]]) + + mesh_pred = uv2mesh(pred) + mesh_orig = uv2mesh(data_valid[0]) + + orig_img = tf.transpose(data_valid[0], [0,2,3,1]) + pred_img = tf.transpose(pred, [0,2,3,1]) + img = tf.concat((orig_img, pred_img), axis=2) + with train_summary_writer.as_default(): + tf.summary.image('images', img, step=step) + + F = np.load("custom_utils/smpl_faces.npy") + garment, faces = maskFacesBatch(mesh_pred.numpy(), F, data_valid[4].numpy().astype(bool)) + gt, _ = maskFacesBatch(mesh_orig.numpy(), F, data_valid[4].numpy().astype(bool)) + + for i in range(len(garment)): + mesh_writer.add_mesh('garment_pred_' + str(i), vertices=garment[i][np.newaxis,:,:], faces=faces[i][np.newaxis,:,:], global_step=step) + mesh_writer.add_mesh('garment_gt_' + str(i), vertices=gt[i][np.newaxis,:,:], faces=faces[i][np.newaxis,:,:], global_step=step) + + print(step) + + step += 1 \ No newline at end of file