yolozyk's picture
update generate tools
c3ec853
Raw
History Blame Contribute Delete
2.27 kB
import torch
import torch.nn as nn
import torch.nn.functional as F
class SMPL2PressureLoss(nn.Module):
"""
Combined loss for SMPL2Pressure cVAE.
- Pressure Map Reconstruction (PMR): MSE Loss
- Point Cloud Reconstruction (PCR): MSE Loss (from condition features)
- KL Divergence: Regularization of latent space
"""
def __init__(self, cfg):
super(SMPL2PressureLoss, self).__init__()
self.cfg_loss = cfg['training']['loss']
# 权重配置
self.pmr_weight = self.cfg_loss.get('pmr_weight', 10.0)
self.pcr_weight = self.cfg_loss.get('pcr_weight', 6.0)
self.kl_weight = self.cfg_loss.get('kl_weight', 2.0)
def forward(self, outputs, target_pressure, target_vertices):
"""
Args:
outputs: cVAE模型的输出字典
target_pressure: 真值压力图 (B, H, W) 或 (B, 1, H, W)
target_vertices: 真值SMPL顶点 (B, 6890, 3)
"""
# 1. 压力图重建损失 (PMR)
recon_pressure = outputs['recon_pressure']
# 统一维度: 确保 target 也是 (B, 1, H, W)
if recon_pressure.dim() == 3:
recon_pressure = recon_pressure.unsqueeze(1)
if target_pressure.dim() == 3:
target_pressure = target_pressure.unsqueeze(1)
loss_pmr = F.mse_loss(recon_pressure, target_pressure, reduction='mean')
# 2. 点云重建损失 (PCR)
# 根据你的提醒,这里的 recon_vertices 应该是从 cond_features 解码出来的
recon_vertices = outputs['recon_vertices']
loss_pcr = F.mse_loss(recon_vertices, target_vertices, reduction='mean')
# 3. KL 散度损失
mu = outputs['mu']
log_var = outputs['log_var']
# KL = -0.5 * sum(1 + log(sigma^2) - mu^2 - sigma^2)
loss_kl = -0.5 * torch.mean(torch.sum(1 + log_var - mu.pow(2) - log_var.exp(), dim=1))
# 4. 总损失加权
total_loss = (self.pmr_weight * loss_pmr +
self.pcr_weight * loss_pcr +
self.kl_weight * loss_kl)
return {
'loss': total_loss,
'loss_pmr': loss_pmr,
'loss_pcr': loss_pcr,
'loss_kl': loss_kl
}