VMD+小波去噪多模型混合Matlab实现:信号去噪完整流程
信号去噪算法这个坑我踩了好几年。做状态监测和故障诊断的人应该深有体会传感器采回来的信号永远不是教科书上那种干干净净的正弦波而是有用分量、谐波、随机噪声、脉冲干扰全混在一起。以前我习惯直接上小波去噪后来试着用VMD变分模态分解再往后又把VMD、优化VMD和WD小波去噪串成一条流水线用Matlab一次性跑完。这套组合我实测下来对付非平稳、非线性信号比单一算法稳得多。这篇记录想把整个实践过程完整呈现出来VMD是怎么回事、Matlab里怎么调参、为什么参数这么敏感、优化VMD怎么做、WD怎么跟VMD配合以及多模型混合后效果到底提升了多少。内容偏工程和代码落地适合正在做信号去噪、故障诊断、生物医学信号处理的研究生和工程师。不管你是刚接触VMD还是已经玩了一阵子下面这几块应该都有值得参考的地方。1. 项目概述与整体思路为什么把VMD、WD和多模型混合凑在一起1.1 核心需求从复杂信号里把有用分量“剥”出来信号去噪的本质就一句话观测信号等于真实信号加噪声加干扰我们要尽量把真实信号还原出来。但在工程现场噪声根本不是单纯的白噪声还夹杂着工频干扰、谐波分量、趋势项、随机冲击毛刺。你要是只做一次低通滤波冲击特征会被磨平只做小波阈值去噪遇到多分量信号时容易把不同频率成分搅在一起。VMD的作用是先把信号拆成若干个窄带模态相当于“分家”。每个IMF对应一个中心频率附近的成分这样后续处理就变成了“逐个房间搞卫生”而不是对着整栋楼乱来。小波去噪WD则在每个模态内部继续清理随机噪声。换句话说项目核心不是选某一种算法而是让不同算法各管一段形成一条完整的信号处理流水线。1.2 单一算法为什么不够用VMD、WD、EMD逐个说每种去噪算法都有它的脾气。移动平均和中值滤波最简单但属于“一刀切”削峰填谷很严重脉冲特征基本保不住。小波去噪WD的优点是非平稳信号也能处理小波基和阈值选得好的话效果相当不错然而它本身不擅长分离频率重叠的多分量信号面对“双频靠得很近”或者“调频加调幅”的复杂成分小波系数混在一起阈值一压就把有用边带也压掉了。EMD算法不用设参数自适应分解听起来很美好但模态混叠和端点效应在工程信号里特别明显。同一频率的成分可能被拆到两个IMF里或者端点处出现大幅抖动处理起来很烦。VMD作为EMD的“升级版”用变分框架和中心频率约束把模态混叠压制住了然而它有两个绕不开的前提模态数K和惩罚因子alpha都得提前给定。这就逼着我去做参数优化。单一算法各有短板所以需要组合这也是多模型混合思路存在的意义。1.3 我采用的VMDWD多模型混合框架我当时搭的框架是分四步走的。第一步是优化VMD用粒子群等寻优算法自动确定K和alpha代替肉眼试参。第二步是VMD正式分解得到若干个IMF和一个残差项。第三步是逐模态WD处理对每个IMF单独做小波去噪高频噪声多的IMF加大阈值低频主能量IMF收着点处理。第四步是分量筛选与重构通过相关系数或包络熵判断哪些IMF属于有效成分哪些属于噪声主导筛选后相加并评估效果。这套流程里的核心思想是“先分离、再清洗、后重构”而不是直接对原始信号做一次全局去噪。实际跑下来VMD负责把信号拆开WD负责在各分量内部精准降噪优化VMD负责让“拆法”更符合信号本身的物理成分。后面所有代码和调参经验都是围绕这条流水线展开的。2. VMD变分模态分解原理和Matlab内置函数使用2.1 VMD到底在算什么窄带模态分离的关键思想VMD全称Variational Mode Decomposition是2014年Dragomiretskiy和Zosso提出的。它的核心假设是一个复杂信号可以看成若干个中心频率分别为ω_k、带宽有限的模态之和。目标是在“所有模态相加等于原始信号”的约束下让每个模态的带宽估计总和最小。这个带宽估计不是简单取频谱宽度而是先对每个模态做Hilbert变换得到解析信号再乘上一个指数项把频谱搬移到基带最后取梯度范数作为带宽度量。整个过程是个带约束的变分问题Matlab内部用交替方向乘子法ADMM求解迭代更新模态u_k、中心频率ω_k和拉格朗日乘子λ直到收敛。数学细节如果一时啃不动可以这样类比VMD像是把一锅混合汤按照“主要食材”分出来每个模态就是一种食材成分中心频率相当于食材的特征味alpha惩罚因子代表“每一种食材的味型必须多么集中”。alpha越大每种食材被要求越纯粹汤底和食材之间分得越干净但搞过头就会把食物本来的层次感也削掉。理解了这个思想再去看参数选择就好办了。2.2 Matlab的vmd函数参数详解NumIMF、PenaltyFactor怎么设Matlab较新版本已经内置了vmd函数属于Signal Processing Toolbox。基本调用方式如下[imf, res, info] vmd(x, NumIMF, K, PenaltyFactor, alpha, Tau, 0.2);参数比较多我整理了一张表方便对照参数含义我的经验值NumIMF模态数K决定拆成几个分量3~8具体看频谱峰数量PenaltyFactor惩罚因子alpha控制模态带宽约束强度1000~3000比较常用Tau噪声容限参数数值越大越容忍噪声噪声强时给0.1~0.5DC是否把第一模态强制设为直流分量默认false趋势项明显时可设trueinit中心频率初始化方式1均匀、2随机、3按频谱能量复现实验用1探索用3tol收敛容差默认1e-6要求高时1e-7其中NumIMF如果不指定算法会根据残差能量自动估一个K。这个自动值不能说没用但工程信号用它经常偏少低频趋势和高频噪声混在一个模态里。我建议先画出信号的频谱数一数再手动给一个初始K后面用优化算法进一步搜。PenaltyFactor默认值我没记错的话是2000附近属于“大家都差不多能用”的档位但遇到窄带冲击成分或者宽频调制成分时需要调整的空间非常大。下面是VMD分解信号的一个基础代码片段fs 1000; t (0:length(xn)-1)/fs; [imf, res, info] vmd(xn, NumIMF, 4, PenaltyFactor, 2000, Tau, 0.3); figure; for k 1:size(imf, 2) subplot(size(imf, 2)1, 1, k); plot(t, imf(:, k)); title([IMF, num2str(k)]); end subplot(size(imf, 2)1, 1, size(imf, 2)1); plot(t, res); title(Residual);有人会问手写VMD和调用内置函数有什么区别。我的建议是除非你是做算法研究或者需要魔改核心方程否则直接用内置函数就好。内置版本经过数值优化稳定性好速度也快没必要自己造轮子。File Exchange上倒是有不少人分享的VMD代码有些版本还能支持低版本Matlab但接口和参数名不统一用之前一定要先看作者文档。2.3 分解结果怎么看频谱、残差、包络谱一起上跑完VMD别急着看时域波形先看频谱。我每次都会把每个IMF的频谱叠在一张图上检查两个事一是各IMF主频是否清晰分离二是相邻模态有没有大面积重叠。如果IMF2和IMF3的主峰几乎重合说明K给大了或者alpha给小了模态被拆碎后又粘在一起。如果某个IMF的频谱几乎是平的说明它已经变成一个噪声容器后面处理时要重点降权或丢弃。残差信号res也不能忽视。残差里如果还有明显的窄带峰代表K设小了有些分量没被提取出来。残差如果接近一条直线说明分解已经比较充分但也要注意是不是过度分解把随机噪声也拆成了独立的窄带模态。在故障诊断场景下还要算包络谱。对感兴趣的IMF做Hilbert解调得到包络信号再对包络做FFT找特征频率。比如轴承外圈故障的特征频率f_o如果在某个IMF的包络谱上清晰可见说明VMD把这部分冲击成分保留得很好如果包络谱噪声乱成一片说明这个IMF混入了太多随机成分后面的WD清理就没做到位。3. 优化VMD用粒子群给K和alpha自动寻优3.1 参数为什么敏感K太小欠分解、太大模态重叠VMD这两大参数K和alpha牵一发动全身。K要是给小了两个频率较近的分量会挤在一个模态里后续WD想拆也拆不动等于是开局就输了。K要是给大了算法会把一个宽频连续谱硬拆成好几个窄带伪模态看起来每个IMF都像模像样实际物理意义一点没有后面重构时互相抵消结果反而更乱。alpha的影响同样直接。alpha大了模态带宽被约束得很窄有用调制边带会被削掉波形趋近于纯正弦alpha小了带宽放宽不同模态频谱重叠VMD就又退化成了EMD那类混叠问题。所以K和alpha必须搭配着调单独调哪一个都不靠谱。这也是为什么我最后决定用优化算法自动搜索而不是靠眼睛盯着频谱来回试。3.2 寻优目标函数怎么定包络熵、信息熵还是峭度参数优化需要一个目标函数也就是“怎样算一次好的分解”。常见的选择有三种。第一种是包络熵。对每个IMF取Hilbert包络计算包络的能量概率分布熵。包络熵越小说明包络的冲击性越集中、成分越单一。故障冲击类信号特别适合用包络熵因为冲击信号包络上会有很明显的周期性峰值熵自然低。第二种是信息熵或排列熵衡量模态时间序列的复杂性。噪声越大的模态排列熵越高所以目标让它尽量低。第三种是峭度反映信号偏离高斯分布的程度冲击信号峭度大。我的做法是把“平均包络熵最小”作为主目标有时再叠加一个相关系数的约束避免算法为了追求熵值低把所有能量都塞进一个模态。相关系数用每个IMF与原始信号之间的相关性有效分量相关系数高噪声分量相关系数低。综合目标函数可以写成fitness mean(包络熵) - 0.3 * mean(相关系数)。具体权重要看信号特性不一定要公式化。3.3 粒子群优化VMD的Matlab实现步骤粒子群算法PSO模拟鸟群觅食每个粒子代表一组候选参数不断朝个体最优和全局最优方向移动。Matlab里有particleswarm函数属于Global Optimization Toolbox没有的话就要自己写一个简单的PSO循环。目标函数文件如下function fitness vmdFitness(p, sig) K round(p(1)); alpha p(2); if K 2 || alpha 0 fitness 1e6; return; end [imf, ~, ~] vmd(sig, NumIMF, K, PenaltyFactor, alpha, Display, false); envEntropy zeros(K, 1); for k 1:K env abs(hilbert(imf(:, k))); if sum(env) eps envEntropy(k) 0; continue; end prob env / sum(env); envEntropy(k) -sum(prob .* log(prob eps)); end corrCoefAll zeros(K, 1); for k 1:K tmp corrcoef(sig, imf(:, k)); corrCoefAll(k) tmp(1, 2); end fitness mean(envEntropy) - 0.3 * mean(abs(corrCoefAll)); end主脚本里调用particleswarmlb [3, 500]; ub [8, 4000]; options optimoptions(particleswarm, SwarmSize, 20, MaxIterations, 30, Display, iter); [fval, bestParas] particleswarm((p) vmdFitness(p, xn), 2, lb, ub, options); K_best round(bestParas(1)); alpha_best bestParas(2);需要注意几个容易坑到人的点。第一K必须是整数直接用particleswarm搜出来的可能是小数要round或者干脆在目标函数里round。第二粒子群是无约束优化可能会跑到负值所以目标函数开头要加参数合法性判断不合法直接给一个很大的fitness。第三VMD每次迭代都挺耗时粒子群SwarmSize不要设太大我一般20个粒子、30代先粗搜一轮再在小范围精搜一轮。数据特别长的时候先降采样到1000点以内再跑优化确定参数后再对原始数据做正式分解。3.4 优化前后的对比一个实例有次我处理一段齿轮箱振动信号明显存在啮合频率、边频带和背景噪声。一开始手动试K4、alpha2000分解结果里IMF2和IMF3的频谱混在一起边频带被压得看不出结构。后来用粒子群优化搜索范围K[3,8]、alpha[500,4000]跑了大概20多代得到K5、alpha2360。用这组参数重新分解五个IMF的中心频率稳定分散在有效频段边频带也完整保留下来。优化后的SNR比固定参数高了约2到3dB包络谱里故障特征峰明显更突出。我不是说粒子群一定比手动调参强而是它能把人在频谱上反复比较的时间省下来并且更容易找到“看起来不太直观但实际效果好”的参数组合。特别是面对一批新信号时跑一次优化比瞎猜靠谱得多。4. 小波去噪WD和多模型混合的完整流程4.1 WD三板斧小波基、分解层数、阈值规则怎么选小波去噪的核心可以概括成三板斧选什么小波基分解多少层用什么阈值规则。小波基相当于“筛子的形状”不同形状筛出来的颗粒分布不一样。工程信号我常用sym8或db8对称性好的小波基相位失真小对振动信号比较友好。分解层数一般3到5层太多会把有效低频成分也当噪声滤掉太少则噪声残留在细节系数里压不下去。阈值规则方面Matlab里常见的有rigrsure、heursure、sqtwolog、minimaxi。rigrsure基于Stein无偏风险估计适合噪声强度比较均匀的白噪声heursure是启发式在信噪比不高时比rigrsure稳sqtwolog是固定阈值简单粗暴minimaxi偏保守保留细节更多。我个人的经验是中高频噪声严重的IMF用heursure低频主能量IMF用rigrsure或者干脆只做轻度处理。阈值处理方式也分软硬。软阈值会把系数朝着零收缩波形平滑但容易削掉真实冲击的幅值硬阈值保留大于阈值的系数原样冲击幅值保得牢但重构信号可能有点抖。如果你处理的对象是轴承故障信号我建议重点保住冲击特征硬阈值或接近硬阈值的处理方式更合适。4.2 VMDWD混合策略先分解再逐模态去噪把小波去噪直接作用在原始含噪信号上最大的问题是不同频率成分互相干扰。比如一个冲击成分和一个窄带谐波重叠小波系数在某个尺度上同时包含两者阈值一加可能把窄带谐波保住了但冲击细节丢了或者反过来。VMD先按中心频率把信号拆开这个问题就减轻很多。具体策略是对VMD分解出的每个IMF分别做WD。高频IMF里噪声占比大阈值可以设高一些去噪力度加大低频IMF承担主要信号能量阈值必须设低否则会把真实的低频波动当噪声干掉。这相当于给每个“房间”设置不同的“清扫力度”。有些IMF强度很低、相关系数很小千万别急着删除先看频谱里有没有物理特征频率噪声主导的可以最后在重构阶段丢。4.3 多模型混合的完整Matlab代码下面这段代码是我实际项目里的精简版完整流程都在里面% 信号长度、采样率 fs 1000; t (0:length(xn)-1)/fs; % 第一步优化VMD参数 lb [3, 500]; ub [8, 4000]; options optimoptions(particleswarm, SwarmSize, 15, MaxIterations, 20, Display, off); [~, bestParas] particleswarm((p) vmdFitness(p, xn), 2, lb, ub, options); K_best round(bestParas(1)); alpha_best bestParas(2); % 第二步VMD分解 [imf, res, ~] vmd(xn, NumIMF, K_best, PenaltyFactor, alpha_best, Tau, 0.3, Display, false); % 第三步逐模态小波去噪 K size(imf, 2); imfClean zeros(size(imf)); for k 1:K if k 2 % 低频模态轻度去噪 imfClean(:, k) wdenoise(imf(:, k), 3, Wavelet, sym8, ... DenoisingMethod, SURE, ThresholdRule, Soft); else % 高频模态加大去噪力度 imfClean(:, k) wdenoise(imf(:, k), 5, Wavelet, sym8, ... DenoisingMethod, Bayes, ThresholdRule, Hard); end end % 第四步基于相关系数筛选有效IMF r zeros(1, K); for k 1:K tmp corrcoef(xn, imfClean(:, k)); r(k) tmp(1, 2); end idxKeep r 0.2; denoised sum(imfClean(:, idxKeep), 2) res; % 第五步效果评估 SNR_after 10*log10(sum(s.^2)/sum((s-denoised).^2)); RMSE_after sqrt(mean((s-denoised).^2));这代码里wdenoise是较新版本才有的函数老版Matlab可以用wden替代参数对比如下imfClean(:, k) wden(imf(:, k), heursure, s, mln, 4, sym8);wden的缺点是没有Bayes方法可选但实际效果差距不大关键是阈值规则和层数要选对。如果是处理实时采集的长信号建议把整个流程封装成函数输入原始信号和采样率输出去噪后信号和参数结构体方便反复调用。4.4 加权融合思路不把鸡蛋放在一个篮子里多模型混合还有另一种玩法不是串行流水线而是并行加权融合。比如同时用VMD重构得到结果A、用WD直接去噪得到结果B然后按权重叠加denoised a*A (1-a)*B。这里的权重a可以通过最小化重构误差或让综合SNR最大来搜索。这种并行融合适合对算法效果不太有底的时候两个模型误差模式不同加权平均往往能消掉一部分互补误差。不过我实际测试下来这个方法对整体提升的贡献没有“VMD分解逐模态WD”那么明显。我更推荐把它当作备选方案当VMD重构和WD结果指标接近、难分伯仲时用加权融合取个折中比强行挑一个更稳。权重a可以先从0.5开始再用一维搜索或者粒子群顺手把它定了反正前面的优化框架已经搭好了。5. 仿真信号与实测数据的实操验证5.1 构造带噪声的非平稳多分量信号为了验证整套流程我先构造一个包含定频分量和扫频分量的非平稳信号再叠加强白噪声。这样我们能知道真实信号是什么样从而计算SNR、RMSE等指标。fs 1000; t (0:1000)/fs; s1 sin(2*pi*30*t); s2 0.5*cos(2*pi*80*t); s3 0.3*chirp(t, 10, 1, 150); s s1 s2 s3; rng(2024); xn s 0.6*randn(size(t));这个信号里30Hz正弦分量、80Hz余弦分量、10到150Hz线性扫频分量混在一起再加噪声后信噪比大概只有4到5dB肉眼已经很难看出干净波形。用这种信号测试去噪算法特别合适既能拆多分量又有非平稳成分。5.2 效果评价指标SNR、RMSE、相关系数算法效果不能靠“看起来干净了”来判断必须有量化指标。我常用的指标有三个SNR信噪比单位dB数值越大越好。计算公式是10乘以log10(真实信号能量除以噪声能量)Matlab里可以这样写SNR 10*log10(sum(s.^2)/sum((s-denoised).^2));RMSE均方根误差反映去噪后与真实信号的偏差大小越小越好RMSE sqrt(mean((s-denoised).^2));相关系数反映波形形状的相似程度。用corrcoef算出来的是矩阵取对角线以外的元素。相关系数接近1说明波形还原度高相位没有错位r corrcoef(s, denoised); corr_val r(1, 2);注意SNR公式里用的是去噪后的误差而不是原噪声所以SNR提升多少能直接体现算法增益。还有一点如果信号做过端点延拓计算评价指标时要先把延拓部分裁剪掉再算否则边缘的虚假误差会拉低结果。5.3 一组实例结果分析以我上面的仿真信号为例直接跑固定参数VMDK4、alpha2000再去噪SNR大概是11.3dB。单独用WD直接去噪sym8、4层、heursure软阈值SNR大概9.8dB。而用“优化VMD逐模态WD相关筛选”完整流程SNR能到14.6dB左右。RMSE方面固定参数VMD是0.31WD单独去噪是0.38混合流程降到0.19。相关系数也从0.93提升到0.98。为什么混合后提升这么明显拆开来看粒子群优化把K从4调到了530Hz正弦和80Hz余弦没有再挤在一个IMF里逐模态WD又对高频IMF做了重点清理相关系数筛选则把几乎全是噪声的IMF踢出重构。三步每一步都在减少误差最后叠加起来差距自然就大了。这不是玄学每一步都能在频谱和IMF波形里找到对应证据。真实数据不一定有这么干净的结果因为真实信号本身可能就不是严格的多分量叠加。但趋势是一致的分解越符合物理结构逐模态去噪越有针对性最终重构出来的信号就越接近真实成分。遇到含噪特别重的数据先做一次轻度WD预清理再用VMD效果往往比直接VMD更好。6. 常见问题与避坑清单6.1 VMD每次运行结果不对齐init参数有讲究有朋友跟我说同样一段信号跑两次vmd结果不完全一样。这大概率是中心频率初始化方式的问题。init默认值是1中心频率均匀初始化结果是确定的但如果之前设置过init2即随机初始化每次迭代起点不同最终结果就可能不同。还有一个因素是ADMM迭代终止阈值tol太宽松时提前停住结果会带一点随机性。我的做法是只要涉及参数对比和结果复现固定init1、tol1e-7并且运行前用rng(固定整数)锁住全局随机种子。这样无论跑多少遍得到的IMF基本一致。另外要注意如果Matlab开启了并行池部分底层函数在并行环境下可能引入微小浮动误差这是正常的不影响工程使用。6.2 模态混叠和端点效应怎么缓解模态混叠最常见的表现是两个IMF频谱大量重叠或者一个IMF在不同时间段呈现差异极大的频率成分。前面说过优先检查K和alpha。出现混叠时我的顺序是先小幅增大alpha看看是否改善不行再减K减少竞争模态数最后再看信号是否本身存在间歇性成分如果有考虑对信号分段后再VMD。端点效应比EMD轻得多但剧烈冲击信号下还是会在两端出现摆动。处理办法是信号延拓用Matlab的wextend函数在两端做对称延拓分解完再裁剪掉extLen round(length(xn)*0.1); xnExt wextend(1D, sym, xn, extLen); [imfExt, ~, ~] vmd(xnExt, NumIMF, K_best, PenaltyFactor, alpha_best); imf imfExt(extLen1:end-extLen, :);延拓长度一般取信号长度的5%到20%太长会引入虚假成分太短压不住端点效应。裁剪后如果端点附近还有明显畸变我建议评价指标时把两端各去掉几十个点再算保证数值稳定。6.3 低版本Matlab没有vmd函数怎么办内置vmd函数只在较新版本里提供老版本确实没有。这时候有两条路。一条路是用File Exchange上开源的VMD实现比如经典的vmd.m和相关子函数。下载后放到当前目录或添加到路径按作者文档的参数格式调用。注意开源版本内部参数名可能不一样有的用K、有的用NumIMF要花点时间读代码。我遇到过一个人装了个旧版Matlab又不想升级就天天用开源VMD后来发现开源版本收敛速度明显比内置函数慢。原因在于内置版本的ADMM实现做了内存和迭代优化。所以如果条件允许升级到能支持vmd和wdenoise的新版本能省很多麻烦。老版本还在用wden的接口也没关系只要把代码按版本兼容性封装好就行。6.4 搜VMD容易搜到硬件驱动注意区分这个看起来和算法无关但真坑过不少人。在搜索引擎里输入VMD跳出来的结果很可能是什么Intel VMD驱动、Western Digital Dashboard、硬盘设备驱动之类的内容跟信号处理八竿子打不着。搜的时候记得带上“变分模态分解”、“信号处理”、“Matlab”这些限定词或者直接搜全称Variational Mode Decomposition能少走很多弯路。磁盘驱动领域里的VMD是Volume Management Device那是对NVMe固态硬盘做热插拔和阵列管理的硬件技术和我们说的VMD变分模态分解只是恰好撞首字母缩写。我见过有学弟搜了半天搜到一堆驱动安装教程以为是自己环境没配好白白浪费时间。6.5 多模型混合计算量太大怎么提速优化VMD本身就是反复调vmd函数几十轮跑下来信号长一点就是几十分钟起步。提速有几个实用招数。第一降采样在保证目标频段不被破坏的前提下把采样率降到峰值频率的5到10倍数据点少了VMD迭代自然快很多。第二先用短数据段做参数优化确定K和alpha后再拿完整数据跑正式分解参数对信号长度不敏感这个操作很稳。第三粒子群参数调小SwarmSize设15、MaxIterations设20粗搜够了没必要追求全局最优。第四逐模态WD本身不慢真正慢的是vmd如果每个IMF还要算包络熵和相关系数建议用向量化写法别写一堆for循环来循环去。另外如果做的是批量数据处理每段信号都要跑一次优化那可以把上次寻优得到的参数作为下一次粒子群的初始种群中心这样能大幅收敛迭代次数。我在批量处理36组实验数据时用这个方法把总时间从接近两小时压到四十分钟效果没有明显损失。这套VMD加优化VMD加WD再加多模型混合的Matlab流程我前后用了小半年才稳定下来。最大的感受是别迷信算法越花哨越好关键是理解每个参数在干什么。K和alpha定了分解结果基本就定了WD阈值规则只要不把峰值削掉怎么选都是锦上添花。遇到新数据先别急着跑全套混合模型先用固定参数VMD跑一次看频谱、看残差、看包络谱再判断要不要优化。最后分享一个实操小技巧每次处理都把随机种子固定把优化得到的K、alpha、小波基、阈值规则、层数连同原始信号一起存成结构体后缀标上日期和实验编号。这样后面复现结果、向同事交代处理过程都有据可查。信号去噪本质是让数据说话参数可以自动寻优但判断标准永远得回到物理意义上。