L = ∑ i ∈ I − 1 ∣ P ( i ) ∣ ∑ p ∈ P ( i ) log exp ( α i T α p / τ ) ∑ b ∈ A ( i ) exp ( α i T α b / τ ) \mathcal{L} = \sum_{i \in I} \frac{-1}{|P(i)|} \sum_{p \in P(i)} \log \frac{\exp\big(\boldsymbol{\alpha}_i^{\mathrm{T}}\boldsymbol{\alpha}p / \tau\big)}{\sum{b \in A(i)} \exp\big(\boldsymbol{\alpha}_i^{\mathrm{T}}\boldsymbol{\alpha}_b / \tau\big)} L=i∈I∑∣P(i)∣−1p∈P(i)∑log∑b∈A(i)exp(αiTαb/τ)exp(αiTαp/τ)
(2)
数据增强只用两种,且与物理场景对应:加高斯噪声 (噪声不确定性)与随机水平平移(时延不确定性)。
python复制代码
import torch, torch.nn.functional as F
def augment(x, rng, noise_std=0.05, max_shift=0.1):
"""两种增强:加性高斯噪声 + 随机水平平移"""
x = x + noise_std * torch.randn_like(x)
k = int(max_shift * x.shape[-1])
if k > 0:
s = rng.integers(-k, k + 1)
x = torch.roll(x, shifts=int(s), dims=-1)
return x
def supcon_loss(feat, labels, tau=0.07):
"""式(2):feat 已归一化,shape (3B, D);labels shape (3B,)"""
feat = F.normalize(feat, dim=1)
sim = feat @ feat.T / tau # (3B, 3B)
self_mask = torch.eye(sim.size(0), device=sim.device).bool()
sim.masked_fill_(self_mask, -1e9)
pos = (labels.unsqueeze(0) == labels.unsqueeze(1)) & (~self_mask)
log_p = sim - torch.logsumexp(sim, dim=1, keepdim=True)
return -(log_p * pos).sum(1) / pos.sum(1).clamp(min=1)
α k = 1 ∣ S k ∣ ∑ Z ∈ S k g ρ ( Z ) , c t ∗ = arg min k ∥ β t − α k ∥ 2 \boldsymbol{\alpha}k = \frac{1}{|S_k|}\sum{\mathbf{Z} \in S_k} g_{\rho}(\mathbf{Z}), \qquad c_t^* = \arg\min_k \|\boldsymbol{\beta}_t - \boldsymbol{\alpha}_k\|^2 αk=∣Sk∣1Z∈Sk∑gρ(Z),ct∗=argkmin∥βt−αk∥2
(3)
python复制代码
@torch.no_grad()
def build_prototypes(encoder, loader, n_cls, dim, device):
"""式(3):支持集按类求均值。新增类别无需重训,只需重算原型"""
encoder.eval()
proto = torch.zeros(n_cls, dim, device=device)
cnt = torch.zeros(n_cls, device=device)
for x, y in loader:
f = encoder(x.to(device))
for c in torch.unique(y):
m = (y.to(device) == c)
proto[c] += f[m].sum(0); cnt[c] += m.sum()
return proto / cnt.clamp(min=1).unsqueeze(1)
@torch.no_grad()
def predict(encoder, x, proto):
f = encoder(x)
logits = -(torch.cdist(f, proto) ** 2)
return logits.argmax(1), logits.softmax(1)
六、实验结果
6.1 方法对比(均以 SNR = 10 dB 数据训练,支持集相同)
方法
−6 dB
−3 dB
0 dB
10 dB
参数量
推理时间
Prior-K-NN
13.76%
20.16%
30.17%
99.11%
20 M
0.18 s
MS-WSN
18.06%
19.15%
22.97%
99.21%
5.4 M
0.05 s
PSPNet
38.55%
40.55%
57.31%
99.21%
0.202 M
0.0006 s
AWSPNet(EfficientNetV2)
52.44%
75.25%
93.56%
99.91%
24 M
0.19 s
AWSPNet(ResNet50)
45.32%
72.54%
91.91%
99.91%
25.5 M
0.20 s
10 dB 上所有方法都接近满分,区分度全在低 SNR 区 。PSPNet 以 0.202 M 参数做到 38.55%,是轻量方案里性价比最高的。
6.2 消融
配置
−6 dB
−3 dB
0 dB
10 dB
推理时间
完整模型
52.44%
75.25%
93.56%
99.91%
0.19 s
去掉 DTCWT
42.12%
72.31%
92.01%
99.01%
0.16 s
去掉注意力
42.18%
72.14%
93.06%
99.91%
0.19 s
去掉预训练权重
15.95%
24.13%
37%
93.45%
0.20 s
去掉预训练权重是灾难性的:−6 dB 掉到 15.95%,0 dB 仅 37%,接近随机猜测。迁移学习是这个方案的承重墙,不是装饰。
6.3 训练集 SNR 分布的影响(最关键的实验)
训练 / 支持集配置
−6 dB
−3 dB
0 dB
10 dB
多 SNR 混合训练
90.45%
94.33%
95.78%
95.01%
仅 −6 dB 数据训练
82.42%
61.91%
55.95%
50.11%
10 dB 训练 + 多 SNR 支持集
42.44%
55.15%
91.49%
99.11%
三条实践结论:多 SNR 混合训练是唯一在全体 SNR 都稳的配置;只用低 SNR 训练会严重偏科(−6 dB 82.42% 但 10 dB 仅 50.11%,噪声形态被当成判别特征);换支持集救不了训练集分布错配(42.44%)。
为什么支持集补偿不了训练集。 原型网络确实有小样本适应能力,但它适应的前提是编码器已经把同类样本映射到邻近区域。若编码器在训练阶段从未见过 −6 dB 的噪声形态,它输出的 −6 dB 样本特征本身就是散乱的,此时无论用哪个分布的支持集去求均值,得到的原型都不具备判别力。一句话:原型网络能适应"新类别",不能适应"新分布",这两件事在实践中经常被混为一谈,部署时应该把"支持集维护"与"编码器重训"当作两个独立流程管理。
另外值得注意的读法:多 SNR 混合训练在 10 dB 上从 99.91% 降到 95.01%,看起来是退步,但换来 −6 dB 从 52.44% 到 90.45%。在真实系统里高 SNR 样本本来就容易分,这笔交易是划算的。
Jia Y, Xiao S, Jia W, et al. AWSPNet: Attention-based dual-tree wavelet scattering prototypical network for MIMO radar target recognition and jamming suppressionJ. arXiv:2510.18422, 2025.
Selesnick I W, Baraniuk R G, Kingsbury N C. The dual-tree complex wavelet transformJ. IEEE Signal Processing Magazine, 2005, 22(6): 123-151.
Bruna J, Mallat S. Invariant scattering convolution networksJ. IEEE Transactions on PAMI, 2013, 35(8): 1872-1886.