基于卷积神经网络的OFDM频谱感知:原理、实现与工程部署
发布时间:2026/9/19 17:22:56 锦皓数字建站

简介基于卷积神经网络的OFDM频谱感知方法论文PDF源自《系统工程与电子技术》期刊面向认知无线电、OFDM信号处理与深度学习交叉领域的研究者也适合通信工程、人工智能方向的学生与工程师参考。资源共1个文件为2.04MB的pdf全文内容包括OFDM循环自相关特性分析、归一化灰度图像转化、基于LeNet-5的CNN网络搭建以及低信噪比环境下的仿真实验层次清晰。已有163人学习浏览。相比传统机器学习方法该论文重点解决了频谱感知训练速度慢、特征提取依赖人工设计等问题给出了可复现的网络结构和实验数据。实验表明所提方法在低信噪比条件下具有较高检测概率对基于深度学习的频谱感知研究具有直接指导价值可作为论文阅读、课题研究与技术调研的优质参考资料。1. 基于卷积神经网络的OFDM频谱感知在哪类场景里真正起作用在低信噪比下做OFDM盲检测传统能量检测的判决门限跟着噪声方差走噪声底稍微估偏一点漏检和虚警就同时失控循环平稳检测虽然抗噪声能力强却要在频域做二维相关搜索现场实时处理很难落地。卷积神经网络换了一条路把一段I/Q采样整理成二维谱图让卷积核去找OFDM导频、子载波间隔和循环前缀留下的周期性结构检测问题被转成了模式识别问题。整套方案覆盖数据生成、输入表示、模型结构和部署调优适合做无线频谱监测、认知无线电和宽带信号盲检的工程师参考。2. OFDM的频谱结构以及CNN感知其中的周期性痕迹2.1 OFDM信号在时频面上留下的“指纹”OFDM信号是多路正交子载波的并行传输每个符号持续时间为T符号前有循环前缀。它在频域上不是一个光滑包络而是一族sinc函数叠加出的固定波纹矩形子载波脉冲对应sinc谱相邻子载波间隔的整数倍位置存在零点叠加之后形成明显的梳状起伏。在时间上循环前缀让每个符号末尾的内容被复制到头部自相关函数会在符号周期T附近出现尖峰。导频结构是更关键的强特征。绝大多数OFDM系统在资源网格里按固定图案插入参考信号导频在子载波方向和时间方向上都有确定的间隔。接收端利用这些导频做信道估计外部检测器则可以把它们当作“已知周期”来利用。综合来看OFDM频谱包含了三个层次的可学习结构子载波间隔决定的频域波纹、循环前缀决定的符号周期、导频决定的二维周期图案。三者组合在一起是噪声不会出现的组织化特征。与单载波或宽带扫频信号不同OFDM的这类特征是“有格子”的。OTFS把信息铺在时延-多普勒域里表现为稀疏脉冲FMCW主要靠线性调频斜率形成距离-速度谱。波形不同能拿去给卷积网络学的东西也完全不同所以针对OFDM做特征工程时应当优先保留上述三种结构而不是把原始波形直接丢给网络。2.2 二元假设模型以及传统方法的识别边界频谱感知本质上是一个二元假设检验问题H0: r[n] w[n]接收信号只有噪声H1: r[n] s[n] w[n]存在OFDM信号叠加上噪声。能量检测的做法是把一段时间内的接收功率与门限比较。它实现简单在噪声方差稳定时接近最优但实际射频前端的增益、噪声系数和邻带干扰都会抬高或压低噪声底门限稍偏低信噪比下的检测性能就明显下滑。循环平稳检测利用OFDM循环前缀带来的周期自相关在低信噪比下依然有效代价是要估计谱相关函数运算量大而且对符号周期、循环频率等参数有依赖现场调参成本高。方法观测对象低信噪比鲁棒性主要瓶颈能量检测频带内总功率差噪声不确定性循环平稳检测循环谱相关峰好计算量大参数依赖强CNN分类时频组织结构取决于训练覆盖范围需要数据和训练流程CNN在推理时不直接做门限比较而是学习一组“出现在OFDM信号里、不出现在噪声里”的组合特征。训练数据覆盖的SNR范围和干扰形态越全网络能稳定工作的SNR下限就越低。这一点决定了它和传统方法的本质差别传统方法把检测器写成解析判决式CNN则是用训练数据隐式构造判决边界。2.3 卷积的归纳偏置和OFDM适配的关系卷积核的本质是局部加权模式匹配。OFDM谱图里子载波间隔对应固定的频域距离导频在时间轴上有固定间隔这两个结构都能用限定感受野的卷积核覆盖。训练完成之后第一层卷积核通常会形成类似频域差分器的模式用来捕捉子载波间的边缘更深层卷积核则倾向于组合多个局部特征例如“导频间距符号周期”联合判别。这种层级特征组合天然适合频谱感知因为它不依赖绝对功率而是依赖相对结构。与全连接网络相比CNN的平移不变性同样重要。接收信号存在不确定的符号定时偏差和频偏反映到谱图上就是图案的少量平移。池化层和卷积权值共享可以吸收这类偏移不需要为每种偏移单独准备模型。这也是选用卷积网络而不是MLP来做OFDM频谱感知的核心理由不需要人工设计特征但需要充足的数据和可控的训练流程。3. 从I/Q数据到训练集OFDM样本生成、输入表示与增广3.1 用仿真链路生成OFDM正负样本真实频谱数据虽然真实但标注困难信号种类、带宽、起始时刻、调制参数都要靠人工确认。工程上最常见的做法是先用仿真链路批量生成带标签的OFDM波形再在需要时用少量真实采集数据做微调。开发阶段全用仿真数据完全可行代码可以直接用numpy实现import numpy as np def ofdm_tx(n_symbols64, n_subcarriers64, cp_len16, modqpsk): np.random.seed(0) constellation np.array([11j, 1-1j, -11j, -1-1j]) / np.sqrt(2) data np.random.randint(0, 4, size(n_symbols, n_subcarriers)) symbols constellation[data] # 对每行做IFFT把频域符号调制到时域 freq_domain np.fft.ifft(symbols, axis1) * np.sqrt(n_subcarriers) # 加循环前缀保留每个符号尾部cp_len个采样点 cyclic_prefix freq_domain[:, -cp_len:] tx np.concatenate([cyclic_prefix, freq_domain], axis1).reshape(-1) return tx def add_channel(tx, snr_db, freq_offset0.001): tx tx / np.sqrt(np.mean(np.abs(tx)**2)) n np.arange(len(tx)) # freq_offset 是归一化频率单位是cycle/sample tx tx * np.exp(1j * 2 * np.pi * freq_offset * n) snr_linear 10 ** (snr_db / 10) noise_std np.sqrt(1 / (2 * snr_linear)) noise noise_std * (np.random.randn(len(tx)) 1j * np.random.randn(len(tx))) return tx noise这段代码做了三件事先把随机比特映射成QPSK符号再按OFDM的规则做IFFT并加循环前缀最后按目标SNR叠加高斯白噪声和频偏。n_subcarriers决定频域上能看到多少个相位调制点cp_len决定循环前缀长度二者都是OFDM系统的基础参数snr_db直接控制样本难度freq_offset用来模拟接收端晶振偏差。负样本直接生成等长度的纯噪声长度与正样本完全对齐。正样本里可以进一步细分QPSK、16QAM等调制方式也可以混合不同子载波数让网络不至于只认出某一种参数组合。3.2 输入表示的选择I/Q双通道还是谱特征图拿到I/Q采样后有三种常见输入表示原始I/Q序列直接作为一维输入形状为(2, N)功率谱作为一维输入形状为(1, N)按OFDM符号周期切帧后做FFT得到符号-子载波复数谱图形状为(2, n_symbols, n_subcarriers)。一维I/Q输入的信息最完整但CNN需要自己从时域波形里学会做FFT收效很慢。功率谱丢弃了相位信息抗频偏能力差只适合宽带粗检。实际项目里最稳妥的是第二种映射先把采样流按符号长度切成帧再做FFT把每个OFDM符号映射到子载波域实部和虚部分开存成两个通道得到一张“符号-子载波”复数谱图。def build_feature(samples, fft_size64, cp_len16, n_keep32): # 去掉循环前缀后按OFDM符号周期堆成二维矩阵 symbol_len fft_size cp_len usable len(samples) // symbol_len frames samples[:usable * symbol_len].reshape(usable, symbol_len) frames frames[:, cp_len:] spec np.fft.fft(frames, axis1) spec spec[:n_keep] real_img spec.real imag_img spec.imag # 返回形状为 (2, n_symbols, n_subcarriers) return np.stack([real_img, imag_img], axis0)这段预处理把一维流变成图像类数据。fft_size对应FFT点数cp_len必须与发射端保持一致否则帧切位不准子载波图案会糊掉n_keep固定保留的符号数量控制一个样本的时间跨度。样本不足时用零填充或者丢弃尾部不足一个符号的部分。经过这种处理后导频位置会呈现为固定坐标的强能量点子载波间的间隔也变成了规整的方格纹理CNN的二维卷积核可以同时抓时间方向和频率方向的结构。3.3 数据增广与正负样本配比训练数据的SNR分布直接影响模型的泛化表现。如果只在0dB附近采样模型在-5dB下几乎必然失效只采低SNR样本又容易把噪声误判为信号。我一般会让SNR在-10dB到10dB之间均匀取样并专门加大-8dB到0dB区间的密度让模型在“似有似无”区间多花能力。频偏也需要做增广。实际接收机的晶振偏差在小数倍子载波间隔以内但不同设备偏差方向不定。每轮训练给样本随机乘一个exp(j2πΔf n)Δf在±0.2个子载波间隔内取值。还可以随机丢掉部分子载波模拟频率选择性衰落下的稀疏OFDM信号。正负样本配比按真实监测场景来。频谱监测中大多数频段是空闲的训练集如果做11配比模型会对虚警不敏感。通常正样本占比控制在0.3到0.5之间配合第4章的加权损失使用。如果训练数据量充足可以按“每个样本包含64个OFDM符号”的窗口堆叠把多个窗口叠成三通道给3D卷积神经网络预留时间维输入不过数据量和训练时间会同步上升先不要作为首版方案。4. 用PyTorch搭CNN模型以及OFDM频谱感知的3个必调参数4.1 模型主体设计模型主体可以借鉴LeNet-5的基本结构两层卷积加池化尾部接全连接分类器。输入是上一章得到的(2, n_symbols, n_subcarriers)谱图输出二分类置信度。import torch import torch.nn as nn class OfdmCnnDetector(nn.Module): def __init__(self, in_channels2, n_classes2): super().__init__() self.features nn.Sequential( nn.Conv2d(in_channels, 16, kernel_size3, padding1), nn.BatchNorm2d(16), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), nn.Conv2d(16, 32, kernel_size3, padding1), nn.BatchNorm2d(32), nn.ReLU(inplaceTrue), nn.AdaptiveAvgPool2d((4, 4)), ) self.classifier nn.Sequential( nn.Flatten(), nn.Linear(32 * 4 * 4, 64), nn.ReLU(inplaceTrue), nn.Dropout(0.5), nn.Linear(64, n_classes), ) def forward(self, x): return self.classifier(self.features(x))第一层卷积用3x3核padding为1保证谱图尺寸不缩池化把空间尺寸减半作为平移不变性的粗化。BatchNorm放在卷积和ReLU之间作用是稳住小批量内的数值尺度——当前batch里SNR分布不同梯度的量级波动很大没有BN时训练容易震荡。AdaptiveAvgPool把特征图强制拉成4x4即使输入样本的符号数或子载波数略有出入尾部全连接维度也能对得上。这个结构不是越深越好。OFDM谱图里子载波间距大约只有几个像素两层3x3卷积的感受野已经足够覆盖“两个相邻子载波加一个导频”的组合。继续加深网络会逼着模型记住训练集里特定SNR的纹理细节泛化能力反而不如小网络。4.2 三个必调参数以及它们对应的物理含义参数推荐起点调整方向卷积核大小3x3想在频域看更大范围时改(3,5)但不要改成(5,5)输入符号数n_keep64实时性受限时降到16重新标定Pfa分类阈值0.5按目标虚警率在验证集上重新校准第一个参数是卷积核大小。3x3核堆两层在子载波方向覆盖约5个频点对导频结构和子载波波纹都够用。改大核尺寸看似能扩大感受野但也会引入更多噪声像素的加权低信噪比下过拟合风险显著上升。第二个参数是输入符号数。64个OFDM符号对应的观测时间大约为64×(TTCP)足以看到导频在时间方向的重复周期。符号数太少导频统计不稳定符号数太多模型等待积攒数据的时延变长。12.5%采样率下的64符号窗口约等于几十毫秒这个量级对多数频谱感知场景都可接受。第三个参数是分类阈值。训练时网络输出的0.5只是一个数学中间值不代表部署时也要用0.5。不同的监测任务对虚警率要求不同军用侦察场景允许虚警稍高但不能漏警频谱共享场景则相反。正确做法是在验证集上固定SNR范围统计不同阈值下的虚警率和检测概率然后挑一个满足业务约束的阈值。# 用验证集按目标虚警率选阈值 from sklearn.metrics import roc_curve y_score model_outputs.detach().cpu().numpy() fpr, tpr, thresholds roc_curve(y_true, y_score) target_fpr 0.05 idx (fpr target_fpr).sum() - 1 print(thresholds[idx])这段代码用验证集输出算出ROC曲线再找到虚警率不高于5%的阈值。部署时使用这个阈值而非0.5否则模型会偏保守或偏激进。4.3 损失函数与评估指标别只用accuracy频谱感知场景存在明显的类别不平衡空闲频段数量多占用频段数量少。直接用交叉熵训练模型会倾向于把模糊样本判成噪声。一个低成本做法是给损失函数加权重criterion nn.CrossEntropyLoss(weighttorch.tensor([0.4, 0.6]))权重里0.4对应噪声类别0.6对应信号类别。想让模型对信号更敏感就继续加大信号类权重。若效果还不够可以换Focal Loss它会让模型把训练重点放在“难分”的样本上而不是已经分对的简单样本。评估指标必须围绕检测概率Pd和虚警率Pfa展开不能只看总准确率。在正负样本比例不均衡时一个全判噪声的模型也能有80%准确率但它完全没有感知能力。评估时把测试样本按SNR分段统计每个SNR点单独计算Pd和Pfa画出类似“检测概率随SNR变化”的曲线才能判断模型在低信噪比下的真实水平。如果某个SNR段的Pd明显低于其他段需要回到数据侧补采该SNR区间的样本而不是盲目加深网络。5. 部署前先做两件事谱包络归一化与滑窗重叠判决5.1 为什么现场必须重新做谱包络归一化仿真数据里噪声功率是已知且恒定的现场接收机的增益、天线噪声和邻带干扰会让谱图的绝对幅度整体偏移。直接拿训练时的归一化参数套到现场数据上模型输入分布和训练时对不齐性能会比仿真时掉一截。常见做法是不要信任BatchNorm的running stats而是对每帧谱图单独做包络归一化。def spectral_envelope_norm(feature): # feature: (2, n_symbols, n_subcarriers) power np.mean(feature ** 2, axis1, keepdimsTrue) baseline np.mean(power, axis-1, keepdimsTrue) feature feature / np.sqrt(baseline 1e-6) return feature这里先统计每个子载波方向上的平均功率作为噪声底估计再把整帧除以它的开方。经过处理后网络看到的是“相对于当前噪声底的相对结构”而不是绝对功率带内平坦干扰和设备增益差异对判断的影响被压下去。注意不要在强干扰信号存在的频段上取基线否则会把真实信号一起压掉如果带内干扰明显基线改用中位数替代均值会更稳。5.2 连续监测时滑窗重叠与决策平滑频谱监测是连续流式任务不是一次性的离线判别。推理时把采样流按固定窗口切割如果窗口首尾相接边界上的部分OFDM符号会被截断产生脉冲突跳。把相邻窗口的重叠率设到50%到75%切碎的符号能出现在完整窗口里漏检率会明显下降。窗口判决后再加一次概率域的指数平滑消除单帧误检带来的抖动alpha 0.8 smoothed_prob alpha * smoothed_prob (1 - alpha) * frame_prob is_signal smoothed_prob deploy_thresholdframe_prob是当前窗口CNN输出的信号概率deploy_threshold是从第4章ROC曲线上选出来的实际门限。平滑系数alpha大则曲线平稳但反应慢alpha小则响应快但抖动大具体值按监测任务对时延的要求调整。部署时还有一步前置操作值得做进入CNN之前先用本地导频互相关或载波频偏估计算法把信号频偏粗补偿一次尽量把残余频偏压到子载波间隔的5%以内。频偏校正后谱图的子载波格点会重新对齐CNN卷积核学到的位置模式才能稳定命中。这一步对最终收益的贡献往往比继续加网络层数或调训练策略更直接。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。