File size: 2,269 Bytes
c3ec853
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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
        }