首页 / 资讯中心 / 文章详情

对抗迁移学习解决自动调制分类跨域性能暴跌问题

对抗迁移学习解决自动调制分类跨域性能暴跌问题 ★ FEATURED ARTICLE
做自动调制分类Automatic Modulation Classification, AMC的人几乎都遇到过同一种尴尬模型在训练集上准确率能做到95%以上换到实际接收环境一测直接掉到70%以下。这不是模型容量不够而是训练数据和部署数据压根不在一个分布上。这篇标题为Adversarial Transfer Learning for Deep Learning Based Automatic Modulation Classification的工作核心就是解决这个问题用对抗迁移学习把基于深度学习的AMC模型从“训练环境”平滑迁移到“真实目标环境”而且目标域可以完全没有标签。这篇内容适合两类人。一类是做无线信号识别、认知无线电、频谱监测的算法工程师另一类是想把域自适应方法落地到时序信号或射频数据上的研究者。我会把这个标题里的三层内容拆开讲清楚AMC任务本身卡在哪、对抗迁移学习为什么能解决、以及这类方法在工程复现时最容易踩的坑。全部内容基于我对该类方案的复现经验和公开实验规律的总结关键步骤尽量给到可以抄作业的程度。1. 先看懂这个标题在解决什么问题1.1 自动调制分类在信号处理链路中的位置自动调制分类的任务用一句话说就是接收机在非协作场景下不知道对方用了什么调制方式必须先从收到的信号里判断出调制类型比如BPSK、QPSK、8PSK、16QAM、64QAM然后才能选择对应的解调方案。它不只是学术题目在认知无线电、频谱监测、干扰识别、电子侦察这些场景里面都是非常关键的处理环节。传统做法大致分两类。第一类是判决理论方法通过似然比检验在候选调制方式里挑一个最大后验概率的理论性能最好但计算量大且对模型失配敏感。第二类是特征统计模式识别先提取高阶累积量、循环谱、瞬时幅度相位统计量等人工特征再送进分类器。这种方法的瓶颈在于特征设计依赖专家经验场景一变特征区分度就掉得很快。深度学习路线之所以这几年成为主流就是因为它把“特征提取分类”合成了一个端到端模型。输入通常就是IQ采样序列也就是把复基带信号拆成I路和Q路当双通道序列处理再交给卷积网络、循环网络或者近年来的Transformer结构。深度模型能在公开数据集上拿到很高的分类准确率尤其在高信噪比区间几乎可以把常见调制类别分得清清楚楚。但问题恰恰出在“高信噪比”和“公开数据集”这两个词上。实际部署场景里接收信号的信噪比是未知的信道可能是多径衰落还有频偏、相位噪声、干扰信号叠加。用实验室采集的数据训练出来的模型一到真实环境就会退化这不是换一个更大的网络就能解决的。1.2 域漂移是深度学习AMC落地的主要障碍要理解这篇论文为什么要引入迁移学习先要理解机器学习里一个非常基础的假设训练集和测试集是独立同分布的。深度AMC模型在训练时默认训练数据的分布和将来使用环境的分布是一致的。但实际系统里这个假设几乎不成立。在AMC场景里“域”这个概念是很具体的。源域指的是有标注信号的数据分布通常来自仿真平台或者理想信道条件下采集的数据。目标域则是实际部署时的信号分布信噪比更低、信道衰落更重、收发机特性也完全不同。即使信号里包含的调制类别是同一套模型看到的特征空间也已经发生了偏移。一个常见的现象是用10dB以上的高信噪比样本训练模型部署到0dB甚至负信噪比环境准确率断崖式下跌。反过来也一样如果训练集集中在某一种信道模型上换到另一种信道模型后模型会把信道特征当成调制类别特征来用泛化能力自然就差。这背后的本质是接收信号的瞬时特征同时包含了“发送端调制行为”和“信道传输影响”两种信息。分类器很容易学到信道特征这种捷径而不是真正与调制方式强相关的信号结构。1.3 迁移学习为什么是解决这个问题的切入点迁移学习的核心思路很直接源域有大量标注数据目标域可能只有少量甚至没有标注数据如何把源域里学到的知识迁移到目标域上。在AMC问题里我们恰好就面临这种“源域标注充足、目标域没有标签”的现实情况。调制识别不像图像分类那样可以靠人工轻松标注目标域信号一进来就要尽快识别不可能先人工标一批再训练。这个设定条件下最合适的一族方法叫直推式迁移学习也叫无监督域适配源域有标签、目标域无标签。域适配的原则是让模型提取出的信号特征具备域不变性也就是说特征的取值应该主要由调制方式决定而不是由信噪比、信道类型或者设备型号决定。想要实现这种域不变性有两种主流手段。一种是显式约束比如最小化最大均值差异MMD这样的分布距离度量让源域和目标域的特征分布尽量重叠。另一种就是这篇标题里强调的对抗方式引入一个判别器和特征提取器互相博弈逼着特征提取器丢掉域相关信息。对抗方法的优势在于不需要人为指定特征距离的度量方式理论上可以适配更复杂的高维分布差异。2. 对抗迁移学习方案是怎么设计的2.1 域对抗思想的来源与本质对抗迁移学习的思路和生成对抗网络GAN的思想一脉相承。GAN里生成器试图骗过判别器最终生成逼真的伪样本域对抗网络中特征提取器试图骗过域判别器最终让特征的来源域无法被区分。你可以把它理解成一个伪造者和鉴定专家的博弈。伪造者想造出一种签名让鉴定专家看不出来自哪个地区鉴定专家则想一眼认出产地。两者不断对抗最终伪造者被迫找出各地签名的公共结构也就是真正表征身份本质的部分。对应到AMC问题特征提取器就是要找出不同信道环境下调制方式的公共结构忽略噪声和信道带来的表象差异。这个思想落地到工程上最经典的是域对抗神经网络DANN。它通过一个梯度反转层GRL实现对抗训练前向计算时GRL啥也不干反向传播时把来自域判别器的梯度取反。这样特征提取器向着“增加判别器错误”的方向更新域判别器向着“降低自身错误”的方向更新从而形成一种对抗关系。2.2 特征提取、调制分类、域判别三个模块的配合整套网络结构可以拆成三个部分。第一部分是特征提取器它是一个共享骨干网络源域和目标域信号都经过同一个特征提取器得到高维特征。第二部分是调制分类器只接收源域特征输出调制类别概率用源域标签监督。第三部分是域判别器接收特征输出这个特征来自源域还是目标域。数据流大致是这样的从源域抽一个batch从目标域抽一个batch。源域样本进入特征提取器后特征同时送入调制分类器和域判别器分别产生分类损失和域判别损失。目标域样本进入特征提取器后特征只送入域判别器产生域判别损失。目标域样本没有标签所以不参与分类损失的计算。特征提取器的参数会收到两个方向的梯度。分类器方向要求特征保留调制类别区分性域判别器方向则要求特征不包含域信息。最终训练出一个状态从源域和目标域提取出的特征在分布上几乎无法区分同时又能正确预测源域的调制类型因此也就能在目标域上有较好的表现。2.3 损失函数与对抗训练节奏的设计总损失函数可以表示成分类损失与域判别损失的组合。分类损失用标准交叉熵约束源域样本的调制类别预测。域判别损失也用交叉熵只不过标签是“域来源”源域记作0目标域记作1。域判别器要最小化这个损失特征提取器在梯度反转层的影响下要最大化这个损失最终形成min-max博弈。如果你用过一个叫CDAN的改进方案会发现一个重要的优化思路域判别器不能只看特征本身最好把调制分类器的类别预测结果也一起作为输入。原因是单纯对齐特征的整体边缘分布不一定能保证两个域在“同一调制类别”上的局部条件分布对齐。加入类别信息后判别器能约束条件分布减少负迁移风险。训练节奏很重要。不能一开始就让域判别器火力全开否则特征提取器还没学会基本的调制特征就先去对抗了最后两边都学不好。常见的做法是先只用源域数据正常训练分类器若干轮再做对抗训练。对抗强度用GRL的超参数控制通常从0开始随着迭代步数线性增长到某个上限这个调度过程需要根据数据集规模去调。3. 复现这套方法的完整实操指南3.1 数据准备与域划分策略拿到调制信号数据之后不要急着喂给网络先把数据划分想清楚。公开的调制识别数据集通常以IQ复数样本为基本单位每条样本附带调制类型标签和信噪比标签。如果你的问题里没有现成目标域数据那就自己构造域差异模拟真实部署场景。我做过比较有效的三种域划分方式。第一种按信噪比划分源域取10dB以上的高信噪比样本目标域取0dB左右的低信噪比样本模拟高信噪比环境下训练、低信噪比环境下部署的情况。第二种按信道模型划分源域用加性高斯白噪声信道目标域用多径衰落信道模拟信道条件变化。第三种按接收设备划分用不同批次采集数据做域划分模拟设备个体差异。预处理方面IQ信号要按样本做归一化不能用全局统计量替代否则个别强信号样本会把整个数据分布撑大。序列长度建议固定常用的是128或256个复数符号长度如果输入样本更长可以切窗。太短了特征不充分太长了计算浪费。归一化之后把IQ两路拼成两通道的实数张量方便送进卷积网络。一个重要提醒目标域样本只能用于无监督适配不能参与任何带标签的训练。如果硬要在训练中观察目标域效果也只能留极小一部分带标签数据做最终评估不能反向影响模型选择。否则你的实验结论会对实际部署产生误导。3.2 模型结构的搭建与代码骨架特征提取器用卷积网络构建是比较稳妥的选择。一个常见的结构是五层卷积块每层卷积加批归一化加ReLU激活前几层可以下采样最后一层做全局平均池化得到特征向量。调制分类器接在特征向量后面用两层全连接加softmax。域判别器结构类似但最后一层用sigmoid输出域来源概率。特征向量维度不用太大256维左右就够用。调制类别数按数据集来常见公开数据的类别数从11类到24类不等。判别器容量要比特征提取器小一些否则判别器学得太快对抗容易失衡。下面给出一个PyTorch风格的代码骨架仅供参考实际实现请根据你的数据和参数调整import torch import torch.nn as nn import torch.nn.functional as F class GRL(nn.Module): def __init__(self, lamb): super().__init__() self.lamb lamb def forward(self, x): return x def backward(self, grad_output): return -self.lamb * grad_output class FeatureExtractor(nn.Module): def __init__(self, in_dim2): super().__init__() self.conv nn.Sequential( nn.Conv1d(in_dim, 64, 7, stride2, padding3), nn.BatchNorm1d(64), nn.ReLU(), nn.Conv1d(64, 64, 5, stride2, padding2), nn.BatchNorm1d(64), nn.ReLU(), nn.Conv1d(64, 128, 5, stride2, padding2), nn.BatchNorm1d(128), nn.ReLU(), nn.Conv1d(128, 256, 3, stride2, padding1), nn.BatchNorm1d(256), nn.ReLU(), nn.AdaptiveAvgPool1d(1), ) self.fc nn.Linear(256, 256) def forward(self, x): x self.conv(x).squeeze(-1) return F.relu(self.fc(x)) class ModClassifier(nn.Module): def __init__(self, n_classes11): super().__init__() self.fc nn.Sequential( nn.Linear(256, 128), nn.ReLU(), nn.Dropout(0.3), nn.Linear(128, n_classes) ) def forward(self, x): return self.fc(x) class DomainDiscriminator(nn.Module): def __init__(self): super().__init__() self.fc nn.Sequential( nn.Linear(256, 128), nn.ReLU(), nn.Dropout(0.3), nn.Linear(128, 1) ) def forward(self, x): return torch.sigmoid(self.fc(x))GRL的实现有多种方式上面这种是朴素的思路。标准做法建议把梯度反转封装成自定义autograd函数保证前向恒等、反向取反我这里只演示结构。3.3 训练流程与关键超参数设置训练时每个iteration从源域和目标域各抽一个batch两个batch的大小尽量一致建议64到128之间。batch太大显存压力大太小的话域判别器的统计噪声会很高导致梯度抖动剧烈。我实测下来batch小于32时对抗训练几乎没法稳定收敛。优化器一般用Adam特征提取器和分类器学习率设成1e-3到1e-4之间域判别器学习率单独设低一些比如特征提取器的0.1倍。这个不对称设置是为了防止判别器在博弈中过早胜出。权重衰减一般取1e-4到1e-5太大了会把特征空间压得太紧。训练步数比epoch数更好控制通常设成20000到40000个iteration。GRL的超参数可以从0开始先让分类器任务稳定再按线性方式增长到最大值。最大值不建议固定为1我看到不少复现里设到0.5就能达到很好的效果需要你自己通过验证集去找。训练过程中需要盯两个指标源域分类准确率和域判别准确率。域判别准确率如果迅速趋近100%说明判别器太强需要打压如果一直在50%附近波动说明特征已经比较难区分来源域对抗基本生效。源域准确率则应该稳步上升如果对抗开启后源域准确率明显下降说明对抗过强把有用的分类特征也洗掉了。3.4 效果评估与对比实验设计评估协议建议这样做在目标域测试集上扫描不同信噪比档位逐档计算调制分类准确率最终画出一条准确率曲线。只看平均准确率是不够的因为对抗迁移往往在中低信噪比下提升明显高信噪比下可能和基线持平甚至略低平均值会把趋势掩盖掉。对比实验至少要有以下几个方案。第一个是Source Only只用源域训练、直接在目标域测试这是底线。第二个是加上简单特征统计对齐的迁移方案比如MMD。第三个是微调方案假设目标域有少量标注时使用。第四个才是完整的对抗迁移方案。这样对比才能说清楚对抗迁移到底带来了多少增益。效果方面可以有一个预期在中低信噪比段对抗迁移相对Source Only会有比较明显的准确率提升有时候能拉回10个百分点以上在高信噪比段增益不大。另一个值得看的现象是混淆矩阵对抗迁移通常能改善那些星座形状相近的调制对比如16QAM和64QAM以及QPSK和8PSK。如果混淆矩阵里这类难分对没有改善就要怀疑你的对抗模块是否真的在对齐类别条件分布。4. 实操中的常见问题与避坑记录4.1 判别器学得太快导致训练失衡这个现象太常见了。训练开始没多少个iteration域判别准确率就冲到95%以上特征提取器再怎么更新都骗不过判别器整条对抗链路就形同虚设。原因无非三个判别器容量太大、学习率太高、GRL强度增长太快。判别器不需要很复杂两层全连接加Dropout就够了。学习率给到特征提取器的十分之一甚至二十分之一都不过分。GRL强度不要线性涨到1可以先固定在0.2观察情况。另外有一个非常实用的检查标准源域分类准确率应该在你开了对抗之后仍然保持稳定。如果源域分类准确率开始持续下跌说明对抗强度失控特征提取器已经开始牺牲分类信息去迁就域不变性这是典型的失衡信号。4.2 负迁移问题加了对抗反而更差做了对抗迁移之后目标域准确率反而比Source Only还要低这种情况叫负迁移。原因主要是两个方向。第一个方向是对抗对齐的是整个特征边缘分布但不同调制类别在目标域上的位形结构不一样。整体分布对齐了不代表每一类条件分布都对齐强行压齐可能导致局面比不做还乱。改进方案是使用类别条件对抗把调制分类器的预测输出拼到域判别器的输入里让对抗约束变成有条件的。第二个方向是对抗强度太大把本来对调制识别的判别性信息也抹掉了。解决方式是把GRL最大值调低或者干脆在对抗阶段做早停用一小部分有标签的目标域数据做监控准确率开始下降就停。我个人的习惯是先不加对抗模块跑通Source Only基线确保分类器本身没有问题再逐项加入对抗模块。如果加完对抗没有正向收益优先怀疑实验设计中的域划分是否合理而不是急着调网络结构。4.3 数值不稳定与训练抖动问题复现过程中最常见的数值问题是训练后期Loss突然变成NaN。这个问题在对抗迁移里比普通分类模型更容易出现因为特征提取器同时受两个方向梯度拉扯特征空间容易失稳。常规排查顺序是先看学习率是不是太高再看判别器输出是否有极端值。域判别器如果输出概率塌缩到0或1反向梯度会非常大对特征提取器冲击很严重。可以给判别器输出加一个很小的梯度裁剪或者用标签平滑把判别目标从0和1改成0.05和0.95。数据增强在AMC对抗迁移里也很有用。随机添加高斯噪声、随机时移、小幅度频偏扰动都能提升模型鲁棒性。不过这要控制尺度过强的增强会让源域本身都难以学习。4.4 关键超参数速查与经验参考下面是我在类似问题上常用的参数起点你可以根据实际数据集调整。表格不是标准答案但它能让你在盲调之前先有个靠谱的落脚点。超参数建议范围说明特征输入长度128或256个IQ符号过短特征不足过长增加计算量特征向量维度256再大收益有限训练更慢源域batch大小64128目标域batch与之保持一致特征提取器学习率1e-41e-3预训练充分时可取上限判别器学习率特征提取器的0.1倍防止判别器过快收敛GRL强度最大值0.30.5多数场景不需要到1训练总步数2000040000步数控制比epoch更精确标签平滑判别目标设为0.05/0.95缓解判别器输出极端化数据增强高斯噪声、时移、频偏微扰增强跨域鲁棒性最后再分享一个我在实际复现中的体会对抗迁移这种方案真正起决定作用的往往不是精巧的loss设计而是你对数据域的划分方式理解和基线模型的扎实程度。先把Source Only做得足够好把域差异想清楚再加对抗模块你会少走很多弯路。如果后续要在真实接收机上做在线适配这套框架还可以往半监督方向扩展目标域出现少量标注时用双分类器做约束收敛会更稳定。
阅读完成 · 觉得有帮助?
咨询建站