pyramid available with 128 res

This commit is contained in:
2022-09-15 10:14:35 +00:00
parent c3a2f558de
commit c6f6f8710d
6 changed files with 337 additions and 58 deletions
+50 -51
View File
@@ -1,5 +1,5 @@
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "1"
os.environ["CUDA_VISIBLE_DEVICES"] = "2"
import tensorflow as tf
gpus = tf.config.experimental.list_physical_devices('GPU')
@@ -37,7 +37,7 @@ from custom_utils.smpl import SMPL
from models.cvae_pyramid_model import Pyramid
name='cvae_pyr_1'
name='cvae_pyr_1_d128'
def init_wandb():
run = wandb.init(project='vae', name=name,
notes='learn offsets. smaller flattened latent vectors. with 25-85k pretraining. smaller batchsize. fixed balancing of reconst and kl loss for baseline. \
@@ -48,7 +48,7 @@ use mean l2 loss. small batch. l2 * 1000, balancing to 1 from 0.01\
fixed gender issue and retrained body encoder\
remove shape from unposed garment\
training on 100 garments with offsets over the average of these\
l2 loss on both 32 and full res, bottom predicts base, high res predicts offsets over this')
l2 loss on both 128 and full res, bottom predicts base, high res predicts offsets over this')
artifact = wandb.Artifact('code', type='code')
artifact.add_file('cvae_pyramid.py')
artifact.add_file('models/cvae_model.py')
@@ -60,9 +60,9 @@ l2 loss on both 32 and full res, bottom predicts base, high res predicts offsets
uv2mesh = UV2Mesh(res=256)
def plot_3d(mesh_gt, mesh_pred_unposed, mesh_pred_unposed_32, faces, collision, collision_faces, collision_color):
def plot_3d(mesh_gt, mesh_pred_unposed, mesh_pred_unposed_low, faces, collision, collision_faces, collision_color):
mesh_pred_unposed[:,2] += 1
mesh_pred_unposed_32[:,2] += 2
mesh_pred_unposed_low[:,2] += 2
collision[:,2] += 3
fig = go.Figure(data=[
go.Mesh3d(
@@ -82,9 +82,9 @@ def plot_3d(mesh_gt, mesh_pred_unposed, mesh_pred_unposed_32, faces, collision,
k = faces[:,2],
),
go.Mesh3d(
x=mesh_pred_unposed_32[:,0],
y=mesh_pred_unposed_32[:,2],
z=mesh_pred_unposed_32[:,1],
x=mesh_pred_unposed_low[:,0],
y=mesh_pred_unposed_low[:,2],
z=mesh_pred_unposed_low[:,1],
i = faces[:,0],
j = faces[:,1],
k = faces[:,2],
@@ -132,22 +132,22 @@ def train_step(batch):
with tf.GradientTape() as tape:
uv_curvature = tf.one_hot(batch['uv_curvature'], 7)
uv_curvature_32 = tf.one_hot(batch['uv_curvature_32'], 7)
uv_curvature_low = tf.one_hot(batch['uv_curvature' + resolution_modifier], 7)
pred_full, mean_full, logvar_full, pred_32, mean_32, logvar_32, = model([batch['uv_unposed'], batch['uv_static'], batch['uv_body_posed'], uv_curvature,
batch['uv_unposed_32'], batch['uv_static_32'], batch['uv_body_posed_32'], uv_curvature_32])
pred_full, mean_full, logvar_full, pred_low, mean_low, logvar_low, = model([batch['uv_unposed'], batch['uv_static'], batch['uv_body_posed'], uv_curvature,
batch['uv_unposed' + resolution_modifier], batch['uv_static' + resolution_modifier], batch['uv_body_posed' + resolution_modifier], uv_curvature_low])
mesh_pred_full = uv2mesh(pred_full)
mesh_pred_posed_full = smpl.run_garment(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_full)
mesh_pred_32 = uv2mesh(pred_32)
mesh_pred_posed_32 = smpl.run_garment(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_32)
mesh_pred_low = uv2mesh(pred_low)
mesh_pred_posed_low = smpl.run_garment(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_low)
mesh_orig = batch['mesh_unposed']
shape = batch['pose_shape'][:, 72:]
gender = tf.cast(tf.greater_equal(shape[:, 10] , 0.5), tf.int32)
shape_offsets = tf.stack([tf.gather(tf.tensordot(shape[i,:10][tf.newaxis, :], smpl.shapedirs[gender[i]], axes=[[1], [2]])[0,:,:], smpl.to_keep, axis=0) for i in range(shape.shape[0])])
mesh_pred_posed_full = mesh_pred_posed_full + shape_offsets * batch['mesh_mask'][:,:,tf.newaxis]
mesh_pred_posed_32 = mesh_pred_posed_32 + shape_offsets * batch['mesh_mask'][:,:,tf.newaxis]
mesh_pred_posed_low = mesh_pred_posed_low + shape_offsets * batch['mesh_mask'][:,:,tf.newaxis]
e_loss = tf.reduce_mean(edge_loss(mesh_pred_full, mesh_orig, batch['mesh_mask']))
c_loss = tf.reduce_mean(collision_penalty(mesh_pred_posed_full, batch['mesh_body_posed'], batch['mesh_mask']))
@@ -156,16 +156,16 @@ def train_step(batch):
ms_ssim = tf.image.ssim_multiscale(pred_full + 1, tf.transpose(batch['uv_unposed'], [0,2,3,1]) + 1, max_val=3)
kl = kl_loss(mean_full, logvar_full)
e_loss_32 = tf.reduce_mean(edge_loss(mesh_pred_32, mesh_orig, batch['mesh_mask']))
c_loss_32 = tf.reduce_mean(collision_penalty(mesh_pred_posed_32, batch['mesh_body_posed'], batch['mesh_mask']))
l1_loss_32 = tf.reduce_sum(tf.reduce_sum((tf.math.abs(tf.transpose(batch['uv_unposed_32'], [0,2,3,1]) - pred_32)), axis=-1), axis=[1, 2])
l2_loss_32 = 1e3 * tf.reduce_mean(tf.reduce_sum(((tf.transpose(batch['uv_unposed_32'], [0,2,3,1]) - pred_32) ** 2), axis=-1), axis=[1, 2])
ms_ssim_32 = tf.image.ssim(pred_32 + 1, tf.transpose(batch['uv_unposed_32'], [0,2,3,1]) + 1, max_val=3)
kl_32 = kl_loss(mean_full, logvar_full)
e_loss_low = tf.reduce_mean(edge_loss(mesh_pred_low, mesh_orig, batch['mesh_mask']))
c_loss_low = tf.reduce_mean(collision_penalty(mesh_pred_posed_low, batch['mesh_body_posed'], batch['mesh_mask']))
l1_loss_low = tf.reduce_sum(tf.reduce_sum((tf.math.abs(tf.transpose(batch['uv_unposed' + resolution_modifier], [0,2,3,1]) - pred_low)), axis=-1), axis=[1, 2])
l2_loss_low = 1e3 * tf.reduce_mean(tf.reduce_sum(((tf.transpose(batch['uv_unposed' + resolution_modifier], [0,2,3,1]) - pred_low) ** 2), axis=-1), axis=[1, 2])
ms_ssim_low = tf.image.ssim(pred_low + 1, tf.transpose(batch['uv_unposed' + resolution_modifier], [0,2,3,1]) + 1, max_val=3)
kl_low = kl_loss(mean_full, logvar_full)
reconstr_loss = l2_loss + l2_loss_32
reconstr_loss = l2_loss + l2_loss_low
reconstr_loss = tf.reduce_mean(reconstr_loss)
loss = reconstr_loss + balancing_coeff * (kl + kl_32)
loss = reconstr_loss + balancing_coeff * (kl + kl_low)
ms_ssim = tf.reduce_mean(ms_ssim)
l1_loss = tf.reduce_mean(l1_loss)
@@ -173,25 +173,24 @@ def train_step(batch):
mean = tf.reduce_mean(mean_full)
logvar = tf.reduce_mean(logvar_full)
ms_ssim_32 = tf.reduce_mean(ms_ssim_32)
l1_loss_32 = tf.reduce_mean(l1_loss_32)
l2_loss_32 = tf.reduce_mean(l2_loss_32)
mean_32 = tf.reduce_mean(mean_32)
logvar_32 = tf.reduce_mean(logvar_32)
ms_ssim_low = tf.reduce_mean(ms_ssim_low)
l1_loss_low = tf.reduce_mean(l1_loss_low)
l2_loss_low = tf.reduce_mean(l2_loss_low)
mean_low = tf.reduce_mean(mean_low)
logvar_low = tf.reduce_mean(logvar_low)
mesh_orig_2 = uv2mesh(batch['uv_unposed'])
metric = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (mesh_orig - mesh_pred_full) ** 2, axis=-1))) / tf.reduce_sum(batch['mesh_mask'])
metric_32 = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (mesh_orig - mesh_pred_32) ** 2, axis=-1))) / tf.reduce_sum(batch['mesh_mask'])
metric_low = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (mesh_orig - mesh_pred_low) ** 2, axis=-1))) / tf.reduce_sum(batch['mesh_mask'])
metric_2 = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (mesh_orig_2 - mesh_pred_full) ** 2, axis=-1))) / tf.reduce_sum(batch['mesh_mask'])
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
return { 'train/loss': loss, 'train/edge_loss': e_loss, 'train/collision_loss': c_loss, 'train/l1_loss': l1_loss, 'train/euclid_error': metric, 'train/ms_ssim': ms_ssim,
'train/euclid_error_reconst': metric_2, 'train/reconstr_loss': reconstr_loss, 'train/mean': mean, 'train/logvar': logvar, 'train/kl_loss': kl,
'train/var': np.e ** logvar, 'train/reg_coeff': reg_coeff, 'train/l2_loss': l2_loss,
'train/edge_loss_32': e_loss_32, 'train/collision_loss_32': c_loss_32, 'train/l1_loss_32': l1_loss_32, 'train/euclid_error_32': metric_32, 'train/ms_ssim_32': ms_ssim_32,
'train/mean_32': mean_32, 'train/logvar_32': logvar_32, 'train/kl_loss_32': kl_32,
'train/var_32': np.e ** logvar_32, 'train/l2_loss_32': l2_loss_32 }
'train/edge_loss' + resolution_modifier: e_loss_low, 'train/collision_loss' + resolution_modifier: c_loss_low, 'train/l1_loss' + resolution_modifier: l1_loss_low, 'train/euclid_error' + resolution_modifier: metric_low, 'train/ms_ssim' + resolution_modifier: ms_ssim_low,
'train/mean' + resolution_modifier: mean_low, 'train/logvar' + resolution_modifier: logvar_low, 'train/kl_loss' + resolution_modifier: kl_low,
'train/var' + resolution_modifier: np.e ** logvar_low, 'train/l2_loss' + resolution_modifier: l2_loss_low }
@tf.function
@@ -235,26 +234,26 @@ def valid_step(batch):
def plot_everything(batch: dict, type: str):
uv_curvature = tf.one_hot(batch['uv_curvature'], 7)
uv_curvature_32 = tf.one_hot(batch['uv_curvature_32'], 7)
pred_full, mean_full, logvar_full, pred_32, mean_32, logvar_32, = model([batch['uv_unposed'], batch['uv_static'], batch['uv_body_posed'], uv_curvature,
batch['uv_unposed_32'], batch['uv_static_32'], batch['uv_body_posed_32'], uv_curvature_32])
uv_curvature_low = tf.one_hot(batch['uv_curvature' + resolution_modifier], 7)
pred_full, mean_full, logvar_full, pred_low, mean_low, logvar_low, = model([batch['uv_unposed'], batch['uv_static'], batch['uv_body_posed'], uv_curvature,
batch['uv_unposed' + resolution_modifier], batch['uv_static' + resolution_modifier], batch['uv_body_posed' + resolution_modifier], uv_curvature_low])
mesh_pred_full = uv2mesh(pred_full)
mesh_pred_32 = uv2mesh(pred_32)
mesh_pred_low = uv2mesh(pred_low)
mesh_orig = batch['mesh_unposed']
orig_img = tf.transpose(batch['uv_unposed'], [0,2,3,1])
uv_static_img = tf.transpose(batch['uv_static'], [0,2,3,1])
uv_body_posed_img = tf.transpose(batch['uv_body_posed'], [0,2,3,1])
pred_img = pred_full
pred_32_up = tf.image.resize(pred_32, (512, 256), tf.image.ResizeMethod.LANCZOS5)
img = tf.concat((uv_static_img, uv_body_posed_img, orig_img, pred_img, pred_32_up), axis=2)
pred_low_up = tf.image.resize(pred_low, (512, 256), tf.image.ResizeMethod.LANCZOS5)
img = tf.concat((uv_static_img, uv_body_posed_img, orig_img, pred_img, pred_low_up), axis=2)
imgs = [wandb.Image((img[i] + 1) / 2.0) for i in range(4)]
F = np.load("custom_utils/smpl_faces.npy")
mask = batch['mesh_mask'].numpy().astype(bool)
garment_unposed, faces = maskFacesBatch(mesh_pred_full.numpy(), F, mask)
garment_unposed_32, faces = maskFacesBatch(mesh_pred_32.numpy(), F, mask)
garment_unposed_low, faces = maskFacesBatch(mesh_pred_low.numpy(), F, mask)
gt = [mesh_orig[i].numpy()[mask[i], :] for i in range(pred_full.shape[0])]
body = batch['mesh_body_posed'].numpy()
@@ -269,7 +268,7 @@ def plot_everything(batch: dict, type: str):
collision_faces = [np.concatenate((F, faces[i] + 14475), axis=0) for i in range(len(garment_posed))]
collision_color = [np.concatenate((np.ones_like(body[i], dtype=np.int32)*100, np.ones_like(garment_posed[i], dtype=np.int32)*230), axis=0) for i in range(len(garment_posed))]
figs = { type + "/garment_" + str(i): plot_3d(gt[i], garment_unposed[i], garment_unposed_32[i], faces[i], collision[i], collision_faces[i], collision_color[i]) for i in range(4) }
figs = { type + "/garment_" + str(i): plot_3d(gt[i], garment_unposed[i], garment_unposed_low[i], faces[i], collision[i], collision_faces[i], collision_color[i]) for i in range(4) }
mean_hist = wandb.Histogram(sequence=mean_full.numpy().mean(axis=0))
logvar_hist = wandb.Histogram(sequence=logvar_full.numpy().mean(axis=0))
@@ -277,8 +276,6 @@ def plot_everything(batch: dict, type: str):
return { **figs, **{ type + '/images': imgs, type + '/mean_hist': mean_hist, type + '/logvar_hist': logvar_hist } }
def sample(folder):
# run = wandb.init(project='vae_plots', name=folder.split('/')[-1])
load_model(model,folder)
@@ -400,6 +397,7 @@ def sample(folder):
print()
if __name__ == '__main__':
init_wandb()
allow_memory_growth()
@@ -408,6 +406,8 @@ if __name__ == '__main__':
args = vars(parser.parse_args())
batch_size = 4
low_resolution = 128
resolution_modifier = '_' + str(low_resolution)
smpl = SMPL()
@@ -416,31 +416,30 @@ if __name__ == '__main__':
'pose_shape': (72 + 11,),
# 'uv_posed': (3, 512, 256,),
'uv_body_posed': (3, 512, 256,),
'uv_body_posed_32': (3, 32, 16,),
'uv_body_posed' + resolution_modifier: (3, low_resolution, low_resolution//2,),
'mesh_body_posed': (14475, 3,),
'mesh_posed': (14475, 3,),
'mesh_unposed': (14475, 3,),
'uv_unposed': (3, 512, 256,),
'uv_unposed_32': (3, 32, 16,),
'uv_unposed' + resolution_modifier: (3, low_resolution, low_resolution//2,),
'uv_curvature': (512, 256),
'uv_curvature_32': (32, 16),
'uv_curvature' + resolution_modifier: (low_resolution, low_resolution//2),
}
signature_static = { 'uv_static': (3, 512, 256,),
'uv_static_32': (3, 32, 16,),
'uv_static' + resolution_modifier: (3, low_resolution, low_resolution//2,),
# 'mesh_static': (14475, 3,),
'mesh_mask': (14475,),
'uv_mask': (512, 256,),
'uv_shaped_body': (3, 512, 256,),
# 'uv_shaped_body': (3, 512, 256,),
}
dataset_train = factory.get_dataset(folder='/home/workspace/local-data/train_100', batch_size=batch_size, signature=signature_dynamic, use_filled=True, resolutions=[512, 32])
static_dataset_train = StaticDataset(folder='/home/workspace/local-data/train_100', signature=signature_static, use_filled=True, resolutions=[512, 32])
dataset_train = factory.get_dataset(folder='/home/workspace/local-data/train_100', batch_size=batch_size, signature=signature_dynamic, use_filled=True, resolutions=[512, low_resolution])
static_dataset_train = StaticDataset(folder='/home/workspace/local-data/train_100', signature=signature_static, use_filled=True, resolutions=[512, low_resolution])
dataset_valid = factory.get_dataset(folder='/home/workspace/local-data/jumpsuit_20/valid', batch_size=batch_size, signature=signature_dynamic)
static_dataset_valid = StaticDataset(folder='/home/workspace/local-data/jumpsuit_20/valid', signature=signature_static)
model = Pyramid(latent_dim=128)
model = Pyramid(latent_dim=128, low_res=low_resolution)
# lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(0.0001, decay_steps=30000, decay_rate=0.1, staircase=False)
optimizer = tf.optimizers.Adam(learning_rate=0.0001)
+2
View File
@@ -61,6 +61,8 @@ class StaticDataset():
assert set(resolutions).issubset(set([32, 128, 512]))
self.possible_keys = ['uv_static', 'uv_static_32', 'uv_static_128' 'mesh_static', 'mesh_mask', 'uv_mask', 'uv_shaped_body']
self.keys = [value for value in signature.keys() if value in self.possible_keys]
if 'uv_static_128' in signature.keys():
self.keys.append('uv_static_128')
self.resolutions = resolutions
self.filled = ''
if use_filled:
+51
View File
@@ -128,3 +128,54 @@ class AutoEncoder32(tf.keras.Model):
# x = x * uv_mask[:,:,:,tf.newaxis]
return x
class Decoder128(tf.keras.Model):
def __init__(self, bottleneck_size, latent_dim):
super(Decoder128, self).__init__()
self.dense = tf.keras.layers.Dense(4 * 2 * bottleneck_size)
self.reshape = tf.keras.layers.Reshape((4, 2, bottleneck_size))
self.decoder = ConvNeXtReverseLabels(depths=list(reversed([16, 16, 9, 9])), dims=list(reversed([bottleneck_size, 256, 128, 64])), nr_of_classes=7)
def call(self, inputs, training=None):
x = inputs
x = self.dense(x)
x = self.reshape(x)
x = self.decoder(x)
return x
class AutoEncoder128(tf.keras.Model):
def __init__(self):
super(AutoEncoder128, self).__init__()
bottleneck_size = 512
latent_dim = 128
self.encoder = ConvNeXt(depths=[16, 16, 9, 9], dims=[64, 128, 256, bottleneck_size], include_top=False)
self.bottleneck = Bottleneck(bottleneck_size, latent_dim)
self.decoder = Decoder128(bottleneck_size, latent_dim)
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.bottleneck(x, training=training)
x = self.decoder(x, training=training)
# x = tf.transpose(x, [0,3,1,2])
# x = x * uv_mask[:,:, tf.newaxis]
# x = x * uv_mask[:,tf.newaxis,:,:]
# x = x * uv_mask[:,:,:,tf.newaxis]
return x
+49
View File
@@ -121,3 +121,52 @@ class AutoEncoder32(tf.keras.Model):
# x = x * uv_mask[:,tf.newaxis,:,:]
return x
class Decoder128(tf.keras.Model):
def __init__(self, bottleneck_size, latent_dim):
super(Decoder128, self).__init__()
self.dense = tf.keras.layers.Dense(4 * 2 * bottleneck_size)
self.reshape = tf.keras.layers.Reshape((4, 2, bottleneck_size))
self.decoder = ConvNeXtReverse(depths=list(reversed([16, 16, 9, 9])), dims=list(reversed([bottleneck_size, 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 AutoEncoder128(tf.keras.Model):
def __init__(self):
super(AutoEncoder128, self).__init__()
bottleneck_size = 512
latent_dim = 128
self.encoder = ConvNeXt(depths=[16, 16, 9, 9], dims=[64, 128, 256, bottleneck_size], include_top=False)
self.bottleneck = Bottleneck(bottleneck_size, latent_dim)
self.decoder = Decoder128(bottleneck_size, latent_dim)
def call(self, inputs, training=None):
x = inputs
x = tf.transpose(x, [0,2,3,1])
x = self.encoder(x, training=training)
x = self.bottleneck(x, training=training)
x = self.decoder(x, training=training)
x = tf.transpose(x, [0,3,1,2])
# x = x * uv_mask[:,:, tf.newaxis]
# x = x * uv_mask[:,tf.newaxis,:,:]
return x
+175
View File
@@ -15,6 +15,10 @@ 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):
@@ -339,6 +343,177 @@ class CVAE32(tf.keras.Model):
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])
+10 -7
View File
@@ -7,15 +7,18 @@ import numpy as np
# import plotly.express as ex
from custom_utils.custom_utils import load_model
from models.cvae_model import CVAE, CVAE32
from models.cvae_model import CVAE, CVAE128, CVAE32
class Pyramid(tf.keras.Model):
def __init__(self, latent_dim=128, avg_garment_path=''):
def __init__(self, low_res=32, latent_dim=128, avg_garment_path=''):
super(Pyramid, self).__init__()
self.model_32 = CVAE32(latent_dim=latent_dim)
if low_res == 32:
self.model_low = CVAE32(latent_dim=latent_dim)
if low_res == 128:
self.model_low = CVAE128(latent_dim=latent_dim)
self.model_full = CVAE(latent_dim=latent_dim)
if avg_garment_path != '':
@@ -24,16 +27,16 @@ class Pyramid(tf.keras.Model):
self.avg_garment = None
def call(self, inputs, training=None):
uv_unposed, uv_static, uv_body_posed, uv_curv, uv_unposed_32, uv_static_32, uv_body_posed_32, uv_curv_32 = inputs
uv_unposed, uv_static, uv_body_posed, uv_curv, uv_unposed_low, uv_static_low, uv_body_posed_low, uv_curv_low = inputs
pred_32, mean_32, logvar_32, _ = self.model_32([uv_unposed_32, uv_static_32, uv_body_posed_32, uv_curv_32], training=training)
pred_low, mean_low, logvar_low, _ = self.model_low([uv_unposed_low, uv_static_low, uv_body_posed_low, uv_curv_low], training=training)
x = tf.image.resize(pred_32, (512, 256), tf.image.ResizeMethod.LANCZOS5)
x = tf.image.resize(pred_low, (512, 256), tf.image.ResizeMethod.LANCZOS5)
pred_full, mean_full, logvar_full, _ = self.model_full([uv_unposed, uv_static, uv_body_posed, uv_curv], training=training)
x = x + pred_full
return x, mean_full, logvar_full, pred_32, mean_32, logvar_32,
return x, mean_full, logvar_full, pred_low, mean_low, logvar_low,