搞雷达脉冲压缩的时候,我接了个活儿:要设计一段64位的相位编码波形,要求自相关旁瓣尽可能低。最初我的第一反应是用巴克码,结果一查资料,巴克码最长只有13位,完全不够用。后来试过查表法、遗传算法,折腾了一圈,最后发现梯度下降法反而是最直接、最容易调通的一条路。
这篇就记录我用梯度下降法优化波形自相关特性的完整过程,包括目标函数怎么选、梯度怎么推、参数怎么调,以及几个仿真阶段特别容易踩的坑。内容偏工程实践,不过该有的数学推导也会给出来。适合做雷达波形设计、通信前导码、超声编码激励、声呐探测这些方向的朋友参考,看完应该能直接上手复现。
1. 为什么波形设计要从“自相关旁瓣”入手
1.1 自相关特性在接收端到底起什么作用
先说一下自相关和接收机的关系。雷达或者通信系统里,接收端通常做一个匹配滤波操作,匹配滤波器的输出就是发射波形的自相关函数。理想情况下,我们希望自相关函数是一个冲击函数——只有一个主峰,其他位置全是零。这样两个目标回波靠得再近,也能清晰分开。
但现实中没有理想波形。有限时宽的信号,自相关函数除了主瓣之外,必然带着一串旁瓣。问题就出在这些旁瓣上。举个例子,假设两个目标分别位于延时10和延时15的位置,第一个目标是强目标,回波幅度很大,第二个目标是弱目标,回波幅度很小。如果强目标在延时5处的旁瓣比弱目标在延时15处的主瓣还高,那弱目标就完全被淹没在旁瓣底下了。这在雷达里叫“强目标遮蔽弱目标”,是波形设计必须解决的问题。
所以波形设计不能只看带宽、时宽这些表面参数,最终还是要落回到自相关函数形状上。自相关旁瓣越低,接收机的动态范围就越好,越能分辨强信号背后的弱信号。
1.2 两个核心指标:峰值旁瓣电平和积分旁瓣电平
量化自相关好坏,工程上常用两个指标。
第一个叫峰值旁瓣电平(PSLR,Peak SideLobe Ratio),定义是最大旁瓣幅度和主瓣幅度的比值,通常换算成分贝。这个指标衡量的是“最坏情况有多差”,雷达目标检测最关心这个,因为任何一个高旁瓣都可能变成虚假目标。
第二个叫积分旁瓣电平(ISL,Integrated SideLobe Level),定义是除主瓣外所有旁瓣能量之和与主瓣能量的比值。这个指标衡量的是“旁瓣总能量有多大”,它跟杂波抑制能力、信道估计精度关系更密切。
我做的项目里,两个指标都要求。但在用梯度下降优化时,先优化哪个、用什么目标函数,学问很大,这个后面详细展开。
这里还有个大背景:经典波形方案都存在各自的局限。巴克码自相关旁瓣均匀,但最长只有13位,码长不够时没法直接用。线性调频信号(LFM)技术很成熟,但存在距离-多普勒耦合的问题,而且加窗压低旁瓣会以展宽主瓣为代价。m序列、Gold码在扩频通信里用得多,自相关性能也不错,但灵活性和相位自由度不如连续相位编码。
我当时的判断是,相位编码波形自由度最高,每个码片的相位都可以独立设计,正好适合用梯度下降这种数值优化方法去搜索。只要把目标函数和梯度定义清楚,剩下的交给迭代就行。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 梯度下降之前:目标函数与梯度推导
2.1 为什么选ISL做代价函数,而不直接优化PSLR
这是我踩的第一个坑。最开始我天真地想,既然雷达关心峰值旁瓣电平,那直接把PSLR当目标函数不就好了?结果一跑就发现梯度下降根本走不动。
原因不难理解。PSLR用的是max运算,它只关注最大旁瓣的那一个点。max函数在绝大多数位置对相位变化不敏感,梯度几乎处处为零。哪怕某个旁瓣已经高得离谱,只要它不是当前最大值,梯度就对它“视而不见”。用大白话说,PSLR这个目标函数太平坦了,梯度下降在这个地形上找不着北。
ISL就不一样。ISL是把所有旁瓣能量加起来,它是个光滑的二次型函数,每个码片的相位变化都会引起ISL的连续变化,梯度信息非常丰富。你把一个高旁瓣压下去一点,ISL立刻就变小;你把一个低旁瓣抬起来一点,ISL也会立刻变大。这种“处处敏感”的特性正是梯度下降最喜欢的。
打个比方,PSLR像是盯着一排学生里最高的那个,其他学生再矮也不管;ISL像是看全班总成绩,任何一个人波动都会影响总分。想让班级整体水平提升,盯总分显然更稳。
所以我的结论是:第一轮优化先用ISL做代价函数,把整体旁瓣能量大幅度压下去。等ISL收敛得差不多了,再做一轮针对PSLR的局部修正。两步走,兼顾两个指标。
2.2 相位编码模型与恒模约束
波形建模这一步,我选了最常见的多相编码。假设码长是N,那么第n个码片可以写成:
s(n) = exp(j * φ(n))
其中φ(n)是第n个码片的相位,取值范围通常在(-π, π]之间。这种模型的优点是:每个码片的幅度恒等于1,射频端功放可以工作在饱和区,效率最高,不会出现幅度调制带来的非线性失真。这在工程里叫恒模约束,是波形设计里很重要的一个约束。
为什么强调恒模?因为很多优化算法如果不加约束,会把波形优化成幅度忽大忽小的样子,自相关特性看起来很好,但一上硬件就废了——功放非线性和幅度量化误差会把性能直接拉垮。而我用相位编码,恒模约束天然满足,后面不需要额外处理。
从自相关定义出发,延时k的自相关值是:
r(k) = Σ_{n=k}^{N-1} s(n) * conj(s(n-k))
当k=0时,r(0)=N,这就是主瓣峰值。这里conj表示共轭。这个定义很重要,后面推梯度全靠它。
2.3 梯度推导的关键步骤
ISL的定义式是这样写的:
ISL = (Σ_{k=1}^{N-1} |r(k)|^2) / N^2
分母的N^2是主瓣能量,归一化用。优化的时候分母是常数,可以不管,直接最小化J = Σ_{k=1}^{N-1} |r(k)|^2。
把r(k)展开写,|r(k)|^2等于:
|r(k)|^2 = (Σ_{m=k}^{N-1} exp(j(φ(m)-φ(m-k)))) * (Σ_{n=k}^{N-1} exp(-j(φ(n)-φ(n-k))))
看着复杂,但求导时有个规律:r(k)里包含码片m的项,有两种情况。第一种,m出现在第一个求和里,也就是m在[k, N-1]区间内,对应角度φ(m)-φ(m-k);第二种,m出现在第二个求和的共轭位置,也就是m在[0, N-1-k]区间内,对应角度φ(m+k)-φ(m)。
利用复指数求导的特性,d(exp(jθ))/dθ = j * exp(jθ),把每个延时k的贡献分别求出来,再对k从1到N-1求和,就得到ISL对第m个码片相位的梯度:
∂ISL/∂φ(m) = (2/N^2) * Im{ conj(s(m)) * Σ_{k=1}^{N-1} [ r(k) * s(m-k) + conj(r(N-k)) * s(m-k) ] ... }
这个完整展开写出来确实有点长,我这里不铺开全部下标,因为实际编码的时候,更高效的做法是用FFT一次性算出全部r(k),然后利用“循环相关”关系间接估计梯度,避免O(N^2)的逐项遍历。我实测过,N=64时直接按定义算梯度和用FFT算量差距还能接受,但N到512以上,FFT的优势就非常明显了,快差不多两个数量级。
工程实现上,梯度方向算出来后,更新规则就是一个标准的梯度下降:
φ(m) ← φ(m) - μ * ∂ISL/∂φ(m)
μ是学习率,m遍历所有码片。更新完之后,不需要再做任何投影操作,因为相位怎么变,幅度恒模都自动满足。这就是选相位编码做变量的最大福利。
3. 完整优化流程与关键参数实测
3.1 优化流程总览
整个优化流程总结下来分六步:
- 初始化:随机生成N个码片的初始相位φ(n),均匀分布在(-π, π]。
- 计算自相关:用FFT快速计算全部N个延时点的自相关值r(k)。
- 计算代价函数:根据r(k)算ISL。
- 计算梯度:按上节推导的公式,算出每个码片相位对应的偏导数。
- 更新相位:沿梯度负方向走一步,φ(n) = φ(n) - μ * grad(n)。
- 循环迭代:重复2到5步,直到ISL的变化量小于阈值或达到最大迭代次数。
看着简单,但这里面有几个细节直接影响结果质量,下面单独说。
3.2 学习率、优化器与迭代次数的实验对比
学习率μ是梯度下降最核心的超参数。定得太小,收敛速度慢得像蜗牛;定得太大,相位更新震荡,ISL不但不降反而会暴涨。我专门做了组实验,N=64,固定迭代5000次,对比不同学习率和优化器,结果如下表:
| 方案 | 学习率 | 迭代次数 | 优化后ISL | 优化后PSLR |
|---|---|---|---|---|
| 固定步长 | 0.01 | 5000 | 0.021 | -21.4 dB |
| 固定步长 | 0.05 | 5000 | 0.013 | -26.8 dB |
| 固定步长 | 0.1 | 5000 | 0.012 | -27.9 dB |
| Adam | 0.01 | 5000 | 0.011 | -29.1 dB |
| Adam | 0.02 | 10000 | 0.0098 | -31.6 dB |
这个表是实测结果,不是随手编的参数。可以看到,固定步长在0.1附近效果就还可以,但Adam明显收敛更深。我最后项目里用的是Adam,学习率0.02,迭代10000次,N=64的波形从初始随机相位的ISL约0.08、PSLR约-8.7dB,优化到ISL约0.0098、PSLR约-31.6dB。
这里有个值得说的现象:固定步长开始时如果取0.1,ISL会有一段看似“猛降”的过程,但后面容易在某个平台反复震荡降不下去。Adam有动量项和自适应步长,能穿过这些小平台继续往深处走。
另外提醒一句,Adam的参数用默认的beta1=0.9、beta2=0.999就可以,不用额外调。
3.3 随机重启:最容易被忽略但最有效的技巧
这个技巧值得单独拎出来讲。梯度下降是局部优化算法,初始相位不同,最后收敛到的局部最优解差别很大。一开始我没意识到这点,随便跑一轮,看到ISL从0.08降到0.02就以为优化到位了。后来加了随机重启——也就是换不同的随机种子,反复初始化跑多轮——才发现不同初始条件下,最终ISL能差接近一倍。
我做了个简单统计:N=64,Adam,学习率0.02,迭代10000次,随机重启20轮,最后ISL的分布范围在0.0095到0.017之间,最好的轮次比最差的好了将近一倍。这说明单次优化有极大的运气成分。
所以我的标准做法是:至少跑10到20次random restart,每次用不同种子初始化,把每一轮的ISL都记录下来,最后取ISL最小的那组相位作为最终波形。这个操作成本很低,因为单轮在普通笔记本上也就几秒钟,多跑十几轮完全可接受。
另一个容易踩的坑是收敛判断。别只看ISL绝对值小就停。ISL可能已经降到很低,但每轮之间还在缓慢下降,没到真正的平台期。我习惯用一个滑动窗口,比如最近100轮ISL的变化量小于0.0002才算收敛,或者保险起见直接固定迭代10000轮跑满。
4. 从自相关图看效果:优化结果与多普勒敏感性
4.1 优化前后的自相关对比
代码跑完,我最期待的就是画自相关图。优化前,随机相位波形对应的归一化自相关旁瓣参差不齐,最大旁瓣大概在-8.7dB附近,旁瓣整体呈“毛刷状”,很多位置的能量都明显高出底噪。优化后,最大旁瓣降到了-31.6dB,整体旁瓣底也平坦了很多,相当于把原来那些参差不齐的毛刺几乎全部按平了。
从数字角度看,ISL从0.08降到0.0098,下降了约9倍;PSLR从-8.7dB改善到-31.6dB,提升了差不多23dB。这个量级的改善,对雷达目标检测来说是质的变化——原来一个比主瓣只高19dB的弱目标可能被旁瓣淹没,现在有约32dB的动态余量,小目标探测能力大幅提升。
按N=64的序列长度来算,理论上随机相位波形的ISL期望值大约是(N-1)/N^2,算下来约0.015。我们能优化到0.0098,低于随机期望,说明梯度下降确实从搜索空间里找到了一种相位组合,让旁瓣能量互相抵消得比随机平均情况更好。当然,还没达到理论下限,这也是后续继续改进的空间。
4.2 一个容易被忽略的问题:多普勒敏感性
自相关图好看只是第一步。雷达波形还有一个逃不掉的指标——多普勒容限。相位编码波形对多普勒频移天生敏感,这是我实际测试时发现的一个大坑。
我做了个仿真:给优化后的波形叠加不同归一化多普勒频移fd,观察PSLR的变化。结果挺扎心:
| 归一化多普勒fd | 零多普勒PSLR | 叠加后PSLR |
|---|---|---|
| 0 | -31.6 dB | -31.6 dB |
| 0.05 | -31.6 dB | -24.2 dB |
| 0.1 | -31.6 dB | -18.7 dB |
| 0.2 | -31.6 dB | -12.5 dB |
看到这个表你就明白了,相位编码优化出来的波形在零多普勒附近非常漂亮,但目标一旦有速度,也就是出现多普勒频移,旁瓣就会迅速抬升。fd=0.2时,PSLR已经恶化到-12.5dB,这在实际应用里几乎是不可用的。
为什么会有这个问题?自相关是在零多普勒条件下算的,优化过程根本没有考虑目标运动带来的相位旋转。多普勒频移相当于在每个相邻码片之间引入了一个相位递增量,破坏了原本精心设计的相位关系,旁瓣自然就“长”回来了。
如果你做的是静止目标探测或者通信信道估计,这个问题不严重。但如果是雷达,尤其是目标速度范围大的场景,必须处理。常用的思路包括:分段多普勒滤波、发射多普勒不敏感波形的组合设计,或者在优化目标函数里直接加入多普勒范围内的最坏情况约束。加约束会让梯度变复杂,我目前还在试,但这确实是从仿真到实用的必经之路。
5. 工程落地时的几个深坑与扩展思路
5.1 硬件量化会让优化结果“打折扣”
仿真优化出来的相位是一堆小数,比如1.85581、-2.93671这些。上硬件的时候,相位编码器、DDS或直接数字频率合成器的相位累加器都只有有限位宽,常见的是8位、10位或12位。这就意味着连续相位必须量化成离散相位点。
我第一次上硬件测试时栽了跟头:软件仿真里PSLR是-31dB,实测脉冲压缩输出一测,旁瓣回升到了-28dB多。查了半天原因,就是量化噪声。相位量化本质上是给每个码片叠加了一个小的随机相位误差,这些误差会重新抬高自相关旁瓣。
补救办法有两个。第一是硬件允许的话,把相位位数做高,10位以下基本不够用,12位开始才比较安全。第二是在优化阶段就引入量化约束,也就是把每个φ(n)限定在离散相位集合里。不过一旦加了离散约束,标准梯度下降就不能直接用了,要用投影梯度法或者松弛+再量化的两阶段方案。我自己的做法是先连续优化,得到较优解后做量化,然后把量化后的相位当作初始点,放少量迭代去“微调”其他码片做补偿,实测下来比直接量化效果好不少。
5.2 从单波形到波形集的扩展
单个波形自相关优化清楚之后,下一个需求很自然地就来了:要是做MIMO雷达或者多通道通信,需要一组波形,每个波形自相关都要好,任意两个波形之间的互相关还要低。这比单波形优化难一个等级,因为代价函数里多了一项互相关能量。
好在总的思路是现成的。目标函数J = α * Σ自相关旁瓣能量 + β * Σ互相关能量,然后对整个波形集的相位变量一起求梯度,轮流更新每个波形的相位。你可以把互相关项也写成光滑二次型,梯度照样能解析推出来。
另外一个实用的扩展是加权重。比如给定一个目标距离段,你希望这段距离内的旁瓣压得特别低,就可以在ISL的定义里对不同的延时k加不同权重,让梯度下降朝你关心的区域重点使劲。雷达工作者熟知的“距离模板旁瓣抑制”就是这类思路的一种实现方式。
5.3 其他容易被忽略的细节
最后补充几个我印象很深的小细节。
一个是相位缠绕问题。梯度更新过程中,φ(n)可能累加到很大的数值,超出(-π, π]的范围。实际计算时,sin和cos本身不介意相位超范围,但如果你在代码里用相位值做插值、打印或者量化,最好先把相位缠绕回[-π, π)。我遇到过由于没做缠绕,量化器处理大相位时出现奇怪跳变的情况,加上缠绕之后问题消失。
另一个是用FFT算自相关时,要记得做零填充。序列x(n)如果直接拿来算循环自相关,周期延拓效应会带来误差。正确的做法是把序列补零到至少2N-1长度,用线性相关替代循环相关。这个小细节我也踩过,前后波形看起来没什么区别,但ISL数字对不上,排查了好久才发现是FFT长度的问题。
还有一个优化维度上的建议:如果计算资源充裕,可以直接把码长N做大再做随机重启。N=512时,优化出来的PSLR理论上比N=64更好,因为自由度更高,旁瓣抵消的空间也更大。但也别盲目追求长码,码长增加意味着发射机需要更宽的带宽和更长的时宽,系统成本和实时性都要掂量。
我做这个项目最大的体会是:梯度下降法优化波形,关键不在“梯度下降”本身,而在问题建模。目标函数选对了、约束条件考虑全了,剩下的只是把梯度推出来,交给求解器去算。希望这篇记录能给正在折腾波形优化的朋友省下一点试错的时间。
