简介:基于卷积神经网络的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_symbols=64, n_subcarriers=64, cp_len=16, mod='qpsk'): np.random.seed(0) constellation = np.array([1+1j, 1-1j, -1+1j, -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, axis=1) * np.sqrt(n_subcarriers) # 加循环前缀,保留每个符号尾部cp_len个采样点 cyclic_prefix = freq_domain[:, -cp_len:] tx = np.concatenate([cyclic_prefix, freq_domain], axis=1).reshape(-1) return tx def add_channel(tx, snr_db, freq_offset=0.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_size=64, cp_len=16, n_keep=32): # 去掉循环前缀后,按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, axis=1) spec = spec[:n_keep] real_img = spec.real imag_img = spec.imag # 返回形状为 (2, n_symbols, n_subcarriers) return np.stack([real_img, imag_img], axis=0)这段预处理把一维流变成图像类数据。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信号。
正负样本配比按真实监测场景来。频谱监测中大多数频段是空闲的,训练集如果做1:1配比,模型会对虚警不敏感。通常正样本占比控制在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_channels=2, n_classes=2): super().__init__() self.features = nn.Sequential( nn.Conv2d(in_channels, 16, kernel_size=3, padding=1), nn.BatchNorm2d(16), nn.ReLU(inplace=True), nn.MaxPool2d(2), nn.Conv2d(16, 32, kernel_size=3, padding=1), nn.BatchNorm2d(32), nn.ReLU(inplace=True), nn.AdaptiveAvgPool2d((4, 4)), ) self.classifier = nn.Sequential( nn.Flatten(), nn.Linear(32 * 4 * 4, 64), nn.ReLU(inplace=True), 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_keep | 64 | 实时性受限时降到16,重新标定Pfa |
| 分类阈值 | 0.5 | 按目标虚警率在验证集上重新校准 |
第一个参数是卷积核大小。3x3核堆两层,在子载波方向覆盖约5个频点,对导频结构和子载波波纹都够用。改大核尺寸看似能扩大感受野,但也会引入更多噪声像素的加权,低信噪比下过拟合风险显著上升。
第二个参数是输入符号数。64个OFDM符号对应的观测时间大约为64×(T+TCP),足以看到导频在时间方向的重复周期。符号数太少,导频统计不稳定;符号数太多,模型等待积攒数据的时延变长。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(weight=torch.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, axis=1, keepdims=True) baseline = np.mean(power, axis=-1, keepdims=True) 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卷积核学到的位置模式才能稳定命中。这一步对最终收益的贡献,往往比继续加网络层数或调训练策略更直接。
本文还有配套的精品资源,点击获取