0. 本文贡献用信号处理读者能读懂的方式介绍 DTNet原论文记作 HSE在 I/Q 调制识别任务中的主要做法双流嵌入 SFE 多尺度扩展 Transformer 长程建模 split-MLP 轻量分类头。给出 RML2016.10b 同一数据口径下的 PyTorch 复现结果并补充三类由代码生成的中文标注图训练曲线、各类调制时域波形、混淆矩阵。完整训练与评估代码已上传 GitHubhttps://github.com/zhanghzsjtu/MATLAB/tree/main/dtnet-rml2016-pytorch。1. 背景与问题自动调制识别AMR的任务是给定一段接收到的复数基带信号判断它采用了哪种调制方式。输入是一个长度为 128 的采样序列每个采样点用两路正交分量表示x∈R128×2x \in \mathbb{R}^{128 \times 2}x∈R128×2其中第一列是同相分量 I第二列是正交分量 Q。输出是 10 个调制类别之一BPSK、QPSK、8PSK、QAM16、QAM64、PAM4、WBFM、CPFSK、GFSK、AM-DSB。传统做法依赖人工设计的特征如星座图、高阶累积量深度学习做法则跳过人工特征直接从 I/Q 波形中抽取判别信息。DTNet 属于后者它的核心思路是同时观察信号的局部片段和更长时段的结构再统一做分类决策。2. 数据长什么样下面这张图从 RML2016.10b 数据集中为每类调制各抽取了一个高 SNR 样本画出其 I 路蓝色与 Q 路橙色随采样点的变化。从波形上可以直观地区分几类调制PSK 类BPSK、QPSK、8PSK包络基本恒定主要差异在相位变化次数。QAM 类QAM16、QAM64幅度和相位同时变化波形兼具调幅与调相特征。PAM4 与 AM-DSB以幅度变化为主包络起伏明显。FM 类WBFM、CPFSK、GFSK频率变化主导波形形态。这些差异正是模型可以用来分类的依据。当信噪比降低时噪声会把这些波形特征淹没分类难度随之上升。3. DTNet 做了哪几件事DTNet 的整体结构可以概括为四个步骤。为便于理解这里只保留输入维度定义其余步骤用功能描述代替推导。3.1 双流嵌入输入x∈R128×2x \in \mathbb{R}^{128 \times 2}x∈R128×2被并行地送入两路卷积支流一局部用较小的卷积核在原始 I/Q 上滑动每次只看 16 个连续采样点提取局部波形特征。支流二全局先经过一个 SFE 模块把两路原始 I/Q 扩展到 128 通道特征图再用更大的感受野提取长时段结构。最后把两支流产出的 token 拼接在一起加上一个分类用的 CLS token 与位置编码供后续模块处理。3.2 SFE 模块SFEScale-Feature-Extension负责把 2 通道原始信号扩展成高维特征图。它包含两条支路Scale 支路用残差卷积 幅度门控注意力提取局部尺度特征。Extension 支路用深度可分离卷积 通道注意力逐步扩展通道数从 2 通道升到 128 通道。整个过程中时间维长度保持 128 不变只是通道维被扩充以便支流二能从更宽的视角观察信号。3.3 Transformer 编码器与 split-MLP拼接后的 token 序列送入 4 层 Transformer 编码器。每一层包含多头自注意力在 25 个 token 之间计算关联权重使每个位置都能看到全局上下文。split-MLP把 40 维特征分成两半各过一个窄前馈网络后再拼接。相比标准前馈参数量大约减半。分类时取最后一层的 CLS token 过一个线性层输出 10 个类别的分数再用 softmax 得到概率。4. 实验结果复现口径RML2016.10b10 类未归一化 I/Q70/15/15 划分train 84 万 / val 18 万 / test 18 万。PyTorch 训练 20 epoch、batch 2048、AMP约 14 分钟。训练损失从第 1 轮的 1.33 单调下降到第 20 轮的 0.89验证准确率从 52.6% 上升到 62.95%。指标test 集数值整体精度62.76%per-SNR 宏平均62.87%最优单 SNR 精度92.90% 12 dB随 SNR 升高精度单调上升低 SNR−20 dB约 11%高 SNR12 dB 以上达 92%。混淆矩阵揭示了 10 类之间的主要误判关系AM-DSB 有 51% 的样本被误判为 QPSK说明这两类在低 SNR 下的波形特征最接近。GFSK 有 19% 误判为 BPSKFM/PSK 类之间的区分在噪声下变得困难。WBFM 与 CPFSK 之间也有少量互混。PAM4、QAM64 的对角线比例相对较高说明模型对这两类的识别相对稳定。5. 训练加速做法具体怎么改的复现训练只用了约 14 分钟20 epoch、batch 2048单张 RTX 4060 Laptop。这不是模型小到可以忽略而是训练管线做了四项针对性加速。它们只改变计算的执行方式不改变网络结构、不改变每层输出的数值语义因此复现结果与原始实现仍然可直接对照。下面逐项说明改了脚本的哪一段、GPU 上发生了什么。5.1 AMP 混合精度改了什么训练循环的前向与反向包进torch.amp.autocast(cuda)并配一个GradScaler做梯度缩放。scalertorch.amp.GradScaler(cuda)withtorch.amp.autocast(cuda,enableduse_amp):logitsmodel(xb)losscrit(logits,yb)scaler.scale(loss).backward()scaler.step(optim)scaler.update()为什么快现代 NVIDIA GPURTX 40 系为 Ada 架构有一组专门的Tensor Core做矩阵乘法时用 fp16半精度2 字节比默认 fp32单精度4 字节快约 2~3 倍且显存占用减半。但 fp16 动态范围小梯度太小会被舍成 0——GradScaler先把损失乘一个大的比例因子再反向让梯度落在 fp16 可表示的范围更新前再除回来从而兼顾速度与数值稳定。我们只在卷积、矩阵乘这些 Tensor Core 擅长的算子用 fp16softmax、LayerNorm 等仍走 fp32避免精度异常。5.2 fused Adam改了什么优化器仍用原版的Adam weight_decay语义只是把内核融合。optimtorch.optim.Adam(model.parameters(),lr4e-3,weight_decay1e-4,fusedtorch.cuda.is_available())为什么快普通Adam的算梯度一阶矩/二阶矩 → 更新参数」每一步都是独立 kernel要在显存里反复读写参数和动量。加fusedTrue后PyTorch 把这几步合并成一个 CUDA kernel参数只载入一次、更新完直接写回少了多次显存往返。我们用try/except包住万一当前 PyTorch 版本没有融合内核就退回普通 Adam不影响正确性。权重衰减项的系数1e-4、学习率4e-3都和原版一致所以更新的数学结果不变只是执行更紧凑。5.3 DataLoader 并行预取改了什么构造数据加载器时开了多进程与锁页内存。loaderDataLoader(ds,batch_size2048,shuffleTrue,num_workers4,pin_memoryTrue,persistent_workersTrue)为什么快默认 DataLoader 在主进程里读 h5、做归一化、组 batchCPU 干活时 GPU 在空等。开num_workers4后4 个子进程在后台并行把下一批样本准备好pin_memoryTrue把张量锁在页锁定内存GPU 用 DMA 直接搬、省掉一次拷贝persistent_workersTrue让子进程在整个训练期不销毁重建避免每个 epoch 重复 fork 的开销。效果是 GPU 几乎不空等计算墙时间被压到接近纯前向/反向耗时。5.4 cuDNN benchmark改了什么训练开始前一行开关。torch.backends.cudnn.benchmarkTrue为什么快cuDNN 对同一个卷积/矩阵乘有多种实现不同分块、不同算法耗时差异可达数倍。benchmarkTrue让它在训练初期用一小批数据实测各实现的速度、记住最快的那个之后固定复用。代价是启动慢几秒但本模型结构固定、要跑 20 epoch这笔开销很快摊平。若输入尺寸每步都在变如动态序列长度则不适合开——这里 128 长 I/Q 序列固定所以稳定受益。5.5 有意不做的两项有两項常见的加速手段没有采用理由一致——网络定义必须与原始 ipynb 逐结构一致这是和 MATLAB 版互证的根基加速只动训练管线不碰网络本体。FlashAttention本模型注意力序列仅 25 个 token25×25 注意力矩阵FlashAttention 针对长序列的内存优化在这里几乎无收益且会引入与原实现的数值差异。torch.compile首次编译开销大且可能改变某些算子的数值行为作为增量实验更合适不在基础复现版启用。梯度累积也曾考虑——但 batch 2048 在本模型上显存占用 2 GB8 GB 显存完全够无需靠累积来撑大有效 batch故不加。6. 为什么高 SNR 效果好高 SNR 下准确率达到 92% 以上不是模型在高 SNR 时突然变强而是信号本身更清晰。在通信系统中SNR 定义为信号功率与噪声功率之比SNRPsignalPnoise\mathrm{SNR} \frac{P_{\mathrm{signal}}}{P_{\mathrm{noise}}}SNRPnoise​Psignal​​当 SNR −20 dB 时噪声功率是信号功率的约 100 倍原始 I/Q 波形几乎被噪声淹没10 类调制的波形特征严重重叠模型只能接近随机猜测约 10%。当 SNR 12 dB 时信号功率远高于噪声各类调制的 I/Q 结构相位跳变、幅度层级、频率变化清晰可分模型从双流嵌入提取出的局部与全局特征稳定可靠因此准确率大幅上升。所以per-SNR 曲线随 SNR 单调上升是 AMR 任务的典型现象反映的是信号被噪声淹没的程度下降而非模型结构本身在低 SNR 下失效。7. 复现口径说明本文复现的 ~62% 整体 / ~92% 高 SNR 水平与原论文报告的 94.4% 差距来自数据口径论文为 11 类、归一化 I/Q、不同验证划分本文为 10 类、未归一化、70/15/15属口径差异而非实现错误。8. 收束DTNet 通过双流嵌入 SFE Transformer在 I/Q 调制识别上取得 ~62% 整体 / ~92% 高 SNR 的复现精度。训练曲线、per-SNR 准确率图、时域波形图、混淆矩阵均由本仓库脚本基于真实数据生成便于他人复现与对照。复现代码已开源https://github.com/zhanghzsjtu/MATLAB/tree/main/dtnet-rml2016-pytorch。