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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| """ LTC-CGMN 完整模型 """
class LTC_CGMN(nn.Module): """ LTC-CGMN: Lightweight Temporal Convolution + Cross-Granularity Mapping Network 架构: 1. Backbone: 轻量 2D-CNN 提取空间特征 2. CGSM: 跨粒度状态映射 3. LTC: 轻量时序卷积 4. 双头输出:离散分类 + 连续 DRI """ def __init__(self, num_classes: int = 6, backbone_dim: int = 256): super().__init__() self.backbone = nn.Sequential( nn.Conv2d(3, 32, 3, stride=2, padding=1), nn.BatchNorm2d(32), nn.GELU(), nn.Conv2d(32, 64, 3, stride=2, padding=1), nn.BatchNorm2d(64), nn.GELU(), nn.Conv2d(64, 128, 3, stride=2, padding=1), nn.BatchNorm2d(128), nn.GELU(), nn.Conv2d(128, backbone_dim, 3, stride=2, padding=1), nn.BatchNorm2d(backbone_dim), nn.GELU(), nn.AdaptiveAvgPool2d((4, 4)) ) self.fine_proj = nn.Linear(backbone_dim * 4, backbone_dim) self.coarse_proj = nn.Linear(backbone_dim * 4, backbone_dim) self.cgsm = CGSM(backbone_dim, backbone_dim, num_heads=4) self.temporal_pool = nn.AdaptiveAvgPool1d(1) self.ltc = LTCBlock(backbone_dim, num_layers=4, kernel_size=3) self.classifier = nn.Sequential( nn.Linear(backbone_dim, backbone_dim // 2), nn.GELU(), nn.Dropout(0.2), nn.Linear(backbone_dim // 2, num_classes) ) self.dri_head = nn.Sequential( nn.Linear(backbone_dim, backbone_dim // 2), nn.GELU(), nn.Dropout(0.2), nn.Linear(backbone_dim // 2, 1), nn.Sigmoid() ) def forward(self, x: torch.Tensor) -> tuple: """ Args: x: (B, T, C, H, W) 视频输入 Returns: logits: (B, num_classes) 离散分类 dri: (B,) 连续风险指数 """ B, T, C, H, W = x.shape x = x.view(B * T, C, H, W) feat = self.backbone(x) feat = feat.view(B, T, -1) fine_feat = self.fine_proj(feat) coarse_feat = self.coarse_proj(feat) aligned = self.cgsm(fine_feat, coarse_feat) aligned = aligned.permute(0, 2, 1) temporal_feat = self.ltc(aligned) pooled = self.temporal_pool(temporal_feat).squeeze(-1) logits = self.classifier(pooled) dri = self.dri_head(pooled).squeeze(-1) return logits, dri
if __name__ == "__main__": model = LTC_CGMN(num_classes=6, backbone_dim=256) x = torch.randn(2, 16, 3, 224, 224) with torch.no_grad(): logits, dri = model(x) print(f"输入: {x.shape}") print(f"分类输出: {logits.shape}") print(f"DRI 输出: {dri.shape}") print(f"DRI 值: {dri.tolist()}") total_params = sum(p.numel() for p in model.parameters()) print(f"\n总参数量: {total_params:,} ({total_params/1e6:.2f}M)") model.eval() import time with torch.no_grad(): for _ in range(5): _ = model(x) start = time.perf_counter() for _ in range(20): _ = model(x) elapsed = time.perf_counter() - start fps = 20 * 16 / elapsed print(f"推理速度: {fps:.1f} FPS (CPU, 估计)")
|