update pyramid for ablation
This commit is contained in:
@@ -100,7 +100,7 @@ from models.upscaler import Upscaler
|
|||||||
|
|
||||||
class PyramidLevel(nn.Module):
|
class PyramidLevel(nn.Module):
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config, use_normals=True):
|
||||||
super(PyramidLevel, self).__init__()
|
super(PyramidLevel, self).__init__()
|
||||||
self.size = config['resolution']
|
self.size = config['resolution']
|
||||||
|
|
||||||
@@ -114,6 +114,7 @@ class PyramidLevel(nn.Module):
|
|||||||
load_model(self.upscale_enhancer, config['upscale_enhancer'])
|
load_model(self.upscale_enhancer, config['upscale_enhancer'])
|
||||||
for param in self.upscale_enhancer.parameters(): param.requires_grad = False
|
for param in self.upscale_enhancer.parameters(): param.requires_grad = False
|
||||||
|
|
||||||
|
self.use_normals = use_normals
|
||||||
|
|
||||||
def enhance(self, low, mask):
|
def enhance(self, low, mask):
|
||||||
x = self.upscale_enhancer([low, mask])
|
x = self.upscale_enhancer([low, mask])
|
||||||
@@ -152,9 +153,13 @@ class PyramidLevel(nn.Module):
|
|||||||
|
|
||||||
|
|
||||||
def forward(self, inputs, z_cond):
|
def forward(self, inputs, z_cond):
|
||||||
uv_unposed, uv_template, uv_body_posed, uv_curv, uv_mask, uv_mask_high = inputs
|
uv_unposed, uv_template, uv_body_posed, uv_normals, uv_mask, uv_mask_high = inputs
|
||||||
|
|
||||||
x = torch.concat([uv_unposed, uv_template, uv_body_posed, uv_curv], dim=1)
|
if self.use_normals:
|
||||||
|
x = torch.concat([uv_unposed, uv_template, uv_body_posed, uv_normals], dim=1)
|
||||||
|
else:
|
||||||
|
x = torch.concat([uv_unposed, uv_template, uv_body_posed], dim=1)
|
||||||
|
|
||||||
mean, logvar = self.encoder(x)
|
mean, logvar = self.encoder(x)
|
||||||
z = self.reparameterize(mean, logvar)
|
z = self.reparameterize(mean, logvar)
|
||||||
z = torch.reshape(z, (mean.shape[0], -1, 8, 4))
|
z = torch.reshape(z, (mean.shape[0], -1, 8, 4))
|
||||||
|
|||||||
+14
-170
@@ -3,11 +3,6 @@ import time
|
|||||||
import random
|
import random
|
||||||
import torch
|
import torch
|
||||||
from torch import nn
|
from torch import nn
|
||||||
import torch.nn.functional as F
|
|
||||||
# import numpy as np
|
|
||||||
# import scipy as sp
|
|
||||||
# import plotly.graph_objects as go
|
|
||||||
# import plotly.express as ex
|
|
||||||
|
|
||||||
from utils.checkpoints import load_model
|
from utils.checkpoints import load_model
|
||||||
from models.base import AEEncoder
|
from models.base import AEEncoder
|
||||||
@@ -15,123 +10,6 @@ from models.pyramid_level import PyramidLevel
|
|||||||
from torchvision.transforms import Resize
|
from torchvision.transforms import Resize
|
||||||
from torchvision.transforms.functional import InterpolationMode
|
from torchvision.transforms.functional import InterpolationMode
|
||||||
|
|
||||||
# class Pyramid(nn.Module):
|
|
||||||
|
|
||||||
# def __init__(self, config):
|
|
||||||
# super(Pyramid, self).__init__()
|
|
||||||
|
|
||||||
# self.static_enc : AEEncoder = AEEncoder(config['cond_ae_static']['encoder_block_settings'], kernel_size=config['cond_ae_static']['kernel_size'], activation=config['cond_ae_static']['activation'])
|
|
||||||
# if config['pyramid']['static_model'] != '':
|
|
||||||
# load_model(self.static_enc, config['pyramid']['static_model'] + '_enc')
|
|
||||||
|
|
||||||
# self.body_enc : AEEncoder = AEEncoder(config['cond_ae_body']['encoder_block_settings'], kernel_size=config['cond_ae_body']['kernel_size'], activation=config['cond_ae_body']['activation'])
|
|
||||||
# if config['pyramid']['body_model'] != '':
|
|
||||||
# load_model(self.body_enc, config['pyramid']['body_model'] + '_enc')
|
|
||||||
|
|
||||||
# self.curv_enc : AEEncoder = AEEncoder(config['cond_ae_curv']['encoder_block_settings'], kernel_size=config['cond_ae_curv']['kernel_size'], activation=config['cond_ae_curv']['activation'])
|
|
||||||
# if config['pyramid']['curvature_model'] != '':
|
|
||||||
# load_model(self.curv_enc, config['pyramid']['curvature_model'] + '_enc')
|
|
||||||
|
|
||||||
# if config['freeze_encoders']:
|
|
||||||
# for param in self.static_enc.parameters(): param.requires_grad = False
|
|
||||||
# for param in self.body_enc.parameters(): param.requires_grad = False
|
|
||||||
# for param in self.curv_enc.parameters(): param.requires_grad = False
|
|
||||||
|
|
||||||
|
|
||||||
# self.levels = [PyramidLevel({ **config['pyramid']['levels'][i], **{ 'cond_ae_static': config['cond_ae_static'], 'cond_ae_body': config['cond_ae_body'], 'cond_ae_curv': config['cond_ae_curv'], } }) for i in range(len(config['pyramid']['levels']))]
|
|
||||||
|
|
||||||
# # if config['is_cape']:
|
|
||||||
# # if len(config['pyramid']['resolutions']) == 2:
|
|
||||||
# # self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# # if len(config['pyramid']['resolutions']) == 3:
|
|
||||||
# # self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# # self.levels[-2].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# # if len(config['pyramid']['resolutions']) == 4:
|
|
||||||
# # self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# # self.levels[-2].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# # self.levels[-3].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# # else:
|
|
||||||
|
|
||||||
# # if len(config['pyramid']['resolutions']) == 2:
|
|
||||||
# # self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# # if len(config['pyramid']['resolutions']) == 3:
|
|
||||||
# # self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 1000)])
|
|
||||||
# # self.levels[-2].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# # if len(config['pyramid']['resolutions']) == 4:
|
|
||||||
# # self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 10000)])
|
|
||||||
# # self.levels[-2].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 1000)])
|
|
||||||
# # self.levels[-3].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# # if len(config['pyramid']['resolutions']) == 5:
|
|
||||||
# # self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100000)])
|
|
||||||
# # self.levels[-2].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 10000)])
|
|
||||||
# # self.levels[-3].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 1000)])
|
|
||||||
# # self.levels[-4].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
|
|
||||||
# # self.add_noise = config['pyramid']['add_noise']
|
|
||||||
# # self.noise_amount = config['pyramid']['noise_amount']
|
|
||||||
# self.use_offsets = config['use_offsets']
|
|
||||||
|
|
||||||
# # self.upscale_enhancer = None
|
|
||||||
# # if config['pyramid']['final_upscale_enhancer'] != '':
|
|
||||||
# # k_size = config['pyramid']['final_upscale_enhancer_kernel_size'] if 'final_upscale_enhancer_kernel_size' in config['pyramid'].keys() else ((3 if config['pyramid']['resolutions'][-1] <= 64 else 5))
|
|
||||||
# # self.upscale_enhancer = UpscalerBasicConv(low_res=config['pyramid']['resolutions'][-1], kernel_size=k_size)
|
|
||||||
# # load_model(self.upscale_enhancer, config['pyramid']['final_upscale_enhancer'])
|
|
||||||
# # self.upscale_enhancer.trainable = False
|
|
||||||
|
|
||||||
# def enhance(self, low, mask):
|
|
||||||
# x = self.upscale_enhancer([low, mask])
|
|
||||||
# return x
|
|
||||||
|
|
||||||
# def encode_conds(self, uv_template, uv_body_posed, uv_curv):
|
|
||||||
# z_static = self.static_enc(uv_template)
|
|
||||||
# z_body = self.body_enc(uv_body_posed)
|
|
||||||
# z_curv = self.curv_enc(uv_curv)
|
|
||||||
|
|
||||||
# z_cond = torch.concat([z_static, z_body, z_curv], dim=-1)
|
|
||||||
|
|
||||||
# return z_cond
|
|
||||||
|
|
||||||
# def call(self, inputs):
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
# # 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)
|
|
||||||
# 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]) # levels_input[i][-2]=uv_mask_res
|
|
||||||
# pred = F.interpolate(pred, size=(self.levels[1].size, self.levels[1].size//2), mode='bilinear')
|
|
||||||
# out_levels.append([pred, mean, logvar])
|
|
||||||
# pred = pred * levels_input[1][-2][:,None,:,:]
|
|
||||||
# else:
|
|
||||||
# pred = self.enhance(pred, levels_input[0][-2])
|
|
||||||
# pred = F.interpolate(pred, size=(512, 256), mode='bilinear')
|
|
||||||
# pred = pred * levels_input[-1][-1][:,None,:,:] # 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)
|
|
||||||
# pred = pred + pred_level
|
|
||||||
# if i != len(self.levels) - 1:
|
|
||||||
# pred = self.levels[i].enhance(pred, levels_input[i][-2])
|
|
||||||
# out_levels.append([pred, mean, logvar])
|
|
||||||
# pred = F.interpolate(pred, size=(self.levels[i+1].size, self.levels[i+1].size//2), mode='bilinear')
|
|
||||||
# pred = pred * levels_input[i+1][-2][:,None,:,:]
|
|
||||||
# else:
|
|
||||||
# pred = self.enhance(pred, levels_input[i][-1])
|
|
||||||
# pred = pred * levels_input[-1][-1][:,None,:,:] # full res uv mask
|
|
||||||
# pred = F.interpolate(pred, size=(512, 256), mode='bilinear')
|
|
||||||
# out_levels.append([pred, mean, logvar])
|
|
||||||
|
|
||||||
# return out_levels
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Pyramid(nn.Module):
|
class Pyramid(nn.Module):
|
||||||
|
|
||||||
@@ -146,57 +24,33 @@ class Pyramid(nn.Module):
|
|||||||
if config['body_model'] != '':
|
if config['body_model'] != '':
|
||||||
load_model(self.body_enc, config['body_model'] + '_enc')
|
load_model(self.body_enc, config['body_model'] + '_enc')
|
||||||
|
|
||||||
self.norm_enc : AEEncoder = AEEncoder(config['cond_ae_norm']['encoder_block_settings'], config['cond_ae_norm']['kernel_size'], config['cond_ae_norm']['activation'], device=config['device'])
|
if config['use_normals']:
|
||||||
if config['normals_model'] != '':
|
self.norm_enc : AEEncoder = AEEncoder(config['cond_ae_norm']['encoder_block_settings'], config['cond_ae_norm']['kernel_size'], config['cond_ae_norm']['activation'], device=config['device'])
|
||||||
load_model(self.norm_enc, config['normals_model'] + '_enc')
|
if config['normals_model'] != '':
|
||||||
|
load_model(self.norm_enc, config['normals_model'] + '_enc')
|
||||||
|
|
||||||
if config['freeze_encoders']:
|
if config['freeze_encoders']:
|
||||||
for param in self.static_enc.parameters(): param.requires_grad = False
|
for param in self.static_enc.parameters(): param.requires_grad = False
|
||||||
for param in self.body_enc.parameters(): param.requires_grad = False
|
for param in self.body_enc.parameters(): param.requires_grad = False
|
||||||
for param in self.norm_enc.parameters(): param.requires_grad = False
|
if config['use_normals']:
|
||||||
|
for param in self.norm_enc.parameters(): param.requires_grad = False
|
||||||
|
|
||||||
self.levels = nn.ModuleList([PyramidLevel({ **config['pyramid']['levels'][i] }) for i in range(len(config['pyramid']['levels']))])
|
self.levels = nn.ModuleList([PyramidLevel({ **config['pyramid']['levels'][i] }, use_normals=config['use_normals']) for i in range(len(config['pyramid']['levels']))])
|
||||||
|
|
||||||
self.resizers = { res: Resize(size=(res, int(res/2)), interpolation=InterpolationMode.BILINEAR).to(config['device']) for res in config['pyramid']['resolutions'] }
|
self.resizers = { res: Resize(size=(res, int(res/2)), interpolation=InterpolationMode.BILINEAR).to(config['device']) for res in config['pyramid']['resolutions'] }
|
||||||
self.resizers[512] = Resize(size=(512, 256), interpolation=InterpolationMode.BILINEAR).to(config['device'])
|
self.resizers[512] = Resize(size=(512, 256), interpolation=InterpolationMode.BILINEAR).to(config['device'])
|
||||||
|
|
||||||
|
self.use_normals = config['use_normals']
|
||||||
# if len(config['pyramid']['resolutions']) == 2:
|
|
||||||
# self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# if len(config['pyramid']['resolutions']) == 3:
|
|
||||||
# self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 1000)])
|
|
||||||
# self.levels[-2].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# if len(config['pyramid']['resolutions']) == 4:
|
|
||||||
# self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 10000)])
|
|
||||||
# self.levels[-2].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 1000)])
|
|
||||||
# self.levels[-3].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
# if len(config['pyramid']['resolutions']) == 5:
|
|
||||||
# self.levels[-1].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100000)])
|
|
||||||
# self.levels[-2].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 10000)])
|
|
||||||
# self.levels[-3].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 1000)])
|
|
||||||
# self.levels[-4].decoder.decoder.last = tf.keras.Sequential([tf.keras.layers.Dense(3), tf.keras.layers.Lambda(lambda x: x / 100)])
|
|
||||||
|
|
||||||
# self.add_noise = config['pyramid']['add_noise']
|
|
||||||
# self.noise_amount = config['pyramid']['noise_amount']
|
|
||||||
# self.use_offsets = config['use_offsets']
|
|
||||||
|
|
||||||
# self.upscale_enhancer = None
|
|
||||||
# if config['pyramid']['final_upscale_enhancer'] != '':
|
|
||||||
# k_size = config['pyramid']['final_upscale_enhancer_kernel_size'] if 'final_upscale_enhancer_kernel_size' in config['pyramid'].keys() else ((3 if config['pyramid']['resolutions'][-1] <= 64 else 5))
|
|
||||||
# self.upscale_enhancer = UpscalerBasicConv(low_res=config['pyramid']['resolutions'][-1], kernel_size=k_size)
|
|
||||||
# load_model(self.upscale_enhancer, config['pyramid']['final_upscale_enhancer'])
|
|
||||||
# self.upscale_enhancer.trainable = False
|
|
||||||
|
|
||||||
# def enhance(self, low, mask, training):
|
|
||||||
# x = self.upscale_enhancer([low, mask], training=training)
|
|
||||||
# return x
|
|
||||||
|
|
||||||
def encode_conds(self, uv_template, uv_body_posed, uv_norm):
|
def encode_conds(self, uv_template, uv_body_posed, uv_norm):
|
||||||
z_static = self.static_enc(uv_template)
|
z_static = self.static_enc(uv_template)
|
||||||
z_body = self.body_enc(uv_body_posed)
|
z_body = self.body_enc(uv_body_posed)
|
||||||
z_norm = self.norm_enc(uv_norm)
|
|
||||||
|
|
||||||
z_cond = torch.concat([z_static, z_body, z_norm], dim=1)
|
if self.use_normals:
|
||||||
|
z_norm = self.norm_enc(uv_norm)
|
||||||
|
z_cond = torch.concat([z_static, z_body, z_norm], dim=1)
|
||||||
|
else:
|
||||||
|
z_cond = torch.concat([z_static, z_body], dim=1)
|
||||||
|
|
||||||
return z_cond
|
return z_cond
|
||||||
|
|
||||||
@@ -206,9 +60,6 @@ class Pyramid(nn.Module):
|
|||||||
|
|
||||||
z_cond = self.encode_conds(uv_static, uv_body, uv_norm)
|
z_cond = self.encode_conds(uv_static, uv_body, uv_norm)
|
||||||
|
|
||||||
# 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 = []
|
out_levels = []
|
||||||
pred, mean, logvar = self.levels[0](levels_input[0], z_cond)
|
pred, mean, logvar = self.levels[0](levels_input[0], z_cond)
|
||||||
# if self.use_offsets:
|
# if self.use_offsets:
|
||||||
@@ -219,7 +70,6 @@ class Pyramid(nn.Module):
|
|||||||
out_levels.append([pred, mean, logvar])
|
out_levels.append([pred, mean, logvar])
|
||||||
pred = pred * levels_input[1][-2][:,None,:,:]
|
pred = pred * levels_input[1][-2][:,None,:,:]
|
||||||
else:
|
else:
|
||||||
# pred = self.enhance(pred, levels_input[0][-2], training=training)
|
|
||||||
pred = self.levels[0].enhance(pred, levels_input[0][-2]) # levels_input[i][-2]=uv_mask_res
|
pred = self.levels[0].enhance(pred, levels_input[0][-2]) # levels_input[i][-2]=uv_mask_res
|
||||||
pred = self.resizers[512](pred)
|
pred = self.resizers[512](pred)
|
||||||
pred = pred * levels_input[-1][-1][:,None,:,:] # full res uv mask
|
pred = pred * levels_input[-1][-1][:,None,:,:] # full res uv mask
|
||||||
@@ -227,12 +77,8 @@ class Pyramid(nn.Module):
|
|||||||
|
|
||||||
for i in range(1, len(self.levels)):
|
for i in range(1, len(self.levels)):
|
||||||
input = levels_input[i]
|
input = levels_input[i]
|
||||||
# input[0] = input[0] - pred
|
input[0] = input[0] - pred
|
||||||
# input_min, input_max = tf.reduce_min(input[0], axis=[1,2,3]), tf.reduce_max(input[0], axis=[1,2,3])
|
|
||||||
# input[0] = (input[0] - input_min[:,None,None,None]) / (input_max - input_min)[:,None,None,None]
|
|
||||||
# input[0] = input[0] * input[-2][:,None,:,:] # uv_mask_res
|
|
||||||
pred_level, mean, logvar = self.levels[i](input, z_cond)
|
pred_level, mean, logvar = self.levels[i](input, z_cond)
|
||||||
# pred_level = ( (pred_level * (input_max - input_min)[:,None,None,None]) + input_min[:,None,None,None] ) * input[-2][:,:,:,None] # uv_mask_res
|
|
||||||
pred = pred + pred_level
|
pred = pred + pred_level
|
||||||
if i != len(self.levels) - 1:
|
if i != len(self.levels) - 1:
|
||||||
pred = self.levels[i].enhance(pred, levels_input[i][-2])
|
pred = self.levels[i].enhance(pred, levels_input[i][-2])
|
||||||
@@ -240,8 +86,6 @@ class Pyramid(nn.Module):
|
|||||||
pred = self.resizers[self.levels[i+1].size](pred)
|
pred = self.resizers[self.levels[i+1].size](pred)
|
||||||
pred = pred * levels_input[i+1][-2][:,None,:,:]
|
pred = pred * levels_input[i+1][-2][:,None,:,:]
|
||||||
else:
|
else:
|
||||||
# if self.upscale_enhancer is not None:
|
|
||||||
# pred = self.enhance(pred, levels_input[-1][-2], training=training)
|
|
||||||
pred = self.levels[-1].enhance(pred, levels_input[-1][-2])
|
pred = self.levels[-1].enhance(pred, levels_input[-1][-2])
|
||||||
pred = self.resizers[512](pred)
|
pred = self.resizers[512](pred)
|
||||||
pred = pred * levels_input[-1][-1][:,None,:,:] # full res uv mask
|
pred = pred * levels_input[-1][-1][:,None,:,:] # full res uv mask
|
||||||
|
|||||||
+52
-65
@@ -11,7 +11,7 @@ parser.add_argument('--debug', action='store_true')
|
|||||||
args = vars(parser.parse_args())
|
args = vars(parser.parse_args())
|
||||||
|
|
||||||
if args['debug']:
|
if args['debug']:
|
||||||
from configs.iccvw.pyr_64_cape_m import config
|
from configs.iccvw.pyr_64_reg import config
|
||||||
else:
|
else:
|
||||||
config_module = importlib.import_module(args['config'])
|
config_module = importlib.import_module(args['config'])
|
||||||
config = config_module.config
|
config = config_module.config
|
||||||
@@ -238,72 +238,41 @@ def train_step(batch):
|
|||||||
res_modifier = '_' + str(res) if res != 512 else ''
|
res_modifier = '_' + str(res) if res != 512 else ''
|
||||||
pred, mean, logvar = out_levels[i]
|
pred, mean, logvar = out_levels[i]
|
||||||
|
|
||||||
mesh_pred = uv2mesh(pred)
|
|
||||||
|
|
||||||
if config['use_skinning']:
|
|
||||||
shape = batch['pose_shape'][:, 72:]
|
|
||||||
gender = torch.greater_equal(shape[:, 10] , 0.5).to(dtype=torch.int64)
|
|
||||||
shape_offsets = torch.stack([torch.tensordot(shape[i,:10][None, :], smpl.shapedirs[gender[i]], dims=[[1], [2]])[0,smpl.to_keep,:] for i in range(shape.shape[0])])
|
|
||||||
|
|
||||||
mesh_pred_shaped = mesh_pred + shape_offsets * batch['mesh_mask'][:,:,None]
|
|
||||||
mesh_pred_posed = smpl(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_shaped)[0]
|
|
||||||
else:
|
|
||||||
mesh_pred_posed = mesh_pred
|
|
||||||
|
|
||||||
# is the output already masked?
|
|
||||||
# ms_ssim = torch.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 = torch.mean(tf.image.ssim(pred + 1, batch['uv_unposed'] + 1, max_val=3))
|
|
||||||
|
|
||||||
e_loss = torch.mean(edge_loss(mesh_pred, mesh_orig, batch['mesh_mask']))
|
|
||||||
c_loss, c_ratio = collision_loss(mesh_pred_posed, batch['mesh_body_posed'], batch['mesh_mask'])
|
|
||||||
c_loss, c_ratio = torch.mean(c_loss), torch.mean(c_ratio)
|
|
||||||
l2_loss = torch.mean(1e3 * torch.mean(torch.sum(((uv_orig - pred) ** 2), dim=-1), dim=[1, 2]))
|
l2_loss = torch.mean(1e3 * torch.mean(torch.sum(((uv_orig - pred) ** 2), dim=-1), dim=[1, 2]))
|
||||||
l2_mesh_loss = torch.mean(1e3 * torch.mean(torch.sum(batch['mesh_mask'][:,:,None] * (batch['mesh_posed'] - mesh_pred_posed) ** 2, dim=-1), dim=-1))
|
|
||||||
n_loss = normal_loss(mesh_pred_posed, batch['mesh_posed'], batch['mesh_mask'], is_skirt=config['is_skirt'], is_smpl_orig=config['is_cape'])
|
|
||||||
kl = kl_loss(mean, logvar)
|
kl = kl_loss(mean, logvar)
|
||||||
|
|
||||||
if config['use_extra_losses']:
|
if config['use_extra_losses']:
|
||||||
|
mesh_pred = uv2mesh(pred)
|
||||||
|
|
||||||
|
if config['use_skinning']:
|
||||||
|
shape = batch['pose_shape'][:, 72:]
|
||||||
|
gender = torch.greater_equal(shape[:, 10] , 0.5).to(dtype=torch.int64)
|
||||||
|
shape_offsets = torch.stack([torch.tensordot(shape[i,:10][None, :], smpl.shapedirs[gender[i]], dims=[[1], [2]])[0,smpl.to_keep,:] for i in range(shape.shape[0])])
|
||||||
|
|
||||||
|
mesh_pred_shaped = mesh_pred + shape_offsets * batch['mesh_mask'][:,:,None]
|
||||||
|
mesh_pred_posed = smpl(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_shaped)[0]
|
||||||
|
else:
|
||||||
|
mesh_pred_posed = mesh_pred
|
||||||
|
|
||||||
|
e_loss = torch.mean(edge_loss(mesh_pred, mesh_orig, batch['mesh_mask']))
|
||||||
|
c_loss, c_ratio = collision_loss(mesh_pred_posed, batch['mesh_body_posed'], batch['mesh_mask'])
|
||||||
|
c_loss, c_ratio = torch.mean(c_loss), torch.mean(c_ratio)
|
||||||
|
n_loss = normal_loss(mesh_pred_posed, batch['mesh_posed'], batch['mesh_mask'], is_skirt=config['is_skirt'], is_smpl_orig=config['is_cape'])
|
||||||
|
l2_mesh_loss = torch.mean(1e3 * torch.mean(torch.sum(batch['mesh_mask'][:,:,None] * (batch['mesh_posed'] - mesh_pred_posed) ** 2, dim=-1), dim=-1))
|
||||||
|
|
||||||
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss + l2_mesh_loss)
|
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss + l2_mesh_loss)
|
||||||
if not config['is_cape']:
|
if not config['is_cape']:
|
||||||
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (e_loss + c_loss) * config['reg_loss_coeff']
|
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (e_loss + c_loss) * config['reg_loss_coeff']
|
||||||
|
if config['use_norm_loss'] and step > 2000:
|
||||||
|
reconstr_loss_total = reconstr_loss_total + n_loss * config['reg_loss_coeff']
|
||||||
else:
|
else:
|
||||||
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss)
|
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']
|
|
||||||
|
|
||||||
kl_total += kl
|
kl_total += kl
|
||||||
loss: torch.Tensor = reconstr_loss_total + g_balancing_coeff * kl_total
|
loss: torch.Tensor = reconstr_loss_total + g_balancing_coeff * kl_total
|
||||||
|
|
||||||
# scaler.scale(loss).backward()
|
|
||||||
# scaler.step(optimizer)
|
|
||||||
# scaler.update()
|
|
||||||
# optimizer.zero_grad()
|
|
||||||
|
|
||||||
# b = 0
|
|
||||||
# from custom_utils.custom_utils import _maskFaces
|
|
||||||
# mesh_mask = batch['mesh_mask'][b].cpu().numpy()
|
|
||||||
# faces = np.load('smpl/smpl_faces_skirt.npy') if batch['garment'][b] in ['Skirt', 'Dress'] else np.load('smpl/smpl_faces.npy')
|
|
||||||
# faces_body = np.load('smpl/smpl_faces.npy')
|
|
||||||
# _, faces = _maskFaces(np.zeros((14475, 3)), faces, mesh_mask)
|
|
||||||
|
|
||||||
# # fig = go.Figure(data=[go.Mesh3d(x=batch['mesh_posed'].cpu().numpy()[0,mesh_mask,0], y=batch['mesh_posed'].cpu().numpy()[0,mesh_mask,2], z=batch['mesh_posed'].cpu().numpy()[0,mesh_mask,1], i=faces[:,0], j=faces[:,1], k=faces[:,2], color='lightpink', opacity=1),
|
|
||||||
# # go.Mesh3d(x=batch['mesh_body_posed'].cpu().numpy()[0,:,0], y=batch['mesh_body_posed'].cpu().numpy()[0,:,2], z=batch['mesh_body_posed'].cpu().numpy()[0,:,1], i=faces_body[:,0], j=faces_body[:,1], k=faces_body[:,2], color='lightblue', opacity=1),
|
|
||||||
# # ])
|
|
||||||
|
|
||||||
# fig = go.Figure(data=[go.Mesh3d(x=mesh_orig.cpu().numpy()[0,mesh_mask,0], y=mesh_orig.cpu().numpy()[0,mesh_mask,2], z=mesh_orig.cpu().numpy()[0,mesh_mask,1], i=faces[:,0], j=faces[:,1], k=faces[:,2], color='lightpink', opacity=1),
|
|
||||||
# ])
|
|
||||||
# fig.update_layout(scene_aspectmode='cube')
|
|
||||||
# fig.update_layout(scene=dict(xaxis=dict(range=[-1,1]), yaxis=dict(range=[-1,1]), zaxis=dict(range=[-1,1])))
|
|
||||||
# fig.show()
|
|
||||||
|
|
||||||
# ex.imshow((uv_orig[b].cpu().numpy().transpose(1,2,0) + 1) / 2).show()
|
|
||||||
# upscaled = model.levels[0].enhance(levels_input[0][0], levels_input[0][-2]) # levels_input[i][-2]=uv_mask_res
|
|
||||||
# upscaled = model.resizers[512](upscaled)
|
|
||||||
# ex.imshow((levels_input[0][0][b].cpu().numpy().transpose(1,2,0) + 1) / 2).show()
|
|
||||||
# ex.imshow((upscaled[b].cpu().numpy().transpose(1,2,0) + 1) / 2).show()
|
|
||||||
|
|
||||||
|
|
||||||
optimizer.zero_grad()
|
optimizer.zero_grad()
|
||||||
loss.backward()
|
loss.backward()
|
||||||
optimizer.step()
|
optimizer.step()
|
||||||
@@ -313,13 +282,33 @@ def train_step(batch):
|
|||||||
mean = torch.mean(mean)
|
mean = torch.mean(mean)
|
||||||
logvar = torch.mean(logvar)
|
logvar = torch.mean(logvar)
|
||||||
|
|
||||||
|
if not config['use_extra_losses']:
|
||||||
|
mesh_pred = uv2mesh(pred)
|
||||||
|
|
||||||
|
if config['use_skinning']:
|
||||||
|
shape = batch['pose_shape'][:, 72:]
|
||||||
|
gender = torch.greater_equal(shape[:, 10] , 0.5).to(dtype=torch.int64)
|
||||||
|
shape_offsets = torch.stack([torch.tensordot(shape[i,:10][None, :], smpl.shapedirs[gender[i]], dims=[[1], [2]])[0,smpl.to_keep,:] for i in range(shape.shape[0])])
|
||||||
|
|
||||||
|
mesh_pred_shaped = mesh_pred + shape_offsets * batch['mesh_mask'][:,:,None]
|
||||||
|
mesh_pred_posed = smpl(batch['pose_shape'][:, :72], batch['pose_shape'][:, 72:], mesh_pred_shaped)[0]
|
||||||
|
else:
|
||||||
|
mesh_pred_posed = mesh_pred
|
||||||
|
|
||||||
|
e_loss = torch.mean(edge_loss(mesh_pred, mesh_orig, batch['mesh_mask']))
|
||||||
|
c_loss, c_ratio = collision_loss(mesh_pred_posed, batch['mesh_body_posed'], batch['mesh_mask'])
|
||||||
|
c_loss, c_ratio = torch.mean(c_loss), torch.mean(c_ratio)
|
||||||
|
l2_mesh_loss = torch.mean(1e3 * torch.mean(torch.sum(batch['mesh_mask'][:,:,None] * (batch['mesh_posed'] - mesh_pred_posed) ** 2, dim=-1), dim=-1))
|
||||||
|
n_loss = normal_loss(mesh_pred_posed, batch['mesh_posed'], batch['mesh_mask'], is_skirt=config['is_skirt'], is_smpl_orig=config['is_cape'])
|
||||||
|
|
||||||
ms_ssim = torch.mean(_MSSSIM(pred + 1, batch['uv_static'] + 1))
|
ms_ssim = torch.mean(_MSSSIM(pred + 1, batch['uv_static'] + 1))
|
||||||
metric = torch.sum(torch.sqrt(torch.sum(batch['mesh_mask'][:,:,None] * (mesh_orig - mesh_pred.detach()) ** 2, axis=-1))) / torch.sum(batch['mesh_mask'])
|
metric = torch.sum(torch.sqrt(torch.sum(batch['mesh_mask'][:,:,None] * (mesh_orig - mesh_pred.detach()) ** 2, axis=-1))) / torch.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,
|
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/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/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, } } #
|
'train/euclid_error': metric, 'train/l2_mesh_loss': l2_mesh_loss, 'train/ms_ssim' + res_modifier: ms_ssim,
|
||||||
|
'train/collision_ratio': c_ratio } } #
|
||||||
|
|
||||||
|
|
||||||
return { **{ 'train/loss': loss, 'train/reconstr_loss_total': reconstr_loss_total, 'train/kl_total': kl_total }, **output }
|
return { **{ 'train/loss': loss, 'train/reconstr_loss_total': reconstr_loss_total, 'train/kl_total': kl_total }, **output }
|
||||||
@@ -359,28 +348,24 @@ def valid_step(batch):
|
|||||||
else:
|
else:
|
||||||
mesh_pred_posed = mesh_pred
|
mesh_pred_posed = mesh_pred
|
||||||
|
|
||||||
# is the output already masked?
|
|
||||||
# ms_ssim = torch.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 = torch.mean(tf.image.ssim(pred + 1, batch['uv_unposed'] + 1, max_val=3))
|
|
||||||
|
|
||||||
e_loss = torch.mean(edge_loss(mesh_pred, mesh_orig, batch['mesh_mask']))
|
e_loss = torch.mean(edge_loss(mesh_pred, mesh_orig, batch['mesh_mask']))
|
||||||
c_loss, c_ratio = collision_loss(mesh_pred_posed, batch['mesh_body_posed'], batch['mesh_mask'])
|
c_loss, c_ratio = collision_loss(mesh_pred_posed, batch['mesh_body_posed'], batch['mesh_mask'])
|
||||||
c_loss, c_ratio = torch.mean(c_loss), torch.mean(c_ratio)
|
c_loss, c_ratio = torch.mean(c_loss), torch.mean(c_ratio)
|
||||||
l2_loss = torch.mean(1e3 * torch.mean(torch.sum(((uv_orig - pred) ** 2), dim=-1), dim=[1, 2]))
|
l2_loss = torch.mean(1e3 * torch.mean(torch.sum(((uv_orig - pred) ** 2), dim=-1), dim=[1, 2]))
|
||||||
l2_mesh_loss = torch.mean(1e3 * torch.mean(torch.sum(batch['mesh_mask'][:,:,None] * (batch['mesh_posed'] - mesh_pred_posed) ** 2, dim=-1), dim=-1))
|
l2_mesh_loss = torch.mean(1e3 * torch.mean(torch.sum(batch['mesh_mask'][:,:,None] * (batch['mesh_posed'] - mesh_pred_posed) ** 2, dim=-1), dim=-1))
|
||||||
n_loss = normal_loss(mesh_pred_posed, batch['mesh_posed'], batch['mesh_mask'], is_skirt=config['is_skirt'], is_smpl_orig=config['is_cape'])
|
n_loss = normal_loss(mesh_pred_posed, batch['mesh_posed'], batch['mesh_mask'], is_skirt=config['is_skirt'], is_smpl_orig=config['is_cape'])
|
||||||
|
|
||||||
kl = kl_loss(mean, logvar)
|
kl = kl_loss(mean, logvar)
|
||||||
|
|
||||||
if config['use_extra_losses']:
|
if config['use_extra_losses']:
|
||||||
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss + l2_mesh_loss)
|
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss + l2_mesh_loss)
|
||||||
if not config['is_cape']:
|
if not config['is_cape']:
|
||||||
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (e_loss + c_loss) * config['reg_loss_coeff']
|
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (e_loss + c_loss) * config['reg_loss_coeff']
|
||||||
|
if config['use_norm_loss'] and step > 2000:
|
||||||
|
reconstr_loss_total = reconstr_loss_total + n_loss * config['reg_loss_coeff']
|
||||||
else:
|
else:
|
||||||
reconstr_loss_total = reconstr_loss_total + config['pyramid']['loss_weights'][i] * (l2_loss)
|
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']
|
|
||||||
|
|
||||||
kl_total += kl
|
kl_total += kl
|
||||||
loss = reconstr_loss_total + g_balancing_coeff * kl_total
|
loss = reconstr_loss_total + g_balancing_coeff * kl_total
|
||||||
|
|
||||||
@@ -825,9 +810,9 @@ def train():
|
|||||||
print(step)
|
print(step)
|
||||||
|
|
||||||
if train_loss['train/euclid_error'] < config['balancing_activation_limit']:
|
if train_loss['train/euclid_error'] < config['balancing_activation_limit']:
|
||||||
g_balancing_coeff += 1 / 10000
|
g_balancing_coeff += 1 / 50000
|
||||||
|
|
||||||
if step % 25000 == 0:
|
if step % 25000 == 0 and not args['debug']:
|
||||||
ckpt_saver(model, step, optimizer, None)
|
ckpt_saver(model, step, optimizer, None)
|
||||||
|
|
||||||
step += 1
|
step += 1
|
||||||
@@ -874,12 +859,14 @@ if __name__ == '__main__':
|
|||||||
if len(config['pyramid']['resolutions']) == 1:
|
if len(config['pyramid']['resolutions']) == 1:
|
||||||
for param in model.static_enc.parameters(): param.requires_grad = False
|
for param in model.static_enc.parameters(): param.requires_grad = False
|
||||||
for param in model.body_enc.parameters(): param.requires_grad = False
|
for param in model.body_enc.parameters(): param.requires_grad = False
|
||||||
for param in model.norm_enc.parameters(): param.requires_grad = False
|
if config['use_normals']:
|
||||||
|
for param in model.norm_enc.parameters(): param.requires_grad = False
|
||||||
else:
|
else:
|
||||||
load_model(model, config['pyramid']['pretrained_pyramid'], iteration=(config['pyramid']['pretrained_pyramid_iteration'] if 'pretrained_pyramid_iteration' in config.keys() else ''))
|
load_model(model, config['pyramid']['pretrained_pyramid'], iteration=config['pyramid']['pretrained_pyramid_iteration'])
|
||||||
for param in model.static_enc.parameters(): param.requires_grad = False
|
for param in model.static_enc.parameters(): param.requires_grad = False
|
||||||
for param in model.body_enc.parameters(): param.requires_grad = False
|
for param in model.body_enc.parameters(): param.requires_grad = False
|
||||||
for param in model.norm_enc.parameters(): param.requires_grad = False
|
if config['use_normals']:
|
||||||
|
for param in model.norm_enc.parameters(): param.requires_grad = False
|
||||||
|
|
||||||
# load_model(model.levels[0].upscale_enhancer, config['pyramid']['levels'][0]['upscale_enhancer'])
|
# load_model(model.levels[0].upscale_enhancer, config['pyramid']['levels'][0]['upscale_enhancer'])
|
||||||
# model.levels[0].upscale_enhancer.trainable = False
|
# model.levels[0].upscale_enhancer.trainable = False
|
||||||
|
|||||||
Reference in New Issue
Block a user