
城市峡谷里跑一圈回来一看轨迹水平误差忽大忽小开阔路段还能压在一两米拐进高楼夹缝就窜到十几米——这种场景做过北斗终端的人大概都不陌生。传统的做法是调环路带宽、换窄相关、上多径估计延迟锁定环能压一部分但压不干净因为多径的统计特性随环境变今天在高架下训出来的参数明天到地下车库入口就未必好使。这几年一个明显的变化是越来越多的人开始把卷积神经网络CNN往卫星导航的接收链路里塞试图绕开手工建模多径这条越走越窄的路。标题写的是综述但真正干活的人关心的不是有多少篇论文而是信号到底以什么形式喂进去、标签从哪来、模型放在链路的哪一级、端到端定位精度到底涨没涨、涨了多少、代价是什么。下面这些内容就是我按这条线梳理出来的东西面向的是已经懂一点基带处理、想动手试的人也尽量把基础概念讲清楚刚入门的同学能跟得上。1. 从城市峡谷的轨迹漂移说起CNN为什么要进导航链路1.1 传统基带处理究竟在哪个环节开始失效先把失效点定准不然模型放错位置等于白干。北斗B1I信号的测距码周期是1ms码率2.046Mcps接收机里最核心的动作就是把本地复现码和 incoming 信号做相关得到一个相关峰然后用早码、即时码、晚码三个或者更多抽头去算鉴相误差驱动码环和载波环。理想情况下这个相关峰是三角形考虑前端带宽后接近峰顶对应真实码相位。问题出在多径上直射信号和反射信号叠加后相关峰不再是干净的三角形峰会歪、会分裂、会整体偏移早迟码鉴相器的过零点跟着偏于是伪距就带了一个系统性偏差。这个偏差有多大开阔环境下C/N0通常在40到45 dB-Hz码跟踪精度可以做到0.1到0.3米量级到了城市峡谷C/N0掉到20到30 dB-Hz很常见加上强反射伪距误差做到几米甚至十几米都不奇怪而且它不是白噪声是有偏的、随时间缓变的进到最小二乘或者卡尔曼滤波里很难被残差检验吃掉。传统对策里窄相关把早迟间隔压到0.1码片以内能抑制一部分长延时多径但会牺牲抗噪性能MEDLL靠多相关器拟合多径参数计算量大且依赖模型假设基于信噪比或者仰角的加权是最省事的可它只能降权不能把已经歪掉的相关峰掰回来。1.2 换一个思路让网络自己去学什么样的相关峰不可信这里的关键转变在于过去我们是先假设一个多径信道模型比如两径、三径、瑞利分布再从观测里反解参数CNN走的是另一条路直接把一段相关器输出或者一段IQ数据当成一张图丢进去让网络自己学判别特征。它不需要你告诉它这个峰左边有个肩它看几千个带标签的样本就能把这个模式记住。这个思路的优势在于对模型假设不敏感城市、高架、林荫道、室内窗边这些差异极大的场景只要样本覆盖到了同一个网络理论上都能吃下来。但优势也是它的软肋CNN不会凭空知道物理约束它对样本分布极度敏感。你在一条固定路线上采的数据训出来的模型换条街可能就掉点。所以真正决定这套方案能不能落地的不是网络结构多花哨而是数据采集方案、标签生成方式、以及模型输出怎么和后面的滤波器和完好性监测衔接。这三点在多数综述里被一笔带过恰恰是工程上最耗时间的部分。2. 喂给CNN的到底是什么北斗信号的四类可学习表征2.1 原始IQ序列信息最全也最难训最直接的方式是把射频前端采样后的复数IQ直接送进网络。以B1I为例中频常用40.96MHz或者零中频量化位宽1到4比特1ms对应四万多个复数样本。直接吃这么长的序列第一层卷积的感受野要设计得跟码片宽度匹配B1I一个码片在40.96MHz采样下大约20个采样点所以第一层卷积核长度设在16到32之间比较合理相当于让网络先学一个码片的局部形状。实操上的麻烦在于数据量。复数要拆成I、Q两路实数或者按幅度相位拆前者保留线性关系、后者对相位噪声更鲁棒。四万点乘两路单个样本就是8万个浮点数一个批次32个样本就是两百多万个数普通显卡训起来很吃力。多数人会先做降采样或者只截取相关峰附近的窗口比如峰前后各50个码片把输入压到几千点这个量级这样既保住了峰形信息又不至于把显存吃光。注意降采样一定要在复数域做完滤波之后再做直接对IQ抽点会把频谱搬移搞乱训出来的模型在实测里会莫名其妙地全判成一类。2.2 相关器输出性价比最高的一种伪图像如果只能选一种输入形式我建议从多相关器输出开始。接收机本来就有一排相关器抽头间隔取0.25或者0.5码片左右各取5到6个加上即时支路一共11到13个抽头每个抽头在1ms积分后得到一个复数值连续取N个历元比如100个就得到一个13×100的复数矩阵拆成实虚两通道就是13×100×2这个尺寸对CNN来说非常友好一层3×3卷积就能同时看到相邻抽头和相邻时间的关系。它的好处是物理意义明确峰形畸变、峰位漂移、峰宽变化全在这张图里而且它已经过了解扩信噪比增益做完了对前端差异不敏感。我在几个项目里对比过同样的网络结构用相关器输出做输入比用原始IQ收敛快得多样本需求也少一个量级。代价是丢掉了扩频前的信息像窄带干扰这种在频域上很明显、在相关器输出上却可能只表现为整体噪底抬升的现象就不太容易分辨。2.3 时频图与C/N0序列给干扰检测和欺骗识别准备的干扰和欺骗这两类任务信息更多藏在频域和时间的宏观变化里。把一段IQ做短时傅里叶变换窗长取256或者512点重叠50%得到一张时频图尺寸比如128×128扫频干扰在上面就是一条斜线脉冲干扰是一列亮点宽带压制是一片亮区CNN处理这类图像基本是成熟套路直接借用图像分类的骨干网络改一改输入通道数就能跑。C/N0序列则是另一种便宜又好用的表征。单颗卫星的C/N0随时间变化是一条一维曲线多颗卫星拼起来就是多通道时间序列用一维卷积处理。欺骗信号的一个典型特征是C/N0出现不符合几何规律的抬升或者多颗卫星的C/N0同步跳变一维卷积对这种局部突变很敏感。这类输入的优点是数据量极小几百个点就够训起来快适合做前置的粗筛。2.4 四类表征怎么选一张对照表表征形式典型尺寸信息完整度样本需求计算开销适合任务原始IQ截窗2×4000 左右最高大高精细多径建模、信号细微畸变分析多相关器输出2×13×100中高中中多径/NLOS判别、码相位偏差估计时频图1×128×128中频域强中中干扰分类、欺骗检测C/N0与残差序列1×N×通道数低但稳定小低粗筛、异常监测、加权决策选择逻辑其实很简单任务关心的是解扩前的频谱特征还是解扩后的峰形特征。前者用时频图后者用相关器输出。两者都要就做双分支融合但先别急着上融合单分支跑通了再说融合带来的调参成本经常超过收益。3. 任务侧拆解CNN在导航链路里被用来干哪几件事3.1 多径与NLOS信号识别这是目前落地最多的一类。做法是把每颗卫星每个观测历元的相关器输出打成样本标签是直射或者非直射网络输出一个概率超过阈值就把这颗卫星从定位解算里剔除或者给它一个更低的权重。相比传统的基于C/N0阈值加仰角门限的方法CNN的优势体现在低仰角但确实是直射和高仰角但被强反射这两类难样本上前者传统方法容易误杀后者传统方法容易漏放。我见过效果比较扎实的方案分类准确率在自采数据集上能做到90%以上但这个数字要小心解读——如果测试集和训练集来自同一条路线同一天90%不说明什么。真正有意义的是跨天跨路线的表现通常会掉到75%到85%之间。所以工程上一般不会让网络单独做决定而是把它输出的概率作为一个观测量送进抗差估计比如把概率映射成方差走加权最小二乘。3.2 干扰与欺骗信号的时频分类干扰识别的任务边界比较清楚扫频、连续波、脉冲、宽带压制这四类在时频图上的形态差异大用一个小型CNN三五层卷积加全局池化就能做到很高的区分度训练样本靠信号源加衰减器在屏蔽室里采一天能采几千个成本可控。落地时的难点不在分类本身而在未知类别的处理——现场遇到的干扰未必是你训过的那几类模型容易把没见过的东西硬塞进已知类别里所以输出端一般会加一个基于能量或者置信度的兜底判决。欺骗检测更难因为欺骗信号在单颗卫星的观测量上可能做得很像真的。有效的做法是多星联合把可见星的C/N0、多普勒、伪距残差拼成一个多通道张量让网络去学整体一致性的破坏。这类模型的解释性差出问题时很难说清是哪颗星出了问题所以通常会配合传统的一致性检验一起用。3.3 伪距残差修正与加权这一类任务直接对准定位精度思路是用网络去预测伪距残差然后从观测里减掉或者反过来预测观测方差用于加权。两种做法各有拥趸减残差看着直观但如果网络预测有偏会把偏差直接注入解算风险更大给方差更稳最差情况是权重给得不理想不会把解算带跑偏。我个人偏向后者。实现上输入一般不只是单颗卫星的相关器输出还会把仰角、方位角、C/N0、前一时刻的残差一起拼进去。输出就是一个标量方差或者一个权重。训练标签用事后用高精度参考轨迹反算出来的残差生成。这里有个坑参考轨迹本身的精度决定了标签质量如果参考系统在城市段的误差就有半米那你训出来的模型最好也只能逼近这半米别指望它把误差压到0.2米。3.4 周跳探测与载波相位质量评估载波相位这块传统方法靠 geometry-free 组合、Melbourne-Wübbena组合加多普勒积分来做周跳探测对小幅周跳1到2周和小采样率下的判断经常不够干脆。载波波长B1I约19厘米B3I约23.6厘米一周的跳变对应厘米级到分米级的距离突变。CNN在这里的用法是把相位残差的时间序列、C/N0、多普勒变化率拼成多通道输入做逐历元的二分类。效果上对小周跳的检出率确实比单一的GF组合高一些尤其是在低采样率1Hz场景下因为网络能用上多颗卫星之间的相关性。但代价是引入了一个新的失效模式模型的漏检和误检都和历史窗口长度强相关窗口取太短抓不住趋势取太长又增加时延。工程上一般取30到60个历元兼顾两者。3.5 各任务的输入输出与评估口径任务输入输出主要评估指标落地风险点多径/NLOS识别多相关器输出直射概率查准率、查全率、跨场景掉点幅度阈值随环境漂移干扰分类时频图类别标签置信度混淆矩阵、未知类拒识率未训类别的误判伪距加权相关器几何残差方差标量定位RMSE、95分位误差标签质量上限周跳探测相位残差序列有无周跳检出率、虚警率、平均时延窗口长度敏感4. 从论文到工程数据、标签与训练链路的落地细节4.1 标签从哪来三条路径的取舍这是整个流程里最花钱的一环。第一条路是纯仿真用信号模拟器按设定的多径模型生成IQ标签天然准确。好处是量大、可控、类别均衡坏处是仿真信道和真实信道总有差距训出来的模型到实测往往掉一截业内叫仿真到实测的鸿沟。缓解办法是在仿真里注入实测的背景噪声或者做域随机化把多径的延迟、衰减、相位在合理范围内随机扫。第二条路是半实物真实接收机采数据同时在场景里布置参考点用已知的几何关系反算哪颗星被遮挡。这条路标签质量高但采不了多少一条路线跑一天能出几千个样本就不错了。第三条是弱监督用定位残差反推某颗星在某个历元的残差明显偏离就认为它可疑。标签噪声大但可以刷量。实际项目里通常是三条路混着来仿真打底、半实物校准、弱监督扩量。4.2 数据切分防止同一段信号同时出现在训练和测试里这个坑踩的人特别多。如果按样本随机切分同一段连续采集的信号会被切到训练集和测试集两边相邻样本高度相关测试准确率虚高十几个点都有可能。正确做法是按采集批次切同一段路线、同一台设备、同一天的采集归为一个组整组进训练或者整组进测试。更严格一点按场景切训练集只用开阔和郊区测试集专门留给城市峡谷这样才能看出泛化能力。4.3 网络结构别一上来就上大模型我见过不少方案直接把ResNet-50搬过来参数两千多万在几万个样本上训结果训练集loss掉到0.01测试集一塌糊涂。卫星导航的信号表征维度其实不高相关器输出13×100这种尺寸三五层卷积加两三个全连接足够。一个可以参考的配置是第一层3×3卷积32通道接批归一化和ReLU第二层3×3卷积64通道接2×2最大池化第三层3×3卷积128通道然后全局平均池化接全连接输出。总参数量控制在几十万量级训练快端侧也能跑。import torch import torch.nn as nn class CorrNet(nn.Module): def __init__(self, in_ch2, n_cls2): super().__init__() self.features nn.Sequential( nn.Conv2d(in_ch, 32, 3, padding1), nn.BatchNorm2d(32), nn.ReLU(inplaceTrue), nn.Conv2d(32, 64, 3, padding1), nn.BatchNorm2d(64), nn.ReLU(inplaceTrue), nn.MaxPool2d(2), nn.Conv2d(64, 128, 3, padding1), nn.BatchNorm2d(128), nn.ReLU(inplaceTrue), ) self.head nn.Sequential( nn.AdaptiveAvgPool2d(1), nn.Flatten(), nn.Dropout(0.3), nn.Linear(128, n_cls) ) def forward(self, x): return self.head(self.features(x))这段代码没什么花哨的但它能用。真正影响结果的是数据管线和损失函数。类别不均衡在NLOS任务里非常严重直射样本通常占八成以上直接训练会让模型倾向于全判直射。用带权交叉熵或者Focal Loss把少数类的权重提上去召回率会有明显提升。4.4 训练中的几个数值问题相关器输出的动态范围很大强信号和弱信号可能差三四个数量级直接送进网络会让梯度爆炸。常规做法是对每个样本的幅度做归一化或者转成对数域再送进去。相位信息要小心处理直接取实虚两路在某些情况下会引入载波相位跳变带来的不连续可以考虑用幅度加相位的正弦余弦编码。还有一点是输入的时间对齐。相关器输出是按历元排的如果采集过程中有丢帧时间轴就断了训出来的时间卷积实际上在学错误的东西。预处理阶段一定要做时间戳校验发现断层就整段丢弃别想着插值补上。5. 部署侧的现实约束算力、时延与泛化5.1 端侧算力预算怎么算接收机端的处理器通常是ARM Cortex-A系列算力从几百MOPS到几个GOPS不等跟手机SoC没法比。一个几十万参数的CNN单次推理大概在几百万次乘加的量级跑在1GHz的A核上大概几毫秒到几十毫秒。这个时延对多径识别、周跳探测这类任务完全够用因为这些决策本来就是秒级或者历元级的不是毫秒级的。但要注意码环和载波环是实时的环路更新周期可能是1ms或者更短任何跟环路串联的模型都必须在这个时间窗内完成。所以工程上的普遍做法是模型不进环路只进观测域环路照常跑模型在观测层做判别和加权这样时延约束就宽松得多。5.2 量化与剪枝别在小模型上用力过猛INT8量化在图像任务上一般掉点不多但在这种信噪比本来就低的任务上要谨慎。相关器输出的弱信号部分幅度很小量化到8位之后有效位数不够弱信号样本的判别精度会明显下降。我的经验是输入层保留FP16或者做逐通道量化中间层再上INT8实测精度损失能控制在1到2个百分点以内。剪枝的收益在小模型上不明显。一个五十万参数的模型剪掉一半推理速度可能只提升20%因为瓶颈往往在内存访问而不是计算。不如直接把输入尺寸降下来比如把13×100的时间窗缩到13×50效果更直接。5.3 跨场景泛化这是最容易被低估的问题同一个城市晴天和雨天的多径特性不一样同一条路早晚高峰车流不同反射面也不同。模型在训练集上90%换到新场景掉到70%是常态。缓解手段有几种一是做在线自适应用无标签的新数据做几次微调但端侧做反向传播代价太大二是做集成训几个在不同场景下表现好的模型用不确定性加权融合三是把模型输出和传统方法做与逻辑只有两者都认为可疑才剔除牺牲一点查全率换稳定性。我个人更倾向第三种因为导航这个领域对连续性和完好性的要求高于对极限精度的追求。宁可少剔除几颗可疑星也不能把好星误剔导致几何构型变差、精度反而下降。6. 评估与踩坑怎么判断模型是真有用还是过拟合了数据6.1 别只看分类准确率分类准确率是最容易好看也最容易骗人的指标。样本不均衡时全判多数类就能有80%的准确率。要看查全率和查准率的平衡画ROC曲线算AUC更重要的是看在固定虚警率下的检出率——工程上虚警的代价通常高于漏检因为频繁剔除卫星会让解算几何变差。可以定一个目标比如虚警率控制在5%以内看检出率能到多少这个数字才有参考价值。6.2 端到端验证模型指标好不等于定位精度好这一点必须单独强调。分类任务涨了两个点定位精度可能一点没变甚至变差。原因是定位解算是一个多星加权的过程单星判别的提升能不能转化成定位提升取决于被正确判别的那些星在几何构型里占多大权重。验证方法只有一个把模型接进完整的解算链路用同一批测试数据跑开环和闭环两种模式比较水平误差的RMS、95分位误差还有固定解率如果用RTK。只有闭环指标提升了才算真有用。6.3 几个踩过的坑第一个坑是标签泄漏。前面提过按样本随机切分的问题还有一种更隐蔽的用参考轨迹反算残差做标签时如果参考轨迹本身用了待评估的那些卫星标签里就混进了被测信号的信息评估结果虚高。第二个坑是预处理不一致。训练时用了某种归一化部署时忘了加或者用了不同的窗长模型在端上表现断崖式下跌。建议把预处理写成一个独立的、可序列化的模块训练和推理共用同一份代码。第三个坑是忽略温度和时间的影响。射频前端的增益随温度漂移采集时的增益设置如果和部署时不同相关器输出的绝对幅度就变了。用幅度归一化能缓解但如果模型偷偷学了绝对幅度的特征比如靠整体能量高低判断强弱信号换个增益就失效。可以在训练时做增益随机化让模型对这个维度不敏感。第四个坑是过度依赖单一数据源。只用一台设备采的数据训出来的模型可能学到的是这台设备的滤波器特性、天线方向图而不是信号本身的物理规律。至少用两三台不同前端的数据混着训泛化会好很多。最后分享一个实际体会这类方案真正的价值不在于把某个指标刷高几个点而在于它提供了一种把难以建模的误差源当成模式识别问题来处理的思路。多径、干扰、欺骗这些东西物理机制复杂到很难写出一组完备的方程但它们在观测数据里留下的痕迹是有规律的CNN擅长的正是抓这种规律。把它的输出当成一个额外的观测量交给后面的抗差估计和完好性监测去消化比让它直接接管决策要稳得多。至于模型结构、输入形式、训练技巧都是在这个框架下逐步磨出来的先跑通最小闭环再谈优化。