Spaces:
Runtime error
Runtime error
| 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 | |
| } | |