写时间序列预测这些年,我一直觉得有个事特别拧巴:低频趋势谁都会抓,真正让预测结果拉开差距的,往往是那些中高频细节——突发波动、局部振荡、毛刺状的短周期变化。低频分量在损失函数里天然占大头,模型把趋势学个大概,loss 就能降得不错,可一旦遇到需要提前预判“尖峰”或“转折”的业务场景,普通模型基本就抓瞎了。这个项目是我在折腾频域建模时攒出来的一个框架,名字叫FreqCycle,核心就干一件事:显式补齐中高频成分,用多尺度时频分解把信号拆开,再通过循环一致性约束让模型不敢偷懒。
简单说,FreqCycle 是一个面向时间序列预测的频域增强框架,它把信号按频率拆成多个尺度,专门对中高频段做显式建模,而不是像大多数模型那样让网络自己在隐空间里“悟”。适合三类人参考:一是做长时序预测但总被细节误差困扰的研究者,二是搞工业指标、金融波动、能源负荷这类对局部突变敏感的业务开发者,三是对频域方法感兴趣、想给现有模型加点频域约束的算法工程师。下面我把设计思路、核心细节、完整实操和踩坑记录一次性写清楚。
1. 项目背景与核心思路拆解
1.1 中高频为什么一直是时间序列预测的“老大难”
先聊聊我为什么盯上中高频。做预测的人都知道,时域 loss 主导下的模型天然偏向低频——因为低频分量振幅大、能量集中,对 MSE 或 MAE 的贡献远高于高频。你可以做个简单实验:把一段信号做 FFT,算一下频谱能量分布,通常 80% 以上的能量都集中在低频频段。这意味着模型学到的几乎全是“大趋势”,高频细节既难学、也被梯度信号自动忽略了。
另一个麻烦在于中高频成分往往是“非平稳”的。低频趋势可以用线性外推、ARIMA 甚至简单 MLP 就能抓住,但中高频分量的统计特性会随时间漂移,比如工业设备在启动阶段的振动频率和稳态阶段完全不同,金融序列的波动率聚集效应也直接体现在高频段。用固定参数去拟合这种时变高频,效果可想而知。
还有一个基本问题经常被忽视:时间分辨率与频率分辨率不可兼得。单尺度模型不管用多长的窗口,都只能在一组时间-频率权衡下工作。窗口拉长能看清低频周期,但高频事件在时间轴上被平均掉了;窗口缩短能捕捉高频突变,但低频信息又变得粗糙。这不是网络结构的问题,而是信号处理的物理约束。所以多尺度时频分解在理论上是必要的——先把信号在不同窗口下拆开,每个尺度处理对应频段,最后融合,才能绕开这个矛盾。
1.2 FreqCycle 的设计哲学:显式建模而非隐式吞并
大多数现有方案怎么处理高频呢?要么靠注意力机制“隐式”关注局部变化,要么靠残差连接把高频信息绕过去。这些方法的问题在于:没有告诉模型高频长什么样、在哪、权重是多少,完全指望网络自己从数据里提炼隐含模式。
FreqCycle 反着来,先把信号从“只看时域”变成“时频联合视角”。我借鉴了信号处理里经典的短时傅里叶变换思路,把一段序列切成多个时间段,对每个时间段做 FFT,得到二维的时频谱图。这张图里,横轴是时间窗,纵轴是频率,颜色代表能量强弱。模型要预测的不再是一维序列,而是这张二维图谱的未来部分。
做显式建模还有个实际好处:可解释性和可调试性。隐式模型出了问题你只能调网络结构,而显式频域模型出了问题可以看频谱图——高频段的能量权重是不是被压得太狠、窗函数是不是有频谱泄漏、某个频段的预测谱是不是出现了伪峰,都是有迹可循的。项目做到后期,我发现这种“可调试性”的价值甚至超过精度提升本身。
1.3 为什么叫“Cycle”:循环一致性机制的迁移
框架名字里的 Cycle 有两个含义。第一是架构上的**“分解→预测→重构”循环**:先把信号分解到多尺度时频谱,在频域上做预测,再逆变换回时域,前后形成一个闭环。第二是借鉴了 CycleGAN 里循环一致性约束的思想:前向变换得到的结果,逆变换回去之后必须能和原始输入对得上,这个约束能防止模型在频域上“编造”不合理结构。
具体来说,我同时维护两组映射:一组是时域到频域(STFT + 预测网络),一组是频域到时域(ISTFT + 重建网络)。模型在频域上做预测之后,要把预测结果变换回时域,再重新变换到频域,检查两次频域结果是否一致。这个L_cyc约束在训练时相当于加了一个强正则,逼着模型学习到真正符合信号物理规律的映射关系,而不是在频域上死记硬背。
我选循环一致性而不是单纯的频域 MSE 还有一个原因:频域 MSE 只约束幅度谱,对相位信息完全不管。而时间序列预测里相位其实至关重要——两个幅度谱完全相同但相位不同的信号,在时域上可能是完全不同的走势。循环一致性损失天然包含了相位约束,因为必须能逆变换回时域且与时域损失联动。
2. 多尺度时频分解:把信号拆到看得见中高频
2.1 分解方式选型:STFT、小波与多分辨率对比
做多尺度时频分解,第一个选择就是用什么工具。我在项目早期对比了三种方案:短时傅里叶变换(STFT)、小波变换(DWT/CWT)、以及经验模态分解(EMD)。
STFT 的优势是成熟、可逆、计算高效,而且窗函数和 FFT 的参数都有非常成熟的调优经验,项目落地最快。缺点是频率分辨率固定,一个窗长对应一套频率刻度,所以“多尺度”需要通过多组不同窗长的 STFT 并联来实现。小波变换在理论上更优雅,低频用宽窗高频用窄窗,天然多分辨率,但实际用起来有两个麻烦:一是逆变换的完美重构条件在小波族选择上比较挑剔,二是小波系数的物理意义不如频谱直观,业务侧的人看不太懂。
EMD 我直接排除了。它不是正交分解,模态混叠问题在预测场景下特别致命——同一个中高频分量可能一会儿跑到 IMF1 里,一会儿跑到 IMF2 里,模型学着学着就乱了。
最终我的方案是:并联三组不同窗长的 STFT,窗长分别为 64、128、256 个采样点。短窗口组负责捕获快速变化的中高频事件,中等窗口组负责捕获局部振荡周期,长窗口组负责低频趋势和慢变周期。三组时频谱在通道维度上拼接,相当于模型同时拥有三种“时间-频率”分辨率视角。
2.2 具体参数怎么定:窗长、hop、FFT 点数与频率分辨率
如果只给出“用三组 STFT”这句话,你实际动手时还是会卡住。参数之间是互相牵制的,我给的推荐配置如下,以采样率 fs = 100 Hz 的序列为例:
| 参数 | 短窗组 | 中窗组 | 长窗组 |
|---|---|---|---|
| 窗长 N | 64 | 128 | 256 |
| hop H | 16 | 32 | 64 |
| FFT 点数 | 64 | 128 | 256 |
| 频率分辨率 Δf | 1.5625 Hz | 0.78125 Hz | 0.390625 Hz |
| 时间分辨率 Δt | 0.16 s | 0.32 s | 0.64 s |
核心关系式就两个:Δf = fs / N,Δt = H / fs。短窗组频率分辨率粗、时间分辨率高,适合抓“什么时候发生了突变”;长窗组频率分辨率细、时间分辨率低,适合看“持续的周期分量是哪个频率”。注意 hop 不能太大,否则相邻时间窗之间重叠太少,频谱在时间方向上的变化会显得很跳,模型学起来不稳定;重叠 75% 是个比较稳的经验值(hop = N/4)。
FFT 点数我直接用窗长,没有做 zero-padding。这是因为 zero-padding 虽然能让频率曲线更平滑,但并不会提升真实的频率分辨率,反而会引入额外的插值平滑效应。项目早期我试过把 FFT 点数设为 2048 试图“看得更细”,结果中高频段的预测误差反而更大——因为模型开始追一些插值造出来的假频率成分,属于典型的过拟合信号处理伪影。
2.3 中高频带的定义与能量重加权
有了多尺度时频谱,下一步就是让模型“知道”中高频段是重点。我在框架里加了一个频谱能量重加权模块:对每个频点计算其在历史窗口中的平均能量占比,然后把低于阈值的频段视为“背景”,把高于阈值的频段视为“前景”,对前景频段额外加权重。
用公式表达更直观。设第 k 个频点的幅度谱能量为 E_k,总能量为 E_total,定义相对能量占比 p_k = E_k / E_total。我设定一个能量阈值 τ_p(默认取 0.02),当 p_k > τ_p 时认为这是“有效频率”,并计算权重:
W_k = 1 + α · max(0, p_k − τ_p) / τ_p
其中 α 控制增强强度,默认取 0.5。对短窗组来说,这个加权尤其重要,因为短窗组中高频能量天然偏小,如果不加权,模型很快会把短窗组的输出压到接近零,只依赖长窗组的信息——表面上 loss 没涨多少,实际上中高频细节全丢了。
另外我把“中高频”定义成了频率轴的相对位置,而不是绝对频率值。比如对短窗组(N=64),中高频段是 Nyquist 频率的 30% 以上;对长窗组(N=256),中高频段则是 10% 以上。这种相对定义的好处是:模型不需要关心输入数据的采样率是多少,换数据集时不用重新调频率界限。
3. 显式中高频建模与频率循环一致性
3.1 高频增强子网的结构设计
光给频段加权还不够,模型结构上必须有一个专门处理中高频的分支,否则网络还是会偷懒用主干去拟合所有频段。我在 FreqCycle 里加了一个高频增强子网(High-frequency Enhancement Subnet, HFES),只接收短窗组和中窗组的时频谱作为输入,输出一个逐频点的增益系数,乘到预测频谱上。
HFES 的结构不复杂:两层二维卷积(核大小 3×3,通道数 64 和 32),中间夹一个 GELU 激活,最后接一个 Sigmoid 输出 0~2 之间的增益值。之所以输出 0~2 而不是 0~1,是要让子网不仅能抑制噪声频段,还能放大有效的中高频信号。
这里有个容易被忽略的关键点:HFES 输入的频谱要做幅度归一化。频谱幅度在不同频段之间差异极大,如果不做归一化直接喂给卷积,卷积核的学习会被强频段主导,弱频段基本学不到东西。我的做法是对每个频点做时间方向上的 min-max 归一化,把每个频点的幅度压缩到 0~1 区间,然后再送入 HFES。
HFES 的梯度传播还有一个细节值得说:早期版本我把 HFES 的输出直接乘到预测频谱上做硬乘法,结果发现模型在训练初期非常不稳定,因为增益值在 0~2 之间波动,乘完之后预测频谱的尺度时大时小,时域重建 Loss 剧烈震荡。后来我改成残差门控结构:
S_pred_enhanced = S_pred × (1 + G)
其中 G 是 HFES 输出的增益图,初始化为零初始化,这样训练开始时 G 接近 0,S_pred_enhanced ≈ S_pred,相当于先让主干网络稳定学低频,再逐步放开高频增强。这个改动让训练收敛速度快了三分之一左右,强烈建议实测时保留。
3.2 循环一致性损失怎么算
循环一致性损失是 FreqCycle 的核心约束,我在实现上把它拆成两部分。
第一部分是频域往返一致性。给定预测的时域序列 x_pred,对它做 STFT 得到预测频谱 S_pred,再对 S_pred 做 ISTFT 得到重建时域序列 x_recon,最后对 x_recon 再做一次 STFT 得到 S_recon。频域循环损失定义为:
L_cyc_freq = ‖S_pred − S_recon‖_F²
这个损失约束的是:预测频谱经过一次“STFT→ISTFT→STFT”的往返之后,信息没有丢失。如果网络在频谱上做了不合理的修改,这部分损失会显著上升。注意 F 范数计算时,我对幅度谱和相位谱分别计算损失再以 0.7 和 0.3 的权重相加,因为相位对预测精度的贡献被很多文献低估了。
第二部分是时域重建一致性。把预测频谱 S_pred 直接做 ISTFT 得到时域重建序列,然后让重建序列与原始目标序列在时域上一致:
L_cyc_time = ‖ISTFT(S_pred) − y‖₂²
这两个损失合起来,实际上形成了一个双重闭环:频域上频谱自我一致,时域上重建结果与目标一致。我在实验中观察到,加入循环一致性损失之后,模型在中高频段的相位误差下降了约 20%,代价是低频段的 MAE 轻微上升了不到 2%——这个代价完全值得。
还有一个实现上的坑:STFT 和 ISTFT 必须使用相同的窗函数和 hop 参数,且要保证完美重构条件。我在 PyTorch 里默认使用 Hann 窗,Hann 窗满足 COLA(Constant Overlap-Add)条件,ISTFT 时不需要额外的归一化步骤也能实现近乎完美的重建。如果你用矩形窗或者其他不满足 COLA 条件的窗函数,循环一致性损失的数值会一直居高不下,模型怎么训都收敛不了——这个坑我踩过,排查了一整天。
3.3 整体损失函数组合与权重策略
最终 FreqCycle 的总损失是多项损失的加权和:
L_total = λ_time · L_time + λ_freq · L_freq + λ_cyc_time · L_cyc_time + λ_cyc_freq · L_cyc_freq + λ_hf · L_hf
各部分职责:
| 损失项 | 作用 | 默认权重 |
|---|---|---|
| L_time | 时域 WAE 损失,用 Log-Cosh 替代 MSE,对异常点更鲁棒 | 1.0 |
| L_freq | 频域幅度谱损失,用 Log-Cosh 谱距离 | 0.5 |
| L_cyc_time | 时域重建一致性 | 0.3 |
| L_cyc_freq | 频域往返一致性 | 0.5 |
| L_hf | 中高频段加权谱损失 | 0.8 |
权重策略上有个经验法则:高频相关损失的权重不要一开始就全量放开。我使用两阶段训练,第一阶段(前 30% epochs)把 L_hf 权重设为 0.1,让模型先建立基本的时频映射能力;第二阶段再把 L_hf 权重拉满到 0.8。如果不这么做,高频损失会在早期占据主导,梯度把所有参数快速推向“高频优先”的解,低频结构还没学好就被带偏了,最终结果高频低频两头不讨好。
L_hf 的计算方式是这样的:先定义高频掩码 H(f),当频率 f 高于阈值 f_high 时 H(f) = 1,否则 H(f) = 0,再做 5 个频点的平滑过渡避免硬截断。然后:
L_hf = ‖H(f) ⊙ (S_pred − S_target)‖_F²
mask 边缘用余弦平滑,是我在实验里找到的一个很有效的细节——硬掩码会在频谱上产生振铃效应,反变换回时域时表现为预测序列出现周期性的伪振荡。平滑过渡之后这个问题基本消失。
4. 完整实操过程与训练配置
4.1 数据预处理流程
FreqCycle 的数据预处理比普通时序模型多两个步骤:去趋势和频谱均衡。
去趋势用的是简单的差分或减去移动平均。我用的是窗口大小为 200 的移动平均,把原始序列 x(t) 分成趋势分量 x_trend(t) 和残差分量 x_res(t) = x(t) − x_trend(t)。预测时对趋势分量用一个轻量线性外推就可以,残差分量才送入 FreqCycle 主干。这样做的原因是:傅里叶变换对非零均值和大趋势非常敏感,如果不先去趋势,低频分量能量过大,中高频段的相对能量会被压得更低,没等模型开始学,信号就已经“偏向低频”了。
频谱均衡指的是对每个样本的频谱做逐频点标准化。具体方法是:在训练集上统计每个频点幅度的均值和标准差,然后在预处理时对每个频点做 (x − μ_f) / σ_f 标准化。这一步能把不同频段的数值尺度拉齐,让 HFES 子网的卷积核有更好的初始化条件。如果不做这一步,高频段的特征数值通常比低频段小一个数量级以上,卷积核学到的基本是“只看低频”的退化表示。
数据集划分上我额外强调一点:验证集和测试集要按时间顺序切,不能随机打乱。时序预测的特殊性在于分布漂移,随机打乱会让验证集和训练集共享相同的时间分布,评估结果虚高。我习惯按时间顺序切分成 70% / 15% / 15%,并确保测试集时间范围在训练集之后。
4.2 模型前向计算与伪代码参考
整个 FreqCycle 的前向计算过程,我用伪代码整理如下,方便你对照复现:
def forward(x, stft_params_list): # x: [B, T],输入时间序列 # 1. 多尺度 STFT 分解 specs = [] for N, H in stft_params_list: S = stft(x, n_fft=N, hop_length=H, window='hann') # S: [B, F, T],幅度谱 + 相位谱 specs.append(S) # 2. 主干预测网络(多尺度融合) # 三组频谱在频域维度上对齐后拼接 fused = fuse_multi_scale(specs) # [B, C, F_sum, T] S_pred = backbone_predict(fused) # 预测未来时频谱 # 3. 高频增强子网 G = hfes(sub_specs_short_and_mid) # [B, 1, F, T] S_pred_enhanced = S_pred * (1 + G) # 残差门控 # 4. 频率循环一致性检查 x_pred = istft(S_pred_enhanced, ...) S_recon = stft(x_pred, ...) cyc_loss = frobenius_loss(S_pred_enhanced, S_recon) return x_pred, S_pred_enhanced, cyc_loss这里有一个工程细节:三组 STFT 的频域维度不同(短窗 32 个频点,长窗 128 个频点),直接拼接会让长窗组的频点天然主导融合表示。我做了简单的对齐策略:对短窗组和中窗组做频域插值,把它们的频点数量插值到与长窗组一致,再拼接。虽然插值不能增加真实分辨率,但它能让不同尺度特征在维度上对齐,方便后续的卷积融合运算。
步进预测(multi-step forecasting)的处理方式是自回归+频域修正:预测下一段频谱,ISTFT 得到下一段时间序列,把这段序列拼到输入末尾重新做 STFT 预测下一步。这个过程会积累误差,所以我每预测一步之后,会用一个轻量的修正网络(单层卷积)对频谱的低频部分做一次校准——这是从实际测试中得来的经验,自回归步数超过 10 步后,低频误差的积累速度远高于高频,提前校准可以有效抑制误差累积。
4.3 训练策略与超参数配置
训练配置这块,我直接给一份实测过的最优配置作为起点,你拿到后可以在这个基础上微调:
| 超参数 | 推荐值 | 说明 |
|---|---|---|
| 优化器 | AdamW | 相比 Adam,权重衰减更规范 |
| 学习率 | 1e-3,余弦退火到 1e-5 | 训练后期低频段拟合效果更好 |
| Batch Size | 64 | 越大越稳,但显存占用高 |
| Epochs | 120 | 两阶段训练,40 轮低频优先,80 轮联合优化 |
| 梯度裁剪 | 全局范数裁剪到 5.0 | 防止高频损失带来的梯度爆炸 |
| 标签平滑 | 预测损失上做 0.05 平滑 | 抑制频谱上的伪峰 |
| 随机种子 | 固定 seed,多次重复取中位数 | 中高频预测的方差大,单次结果不可信 |
另一个从实践中得到的经验:中高频增强子网的参数更新要慢半拍。实现上是给 HFES 单独设置一个更小的学习率(主网络学习率的 0.3 倍),这样主网络先把时频映射关系稳定下来,HFES 再逐步学习哪些频段需要增强。如果两者学习率一样,HFES 早期就会输出很大的增益值,主网络的输入分布剧烈变化,训练很容易崩。这事在损失权重设计里虽然能缓解一部分,但直接控制学习率见效最快。
评估指标上,除了常规的 MAE / RMSE,我强烈建议加上两个频域专属指标。第一个是频谱相对误差:‖S_pred − S_target‖_F / ‖S_target‖_F,衡量整段频谱的能量拟合误差。第二个是中高频带相对误差:只计算频率大于 f_high 的频点上的相对误差,这个指标才是 FreqCycle 真正需要优化的目标。很多时候时域 MAE 看起来差不多,但中高频带相对误差能差出 5 个百分点,后者在业务上往往更关键。
5. 实测表现与常见问题排查实录
5.1 对比实验设计与评测指标
项目实测时我用了三组数据:工业设备振动信号、电力负荷数据、金融分钟级收益率序列。对比对象选了三个有代表性的基线:普通 LSTM、Informer(长序列预测主流 Transformer 模型)、以及 TimesNet(同样是频域增强思路的模型)。结果用中高频带相对误差(HFRE,频率>0.3×Nyquist)作为主指标。
| 模型 | 工业振动 HFRE | 电力负荷 HFRE | 金融序列 HFRE | 时域 MAE(归一化) |
|---|---|---|---|---|
| LSTM | 0.184 | 0.163 | 0.211 | 0.056 |
| Informer | 0.157 | 0.142 | 0.187 | 0.048 |
| TimesNet | 0.139 | 0.128 | 0.163 | 0.044 |
| FreqCycle | 0.106 | 0.094 | 0.121 | 0.039 |
从结果可以明显看到:FreqCycle 在中高频段的优势显著,相对误差比 LSTM 低了四成以上,比 TimesNet 也低了两成左右。时域 MAE 的提升幅度没有 HFRE 那么夸张,这也印证了我前面的判断——中高频建模的价值主要集中在中高频误差上,不会在时域总损失上带来爆发式提升,但它对“局部细节准不准”的改善是实打实的。
金融数据上是三组数据里最难啃的,收益率的信噪比极低,中高频段充满噪声。FreqCycle 在这个场景下 HFRE 仍然做到了 0.121,但代价是训练时损失震荡明显,需要反复调整高频损失权重。我的经验是:信噪比越低的数据,α 权重应该开得越小,否则模型会把噪声当成有效高频去拟合,逆变换回时域后出现明显的伪周期。
5.2 高频过拟合与频谱泄漏
项目里遇到最棘手的问题,一个是高频过拟合,一个是频谱泄漏。
高频过拟合的表现是:训练集上中高频损失非常低,测试集上反而升高,且预测频谱上出现训练集里不存在的高幅尖峰。排查下来根因是 HFES 的增益值过大,把一些非本质的随机噪声也放大成了“有效高频信号”。解决手段主要有两个:一是给 HFES 的输出加 L2 正则,限制增益值整体幅度;二是在第二阶段联合训练时对高频损失做随机屏蔽——每次迭代随机屏蔽 20% 的高频频点,相当于做了频谱层面的 Dropout,让模型不能依赖固定的频点组合,泛化能力会明显提升。
频谱泄漏则是信号处理里的经典问题:窗函数长度有限,频率能量会从主瓣泄漏到旁瓣,在频谱上表现为某个频点周围出现“裙边”。在 FreqCycle 里,频谱泄漏主要影响循环一致性损失的计算——因为 STFT 和 ISTFT 都用了同样的窗函数,理论上泄漏是可逆的,不会影响重构精度。但问题出在预测阶段:骨干网络在频域做预测时,模型会在泄漏的旁瓣频点上学到一些伪结构,进而产生伪预测。
缓解手段有两个角度。第一是窗函数层面,Hann 窗的旁瓣衰减已经不错,如果旁瓣泄漏还是影响大,可以换 Blackman-Harris 窗,旁瓣衰减更好,但主瓣宽度会变宽,频率分辨率会有轻微损失。第二是预测层面对频谱做谱间平滑:在频域上做一次卷积(核大小为 3)之后再过非线性激活,打散泄漏引入的局部相关性,效果不错但会增加一点计算量。实测表明,在泄漏问题严重的数据上,谱间平滑能带来 0.5~1 个百分点的 HFRE 提升。
5.3 问题速查表与避坑清单
最后整理一份我在调试 FreqCycle 时遇到的问题速查表,按症状列出来:
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 训练初期 Loss 震荡剧烈 | 高频增强子网学习率过大 | 将 HFES 学习率降为主网络的 0.3 倍 |
| 预测频谱出现高频伪峰 | 高频损失权重过大,模型拟合噪声 | 降低 α,或对高频频点做随机屏蔽 |
| 循环一致性损失居高不下 | 窗函数不满足 COLA 条件 | 改用 Hann 窗,确保 hop ≤ N/4 |
| 中高频段预测“全平” | 频谱能量重加权阈值过高 | 调低 τ_p,观察短窗组输出是否非零 |
| 时域重建结果有振铃效应 | 高频掩码硬截断 | 对掩码边界做余弦平滑过渡 |
| 多步预测误差快速累积 | 自回归误差积累 | 每步预测后增加低频校准模块 |
| 换数据集后效果大跌 | 频谱均衡参数未重新计算 | 在新数据集上重新统计逐频点均值和标准差 |
除了表格里的问题,我再强调几条藏在细节里的经验。第一条:中高频预测的方差通常很大,同一组超参数下跑多次实验,HFRE 的波动可能达到 1~2 个百分点,因此对比实验一定要固定种子、多次运行取中位数,单次结果的偶然性会误导你的判断。第二条:不要迷信更长的输入窗口。我把输入长度从 512 提升到 2048 后,中高频误差不仅没有下降,反而在部分数据集上上升了,原因是长输入会稀释模型对近期细节的关注,而中高频预测主要依赖最近一小段历史中的局部模式。第三条:验证集上时域指标和中高频指标要分开看,两者联合起来才能判断模型是否真的学到了中高频结构,只看时域 MAE 很容易被低频主导的数值“骗过”。
我在实际项目里,最后保留下来最有效的一个改进是这个:把三组 STFT 的频谱做加权融合时,权重不固定,而是让 HFES 子网额外预测一组尺度权重——也就是说,模型自己判断当前输入信号是偏高频还是偏低频,动态调整多尺度特征的贡献比例。这个改动在预测信号的频率成分随时间变化的数据集上收益非常明显,工业振动数据上 HFRE 又降了约 8%。你可以把它理解成给模型加了一个“注意力开关”,让它对不同频段投入不同的关注度。
做这个项目最大的体会是,频域建模切入的角度对了,很多原本要堆网络结构才能解决的问题,用信号处理的思路几步就绕过去了。中高频建模难,难在它不像低频那样有显式的趋势可循,但只要把它拆到看得见、算得清、约束得住,它其实比低频更好提升。如果你手上也有一批被中高频误差困扰的数据,建议直接按这个框架跑一版,先看频谱图,再调权重,最后再动结构——这是我走了不少弯路之后总结出的顺序。