Author SHA1 Message Date
luni 2489e28de4 fine tune 2023-01-31 16:31:30 +00:00
luni 6e24c1f41b also use vae latent for second level 2023-01-30 19:51:14 +00:00
luni 2b8abd776b calculate error 2023-01-29 10:09:58 +00:00
luni 1f8793e4e8 evaluate 2023-01-29 00:37:44 +00:00
luni 0dfe7f7659 create end2end laplacian pyramid 2023-01-26 20:39:54 +00:00
14 changed files with 169 additions and 481 deletions
+7
View File
@@ -1,3 +1,10 @@
nohup python cvae_pyramid.py --name="lhunor_pyr_abl_32_64_e2e_r3" > nohup/review/pyr_abl_32_64_e2e_r3.out 2>&1 &
nohup python cvae_pyramid.py --name="lhunor_pyr_abl_32_64_e2e_r3_pre" > nohup/review/pyr_abl_32_64_e2e_r3_pre.out 2>&1 &
nohup python cvae_pyramid.py --name="lhunor_pyr_abl_32_64_e2e_r3_fine" > nohup/review/pyr_abl_32_64_e2e_r3_fine.out 2>&1 &
nohup python evaluate_ae_pyramid.py --name evaluate_pyr_abl_32_64_e2e_r3 > nohup/evaluate/pyr_abl_32_64_e2e_r3.out 2>&1 &
nohup python calculate_error.py --name error_pyr_abl_32_64_e2e_r3 > nohup/error/pyr_abl_32_64_e2e_r3.out 2>&1 &
one final convolutional layer for smoothing, on the final coordinates
skirts!!!!
+1 -1
View File
@@ -95,7 +95,7 @@ def dice_dense(prediction, ground_truth, weight_map=None):
return tf.reduce_mean(dice_score)
# @tf.function
@tf.function
def train_step(batch):
with tf.GradientTape() as tape:
pred = model([batch['uv_curvature'], batch['uv_mask']], training=True)
+3 -3
View File
@@ -1,6 +1,6 @@
import os
import sys
from configs.config_abl_all_post import config
from configs.config_abl_pyr_32 import config
os.environ["CUDA_VISIBLE_DEVICES"] = config['gpu']
# import tensorflow as tf
@@ -59,13 +59,13 @@ if __name__ == '__main__':
folder = config['test_dir']
checkpoint_name = config['name']
iteration = ''
iteration = '200000'
F = np.load("custom_utils/smpl_faces" + skirt_modifier + ".npy").astype(np.int32)
garment_type_table = np.load('custom_data/garment_type_table_test.npy', allow_pickle=True).item()
output_folder = '/home/workspace/data/results/post/' + checkpoint_name + '-' + iteration
output_folder = '/home/workspace/data/results/' + checkpoint_name + '-' + iteration
faces_folder = '/home/workspace/data/results/support/faces' + ('_skirt' if config['is_skirt'] else '')
+1 -1
View File
@@ -19,7 +19,7 @@ config['only_curvatures'] = True
ablation_count = [config['use_skinning'], config['remove_global_orientation'], config['use_curvature'], config['use_extra_losses'], config['use_offsets']].count(False)
assert ablation_count == 1 or ablation_count == 0
config['gpu'] = '3'
config['gpu'] = '5'
config['name'] = 'abl_overfit_jumpsuit_2'
config['notes'] = 'remove other conditions from input as well'
+10 -6
View File
@@ -1,8 +1,9 @@
config = dict()
config['gpu'] = '0'
config['name'] = 'pyr_abl_32_r1'
config['name'] = 'pyr_abl_32_64_e2e_r3_fine_2'
config['notes'] = ''
config['tags'] = ['review_3']
# DON'T FORGET TO RESET SSIM LOSS USAGE
# DON'T FORGET TO CHECK MODEL LOADING
@@ -21,9 +22,12 @@ config['use_offsets'] = False
config['pyramid'] = dict()
config['pyramid']['resolutions'] = [32]
config['pyramid']['resolutions'] = [32, 64]
config['pyramid']['pretrained_pyramid'] = ''
config['pyramid']['final_upscale_enhancer'] = 'checkpoints/32_512_4'
config['pyramid']['final_upscale_enhancer'] = 'checkpoints/64_512_2'
config['pretrained_model'] = 'checkpoints/pyr_abl_32_64_e2e_r3_fine'
config['pretrained_model_iteration'] = ''
config['train_dir'] = '/home/workspace/local-data/train'
config['valid_dir'] = '/home/workspace/local-data/valid'
@@ -40,7 +44,7 @@ config['smpl_res'] = 14475
if config['is_cape']:
config['smpl_res'] = 3638
config['lr'] = 0.0001
config['lr'] = 0.00001
config['starting_balancing_coeff'] = 0.0001
config['reg_loss_coeff'] = 0.1 # set to 0 if don't want to use edge+collision
config['avg_garment_path'] = ''
@@ -64,7 +68,7 @@ config['pyramid']['latent_dim'] = config['latent_dim']
config['pyramid']['add_noise'] = True
config['pyramid']['noise_amount'] = 0.025
config['pyramid']['loss_weights'] = [1,1,1,1,1]
config['pyramid']['loss_weights'] = [2,1,1,1,1]
for res in config['pyramid']['resolutions']:
if res != 512:
@@ -149,7 +153,7 @@ for res in config['pyramid']['resolutions']:
level['decoder_depths'] = [9, 9]
level['decoder_dims'] = [256, 256]
level['avg_garment_path'] = ''
level['upscale_enhancer'] = ''#'checkpoints/up_3_d32_64_2'
level['upscale_enhancer'] = 'checkpoints/32_512_4'#'checkpoints/up_3_d32_64_2'
level['upscale_enhancer_freeze'] = True
config['pyramid']['levels'].append(level)
else:
-348
View File
@@ -1,348 +0,0 @@
import os
import sys
os.environ["CUDA_VISIBLE_DEVICES"] = '4'
import tqdm
import argparse
import random
import string
import time
import numpy as np
import trimesh as tm
import cmapy as cm
import scipy as sp
import scipy.io as sio
import plotly.graph_objects as go
from pyntcloud import PyntCloud
from scipy.sparse import csr_matrix, coo_matrix
from scipy.sparse.csgraph import floyd_warshall, dijkstra
from plotly.subplots import make_subplots
from custom_utils.custom_utils import _maskFaces
from postprocessing import fix_collision
from custom_utils.supersmpl_io import readPC2, readPC2Frame, writePC2, readOBJ
from custom_utils.custom_utils import _maskFaces
from auto_encoder_curv import dice_dense
def postprocess(mesh, faces, mask=None, body=None, do_smoothing=True):
if body is not None:
mesh_fixed = fix_collision(mesh, body[np.newaxis,:,:], mask[np.newaxis,:])[0].numpy()[mask, :]
else:
mesh_fixed = mesh
if do_smoothing:
m = tm.Trimesh(mesh_fixed, faces, process=False, validate=False)
outliers = np.array([len(v) for v in m.vertex_neighbors]) == 0
outliers = np.nonzero(outliers)[0]
outliers_n_neighbours = get_closest_n_points(mesh_fixed, outliers, 2)
outliers_faces = np.concatenate((outliers[:, np.newaxis], outliers_n_neighbours), axis=-1)
faces_fixed = np.concatenate((faces, outliers_faces), axis=0)
m = tm.Trimesh(mesh_fixed, faces_fixed, process=False, validate=False)
tm.smoothing.filter_humphrey(m, iterations=1, alpha=0.6, beta=0.4)
mesh = m.vertices
else:
mesh = mesh_fixed
return mesh
def export_to_ply(mesh, file):
ply = tm.exchange.ply.export_ply(mesh, encoding='binary', vertex_normal=True, include_attributes=True)
output_file = open(file, "wb+")
output_file.write(ply)
output_file.close()
def get_closest_n_points(verts, idx, n):
dist = sp.spatial.distance.cdist(verts[idx, :], verts)
dist[dist == 0] = 1e9
idx_sort = np.argsort(dist, axis=-1)
closest = idx_sort[:, :n]
return closest
def calculate_dist(folder, neighbourhood):
out = dict()
frames = sorted(os.listdir(os.path.join(folder, 'mesh_posed')))[int(args.start):int(args.end)]
for frame in tqdm.tqdm(frames):
id = frame.split('_')[0]
if id in out.keys():
continue
mask = np.load(os.path.join(folder, 'mesh_mask', f'{id}.npy')).astype(bool)
k_neighbors = np.argsort(dist[mask, :][:, mask], axis=-1)[:, :neighbourhood] #cloud.get_neighbors(k=neighbourhood)
out[id] = k_neighbors
return out
def histedges_equalN(x, nbin):
npt = len(x)
return np.interp(np.linspace(0, npt, nbin + 1),
np.arange(npt),
np.sort(x))
def get_bins(values, nr_of_bins):
flattened = []
for c in values:
flattened.extend(c.flatten())
flattened = np.array(flattened)
bins = histedges_equalN(flattened, nr_of_bins)
return bins
def generate_curvatures(v, faces, mask, neighbourhood=25, nr_of_labels=6):
# id = frame.split('_')[0]
# frame_nr = int(frame.split('_')[1].split('.')[0])
# mask = np.load(os.path.join(folder, 'mesh_mask', f'{id}.npy')).astype(bool)
# _, faces = _maskFaces(np.zeros((14475,3)), F, mask)
# v = np.load(os.path.join(folder, 'mesh_posed', f'{id}_{frame_nr}.npz'))['mesh_posed'][mask,:]
m = tm.Trimesh(v, faces, process=False, validate=False)
outliers = np.array([len(v) for v in m.vertex_neighbors]) == 0
outliers = np.nonzero(outliers)[0]
outliers_n_neighbours = get_closest_n_points(v, outliers, 2)
outliers_faces = np.concatenate((outliers[:, np.newaxis], outliers_n_neighbours), axis=-1)
faces = np.concatenate((faces, outliers_faces), axis=0)
verts = v
m = tm.Trimesh(verts, faces, process=False, validate=False)
export_to_ply(m, temp_file)
cloud = PyntCloud.from_file(temp_file)
k_neighbors = np.argsort(dist[mask, :][:, mask], axis=-1)[:, :neighbourhood]
# k_neighbors = cloud.get_neighbors(k=neighbourhood)
# tree = sp.spatial.cKDTree(verts)
# k_neighbors = tree.query(verts, 25)[1]
#k_neighbors = k_neighbors_cache[id] # np.argsort(dist[mask, :][:, mask], axis=-1)[:, :neighbourhood] #cloud.get_neighbors(k=neighbourhood)
ev = cloud.add_scalar_field("eigen_values", k_neighbors=k_neighbors)
cloud.add_scalar_field("curvature", ev=ev)
curvature = np.array(cloud.points["curvature(" + str(neighbourhood+1) + ")"])
bins = np.load(f'custom_data/train_bins.npy')
# bins = get_bins(curvature, nr_of_labels)
labels = np.linspace(0, bins.shape[0] - 2, bins.shape[0] - 1)
frame_labels = np.zeros((curvature.shape[0]), dtype=np.float32)
for j in range(bins.shape[0] - 2):
frame_labels[(curvature >= bins[j]) * (curvature < bins[j+1])] = labels[j]
frame_labels[curvature >= bins[-2]] = labels[-1]
return frame_labels, curvature
import tensorflow as tf
from configs.config_abl_overfit_jumpsuit_2 import config
from custom_utils.custom_utils import batch_to_dict, load_model, plot_3d, UV2Mesh, get_summary_html, maskFacesBatch, _maskFaces, plot_3d_collision, UV2MeshLabel
from custom_utils.smpl import SMPL
from models.cvae_model import CVAE
uv2mesh = UV2Mesh(res=256, is_skirt=False, is_adaptive=False, is_smpl_orig=False)
uv2meshlabel = UV2MeshLabel(res=256, is_skirt=False)
def get_prediction(folder, frame, curv):
smpl = SMPL(use_one_hot=False, orig_smpl=False)
model = CVAE(config)
load_model(model, 'checkpoints/' + config['name'])
id = frame.split('_')[0]
frame_nr = frame.split('_')[1].split('.')[0]
mesh_mask = np.load(os.path.join(folder, 'mesh_mask', f'{id}.npy')).astype(bool)
uv_mask = np.load(os.path.join(folder, 'uv_mask', f'{id}.npz'))['uv_mask'].astype(np.float32)
pose_shape = np.load(os.path.join(folder, 'pose_shape', f'{id}_{frame_nr}.npy')).astype(np.float32)
pose_shape[:3] = 0
uv_unposed = np.load(os.path.join(folder, 'uv_unposed_no_shape', f'{id}_{frame_nr}.npz'))['uv_unposed_no_shape']
uv_static = np.load(os.path.join(folder, 'uv_static', f'{id}.npz'))['uv_static']
uv_body_posed = np.load(os.path.join(folder, 'uv_posed_body_no_orient_2', f'{id}_{frame_nr}.npz'))['uv_posed_body_no_orient']
pred, _, _ = model([uv_unposed[None,:,:,:], uv_static[None,:,:,:], uv_body_posed[None,:,:,:], curv[None,:,:,:], uv_mask[None,:,:]], training=False)
mesh_pred = uv2mesh(pred)
shape = pose_shape[None, 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_shaped = mesh_pred + shape_offsets * mesh_mask[tf.newaxis,:,tf.newaxis]
mesh_pred_posed = smpl.run_garment(pose_shape[None, :72], pose_shape[None, 72:], mesh_pred_shaped)
return mesh_pred_posed.numpy()[0,mesh_mask,:]
def visualize_curvature_labels(folder, results_folder, frame):
id = frame.split('_')[0]
frame_nr = frame.split('_')[1].split('.')[0]
mask = np.load(os.path.join(folder, 'mesh_mask', f'{id}.npy')).astype(bool)
_, faces = _maskFaces(np.zeros((14475,3)), F, mask)
verts = np.load(os.path.join(folder, 'mesh_posed', f'{id}_{frame_nr}.npz'))['mesh_posed'][mask,:]
pred = np.load(os.path.join(results_folder, frame + '.npy'))
pred = postprocess(pred, faces)
uv_curvature = np.load(os.path.join(folder, 'uv_curvature', f'{id}_{frame_nr}.npz'))['curvature_uv']
mesh_curvature = np.load(os.path.join(folder, 'mesh_curvature', f'{id}_{frame_nr}.npz'))['mesh_curvature'][mask]
mesh_curvature_raw = np.load(os.path.join(folder, 'mesh_curvature_raw', f'{id}_{frame_nr}.npz'))['mesh_curvature_raw'][mask]
uv_curvature = tf.one_hot(uv_curvature, 7)
pred_new = get_prediction(folder, frame, uv_curvature)
pred_new = postprocess(pred_new, faces)
curvature_labels_gt, curv_gt = generate_curvatures(verts, faces, mask, 25)
curvature_labels_pred, _ = generate_curvatures(pred, faces, mask, 25)
curvatures_new = (uv2meshlabel(uv_curvature[None,:,:,:])[0].numpy() * mask[:,None])[mask, :]
curvatures_pred_new, curv_gt_new = generate_curvatures(pred_new, faces, mask, 25)
dice = dice_dense(tf.one_hot(curvature_labels_pred, 7)[None,:], tf.one_hot(curvature_labels_gt, 7)[None,:])
dice_new = dice_dense(tf.one_hot(curvatures_pred_new, 7)[None,:], curvatures_new[None,:])
curvatures_new = curvatures_new.argmax(axis=-1) - 1
colors_binned_all = []
for curvature_labels in [curvature_labels_gt, curvature_labels_pred, curvatures_new, curvatures_pred_new]:
colors = np.array([cm.color('jet', 1 - i) for i in np.linspace(0, 1, int(curvature_labels.max()+1))])
colors_binned = np.zeros((curvature_labels.shape[0], 3))
for i in range(int(curvature_labels.max())+1):
# print(np.count_nonzero(curvature_labels == i))
colors_binned[curvature_labels == i, :] = colors[i]
colors_binned_all.append(colors_binned)
fig = make_subplots(rows=1, cols=4, start_cell="top-left", specs = [ [{ 'type': 'scene' } for _ in range(4)] ])
fig.add_trace(go.Mesh3d(
# 8 vertices of a cube
x=verts[:,0],
y=verts[:,1],
z=verts[:,2],
# i, j and k give the vertices of triangles
i = faces[:,0],
j = faces[:,1],
k = faces[:,2],
vertexcolor=colors_binned_all[0]
),
row=1, col=1)
fig.add_trace(go.Mesh3d(
# 8 vertices of a cube
x=-pred[:,0],
y=pred[:,2],
z=pred[:,1],
# i, j and k give the vertices of triangles
i = faces[:,0],
j = faces[:,1],
k = faces[:,2],
vertexcolor=colors_binned_all[1],
text=f'dice: {dice}'
),
row=1, col=2)
fig.add_trace(go.Mesh3d(
# 8 vertices of a cube
x=verts[:,0],
y=verts[:,1],
z=verts[:,2],
# i, j and k give the vertices of triangles
i = faces[:,0],
j = faces[:,1],
k = faces[:,2],
vertexcolor=colors_binned_all[2]
),
row=1, col=3)
fig.add_trace(go.Mesh3d(
# 8 vertices of a cube
x=-pred_new[:,0],
y=pred_new[:,2],
z=pred_new[:,1],
# i, j and k give the vertices of triangles
i = faces[:,0],
j = faces[:,1],
k = faces[:,2],
vertexcolor=colors_binned_all[3],
text=f'dice: {dice_new}'
),
row=1, col=4)
fig.update_layout(scene_aspectmode='manual', scene_aspectratio=dict(x=1, y=1, z=1),
scene2_aspectmode='manual', scene2_aspectratio=dict(x=1, y=1, z=1),
scene3_aspectmode='manual', scene3_aspectratio=dict(x=1, y=1, z=1),
scene4_aspectmode='manual', scene4_aspectratio=dict(x=1, y=1, z=1),
# scene5_aspectmode='manual', scene5_aspectratio=dict(x=1, y=1, z=1),
)
helper = dict(xaxis = dict(range=[-1,1], showbackground=False, showticklabels=False, showaxeslabels=False, showspikes=False, visible=False),
yaxis = dict(range=[-1,1], showbackground=False, showticklabels=False, showaxeslabels=False, showspikes=False, visible=False),
zaxis = dict(range=[-1,1], showbackground=False, showticklabels=False, showaxeslabels=False, showspikes=False, visible=False),)
fig.update_layout(scene = helper,
scene2 = helper,
scene3 = helper,
scene4 = helper,
# scene5 = helper,
)
# meshes = [go.Mesh3d(
# x=x[:,0],
# y=x[:,1],
# z=x[:,2],
# i = faces[:,0],
# j = faces[:,1],
# k = faces[:,2],
# vertexcolor=colors_binned
# )]
# fig = go.Figure(data=meshes)
# fig.update_layout(scene_aspectmode='manual', scene_aspectratio=dict(x=1, y=1, z=1))
# fig.update_layout(
# scene = dict(
# xaxis = dict(nticks=4, range=[-1,1],),
# yaxis = dict(nticks=4, range=[-1,1],),
# zaxis = dict(nticks=4, range=[-1,1],),)
# )
return fig, dice
import wandb
def init_wandb():
run = wandb.init(project='plots', name='review_5', dir='/home/workspace/local-data/temp/')
artifact = wandb.Artifact('code', type='code')
artifact.add_file('curvature_analysis.py')
run.log_artifact(artifact)
if __name__ == '__main__':
# init_wandb()
is_skirt = False
skirt_modifier = '_skirt' if is_skirt else ''
F = np.load("custom_utils/smpl_faces" + skirt_modifier + ".npy").astype(np.int32)
# k_neighbours(k=25)
folder = '/home/workspace/local-data/train'
results_folder = '/home/workspace/data/results/post/abl_overfit_jumpsuit_2-'
frames_file = 'frames_jumpsuit_30k.txt'
frames = []
with open(os.path.join(folder, frames_file), 'r') as f:
lines = f.readlines()
lines = [line.strip() for line in lines]
frames = lines
temp_file = '/home/workspace/local-data/temp/' + ''.join(random.choice(string.ascii_lowercase) for i in range(10)) + '.ply'
if not is_skirt:
dist = np.load('custom_data/dijkstra.npy')
else:
dist = np.load('custom_data/dijkstra_skirt.npy')
i = 0
while True:
# frame = np.random.choice(frames)
frame = '02806_129'
fig, dice = visualize_curvature_labels(folder, results_folder, frame)
wandb.log({f'{frame}-dice:{dice}': fig}, step=i)
i += 1
print(frame)
Binary file not shown.
+1 -1
View File
@@ -45,7 +45,7 @@ class UV2Mesh(tf.keras.Model):
if uv.shape[1] == 3:
uv = tf.transpose(uv, [0,2,3,1])
if uv.shape[1] != 512:
uv = tf.image.resize(uv, (512, 256), tf.image.ResizeMethod.LANCZOS5)
uv = tf.image.resize(uv, (512, 256), tf.image.ResizeMethod.BILINEAR)
batch_size = uv.shape[0]
+2 -2
View File
@@ -1,6 +1,6 @@
import os
import sys
from configs.config_abl_overfit_jumpsuit_2 import config
from configs.config_abl_all_post import config
os.environ["CUDA_VISIBLE_DEVICES"] = config['gpu']
import tensorflow as tf
@@ -41,7 +41,7 @@ from losses import collision_loss as collision_penalty
from custom_utils.custom_utils import batch_to_dict, load_model, plot_3d, UV2Mesh, get_summary_html, maskFacesBatch, _maskFaces, plot_3d_collision
from dataset import DatasetFactory, StaticDataset
from custom_utils.smpl import SMPL
from models.cvae_model import CVAE
from models.cvae_model import CVAENew as CVAE
def init_wandb():
+116 -106
View File
@@ -1,6 +1,6 @@
import os
import sys
from configs.config_abl_pyr_32_skirt import config
from configs.config_abl_pyr_32 import config
os.environ["CUDA_VISIBLE_DEVICES"] = config['gpu']
import tensorflow as tf
@@ -210,73 +210,77 @@ def plot_3d(mesh_gt, mesh_pred_unposed_levels, faces, mesh_posed, collision, col
return fig
# @tf.function
@tf.function
def train_step(batch):
levels_input, conds = group_inputs_for_levels(batch, config)
with tf.GradientTape() as tape:
out_levels = model([levels_input, conds], training=True)
if config['use_skinning']:
mesh_orig, uv_orig = batch['mesh_unposed'], batch['uv_unposed']
else:
mesh_orig, uv_orig = batch['mesh_posed'], batch['uv_posed']
mesh_orig, uv_orig = batch['mesh_unposed'], batch['uv_unposed']
output = dict()
reconstr_loss_total = 0
kl_total = 0
#for i, res in enumerate(config['pyramid']['resolutions']):
i = -1
res = config['pyramid']['resolutions'][-1]
res_modifier = '_' + str(res) if res != 512 else ''
pred, mean, logvar = out_levels[i]
for i, res in enumerate(config['pyramid']['resolutions']):
# i = -1
# res = config['pyramid']['resolutions'][-1]
if res != 512:
if i == len(config['pyramid']['resolutions']) - 1:
res_modifier = ''
else:
res_modifier = '_' + str(res)
else:
res_modifier = ''
mesh_pred = uv2mesh(pred)
pred, mean, logvar = out_levels[i]
if config['use_skinning']:
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 = uv2mesh(pred)
mesh_pred_shaped = mesh_pred + shape_offsets * batch['mesh_mask'][:,:,tf.newaxis]
mesh_pred_posed = smpl.run_garment(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_shaped)
else:
mesh_pred_posed = mesh_pred
if config['use_skinning']:
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])])
# is the output already masked?
mesh_pred_shaped = mesh_pred + shape_offsets * batch['mesh_mask'][:,:,tf.newaxis]
mesh_pred_posed = smpl.run_garment(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_shaped)
else:
mesh_pred_posed = mesh_pred
e_loss = tf.reduce_mean(edge_loss(mesh_pred, mesh_orig, batch['mesh_mask']))
c_loss, c_ratio = collision_penalty(mesh_pred_posed, batch['mesh_body_posed'], batch['mesh_mask'])
c_loss, c_ratio = tf.reduce_mean(c_loss), tf.reduce_mean(c_ratio)
l2_loss = tf.reduce_mean(1e3 * tf.reduce_mean(tf.reduce_sum(((uv_orig - pred) ** 2), axis=-1), axis=[1, 2]))
# ms_ssim = tf.reduce_mean(tf.image.ssim_multiscale(pred + 5, batch['uv_unposed'] + 5, max_val=10, power_factors=(0.5, 0.2, 0.1, 0.1, 0.1)))
# ms_ssim = tf.reduce_mean(tf.image.ssim(pred + 1, batch['uv_unposed'] + 1, max_val=3))
l2_mesh_loss = tf.reduce_mean(1e3 * tf.reduce_mean(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (batch['mesh_posed'] - mesh_pred_posed) ** 2, axis=-1), axis=-1))
n_loss = normal_loss(mesh_pred_posed, batch['mesh_posed'], batch['mesh_mask'], is_skirt=config['is_skirt'])
kl = kl_loss(mean, logvar)
# is the output already masked?
if config['use_extra_losses']:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss + l2_mesh_loss)
if not config['is_cape']:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (e_loss + c_loss) * config['reg_loss_coeff']
else:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss)
e_loss = tf.reduce_mean(edge_loss(mesh_pred, mesh_orig, batch['mesh_mask']))
c_loss, c_ratio = collision_penalty(mesh_pred_posed, batch['mesh_body_posed'], batch['mesh_mask'])
c_loss, c_ratio = tf.reduce_mean(c_loss), tf.reduce_mean(c_ratio)
l2_loss = tf.reduce_mean(1e3 * tf.reduce_mean(tf.reduce_sum(((batch['uv_unposed' + res_modifier] - pred) ** 2), axis=-1), axis=[1, 2]))
# ms_ssim = tf.reduce_mean(tf.image.ssim_multiscale(pred + 5, batch['uv_unposed'] + 5, max_val=10, power_factors=(0.5, 0.2, 0.1, 0.1, 0.1)))
# ms_ssim = tf.reduce_mean(tf.image.ssim(pred + 1, batch['uv_unposed'] + 1, max_val=3))
l2_mesh_loss = tf.reduce_mean(1e3 * tf.reduce_mean(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (batch['mesh_posed'] - mesh_pred_posed) ** 2, axis=-1), axis=-1))
n_loss = normal_loss(mesh_pred_posed, batch['mesh_posed'], batch['mesh_mask'], is_skirt=config['is_skirt'])
kl = kl_loss(mean, logvar)
# if config['use_norm_loss'] and step > 2000:
# reconstr_loss_total = reconstr_loss_total + n_loss * config['reg_loss_coeff']
kl_total += kl
if config['use_extra_losses']:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss + l2_mesh_loss)
if not config['is_cape']:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (e_loss + c_loss) * config['reg_loss_coeff']
else:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss)
mean = tf.reduce_mean(mean)
logvar = tf.reduce_mean(logvar)
# if config['use_norm_loss'] and step > 2000:
# reconstr_loss_total = reconstr_loss_total + n_loss * config['reg_loss_coeff']
kl_total += kl
metric = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (mesh_orig - mesh_pred) ** 2, axis=-1))) / tf.reduce_sum(batch['mesh_mask'])
mean = tf.reduce_mean(mean)
logvar = tf.reduce_mean(logvar)
output = { **output, **{ 'train/edge_loss' + res_modifier: e_loss, 'train/collision_loss' + res_modifier: c_loss,'train/euclid_error' + res_modifier: metric,
'train/mean' + res_modifier: mean, 'train/logvar' + res_modifier: logvar, 'train/kl_loss' + res_modifier: kl,
'train/var' + res_modifier: np.e ** logvar, 'train/l2_loss' + res_modifier: l2_loss, 'train/normal_loss': n_loss,
'train/euclid_error': metric, 'train/l2_mesh_loss': l2_mesh_loss } } # 'train/ms_ssim' + res_modifier: ms_ssim,
metric = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (mesh_orig - mesh_pred) ** 2, axis=-1))) / tf.reduce_sum(batch['mesh_mask'])
output = { **output, **{ 'train/edge_loss' + res_modifier: e_loss, 'train/collision_loss' + res_modifier: c_loss,'train/euclid_error' + res_modifier: metric,
'train/mean' + res_modifier: mean, 'train/logvar' + res_modifier: logvar, 'train/kl_loss' + res_modifier: kl,
'train/var' + res_modifier: np.e ** logvar, 'train/l2_loss' + res_modifier: l2_loss, 'train/normal_loss': n_loss,
'train/euclid_error': metric, 'train/l2_mesh_loss': l2_mesh_loss } } # 'train/ms_ssim' + res_modifier: ms_ssim,
loss = reconstr_loss_total + balancing_coeff * kl_total
@@ -290,66 +294,69 @@ def valid_step(batch):
levels_input, conds = group_inputs_for_levels(batch, config)
out_levels = model([levels_input, conds], training=False)
if config['use_skinning']:
mesh_orig, uv_orig = batch['mesh_unposed'], batch['uv_unposed']
else:
mesh_orig, uv_orig = batch['mesh_posed'], batch['uv_posed']
mesh_orig, uv_orig = batch['mesh_unposed'], batch['uv_unposed']
output = dict()
reconstr_loss_total = 0
kl_total = 0
#for i, res in enumerate(config['pyramid']['resolutions']):
i = -1
res = config['pyramid']['resolutions'][-1]
res_modifier = '_' + str(res) if res != 512 else ''
pred, mean, logvar = out_levels[i]
for i, res in enumerate(config['pyramid']['resolutions']):
# i = -1
# res = config['pyramid']['resolutions'][-1]
if res != 512:
if i == len(config['pyramid']['resolutions']) - 1:
res_modifier = ''
else:
res_modifier = '_' + str(res)
else:
res_modifier = ''
mesh_pred = uv2mesh(pred)
pred, mean, logvar = out_levels[i]
if config['use_skinning']:
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 = uv2mesh(pred)
mesh_pred_shaped = mesh_pred + shape_offsets * batch['mesh_mask'][:,:,tf.newaxis]
mesh_pred_posed = smpl.run_garment(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_shaped)
else:
mesh_pred_posed = mesh_pred
# is the output already masked?
if config['use_skinning']:
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])])
e_loss = tf.reduce_mean(edge_loss(mesh_pred, mesh_orig, batch['mesh_mask']))
c_loss, c_ratio = collision_penalty(mesh_pred_posed, batch['mesh_body_posed'], batch['mesh_mask'])
c_loss, c_ratio = tf.reduce_mean(c_loss), tf.reduce_mean(c_ratio)
l2_loss = tf.reduce_mean(1e3 * tf.reduce_mean(tf.reduce_sum(((uv_orig - pred) ** 2), axis=-1), axis=[1, 2]))
# ms_ssim = tf.reduce_mean(tf.image.ssim_multiscale(pred + 5, batch['uv_unposed'] + 5, max_val=10, power_factors=(0.5, 0.2, 0.1, 0.1, 0.1)))
# ms_ssim = tf.reduce_mean(tf.image.ssim(pred + 1, batch['uv_unposed'] + 1, max_val=3))
l2_mesh_loss = tf.reduce_mean(1e3 * tf.reduce_mean(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (batch['mesh_posed'] - mesh_pred_posed) ** 2, axis=-1), axis=-1))
n_loss = normal_loss(mesh_pred_posed, batch['mesh_posed'], batch['mesh_mask'], is_skirt=config['is_skirt'])
kl = kl_loss(mean, logvar)
mesh_pred_shaped = mesh_pred + shape_offsets * batch['mesh_mask'][:,:,tf.newaxis]
mesh_pred_posed = smpl.run_garment(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_shaped)
else:
mesh_pred_posed = mesh_pred
# is the output already masked?
if config['use_extra_losses']:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss + l2_mesh_loss)
if not config['is_cape']:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (e_loss + c_loss) * config['reg_loss_coeff']
else:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss)
# if config['use_norm_loss'] and step > 2000:
# reconstr_loss_total = reconstr_loss_total + n_loss * config['reg_loss_coeff']
e_loss = tf.reduce_mean(edge_loss(mesh_pred, mesh_orig, batch['mesh_mask']))
c_loss, c_ratio = collision_penalty(mesh_pred_posed, batch['mesh_body_posed'], batch['mesh_mask'])
c_loss, c_ratio = tf.reduce_mean(c_loss), tf.reduce_mean(c_ratio)
l2_loss = tf.reduce_mean(1e3 * tf.reduce_mean(tf.reduce_sum(((batch['uv_unposed' + res_modifier] - pred) ** 2), axis=-1), axis=[1, 2]))
# ms_ssim = tf.reduce_mean(tf.image.ssim_multiscale(pred + 5, batch['uv_unposed'] + 5, max_val=10, power_factors=(0.5, 0.2, 0.1, 0.1, 0.1)))
# ms_ssim = tf.reduce_mean(tf.image.ssim(pred + 1, batch['uv_unposed'] + 1, max_val=3))
l2_mesh_loss = tf.reduce_mean(1e3 * tf.reduce_mean(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (batch['mesh_posed'] - mesh_pred_posed) ** 2, axis=-1), axis=-1))
n_loss = normal_loss(mesh_pred_posed, batch['mesh_posed'], batch['mesh_mask'], is_skirt=config['is_skirt'])
kl = kl_loss(mean, logvar)
if config['use_extra_losses']:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss + l2_mesh_loss)
if not config['is_cape']:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (e_loss + c_loss) * config['reg_loss_coeff']
else:
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss)
kl_total += kl
# if config['use_norm_loss'] and step > 2000:
# reconstr_loss_total = reconstr_loss_total + n_loss * config['reg_loss_coeff']
kl_total += kl
mean = tf.reduce_mean(mean)
logvar = tf.reduce_mean(logvar)
mean = tf.reduce_mean(mean)
logvar = tf.reduce_mean(logvar)
metric = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (mesh_orig - mesh_pred) ** 2, axis=-1))) / tf.reduce_sum(batch['mesh_mask'])
metric = tf.reduce_sum(tf.math.sqrt(tf.reduce_sum(batch['mesh_mask'][:,:,tf.newaxis] * (mesh_orig - mesh_pred) ** 2, axis=-1))) / tf.reduce_sum(batch['mesh_mask'])
output = { **output, **{ 'valid/edge_loss' + res_modifier: e_loss, 'valid/collision_loss' + res_modifier: c_loss,'valid/euclid_error' + res_modifier: metric,
'valid/mean' + res_modifier: mean, 'valid/logvar' + res_modifier: logvar, 'valid/kl_loss' + res_modifier: kl,
'valid/var' + res_modifier: np.e ** logvar, 'valid/l2_loss' + res_modifier: l2_loss, 'valid/normal_loss': n_loss,
'valid/euclid_error': metric, 'valid/l2_mesh_loss': l2_mesh_loss } } # 'valid/ms_ssim' + res_modifier: ms_ssim,
output = { **output, **{ 'valid/edge_loss' + res_modifier: e_loss, 'valid/collision_loss' + res_modifier: c_loss,'valid/euclid_error' + res_modifier: metric,
'valid/mean' + res_modifier: mean, 'valid/logvar' + res_modifier: logvar, 'valid/kl_loss' + res_modifier: kl,
'valid/var' + res_modifier: np.e ** logvar, 'valid/l2_loss' + res_modifier: l2_loss, 'valid/normal_loss': n_loss,
'valid/euclid_error': metric, 'valid/l2_mesh_loss': l2_mesh_loss } } # 'valid/ms_ssim' + res_modifier: ms_ssim,
loss = reconstr_loss_total + balancing_coeff * kl_total
@@ -733,7 +740,7 @@ def speed_step(levels_input, conds):
if __name__ == '__main__':
# init_wandb()
init_wandb()
parser = argparse.ArgumentParser(description='')
parser.add_argument('--name', type=str, default='lhunor')
args = vars(parser.parse_args())
@@ -800,16 +807,19 @@ if __name__ == '__main__':
# assert len(config['pyramid']['resolutions']) == 1
load_model(model, config['pretrained_model'], iteration=config['pretrained_model_iteration'])
if len(config['pyramid']['resolutions']) == 1:
model.static_enc.trainable = False
model.body_enc.trainable = False
model.curv_enc.trainable = False
else:
load_model(model, config['pyramid']['pretrained_pyramid'], iteration=(config['pyramid']['pretrained_pyramid_iteration'] if 'pretrained_pyramid_iteration' in config.keys() else ''))
model.static_enc.trainable = False
model.body_enc.trainable = False
model.curv_enc.trainable = False
model.cond_encoder.trainable = False
model.static_enc.trainable = False
model.body_enc.trainable = False
model.curv_enc.trainable = False
# model.trainable = False
# model.cond_encoder_2.trainable = True
# if len(config['pyramid']['resolutions']) == 1:
# else:
# load_model(model, config['pyramid']['pretrained_pyramid'], iteration=(config['pyramid']['pretrained_pyramid_iteration'] if 'pretrained_pyramid_iteration' in config.keys() else ''))
# model.static_enc.trainable = False
# model.body_enc.trainable = False
# model.curv_enc.trainable = False
# model.cond_encoder.trainable = False
# load_model(model.levels[0].upscale_enhancer, config['pyramid']['levels'][0]['upscale_enhancer'])
# model.levels[0].upscale_enhancer.trainable = False
@@ -822,8 +832,8 @@ if __name__ == '__main__':
load_model(model.upscale_enhancer, config['pyramid']['final_upscale_enhancer'])
model.upscale_enhancer.trainable = False
for i in range(len(model.levels)-1):
model.levels[i].trainable = False
# for i in range(len(model.levels)-1):
# model.levels[i].trainable = False
# load_model(model.cond_encoder, config['pyramid']['pretrained_pyramid'])
# load_model(model.levels[0], config['pyramid']['pretrained_pyramid'])
+3 -3
View File
@@ -1,6 +1,6 @@
import os
import sys
from configs.config_abl_overfit_jumpsuit_2 import config
from configs.config_abl_all_post import config
os.environ["CUDA_VISIBLE_DEVICES"] = config['gpu']
import tensorflow as tf
@@ -42,7 +42,7 @@ from losses import collision_loss as collision_penalty
from custom_utils.custom_utils import batch_to_dict, load_model, plot_3d, UV2Mesh, get_summary_html, maskFacesBatch, _maskFaces, plot_3d_collision
from dataset import DatasetFactory, StaticDataset
from custom_utils.smpl import SMPL
from models.cvae_model import CVAE
from models.cvae_model import CVAENew as CVAE
from custom_utils.supersmpl_io import writeOBJ
# from unif_metric import chamfer_and_score
@@ -104,7 +104,7 @@ if __name__ == '__main__':
iteration = ''
load_model(model, 'checkpoints/' + checkpoint_name, iteration=iteration)
load_model(model, 'checkpoints/post/' + checkpoint_name, iteration=iteration)
# load_model(model, 'checkpoints/' + 'abl_all_120k')
output_folder = '/home/workspace/data/results/post/' + checkpoint_name + '-' + iteration
+2 -2
View File
@@ -1,6 +1,6 @@
import os
import sys
from configs.config_abl_2_pyr_32_64_128_256_512 import config
from configs.config_abl_pyr_32 import config
os.environ["CUDA_VISIBLE_DEVICES"] = config['gpu']
import tensorflow as tf
@@ -97,7 +97,7 @@ if __name__ == '__main__':
ids = [id.split('_')[0] for id in ids]
ids = set(ids)
iteration = '50000'
iteration = '200000'
load_model(model, 'checkpoints/' + checkpoint_name, iteration=iteration)
# load_model(model, 'checkpoints/' + 'abl_all_120k')
+1 -1
View File
@@ -92,7 +92,7 @@ class PyramidLevel(tf.keras.Model):
# x = x * uv_mask_high[:,:,:,tf.newaxis]
return x, mean, logvar
return x, z, mean, logvar
+22 -7
View File
@@ -78,6 +78,11 @@ class Pyramid(tf.keras.Model):
load_model(self.upscale_enhancer, config['pyramid']['final_upscale_enhancer'])
self.upscale_enhancer.trainable = False
self.cond_encoder_2 = 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(config['pyramid']['latent_dim'], activation='tanh'),])
def enhance(self, low, mask, training):
x = self.upscale_enhancer([low, mask], training=training)
return x
@@ -90,44 +95,54 @@ class Pyramid(tf.keras.Model):
z_cond = tf.concat([z_static, z_body, z_curv], axis=-1)
z_cond = self.cond_encoder(z_cond, training=training)
return z_cond, z_static, z_body, z_curv
def encode_conds_2(self, z, z_static, z_body, z_curv, training):
z_cond = tf.concat([z, z_static, z_body, z_curv], axis=-1)
z_cond = self.cond_encoder_2(z_cond, training=training)
return z_cond
def call(self, inputs, training):
levels_input, conds = inputs
uv_static, uv_body, uv_curv = conds[0], conds[1], conds[2]
z_cond = self.encode_conds(uv_static, uv_body, uv_curv, training)
z_cond, z_static, z_body, z_curv = self.encode_conds(uv_static, uv_body, uv_curv, training)
if self.add_noise == True and training == True:
z_cond = z_cond + (tf.random.uniform(z_cond.shape, maxval=self.noise_amount * 2) - self.noise_amount)
out_levels = []
pred, mean, logvar = self.levels[0](levels_input[0], z_cond, training=training)
pred, z, mean, logvar = self.levels[0](levels_input[0], z_cond, training=training)
if self.use_offsets:
pred = pred + levels_input[0][2] # uv_body_posed_32
if 1 != len(self.levels):
pred = self.levels[0].enhance(pred, levels_input[0][-2], training=training) # levels_input[i][-2]=uv_mask_res
pred = tf.image.resize(pred, (self.levels[1].size, self.levels[1].size//2), tf.image.ResizeMethod.LANCZOS5)
out_levels.append([pred, mean, logvar])
pred = tf.image.resize(pred, (self.levels[1].size, self.levels[1].size//2), tf.image.ResizeMethod.BILINEAR)
pred = pred * levels_input[1][-2][:,:,:,tf.newaxis]
else:
pred = self.enhance(pred, levels_input[0][-2], training=training)
pred = tf.image.resize(pred, (512, 256), tf.image.ResizeMethod.LANCZOS5)
pred = tf.image.resize(pred, (512, 256), tf.image.ResizeMethod.BILINEAR)
pred = pred * levels_input[-1][-1][:,:,:,tf.newaxis] # full res uv mask
out_levels.append([pred, mean, logvar])
for i in range(1, len(self.levels)):
pred_level, mean, logvar = self.levels[i](levels_input[i], z_cond, training=training)
input = levels_input[i]
input[0] = pred # use previous level output as input for next level
z_cond_2 = self.encode_conds_2(z, z_static, z_body, z_curv, training=training)
pred_level, z, mean, logvar = self.levels[i](input, z_cond_2, training=training)
pred = pred + pred_level
if i != len(self.levels) - 1:
pred = self.levels[i].enhance(pred, levels_input[i][-2], training=training)
out_levels.append([pred, mean, logvar])
pred = tf.image.resize(pred, (self.levels[i+1].size, self.levels[i+1].size//2), tf.image.ResizeMethod.LANCZOS5)
pred = tf.image.resize(pred, (self.levels[i+1].size, self.levels[i+1].size//2), tf.image.ResizeMethod.BILINEAR)
pred = pred * levels_input[i+1][-2][:,:,:,tf.newaxis]
else:
if self.upscale_enhancer is not None:
pred = self.enhance(pred, levels_input[-1][-2], training=training)
pred = tf.image.resize(pred, (512, 256), tf.image.ResizeMethod.LANCZOS5)
pred = tf.image.resize(pred, (512, 256), tf.image.ResizeMethod.BILINEAR)
pred = pred * levels_input[-1][-1][:,:,:,tf.newaxis] # full res uv mask
out_levels.append([pred, mean, logvar])