import os import time import random import tensorflow as tf import numpy as np import scipy as sp # import plotly.graph_objects as go # import plotly.express as ex from custom_utils.custom_utils import load_model from convnext.models.convnext_tf import ConvNeXt, ConvNeXtReverse, Block from models.ae_body_model import AutoEncoder as BodyAE from models.ae_curv_model import AutoEncoder as CurvatureAE from models.ae_static_model import AutoEncoder as StaticAE from models.ae_body_model import AutoEncoder32 as BodyAE32 from models.ae_curv_model import AutoEncoder32 as CurvatureAE32 from models.ae_static_model import AutoEncoder32 as StaticAE32 from models.ae_body_model import AutoEncoder128 as BodyAE128 from models.ae_curv_model import AutoEncoder128 as CurvatureAE128 from models.ae_static_model import AutoEncoder128 as StaticAE128 class Bottleneck(tf.keras.Model): def __init__(self, dim): super(Bottleneck, self).__init__() self.bottleneck = tf.keras.Sequential( [Block(dim=dim, drop_path=0, layer_scale_init_value=1e-6, prefix=f'bottleneck{j}') for j in range(5)] ) def call(self, inputs, training=None): x = inputs x = self.bottleneck(x, training=training) return x class Encoder(tf.keras.Model): def __init__(self, latent_dim): super(Encoder, self).__init__() self.encoder = ConvNeXt(depths=[3, 3, 9, 3], dims=[32, 64, 128, 256], include_top=False) self.flatten = tf.keras.layers.Flatten() self.mean = tf.keras.layers.Dense(latent_dim) self.log_var = tf.keras.layers.Dense(latent_dim) def call(self, inputs, training=None): x = inputs x = self.encoder(x) x = self.flatten(x) mean = self.mean(x) log_var = self.log_var(x) return mean, log_var class Decoder(tf.keras.Model): def __init__(self): super(Decoder, self).__init__() self.dense = tf.keras.layers.Dense(16 * 8 * 80) self.reshape = tf.keras.layers.Reshape((16, 8, 80)) self.decoder = ConvNeXtReverse(depths=list(reversed([3, 3, 9, 3])), dims=list(reversed([256, 128, 64, 16]))) def call(self, inputs, training=None): x = inputs x = self.dense(x) x = self.reshape(x) x = self.decoder(x) return x class CVAE(tf.keras.Model): def __init__(self, latent_dim=128, avg_garment_path='', static_model='', body_model='', curvature_model='', freeze_encoders=False): super(CVAE, self).__init__() self.latent_dim = latent_dim model : StaticAE = StaticAE() if static_model != '': load_model(model, static_model) self.static_enc = tf.keras.Sequential([model.encoder, model.bottleneck]) model : BodyAE = BodyAE() if body_model != '': load_model(model, body_model) self.body_enc = tf.keras.Sequential([model.encoder, model.bottleneck]) model : CurvatureAE = CurvatureAE() if curvature_model != '': load_model(model, curvature_model) self.curv_enc = tf.keras.Sequential([model.encoder, model.bottleneck]) if freeze_encoders: self.static_enc.trainable = False self.body_enc.trainable = False self.curv_enc.trainable = False self.encoder = Encoder(latent_dim) self.decoder = Decoder() if avg_garment_path != '': self.avg_garment = np.load(avg_garment_path) else: self.avg_garment = None self.cond_encoder = tf.keras.Sequential([tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dense(256, activation='relu'), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dense(latent_dim),]) # self.shuffle = tf.keras.layers.Lambda(lambda x: tf.stack([tf.gather(x[i], tf.random.shuffle(tf.range(x[i].shape[0]))) for i in range(x.shape[0])])) # @tf.function def sample(self, uv_template, uv_body_posed, uv_curv, uv_mask, nr_of_samples=4, fix_noise=False, zero_latent=False): if not fix_noise: eps = tf.random.normal(shape=(nr_of_samples, self.latent_dim)) else: eps = tf.random.normal(shape=(1, self.latent_dim)) eps = tf.tile(eps, [nr_of_samples,1]) uv_template = tf.tile(tf.transpose(uv_template, [1,2,0])[tf.newaxis,:,:,:], [nr_of_samples,1,1,1]) uv_body_posed = tf.tile(tf.transpose(uv_body_posed, [1,2,0])[tf.newaxis,:,:,:], [nr_of_samples,1,1,1]) if len(uv_curv.shape) == 3: uv_curv = tf.tile(uv_curv[tf.newaxis,:,:,:], [nr_of_samples,1,1,1]) uv_mask = tf.tile(uv_mask[tf.newaxis,:,:], [nr_of_samples,1,1]) # uv_template, uv_body_posed = tf.transpose(uv_template, [0,2,3,1]), tf.transpose(uv_body_posed, [0,2,3,1]) z_static = self.static_enc(uv_template) z_body = self.body_enc(uv_body_posed) z_curv = self.curv_enc(uv_curv) z_cond = tf.concat([z_static, z_body, z_curv], axis=-1) z_cond = self.cond_encoder(z_cond) if zero_latent: eps = tf.zeros_like(eps) z = tf.concat([eps, z_cond], axis=-1) x = self.decoder(z) x = x + self.avg_garment[tf.newaxis,:,:,:] x = x * uv_mask[:,:,:,tf.newaxis] return x def reparameterize(self, mean, logvar): eps = tf.random.normal(shape=mean.shape) return eps * tf.exp(logvar * .5) + mean def decode(self, z, apply_sigmoid=False): logits = self.decoder(z) if apply_sigmoid: probs = tf.sigmoid(logits) return probs return logits def call(self, inputs, training=None, zero_latent=False): uv_unposed, uv_template, uv_body_posed, uv_curv = inputs uv_unposed, uv_template, uv_body_posed = tf.transpose(uv_unposed, [0,2,3,1]), tf.transpose(uv_template, [0,2,3,1]), tf.transpose(uv_body_posed, [0,2,3,1]) z_static = self.static_enc(uv_template) z_body = self.body_enc(uv_body_posed) z_curv = self.curv_enc(uv_curv) x = tf.concat([uv_unposed, uv_template, uv_body_posed, uv_curv], axis=-1) mean, logvar = self.encoder(x) z = self.reparameterize(mean, logvar) z_cond = tf.concat([z_static, z_body, z_curv], axis=-1) z_cond = self.cond_encoder(z_cond) if zero_latent: z = tf.zeros_like(z) z = tf.concat([z, z_cond], axis=-1) # z = self.shuffle(z) # z = tf.concat([z, z_curv], axis=-1) x = self.decoder(z) # x = tf.transpose(x, [0,3,1,2]) # x = x * uv_mask[:,tf.newaxis,:,:] # x = tf.image.resize(x, (512, 256), tf.image.ResizeMethod.LANCZOS5) # x = x + tf.transpose(uv_shaped_body, [0,2,3,1]) if self.avg_garment is not None: x = x + self.avg_garment[tf.newaxis,:,:,:] # x = x * uv_mask[:,:,:,tf.newaxis] return x, mean, logvar, z class Encoder32(tf.keras.Model): def __init__(self, latent_dim): super(Encoder32, self).__init__() self.encoder = ConvNeXt(depths=[27, 27], dims=[256, 256], include_top=False) self.flatten = tf.keras.layers.Flatten() self.mean = tf.keras.layers.Dense(latent_dim) self.log_var = tf.keras.layers.Dense(latent_dim) def call(self, inputs, training=None): x = inputs x = self.encoder(x) x = self.flatten(x) mean = self.mean(x) log_var = self.log_var(x) return mean, log_var class Decoder32(tf.keras.Model): def __init__(self): super(Decoder32, self).__init__() self.dense = tf.keras.layers.Dense(4 * 2 * 256) self.reshape = tf.keras.layers.Reshape((4, 2, 256)) self.decoder = ConvNeXtReverse(depths=list(reversed([27, 27])), dims=list(reversed([256, 256]))) def call(self, inputs, training=None): x = inputs x = self.dense(x) x = self.reshape(x) x = self.decoder(x) return x class CVAE32(tf.keras.Model): def __init__(self, latent_dim=128, avg_garment_path='', static_model='', body_model='', curvature_model='', freeze_encoders=False): super(CVAE32, self).__init__() self.latent_dim = latent_dim model : StaticAE32 = StaticAE32() if static_model != '': load_model(model, static_model) self.static_enc = tf.keras.Sequential([model.encoder, model.bottleneck]) model : BodyAE32 = BodyAE32() if body_model != '': load_model(model, body_model) self.body_enc = tf.keras.Sequential([model.encoder, model.bottleneck]) model : CurvatureAE32 = CurvatureAE32() if curvature_model != '': load_model(model, curvature_model) self.curv_enc = tf.keras.Sequential([model.encoder, model.bottleneck]) if freeze_encoders: self.static_enc.trainable = False self.body_enc.trainable = False self.curv_enc.trainable = False self.encoder = Encoder32(latent_dim) self.decoder = Decoder32() if avg_garment_path != '': self.avg_garment = np.load(avg_garment_path) else: self.avg_garment = None self.cond_encoder = tf.keras.Sequential([tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dense(256, activation='relu'), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dense(latent_dim),]) # @tf.function def sample(self, uv_template, uv_body_posed, uv_curv, uv_mask, nr_of_samples=4, fix_noise=False, zero_latent=False): if not fix_noise: eps = tf.random.normal(shape=(nr_of_samples, self.latent_dim)) else: eps = tf.random.normal(shape=(1, self.latent_dim)) eps = tf.tile(eps, [nr_of_samples,1]) uv_template = tf.tile(tf.transpose(uv_template, [1,2,0])[tf.newaxis,:,:,:], [nr_of_samples,1,1,1]) uv_body_posed = tf.tile(tf.transpose(uv_body_posed, [1,2,0])[tf.newaxis,:,:,:], [nr_of_samples,1,1,1]) if len(uv_curv.shape) == 3: uv_curv = tf.tile(uv_curv[tf.newaxis,:,:,:], [nr_of_samples,1,1,1]) uv_mask = tf.tile(uv_mask[tf.newaxis,:,:], [nr_of_samples,1,1]) # uv_template, uv_body_posed = tf.transpose(uv_template, [0,2,3,1]), tf.transpose(uv_body_posed, [0,2,3,1]) z_static = self.static_enc(uv_template) z_body = self.body_enc(uv_body_posed) z_curv = self.curv_enc(uv_curv) z_cond = tf.concat([z_static, z_body, z_curv], axis=-1) z_cond = self.cond_encoder(z_cond) if zero_latent: eps = tf.zeros_like(eps) z = tf.concat([eps, z_cond], axis=-1) x = self.decoder(z) x = x + self.avg_garment[tf.newaxis,:,:,:] x = x * uv_mask[:,:,:,tf.newaxis] return x def reparameterize(self, mean, logvar): eps = tf.random.normal(shape=mean.shape) return eps * tf.exp(logvar * .5) + mean def decode(self, z, apply_sigmoid=False): logits = self.decoder(z) if apply_sigmoid: probs = tf.sigmoid(logits) return probs return logits def call(self, inputs, training=None, zero_latent=False): uv_unposed, uv_template, uv_body_posed, uv_curv = inputs uv_unposed, uv_template, uv_body_posed = tf.transpose(uv_unposed, [0,2,3,1]), tf.transpose(uv_template, [0,2,3,1]), tf.transpose(uv_body_posed, [0,2,3,1]) z_static = self.static_enc(uv_template) z_body = self.body_enc(uv_body_posed) z_curv = self.curv_enc(uv_curv) x = tf.concat([uv_unposed, uv_template, uv_body_posed, uv_curv], axis=-1) mean, logvar = self.encoder(x) z = self.reparameterize(mean, logvar) z_cond = tf.concat([z_static, z_body, z_curv], axis=-1) z_cond = self.cond_encoder(z_cond) if zero_latent: z = tf.zeros_like(z) z = tf.concat([z, z_cond], axis=-1) # z = self.shuffle(z) # z = tf.concat([z, z_curv], axis=-1) x = self.decoder(z) # x = tf.transpose(x, [0,3,1,2]) # x = x * uv_mask[:,tf.newaxis,:,:] # x = tf.image.resize(x, (512, 256), tf.image.ResizeMethod.LANCZOS5) # x = x + tf.transpose(uv_shaped_body, [0,2,3,1]) if self.avg_garment is not None: x = x + self.avg_garment[tf.newaxis,:,:,:] # x = x * uv_mask[:,:,:,tf.newaxis] return x, mean, logvar, z class Encoder128(tf.keras.Model): def __init__(self, latent_dim): super(Encoder128, self).__init__() self.encoder = ConvNeXt(depths=[16, 16, 9, 9], dims=[256, 256, 128, 64], include_top=False) self.flatten = tf.keras.layers.Flatten() self.mean = tf.keras.layers.Dense(latent_dim) self.log_var = tf.keras.layers.Dense(latent_dim) def call(self, inputs, training=None): x = inputs x = self.encoder(x) x = self.flatten(x) mean = self.mean(x) log_var = self.log_var(x) return mean, log_var class Decoder128(tf.keras.Model): def __init__(self): super(Decoder128, self).__init__() self.dense = tf.keras.layers.Dense(4 * 2 * 128) self.reshape = tf.keras.layers.Reshape((4, 2, 128)) self.decoder = ConvNeXtReverse(depths=list(reversed([16, 16, 9, 9])), dims=list(reversed([256, 256, 128, 64]))) def call(self, inputs, training=None): x = inputs x = self.dense(x) x = self.reshape(x) x = self.decoder(x) return x class CVAE128(tf.keras.Model): def __init__(self, latent_dim=128, avg_garment_path='', static_model='', body_model='', curvature_model='', freeze_encoders=False): super(CVAE128, self).__init__() self.latent_dim = latent_dim model : StaticAE128 = StaticAE128() if static_model != '': load_model(model, static_model) self.static_enc = tf.keras.Sequential([model.encoder, model.bottleneck]) model : BodyAE128 = BodyAE128() if body_model != '': load_model(model, body_model) self.body_enc = tf.keras.Sequential([model.encoder, model.bottleneck]) model : CurvatureAE128 = CurvatureAE128() if curvature_model != '': load_model(model, curvature_model) self.curv_enc = tf.keras.Sequential([model.encoder, model.bottleneck]) if freeze_encoders: self.static_enc.trainable = False self.body_enc.trainable = False self.curv_enc.trainable = False self.encoder = Encoder128(latent_dim) self.decoder = Decoder128() if avg_garment_path != '': self.avg_garment = np.load(avg_garment_path) else: self.avg_garment = None self.cond_encoder = tf.keras.Sequential([tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dense(256, activation='relu'), tf.keras.layers.Dense(128, activation='relu'), tf.keras.layers.Dense(latent_dim),]) # @tf.function def sample(self, uv_template, uv_body_posed, uv_curv, uv_mask, nr_of_samples=4, fix_noise=False, zero_latent=False): if not fix_noise: eps = tf.random.normal(shape=(nr_of_samples, self.latent_dim)) else: eps = tf.random.normal(shape=(1, self.latent_dim)) eps = tf.tile(eps, [nr_of_samples,1]) uv_template = tf.tile(tf.transpose(uv_template, [1,2,0])[tf.newaxis,:,:,:], [nr_of_samples,1,1,1]) uv_body_posed = tf.tile(tf.transpose(uv_body_posed, [1,2,0])[tf.newaxis,:,:,:], [nr_of_samples,1,1,1]) if len(uv_curv.shape) == 3: uv_curv = tf.tile(uv_curv[tf.newaxis,:,:,:], [nr_of_samples,1,1,1]) uv_mask = tf.tile(uv_mask[tf.newaxis,:,:], [nr_of_samples,1,1]) # uv_template, uv_body_posed = tf.transpose(uv_template, [0,2,3,1]), tf.transpose(uv_body_posed, [0,2,3,1]) z_static = self.static_enc(uv_template) z_body = self.body_enc(uv_body_posed) z_curv = self.curv_enc(uv_curv) z_cond = tf.concat([z_static, z_body, z_curv], axis=-1) z_cond = self.cond_encoder(z_cond) if zero_latent: eps = tf.zeros_like(eps) z = tf.concat([eps, z_cond], axis=-1) x = self.decoder(z) x = x + self.avg_garment[tf.newaxis,:,:,:] x = x * uv_mask[:,:,:,tf.newaxis] return x def reparameterize(self, mean, logvar): eps = tf.random.normal(shape=mean.shape) return eps * tf.exp(logvar * .5) + mean def decode(self, z, apply_sigmoid=False): logits = self.decoder(z) if apply_sigmoid: probs = tf.sigmoid(logits) return probs return logits def call(self, inputs, training=None, zero_latent=False): uv_unposed, uv_template, uv_body_posed, uv_curv = inputs uv_unposed, uv_template, uv_body_posed = tf.transpose(uv_unposed, [0,2,3,1]), tf.transpose(uv_template, [0,2,3,1]), tf.transpose(uv_body_posed, [0,2,3,1]) z_static = self.static_enc(uv_template) z_body = self.body_enc(uv_body_posed) z_curv = self.curv_enc(uv_curv) x = tf.concat([uv_unposed, uv_template, uv_body_posed, uv_curv], axis=-1) mean, logvar = self.encoder(x) z = self.reparameterize(mean, logvar) z_cond = tf.concat([z_static, z_body, z_curv], axis=-1) z_cond = self.cond_encoder(z_cond) if zero_latent: z = tf.zeros_like(z) z = tf.concat([z, z_cond], axis=-1) # z = self.shuffle(z) # z = tf.concat([z, z_curv], axis=-1) x = self.decoder(z) # x = tf.transpose(x, [0,3,1,2]) # x = x * uv_mask[:,tf.newaxis,:,:] # x = tf.image.resize(x, (512, 256), tf.image.ResizeMethod.LANCZOS5) # x = x + tf.transpose(uv_shaped_body, [0,2,3,1]) if self.avg_garment is not None: x = x + self.avg_garment[tf.newaxis,:,:,:] # x = x * uv_mask[:,:,:,tf.newaxis] return x, mean, logvar, z