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
| import torch import torch.nn as nn
class ECRAR(nn.Module): """ ECRAR: 环境上下文感知雷达动作识别 两个并行分支: 1. 人体运动分支: 4D 点云 → 运动特征 2. 场景上下文分支: 雷达背景 → 场景特征 3. 联合推理: 运动 × 场景 → 动作分类 """ def __init__(self, num_classes=10, hidden_dim=256): super().__init__() self.motion_encoder = MotionEncoder4D( in_channels=5, hidden_dim=hidden_dim ) self.context_encoder = SceneContextEncoder( in_channels=5, hidden_dim=hidden_dim ) self.fusion = nn.Sequential( nn.Linear(hidden_dim * 2, hidden_dim), nn.GELU(), nn.Dropout(0.2), nn.Linear(hidden_dim, num_classes) ) def forward(self, human_points, scene_points): """ Args: human_points: (B, N_h, 5) 人体雷达点 scene_points: (B, N_s, 5) 场景雷达点 """ motion_feat = self.motion_encoder(human_points) context_feat = self.context_encoder(scene_points) combined = torch.cat([motion_feat, context_feat], dim=-1) logits = self.fusion(combined) return logits
class MotionEncoder4D(nn.Module): """4D 雷达人体运动编码器""" def __init__(self, in_channels=5, hidden_dim=256): super().__init__() self.mlp = nn.Sequential( nn.Linear(in_channels, 64), nn.ReLU(), nn.Linear(64, 128), nn.ReLU(), nn.Linear(128, hidden_dim) ) self.temporal = nn.GRU( hidden_dim, hidden_dim // 2, batch_first=True, bidirectional=True ) def forward(self, points): feat = self.mlp(points) feat = feat.max(dim=1)[0] if feat.dim() == 3: feat, _ = self.temporal(feat) feat = feat[:, -1, :] return feat
class SceneContextEncoder(nn.Module): """场景上下文编码器""" def __init__(self, in_channels=5, hidden_dim=256): super().__init__() self.encoder = nn.Sequential( nn.Linear(in_channels, 64), nn.ReLU(), nn.Linear(64, 128), nn.ReLU(), nn.Linear(128, hidden_dim) ) self.spatial_attn = nn.Sequential( nn.Linear(hidden_dim, 1), nn.Softmax(dim=1) ) def forward(self, scene_points): feat = self.encoder(scene_points) attn = self.spatial_attn(feat) feat = (feat * attn).sum(dim=1) return feat
if __name__ == "__main__": model = ECRAR(num_classes=10) human = torch.randn(2, 100, 5) scene = torch.randn(2, 500, 5) out = model(human, scene) print(f"Human points: {human.shape}") print(f"Scene points: {scene.shape}") print(f"Output: {out.shape}") print(f"Params: {sum(p.numel() for p in model.parameters()):,}")
|