Files
cvpr_2023/models/pyramid_level.py
T
2023-07-14 10:12:00 +02:00

90 lines
3.0 KiB
Python

import os
import time
import random
import torch
from torch import nn
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 models.base import AEEncoder, VariationalEncoder, Decoder
from models.upscaler import Upscaler
class PyramidLevel(nn.Module):
def __init__(self, config, use_normals=True):
super(PyramidLevel, self).__init__()
self.size = config['resolution']
self.encoder: VariationalEncoder = VariationalEncoder(config['encoder_block_settings'], input_features=config['input_features'], kernel_size=config['kernel_size'])
self.decoder: Decoder = Decoder(config['decoder_block_settings'], config['kernel_size'])
self.upscale_enhancer = None
if config['upscale_enhancer'] != '':
k_size = config['kernel_size']
self.upscale_enhancer = Upscaler(config['resolution'], kernel_size=k_size).to('cuda')
load_model(self.upscale_enhancer, config['upscale_enhancer'])
for param in self.upscale_enhancer.parameters(): param.requires_grad = False
self.use_normals = use_normals
self.scaling = 1.0 if 'scaling' not in config else config['scaling']
def enhance(self, low, mask):
x = self.upscale_enhancer([low, mask])
return x
def sample(self, z_cond, uv_mask, noise=None):
if noise is None:
eps = torch.randn(z_cond.shape).to(uv_mask.device)
else:
eps = noise
z = torch.cat([eps, z_cond], dim=1)
x = self.decoder(z)
x = x * uv_mask[:,None,:,:]
return x
def reparameterize(self, mean, logvar, fix_noise=False):
if self.training == True:
if not fix_noise:
eps = torch.normal(mean=0.0, std=1.0, size=mean.shape).to(mean.device)
else:
eps = torch.normal(mean=0.0, std=1.0, size=mean.shape).to(mean.device)
eps = torch.tile(eps, [mean.shape[0],1])
out = eps * torch.exp(logvar * .5) + mean
else:
out = torch.exp(logvar * .5) + mean
return out
def forward(self, inputs, z_cond):
uv_unposed, uv_template, uv_body_posed, uv_normals, uv_mask, uv_mask_high = inputs
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)
z = self.reparameterize(mean, logvar)
z = torch.reshape(z, (mean.shape[0], -1, 8, 4))
z = torch.concat([z, z_cond], dim=1)
x = self.decoder(z)
x = x * uv_mask[:,None,:,:]
# if self.upscale_enhancer is not None:
# pred_low = self.enhance(x, uv_mask, training=training)
# x = tf.image.resize(pred_low, (512, 256), tf.image.ResizeMethod.LANCZOS5)
# x = x * uv_mask_high[:,:,:,tf.newaxis]
x = x * self.scaling
return x, mean, logvar