Files
cvpr/models/cvae_curv_model.py
2023-03-02 16:13:18 +00:00

151 lines
5.6 KiB
Python

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 models.base import AEEncoderNew, VariationalEncoderNew, DecoderNew
class CVAE(tf.keras.Model):
def __init__(self, config):
super(CVAE, self).__init__()
self.latent_dim = config['latent_dim']
self.latent_dim = config['cvae']['latent_dim']
self.size = config['resolution']
self.static_enc : AEEncoderNew = AEEncoderNew(config['cond_ae_static']['encoder_depths'], config['cond_ae_static']['encoder_dims'], config['cond_ae_static']['kernel_size'], config['cond_ae_static']['activation'])
if config['static_model'] != '':
load_model(self.static_enc, config['static_model'] + '_enc')
self.body_enc : AEEncoderNew = AEEncoderNew(config['cond_ae_body']['encoder_depths'], config['cond_ae_body']['encoder_dims'], config['cond_ae_body']['kernel_size'])
if config['body_model'] != '':
load_model(self.body_enc, config['body_model'] + '_enc')
if config['freeze_encoders']:
self.static_enc.trainable = False
self.body_enc.trainable = False
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(self.latent_dim, activation='tanh'),])
self.encoder = VariationalEncoderNew(config['cvae']['encoder_depths'], config['cvae']['encoder_dims'], kernel_size=config['cvae']['kernel_size'], latent_dim=config['cvae']['latent_dim'])
self.decoder = DecoderNew(config['cvae']['decoder_depths'], config['cvae']['decoder_dims'], config['cvae']['kernel_size'], is_label=config['cvae']['is_label'])
self.reshape = tf.keras.layers.Reshape((8, 4, config['cvae']['latent_dim']))
self.add_noise = config['cvae']['add_noise']
self.noise_amount = config['cvae']['noise_amount']
# @tf.function
def sample_single(self, uv_template, uv_body_posed, uv_mask, eps=None, nr_of_samples=4):
if eps is None:
eps = tf.random.normal(shape=(nr_of_samples, self.latent_dim))
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])
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_cond = tf.concat([z_static, z_body], axis=-1)
z_cond = self.cond_encoder(z_cond)
z = tf.concat([eps, z_cond], axis=-1)
x = self.decoder(z)
x = x * uv_mask[:,:,:,tf.newaxis]
return x
def encode_conds(self, uv_template, uv_body_posed, training):
z_static = self.static_enc(uv_template, training=training)
z_body = self.body_enc(uv_body_posed, training=training)
z_cond = tf.concat([z_static, z_body], axis=-1)
z_cond = self.cond_encoder(z_cond, training=training)
return z_cond
def sample(self, uv_template, uv_body_posed, uv_mask, noise=None):
if noise is None:
eps = tf.random.normal(shape=(uv_template.shape[0], self.latent_dim))
else:
eps = noise
z_cond = self.encode_conds(uv_template, uv_body_posed, training=False)
z = tf.concat([eps, z_cond], axis=-1)
x = self.decoder(z, training=False)
# x = x * uv_mask[:,:,:,tf.newaxis]
# background = tf.ones((uv_template.shape[0],512,256,1)) * (1 - uv_mask[:,:,:,tf.newaxis])
# x = tf.concat((background, x), axis=-1)
# x = tf.math.softmax(x)
return x
# encoders have to be the same for curv_vae and general CVAE
def sample_without_encoding(self, z_static, z_body, uv_mask, eps=None):
eps = tf.random.normal(shape=(z_static.shape[0], self.latent_dim))
z_cond = tf.concat([z_static, z_body], axis=-1)
z = tf.concat([eps, z_cond], axis=-1)
x = self.decoder(z)
x = x * uv_mask[:,:,:,tf.newaxis]
return x
def reparameterize(self, mean, logvar, training, fix_noise=False):
if training == True:
if not fix_noise:
eps = tf.random.normal(shape=mean.shape)
else:
eps = tf.random.normal(shape=(1, mean.shape[1]))
eps = tf.tile(eps, [mean.shape[0],1])
out = eps * tf.exp(logvar * .5) + mean
else:
out = tf.exp(logvar * .5) + mean
return out
def call(self, inputs, training):
uv_template, uv_body_posed, uv_curv, uv_mask = inputs
x = tf.concat([uv_template, uv_body_posed, uv_curv], axis=-1)
mean, logvar = self.encoder(x)
z = self.reparameterize(mean, logvar, training=training)
z = self.reshape(z)
z_cond = self.encode_conds(uv_template, uv_body_posed, training=training)
z = tf.concat([z, z_cond], axis=-1)
x = self.decoder([z, uv_mask], training=training)
# x = x * uv_mask[:,:,:,tf.newaxis]
# background = tf.ones((4,512,256,1)) * (1 - uv_mask[:,:,:,tf.newaxis])
# x = tf.concat((background, x), axis=-1)
# x = tf.math.softmax(x)
return x, mean, logvar