MATLAB数字调制样式识别:特征提取与分类实战
发布时间:2026/10/27 7:52:04 锦皓数字建站

简介这份数字调制样式识别程序源代码基于MATLAB编写面向通信仿真、信号处理课程设计或科研入门者解决在接收端自动辨别数字调制方式的问题。代码工程共十四个文件其中四个核心脚本分别承担调制信号源仿真、信道模拟、瞬时参数提取与样式识别任务此外附有十个相关辅助链接整个压缩包仅约11KB便于快速下载核对。实现上覆盖二进制幅移键控、四进制幅移键控、二进制相移键控、四进制相移键控、二进制频移键控、四进制频移键控以及十六进制正交幅度调制共七种样式的判决完整展示了从产生测试信号到提取瞬时特征、最终归类识别的工作流程。需要注意样式识别环节中的门限值并非固定需根据实际统计分布自行确定这也意味着学习者需要动手完成参数标定从而加深对特征阈值与调制方式内在联系的理解。已有1036人学习使用对想要看懂调制识别实现细节并自行扩展算法的人员具有较好的参考价值。1. 数字调制解调样式识别先分清你面对的任务是识别而不是解调数字调制解调样式识别简单说就是给一段接收到的 IQ 波形判断发送端用的是哪种数字调制方式——是 BPSK、QPSK、8PSK还是 16QAM、2FSK、4FSK。它和解调是两码事解调要把比特流还原出来识别只关心调制样式哪怕不知道对方说了什么。这个任务在频谱监测、协议识别、认知无线电和信号侦察里都很常见也是通信类课程设计和毕业设计的经典选题。MATLAB 做这件事有一个很直接的优势信号生成、加噪、特征提取、分类器训练都能在一个脚本里打通不像 C 平台要先处理文件读取和内存管理。后面这套流程从零做出来需要的代码量不大但坑不少——比如相位模糊、符号定时、频偏都会让特征变得不稳定。下面是给课设、论文验证和工程预研用的可复现路径先跑通再逐步替换。2. 调制样式识别的核心是特征先会算高阶累积量和瞬时统计量2.1 为什么先做特征工程而不是一上来就上深度学习很多人拿到这个题目第一反应是扔给神经网络。深度学习从 I/Q 样本直接出调制类型确实能到很高的正确率但有两个现实问题第一需要大量带标签样本每个信噪比下每种调制至少几千帧否则网络很容易记住噪声第二MATLAB 里训练 CNN/LSTM 虽然方便但调参周期长一个 epoch 可能在 CPU 上跑好几分钟课设和工程预研都耗不起。特征工程路径不一样先用领域知识把 IQ 波形压缩成几个有物理意义的数字再用决策树、SVM 甚至最朴素的最近邻分类。样本量几百到几千就够单帧特征提取在零点几毫秒级跑一遍数据集几分钟。更重要的是特征可解释——当某两类调制分不开时你能明确指出是幅度特征失效还是相位特征失效这对调试非常关键。所以我的建议是无论最终要不要用深度学习都先把手工特征基线做出来。这个基线一旦稳定在 80%90% 准确率后面换模型就有对照物如果基线就乱成一团直接上深度学习只会更乱。后面所有内容都基于这条路线展开。2.2 一组能区分 PSK、FSK、QAM 的特征数字调制样式识别常用的特征分成三类瞬时幅度、瞬时相位/频率、高阶累积量。它们分别对应调制最基本的差异幅度变化、相位跳变、频率切换以及星座图的对称性。瞬时幅度特征最直观。比如 2ASK 的包络忽大忽小而 BPSK、QPSK 的包络基本恒定。用a abs(x)得到幅度序列再计算零中心归一化瞬时幅度谱峰值gamma_max这个值对幅度调制比较敏感。瞬时相位/频率特征能分开 PSK 和 FSK。FSK 的瞬时频率在几个离散频率值之间跳标准差大PSK 的瞬时频率集中在零附近只是因为相位跳变产生短暂脉冲。计算时先unwrap(angle(x))去掉相位折叠再差分得到近似瞬时频率。高阶累积量是最有区分力的一组特征。它的思想是不同星座图的统计对称性不同BPSK 的 I/Q 分量分布和 16QAM 很不一样这种差异会体现在四阶以上矩里。一个好特性是抗高斯噪声能力比较强因为高斯过程的四阶累积量理论上为零。下面给出一个完整的特征提取函数骨架输入是复基带 IQ 序列输出是 5 维特征向量function feat extractFeature(sig) % 输入: 复基带信号行向量或列向量均可 % 输出: [gamma_max, sigma_f, Mc40, Mc41, Mc42] sig sig(:).; N length(sig); % 1) 零中心归一化瞬时幅度谱峰值 a abs(sig); a_cn a / mean(a) - 1; gamma_max max(abs(fft(a_cn)).^2) / N; % 2) 零中心归一化瞬时频率绝对值的标准差 ph unwrap(angle(sig)); inst_freq [0, diff(ph)]; inst_freq inst_freq / (max(abs(inst_freq)) eps); sigma_f std(abs(inst_freq)); % 3) 二阶、四阶矩 m20 mean(sig.^2); m21 mean(abs(sig).^2); m40 mean(sig.^4); m41 mean(sig.^3 .* conj(sig)); m42 mean(sig.^4 .* conj(sig).^2); % 4) 四阶累积量并用二阶矩做尺度归一 c40 m40 - 3 * m20^2; c41 m41 - 3 * m20 * m21; c42 m42 - abs(m20)^2 - 2 * m21^2; feat [gamma_max, sigma_f, abs(c40)/m21^2, ... abs(c41)/m21^2, abs(c42)/m21^2]; end逻辑上gamma_max捕捉幅度包络的变化强度sigma_f捕捉频率切换的离散程度三个四阶累积量捕捉星座图对称性。注意inst_freq除以最大值只是尺度化不是精确的频率估计如果后续要做更精细的 FSK 识别建议改用diff(unwrap(angle(sig))) / (2*pi*Ts)得到真实频率再统计频点个数。参数归一化用m21^2是因为四阶矩的物理量纲是功率的平方归一化后特征与接收信号整体增益无关否则同样的调制换个增益特征就漂了。2.3 特征组合与区分能力上面的 5 维特征不是每个都对所有调制都有效。我一般会先画一张特征分布表搞清楚哪些特征负责分开哪几类。下面是常见的对应关系调制样式幅度特征 gamma_max频率特征 sigma_f|c40|/m21^2|c42|/m21^22ASK明显大于 1接近 0中等中等BPSK接近 0接近 0大接近 0QPSK/8PSK接近 0接近 0小接近 016QAM中等接近 0非零明显非零2FSK/4FSK接近 0明显大于 0接近 0接近 0这个表的数值不是绝对的因为不同载波频偏、成型滤波、信噪比都会改变绝对大小但相对趋势稳定。比如 BPSK 的|c40|明显大于 QPSK因为 BPSK 只有两个相位统计上峰值更大QPSK 四象限对称部分高阶累积量被抵消。这个规律在很多教材和论文里都能验证。单独一个特征不能覆盖所有调制但组合起来以后BPSK 和 QPSK 靠|c40|PSK 和 FSK 靠sigma_f2ASK 靠gamma_maxQAM 靠|c42|。特征维度不高分类器就不容易过拟合这是这套特征能跑通的基础。2.4 特征为什么必须先做归一化从extractFeature出来的 5 个特征量纲差很多gamma_max可能是几十|c42|/m21^2可能只有 0.1。如果不做归一化决策树虽然对尺度不敏感但 SVM、KNN 这类需要距离度量的分类器就会完全被大尺度特征主导即使是决策树SVM 和集成模型混用的时候也会有麻烦。常见的做法是在训练集上计算每个特征的均值和标准差然后zscore (feat - mu) / std。注意均值和标准差必须只在训练集上算再应用到测试集千万不要在包含测试样本的整个数据集上统一归一化那样会泄漏测试信息导致评估虚高。保存这两个参数后面在线识别同一套到底。% 训练集 [featNorm, mu, stdv] zscore(Xtrain); % 测试集必须用训练集的 mu/stdv XtestNorm (Xtest - mu) ./ stdv;这个细节在不少课设项目里被忽略最后混淆矩阵漂亮得不行换一段新信号却崩盘。记住归一化是模型的一部分不是数据预处理的外部步骤。如果换了新的接收机增益特征的整体尺度会变但用固定的mu/stdv调整后分类器依然能正确响应这就是把归一化常数当成模型参数保存的好处。3. 用 MATLAB 搭通一套最小可跑的识别流程信号生成、特征提取、分类3.1 生成调制样本从 pskmod/qammod 到基带 IQ做识别第一步是准备样本。不要急着拿真实采集的数据先自己仿真生成因为真实信号没有标签你不知道它到底是什么调制没法评估正确率。仿真信号的好处是标签天然存在等整个流程验证过了再换真实数据。常见的做法是用 Communications Toolbox 里的pskmod、qammod生成 PSK/QAM用fskmod或自定义振荡器生成 FSK。下面这段生成 QPSK 基带信号M 4; % QPSK numSym 2000; % 符号数 sps 8; % 每符号采样点数 data randi([0 M-1], numSym, 1); modSym pskmod(data, M, 0, gray); % 可选升余弦成型滤波 rrcTx comm.RaisedCosineTransmitFilter( ... RolloffFactor, 0.35, ... FilterSpanInSymbols, 10, ... OutputSamplesPerSymbol, sps); tx rrcTx(modSym);pskmod的第三个参数是初始相位设成 0 表示星座图以标准方向摆好。注意这里modSym是符号速率的复数序列直接用的话相邻符号之间会有相位跳变频谱会带外泄漏加成型滤波器会让信号更接近真实发射机。对于特征提取成型滤波不是必须的但加上以后特征分布更平滑分类器更容易收敛。RolloffFactor取 0.35 是工程上最常见的取值滤波器跨符号 10 个能基本收敛sps8是为了后续特征计算时每个符号有足够的采样点。FSK 不能用pskmod直接改常见做法是创建频率序列再积分成相位function sig genFSK(numSym, sps, fSpace, M) % 生成 MFSK 基带信号fSpace 为相邻频点间隔 h fSpace / sps; % 调制指数折算 data randi([0 M-1], numSym, 1); phase zeros(numSym*sps, 1); for n 1:numSym idx (n-1)*sps (1:sps); phase(idx) 2*pi*h*(data(n)- (M-1)/2) * (0:sps-1) / sps; end sig exp(1j * cumsum(phase)); end这段是简化做法没有做相位连续处理但用来做识别样本足够了。实际工程中FSK 调制指数会影响瞬时频率特征fSpace太小时 2FSK 和 4FSK 的频率直方图会重叠识别会变难。后面避坑部分会展开。3.2 把接收信号加噪识别必须在不同信噪比下测试。MATLAB 给复基带信号加高斯白噪声的标准做法SNRdB 10; noise (randn(size(tx)) 1j*randn(size(tx))) / sqrt(2); rx tx 10^(-SNRdB/20) * noise;注意10^(-SNRdB/20)这个系数对应的是电压信噪比因为信号和噪声都是复数幅度。如果你已经做了成型滤波这里可以直接对滤波后信号加噪没滤波也可以但要保证符号序列幅度归一化。经验是每个信噪比多生成几个独立样本比如 200 个取不同随机数据和不同噪声实现避免模型只记住某个噪声样板。这里有个容易搞混的地方噪声功率应该由信号的Es/N0而不是采样点数来判断。如果直接对信号序列加噪SNRdB是定义在采样点上的信噪比如果你后续要对符号级特征做分析需要把sps的因素考虑进去。简单起见我们统一在采样序列级别加噪所有特征也都在采样序列上计算保持口径一致。3.3 批量构造训练数据集数据集结构很简单一个特征矩阵X一个标签向量Y。下面这段把所有调制类型、所有信噪比、多次重复组合起来modSet {BPSK,QPSK,8PSK,16QAM,2FSK,4FSK}; snrSet -5:5:15; numRep 200; X []; Y []; for mi 1:numel(modSet) for si 1:numel(snrSet) for rep 1:numRep sig genSignal(modSet{mi}, snrSet(si)); feat extractFeature(sig); X [X; feat]; Y [Y; modSet{mi}]; end end end Y categorical(Y);这里genSignal需要你自己封装一个函数根据调制名返回一个加噪后的 IQ 序列具体实现就是 3.1 和 3.2 两段代码的组合。X是 6000×5 的矩阵Y是 6000×1 的 categorical。用repmat或cellfun可以写得更优雅但 for 循环最容易读、不容易错前期就这样。有一个细节每个样本的符号数numSym取多少。特征提取里涉及 FFT、相位差分符号太少参数估计方差大建议不少于 1000符号太多则单样本计算慢也没必要。折中是 1024 或 2048这是很多论文里常用的帧长度。你可以做个实验numSym256时准确率掉多少4096时又提升多少最后选一个性价比最高的。3.4 训练决策树分类器并做交叉验证特征和标签准备好以后第一版分类器用决策树就够了。MATLAB 的fitctree自带交叉验证选项rng(1); mdl fitctree(X, Y, CrossVal, on, KFold, 5); acc 1 - kfoldLoss(mdl); fprintf(5折交叉验证正确率: %.2f%%\n, acc*100);KFold5表示把样本分成 5 份轮流用 4 份训练、1 份验证最终准确率是 5 次平均。第一次跑这个流程如果准确率能上 85%说明特征和标签没问题如果只有 50%60%不要急着换分类器八成是前面的生成或特征代码写错了。决策树的好处是简单、训练快、不需要调太多超参适合当冒烟测试。注意这里我们刻意没有把X归一化因为fitctree本身不依赖尺度。但如果你后面要跑 KNN 或 SVM一定要回到 2.4 节做归一化。交叉验证的结果只是告诉你基线的水平不能代替独立测试集后面评估章节会再说。3.5 一个可维护的脚本结构到这一步代码已经有点散了。我会把它组织成四个文件这样改一个环节不动其他地方genSignal.m根据调制方式名和 SNR 生成加噪 IQ 序列extractFeature.m上一章的特征提取函数buildDataset.m批量生成样本并返回 X、Ymain.m主流程包括数据划分、训练、评估genSignal内部用switch分派到pskmod、qammod或自定义 FSK 生成器。这样的结构对后面扩展新调制类型很友好加一个 case跑一遍数据集看混淆矩阵哪里变差就行。不要让主脚本变得像一个超长的面条否则后续加特征、加调制样式都会牵连到别处血泪经验。4. 样式识别系统的评估别只看总准确率要分信噪比看混淆矩阵4.1 为什么按信噪比分段统计总准确率是一个笼统指标。一个模型如果只在 15dB 下测试准确率可能 99%但真实信号大多在 05dB 甚至更差这时 QPSK 和 8PSK、16QAM 和 64QAM 几乎分不开。设计识别系统时需求通常有一个信噪比范围比如“在 SNR≥0dB 时正确率不低于 90%”。所以评估必须拆开信噪比来看。正确的做法是把测试集按照生成时的 SNR 分组或者直接让测试集覆盖同一个 SNR 网格然后分别统计每组的正确率画一条“正确率-SNR”曲线。如果你的特征在 0dB 下只有 60%大概率需要补特征或换分类器如果 15dB 下还是 80%那问题出在特征本身或者标签方案上。画分 SNR 准确率曲线时我通常会这样写snrGroup repelem(snrSet, numRep * numel(modSet)); % 与 X 的行一一对应 % 注意 X 的行顺序是由三层循环生成的外层调制、中层SNR、内层重复 accBySnr zeros(size(snrSet)); for si 1:numel(snrSet) idx snrGroup snrSet(si); accBySnr(si) mean(Ypred(idx) Ytest(idx)); end plot(snrSet, accBySnr * 100, o-); xlabel(SNR (dB)); ylabel(正确率 (%));这里的核心是保证snrGroup和特征矩阵的行顺序一致。如果你在buildDataset里用的是循环而不是repmat一定按照循环顺序排列顺序乱了整条曲线都没意义。分 SNR 统计后你能看到模型在低信噪比下的疲态这比单个数字有价值得多。4.2 用混淆矩阵定位“到底谁和谁混了”比总准确率更值得看的是混淆矩阵。MATLAB 里confusionchart一行代码就能画Ypred predict(mdl, Xtest); figure; confusionchart(Ytest, Ypred);这里的mdl可以是训练好的分类器Xtest/Ytest是独立测试集。如果矩阵对角线上数字很大说明模型整体可靠如果某两行之间有大块非零值说明这两类特征高度重叠。常见的重叠模式是QPSK 和 8PSK 混、16QAM 和 64QAM 混、2FSK 和 4FSK 混。这些调制在星座图或频率图上相似单靠五维特征可能压不下去后面增补特征才有效。拿到混淆矩阵后不要只看一眼就翻过去。我会把它按行归一化成百分比比如“真实 8PSK 的信号有多少被判成 QPSK”这能暴露分类器的偏置。如果训练集各类样本数量均衡百分比和原始计数差不了太多但归一化后更容易对比。还可以把不同信噪比下的混淆矩阵打印出来观察误判是从哪个 SNR 开始爆发的。4.3 决策树不够就换集成或 SVM基线跑通后可以试试更复杂的分类器。MATLAB 常用三个选项分类器调用函数适合场景注意决策树fitctree特征少、要解释性容易过拟合随机森林/装袋fitcensemble(...,Method,Bag)特征稍多、样本量大训练慢但稳定SVMfitcecoc特征量级已归一化必须做 zscore示例bagMdl fitcensemble(Xtrain, Ytrain, Method, Bag, ... NumLearningCycles, 30); svmMdl fitcecoc(Xtrain, Ytrain);NumLearningCycles可以理解成树的数量30 棵左右在 6000 样本下已经能稳定。SVM 的fitcecoc会自动做一对一多分类不用手工拆。对比时固定同一个测试集记录训练时间和准确率。结论往往是这样SVM 在低 SNR 下比决策树好 35 个百分点但训练时间也长了 10 倍随机森林则居中。需要注意的是fitcecoc默认用线性核还是 RBF 核取决于版本和参数如果特征没有归一化SVM 的结果可能比决策树还差所以前面强调的zscore不能省略。保存模型用save(trainedModel.mat, mdl, mu, stdv)下次直接加载不需要重新训练。4.4 调参顺序先特征、后样本量、再分类器很多人在分类器超参数上反复调但效果不明显。我的经验是严格按三步来先看混淆矩阵确定哪两类混。是gamma_max区分不了 2ASK 和 BPSK还是|c42|区分不了 16QAM 和 64QAM针对性地增加一个特征例如从四阶累积量扩展到六阶或者加入高阶统计特征。再看样本量。如果混的那类样本只有几十个特征再准也学不好。增加到每类每 SNR 至少 200 个样本一般都会有明显提升。最后才碰分类器超参数。比如决策树的MinLeafSize或集成里的NumLearningCycles。超参调整对准确率的影响往往在 23 个百分点以内远小于前两步。这个顺序能避免把大量时间花在最不重要的环节。调参时每次只改一个变量记录结果否则没法判断是哪个改动起了作用。我见过有人把NumLearningCycles从 10 调到 2000准确率只涨了 0.5%却认为是模型变强了——其实早就收敛了。5. 避坑指南调制样式识别最容易翻车的五个细节5.1 相位模糊让 QPSK 特征忽高忽低现象同一段 QPSK 信号稍微旋转星座图|c40|和|c42|差好几倍分类器在训练时学到的规律到测试时失效。原因高阶累积量对信号的整体相位很敏感。接收机不知道载波绝对相位解调后的星座图可能整体旋转任意角度QPSK 在旋转 45° 时统计特性会变。解决特征提取前做相位归一化。常见做法是把 IQ 序列乘一个旋转因子让星座图的主轴对准实轴比如计算phi angle(mean(sig.^2)) / 2然后sig sig * exp(-1j*phi)。这个操作对 BPSK/QPSK 有效但对 QAM 不总能确定唯一主轴这时可以直接用累积量的绝对值并在训练数据里加入随机相位偏移让分类器学到旋转不变性。5.2 符号定时不准让瞬时幅度特征失效现象2ASK 的gamma_max理论上应该很大但实际计算时整个包络都差不多识别不出来。原因采样点落在符号跳变边缘上幅度被平均了。基带符号经过成型滤波后如果定时时刻偏了半个符号眼图张开度最小幅度特征会被磨平。解决在生成信号时固定sps并在接收端做匹配滤波然后按最佳采样点抽取。简单测试中可以用升余弦滤波器的群延迟补偿更实际的做法是先用comm.SymbolSynchronizer恢复符号定时再对输出信号做特征提取。识别不一定要精确解调但定时偏差会严重破坏幅度和相位特征这点和做离散时间系统仿真不一样不能只看波形形状。5.3 载波频偏把 FSK 特征推到系统性的误差上现象2FSK 在无频偏时sigma_f很大加一点频偏反而变小最后 2FSK 被识别成 PSK。原因瞬时频率是瞬时相位的差分频偏会给所有采样点加一个固定偏移。归一化除以最大值时如果频偏大于调制频偏那调制频偏就被压缩到很小的比例特征区分度消失。解决先做粗频偏估计。简单做法是取瞬时频率直方图的众数作为频偏估计从相位差分中减掉或者对信号做平方/四次方后估计残留载波频偏适用于 PSK再用comm.CoarseFrequencyCompensator。对于 FSK可以直接用频率直方图的峰间距作为特征而不是统计标准差。5.4 训练和测试信噪比范围不匹配现象训练时只用 0dB 样本测试时 12dB 样本准确率反而下降或者训练时覆盖全范围但测试时集中在某一段结果波动大。原因分类器在训练数据密度高的区域发挥好在密度低的区域会偏向先验概率。信噪比不同的特征分布并不重合只是部分重叠。解决训练集按 2dB 步长覆盖目标范围的每个点每个点采样数量均衡。如果目标范围是 -515dB就按 -5:2:15 分成 11 个点每点 100 个样本而不是只在 -5、0、5、10、15 五个点抽样。测试时也要用同样的 SNR 网格画出曲线后看是否平滑如果曲线在某个点突然塌陷大概率那个点的样本太少或噪声实现有倾向。5.5 不同 MATLAB 版本的工具箱函数差异让人反复翻车现象同学电脑上fskmod能用你这里报错Undefined function或者pskmod的参数在旧版本不支持gray选项。原因Communications Toolbox 的函数名和签名在不同版本有调整。fskmod在 R2018b 之后有过行为修改升余弦滤波器的对象写法也有变化。解决代码开头加存在性检查或者统一使用最稳定的函数组合。我的做法是PSK/QAM 用pskmod/qammod加旧式rcosfir滤波器FSK 自己写积分器调频生成完全不依赖fskmod。这样同一份代码在 R2016a 到 R2023b 上都能跑。另一点不要在代码里写死路径或使用addpath指向带中文的文件夹MATLAB 在部分版本上会报编码错误。6. 进阶用滑窗把离线识别变成对连续 IQ 流的在线识别离线数据集训练好以后真正工程中拿到的是连续 IQ 流比如软件无线电采集的几百万个采样点。要识别每一段的调制样式需要用滑动窗口把长序列切成块逐块提取特征、逐块分类。这比离线仿真多一个窗口参数问题。先看最简单的滑窗实现winLen 4096; % 窗长对应至少几百个符号 hopLen 2048; % 步进50% 重叠 blocks buffer(rxStream, winLen, winLen - hopLen); % 每行一个窗 labels categorical(zeros(size(blocks,1),1)); % 预分配 for k 1:size(blocks,1) feat extractFeature(blocks(k,:)); feat_norm (feat - mu) ./ stdv; % mu/stdv 来自训练集 labels(k) predict(mdl, feat_norm); endbuffer是信号处理工具箱的函数第一个参数是长序列第二个是块长第三个是重叠长度。这里winLen-hopLen2048表示每次后移 2048 点两块之间重叠 2048 点。窗长和时延要权衡窗太长识别一个标签要等很久如果信号中途切换调制切换处会模糊窗太短特征估计方差大误判多。我的经验是窗内至少包含 500 个符号这样才能让高阶累积量稳定到可用程度重叠率 50% 可以在时延和更新率之间取折中。滑动窗口输出的标签序列可以做后处理比如用多数投票去掉孤立跳变。常见做法是对连续 5 个窗的标签取众数只有连续 3 个以上窗口都变成新标签才认为调制切换了否则认为是一次误判。这个后处理很像通信里的判决器能让在线结果稳定很多。验证在线识别是否可靠要重放一段已知调制顺序的信号比如前 3 秒 QPSK、中间 2 秒 16QAM、后面 3 秒 2FSK逐窗输出预测标签再和真实切换时刻对比统计切换延迟和误判点。如果不做这个测试很难发现滑窗参数的坑。我第一次跑的时候窗长取了 1024结果高阶累积量在 16QAM 和 QPSK 之间乱跳误报率特别高后来把窗长提到 4096再叠加多数投票才稳定下来。这个教训让我记住了在线识别不是把离线函数拿来套一下就完事窗长和重叠度要按特征方差重新调最好先把特征提取函数做成独立对象固定所有参数避免每次调用因为状态不同而结果漂移。希望帮到你。本文还有配套的精品资源点击获取
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。