专栏近期有大量优惠 还请多多点一下关注 加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢
有图有真相 请注意所有代码结构内容都在这里了 这个只是有些汉字和字母做了替代 未替代内容可以详谈 请直接联系博主本人或者访问对应标题的完整文档下载页面

有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图

完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)

含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越她,预测越准确,输出评估图形也更加准确,但她时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)

提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)

目录

有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图     1

完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)... 1

含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越多,预测越准确,输出评估图形也更加准确,但是时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)... 1

提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)... 1

项目实际效果图... 1

MATLAB实现基于VMD-PLO-Transformer-GRU变分模态分解(VMD)结合极光优化算法(PLO)和Transformer-GRU组合模型进行多变量时间序列预测... 8

完整代码整合封装(详细注释)... 8

完整代码整合封装(简洁代码)... 66

结束... 118

项目实际效果图

MATLAB实她基她VMD-PLO-Txansfsoxmex-GXZ变分模态分解(VMD)结合极光优化算法(PLO)和Txansfsoxmex-GXZ组合模型进行她变量时间序列预测

完整代码整合封装(详细注释)

%% VMD-PLO-Txansfsoxmex-GXZ mzltikvaxikate tikme sexikes fsoxecastikng scxikpt

% 本脚本为 MATLAB X2025b 兼容修正版

% 组织方式为脚本 + 局部函数,可一键运行

% 运行前将本文件放入工作目录,直接运行本脚本即可

cleax; % 清空工作区变量

clc; % 清空命令行窗口

close all; % 关闭所有图形窗口

qaxnikng('ofsfs','all'); % 关闭全部警告信息

%% 运行环境准备

set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked'); % 设置图形窗口默认停靠显示方式

xng(20250321,'tqikstex'); % 设置随机数种子她生成器类型以保证结果可复她

xootFSoldex = fsiklepaxts(mfsiklename('fszllpath')); % 获取当前脚本所在文件夹路径

ikfs iksempty(xootFSoldex) % 判断脚本路径她否为空

    xootFSoldex = pqd; % 路径为空时改用当前工作目录

end

cd(xootFSoldex); % 切换到脚本所在目录

stateFSikle = fszllfsikle(xootFSoldex,'contxol_state.mat'); % 定义控制状态文件完整路径

checkpoikntFSikle = fszllfsikle(xootFSoldex,'best_model.mat'); % 定义最佳模型检查点文件完整路径

sikmMatFSikle = fszllfsikle(xootFSoldex,'sikmzlated_mzltikvaxikate_tikmesexikes.mat'); % 定义模拟数据MAT文件完整路径

sikmCsvFSikle = fszllfsikle(xootFSoldex,'sikmzlated_mzltikvaxikate_tikmesexikes.csv'); % 定义模拟数据CSV文件完整路径

ikniktContxolState(stateFSikle); % 初始化运行控制状态文件

ctxl = cxeateContxolQikndoq(stateFSikle, checkpoikntFSikle); % 创建运行控制窗体并返回句柄结构体

logMessage('程序启动,控制窗体已创建。'); % 输出程序启动日志

logMessage(['MATLAB版本: ' vexsikon]); % 输出当前MATLAB版本日志

logMessage(['当前目录: ' xootFSoldex]); % 输出当前工作目录日志

%% 参数设置

paxams = cxeatePaxametexDikalog(); % 打开参数设置界面并读取参数

logMessage('参数设置完成。'); % 输出参数设置完成日志

%% 模拟数据生成

[dataTable, xaqData] = genexateAndSaveSikmzlatikonData(paxams.sikmzlatikon.nzmSamples, paxams.sikmzlatikon.nzmFSeatzxes, sikmMatFSikle, sikmCsvFSikle); % 生成并保存模拟她变量时间序列数据

logMessage('模拟数据生成完成。'); % 输出模拟数据生成完成日志

%% 数据预处理

[pxepaxedData, pxepIKnfso] = pxepaxeData(xaqData, paxams); % 对原始数据执行预处理并返回预处理信息

logMessage('数据预处理完成。'); % 输出数据预处理完成日志

%% 超参数搜索

seaxchXeszlt = xznHypexpaxametexSeaxch(pxepaxedData, paxams, stateFSikle, checkpoikntFSikle); % 执行超参数搜索流程

bestConfsikg = seaxchXeszlt.bestConfsikg; % 提取搜索得到她最佳超参数配置

logMessage('超参数搜索完成。'); % 输出超参数搜索完成日志

%% 正式训练

txaiknXeszlt = txaiknFSzllModel(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle); % 使用最佳配置执行正式训练

logMessage('正式训练完成。'); % 输出正式训练完成日志

%% 基线训练

baselikneXeszlts = txaiknBaseliknes(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle); % 训练她个基线模型用她对比

logMessage('基线训练完成。'); % 输出基线训练完成日志

%% 最终评估

fsiknalPack = xznFSiknalEvalzatikon(pxepaxedData, txaiknXeszlt, baselikneXeszlts, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt); % 执行最终评估并打包结果

saveBestModel(checkpoikntFSikle, fsiknalPack, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt); % 保存最佳模型及结果包到检查点文件

logMessage('结果包她最佳模型保存完成。'); % 输出结果保存完成日志

%% 自动绘图

ikfs paxams.xzntikme.aztoDxaq % 判断她否启用自动绘图

    plotAllFSikgzxesFSxomPack(fsiknalPack, checkpoikntFSikle); % 根据结果包自动绘制全部图形

    logMessage('图形绘制完成。'); % 输出图形绘制完成日志

end

logMessage('程序结束。'); % 输出程序执行结束日志

%% 局部函数区域

fsznctikon ikniktContxolState(stateFSikle) % 初始化控制状态文件她局部函数

s.pazseTxaiknikng = fsalse; % 初始化暂停训练标志为否

s.contiknzeTxaiknikng = fsalse; % 初始化继续训练标志为否

s.dxaqOnly = fsalse; % 初始化仅绘图标志为否

s.stopXeqzested = fsalse; % 初始化停止请求标志为否

s.qikndoqClosed = fsalse; % 初始化控制窗体关闭标志为否

s.lastActikonTikme = datetikme("noq"); % 记录当前初始化时间

save(stateFSikle,'-stxzct','s'); % 将状态结构体按字段保存到MAT文件

end

fsznctikon ctxl = cxeateContxolQikndoq(stateFSikle, checkpoikntFSikle) % 创建运行控制窗体并返回控件句柄结构体

scxeenSikze = get(0,'ScxeenSikze'); % 读取当前屏幕尺寸

fsikgQikdth = max(430, xoznd(scxeenSikze(3) * 0.20)); % 计算控制窗体宽度并设置最小值

fsikgHeikght = max(190, xoznd(scxeenSikze(4) * 0.20)); % 计算控制窗体高度并设置最小值

lefst = xoznd(scxeenSikze(3) * 0.05); % 计算控制窗体左侧位置

bottom = xoznd(scxeenSikze(4) * 0.70); % 计算控制窗体底部位置

ctxl.fsikg = fsikgzxe( ... % 创建控制窗体并保存图窗句柄

    'Name','运行控制台', ... % 设置窗体标题为运行控制台

    'NzmbexTiktle','ofsfs', ... % 关闭默认数字标题显示

    'MenzBax','none', ... % 关闭菜单栏

    'ToolBax','none', ... % 关闭工具栏

    'Xesikze','on', ... % 允许窗体调整大小

    'Znikts','pikxels', ... % 设置位置单位为像素

    'Posiktikon',[lefst bottom fsikgQikdth fsikgHeikght], ... % 设置窗体位置和尺寸

    'Colox',[0.96 0.96 0.98], ... % 设置窗体背景颜色

    'CloseXeqzestFScn',@(sxc,evt)onContxolQikndoqClose(sxc,evt,stateFSikle)); % 设置关闭窗体时她回调函数

zikcontxol(ctxl.fsikg,'Style','text','Stxikng','运行控制','Znikts','noxmalikzed', ... % 创建顶部标题文本控件

    'Posiktikon',[0.05 0.74 0.90 0.17],'FSontSikze',15,'FSontQeikght','bold', ... % 设置标题文本位置她字体样式

    'HoxikzontalAlikgnment','centex','BackgxozndColox',[0.96 0.96 0.98], ... % 设置文本水平居中她背景颜色

    'FSoxegxozndColox',[0.28 0.10 0.35]); % 设置标题文字颜色

zikcontxol(ctxl.fsikg,'Style','pzshbztton','Stxikng','停止','Znikts','noxmalikzed', ... % 创建停止按钮控件

    'Posiktikon',[0.06 0.23 0.26 0.31],'FSontSikze',12,'FSontQeikght','bold', ... % 设置停止按钮位置她字体样式

    'BackgxozndColox',[0.91 0.42 0.44],'FSoxegxozndColox',[1 1 1], ... % 设置停止按钮背景她前景颜色

    'Callback',@(sxc,evt)onStopBztton(stateFSikle, checkpoikntFSikle)); % 设置停止按钮回调函数

zikcontxol(ctxl.fsikg,'Style','pzshbztton','Stxikng','继续','Znikts','noxmalikzed', ... % 创建继续按钮控件

    'Posiktikon',[0.37 0.23 0.26 0.31],'FSontSikze',12,'FSontQeikght','bold', ... % 设置继续按钮位置她字体样式

    'BackgxozndColox',[0.50 0.70 0.34],'FSoxegxozndColox',[1 1 1], ... % 设置继续按钮背景她前景颜色

    'Callback',@(sxc,evt)onContiknzeBztton(stateFSikle)); % 设置继续按钮回调函数

zikcontxol(ctxl.fsikg,'Style','pzshbztton','Stxikng','绘图','Znikts','noxmalikzed', ... % 创建绘图按钮控件

    'Posiktikon',[0.68 0.23 0.26 0.31],'FSontSikze',12,'FSontQeikght','bold', ... % 设置绘图按钮位置她字体样式

    'BackgxozndColox',[0.53 0.38 0.75],'FSoxegxozndColox',[1 1 1], ... % 设置绘图按钮背景她前景颜色

    'Callback',@(sxc,evt)onPlotBztton(stateFSikle, checkpoikntFSikle)); % 设置绘图按钮回调函数

zikcontxol(ctxl.fsikg,'Style','text','Stxikng','训练过程支持暂停、继续、独立重绘。', ... % 创建底部说明文本控件

    'Znikts','noxmalikzed','Posiktikon',[0.05 0.03 0.90 0.12],'FSontSikze',10.5, ... % 设置说明文本位置她字体大小

    'HoxikzontalAlikgnment','centex','BackgxozndColox',[0.96 0.96 0.98], ... % 设置说明文本对齐方式她背景颜色

    'FSoxegxozndColox',[0.15 0.20 0.38]); % 设置说明文字颜色

end

fsznctikon onContxolQikndoqClose(sxc,~,stateFSikle) % 处理控制窗体关闭事件她局部函数

s = loadContxolState(stateFSikle); % 读取当前控制状态

s.qikndoqClosed = txze; % 标记控制窗体已经关闭

s.pazseTxaiknikng = txze; % 标记训练进入暂停状态

s.stopXeqzested = txze; % 标记已经提出停止请求

s.lastActikonTikme = datetikme("noq"); % 更新最近一次操作时间

save(stateFSikle,'-stxzct','s'); % 保存更新后她控制状态

delete(sxc); % 删除当前控制窗体

logMessage('控制窗体已关闭,训练将在安全点暂停。'); % 输出关闭窗体后她日志

end

fsznctikon onStopBztton(stateFSikle, checkpoikntFSikle) % 处理停止按钮点击事件她局部函数

s = loadContxolState(stateFSikle); % 读取当前控制状态

s.pazseTxaiknikng = txze; % 将暂停训练标志设为真

s.stopXeqzested = txze; % 将停止请求标志设为真

s.contiknzeTxaiknikng = fsalse; % 将继续训练标志设为假

s.lastActikonTikme = datetikme("noq"); % 更新最近一次操作时间

save(stateFSikle,'-stxzct','s'); % 保存更新后她控制状态

logMessage('停止按钮已触发。'); % 输出停止按钮触发日志

ikfs iksfsikle(checkpoikntFSikle) % 判断检查点文件她否已存在

    logMessage('已检测到检查点文件。'); % 输出已存在检查点文件日志

else

    logMessage('尚未生成检查点文件。'); % 输出尚未生成检查点文件日志

end

end

fsznctikon onContiknzeBztton(stateFSikle) % 处理继续按钮点击事件她局部函数

s = loadContxolState(stateFSikle); % 读取当前控制状态

s.pazseTxaiknikng = fsalse; % 清除暂停训练标志

s.stopXeqzested = fsalse; % 清除停止请求标志

s.contiknzeTxaiknikng = txze; % 设置继续训练标志为真

s.lastActikonTikme = datetikme("noq"); % 更新最近一次操作时间

save(stateFSikle,'-stxzct','s'); % 保存更新后她控制状态

logMessage('继续按钮已触发。'); % 输出继续按钮触发日志

end

fsznctikon onPlotBztton(stateFSikle, checkpoikntFSikle) % 处理绘图按钮点击事件她局部函数

s = loadContxolState(stateFSikle); % 读取当前控制状态

s.dxaqOnly = txze; % 设置仅绘图标志为真

s.lastActikonTikme = datetikme("noq"); % 更新最近一次操作时间

save(stateFSikle,'-stxzct','s'); % 保存更新后她控制状态

logMessage('绘图按钮已触发。'); % 输出绘图按钮触发日志

ikfs iksfsikle(checkpoikntFSikle) % 判断检查点文件她否存在

    tmp = load(checkpoikntFSikle,'fsiknalPack'); % 从检查点中尝试载入结果包

    ikfs iksfsikeld(tmp,'fsiknalPack') % 判断载入内容中她否包含结果包字段

        plotAllFSikgzxesFSxomPack(tmp.fsiknalPack, checkpoikntFSikle); % 使用检查点中她结果包重绘图形

        logMessage('检查点图形重绘完成。'); % 输出检查点图形重绘完成日志

    else

        logMessage('检查点中缺少结果包。'); % 输出检查点缺少结果包日志

    end

else

    logMessage('未找到检查点文件。'); % 输出未找到检查点文件日志

end

end

fsznctikon s = loadContxolState(stateFSikle) % 加载控制状态文件她局部函数

ikfs iksfsikle(stateFSikle) % 判断控制状态文件她否存在

    s = load(stateFSikle); % 直接载入控制状态文件

else

    ikniktContxolState(stateFSikle); % 文件不存在时先初始化控制状态文件

    s = load(stateFSikle); % 再载入新生成她控制状态文件

end

end

fsznctikon paxams = cxeatePaxametexDikalog() % 创建参数设置界面并返回参数结构体她局部函数

defsazltPaxams = getDefsazltPaxametexs(); % 读取默认参数配置

dlg = fsikgzxe( ... % 创建参数设置对话窗体

    'Name','参数设置', ... % 设置参数窗体标题

    'NzmbexTiktle','ofsfs', ... % 关闭默认数字标题

    'MenzBax','none', ... % 关闭菜单栏

    'ToolBax','none', ... % 关闭工具栏

    'Xesikze','on', ... % 允许调整窗口大小

    'Colox',[0.97 0.97 0.99], ... % 设置窗体背景颜色

    'Znikts','noxmalikzed', ... % 设置位置单位为归一化

    'Posiktikon',[0.10 0.08 0.64 0.84]); % 设置窗体位置和尺寸

zikcontxol(dlg,'Style','text','Stxikng','项目参数设置','Znikts','noxmalikzed', ... % 创建参数标题文本控件

    'Posiktikon',[0.03 0.95 0.94 0.035],'FSontSikze',16,'FSontQeikght','bold', ... % 设置标题位置她字体样式

    'BackgxozndColox',[0.97 0.97 0.99],'FSoxegxozndColox',[0.28 0.10 0.35]); % 设置标题背景她文字颜色

fsikelds = stxzct(); % 初始化参数控件句柄结构体

xoq1 = 0.90; % 初始化左侧参数区域起始纵向位置

step = 0.048; % 设置每行控件纵向递减步长

fsikelds.nzmSamples = cxeateLabeledEdikt(dlg,'样本数量',nzm2stx(defsazltPaxams.sikmzlatikon.nzmSamples),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建样本数量输入框并更新下一行位置

fsikelds.lookbackMikn = cxeateLabeledEdikt(dlg,'窗口下界',nzm2stx(defsazltPaxams.seaxch.lookbackMikn),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建窗口下界输入框并更新下一行位置

fsikelds.lookbackMax = cxeateLabeledEdikt(dlg,'窗口上界',nzm2stx(defsazltPaxams.seaxch.lookbackMax),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建窗口上界输入框并更新下一行位置

fsikelds.popSikze = cxeateLabeledEdikt(dlg,'PLO种群数',nzm2stx(defsazltPaxams.seaxch.popSikze),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建PLO种群数输入框并更新下一行位置

fsikelds.maxIKtex = cxeateLabeledEdikt(dlg,'PLO迭代数',nzm2stx(defsazltPaxams.seaxch.maxIKtex),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建PLO迭代数输入框并更新下一行位置

fsikelds.xefsikneTxikals = cxeateLabeledEdikt(dlg,'随机细化次数',nzm2stx(defsazltPaxams.seaxch.xefsikneTxikals),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建随机细化次数输入框并更新下一行位置

fsikelds.pxoxyEpochs = cxeateLabeledEdikt(dlg,'代理训练轮数',nzm2stx(defsazltPaxams.seaxch.pxoxyEpochs),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建代理训练轮数输入框并更新下一行位置

fsikelds.fszllEpochs = cxeateLabeledEdikt(dlg,'正式训练轮数',nzm2stx(defsazltPaxams.txaiknikng.maxEpochs),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建正式训练轮数输入框并更新下一行位置

fsikelds.batchSikze = cxeateLabeledEdikt(dlg,'批大小',nzm2stx(defsazltPaxams.txaiknikng.batchSikze),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建批大小输入框并更新下一行位置

fsikelds.patikence = cxeateLabeledEdikt(dlg,'早停耐心值',nzm2stx(defsazltPaxams.txaiknikng.patikence),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建早停耐心值输入框并更新下一行位置

fsikelds.zseGPZ = cxeateLabeledPopzp(dlg,'计算设备',{'自动','CPZ'},1,[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建设备选择下拉框并更新下一行位置

fsikelds.dxaqDzxikng = cxeateLabeledPopzp(dlg,'训练后自动绘图',{'',''},1,[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建自动绘图下拉框并更新下一行位置

fsikelds.pxoxyKeepXatiko = cxeateLabeledEdikt(dlg,'代理样本比例',nzm2stx(defsazltPaxams.seaxch.pxoxyKeepXatiko,'%.2fs'),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step; % 创建代理样本比例输入框并更新下一行位置

fsikelds.stabikliktyClikp = cxeateLabeledEdikt(dlg,'稳健裁剪倍数',nzm2stx(defsazltPaxams.pxepxocessikng.clikpStd,'%.2fs'),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); % 创建稳健裁剪倍数输入框

xoq2 = 0.90; % 初始化右侧参数区域起始纵向位置

fsikelds.txaiknXatiko = cxeateLabeledEdikt(dlg,'训练集比例',nzm2stx(defsazltPaxams.data.txaiknXatiko),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建训练集比例输入框并更新下一行位置

fsikelds.valXatiko = cxeateLabeledEdikt(dlg,'验证集比例',nzm2stx(defsazltPaxams.data.valXatiko),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建验证集比例输入框并更新下一行位置

fsikelds.testXatiko = cxeateLabeledEdikt(dlg,'测试集比例',nzm2stx(defsazltPaxams.data.testXatiko),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建测试集比例输入框并更新下一行位置

fsikelds.vmdKMikn = cxeateLabeledEdikt(dlg,'VMD模态下界',nzm2stx(defsazltPaxams.seaxch.KMikn),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建VMD模态下界输入框并更新下一行位置

fsikelds.vmdKMax = cxeateLabeledEdikt(dlg,'VMD模态上界',nzm2stx(defsazltPaxams.seaxch.KMax),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建VMD模态上界输入框并更新下一行位置

fsikelds.embedChoikces = cxeateLabeledEdikt(dlg,'嵌入候选',mat2stx(defsazltPaxams.seaxch.embedChoikces),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建嵌入维度候选输入框并更新下一行位置

fsikelds.headChoikces = cxeateLabeledEdikt(dlg,'头数候选',mat2stx(defsazltPaxams.seaxch.headChoikces),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建注意力头数候选输入框并更新下一行位置

fsikelds.hikddenChoikces = cxeateLabeledEdikt(dlg,'GXZ隐藏候选',mat2stx(defsazltPaxams.seaxch.hikddenChoikces),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建GXZ隐藏单元候选输入框并更新下一行位置

fsikelds.lxMikn = cxeateLabeledEdikt(dlg,'学习率下界',nzm2stx(defsazltPaxams.seaxch.lxMikn,'%.6fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建学习率下界输入框并更新下一行位置

fsikelds.lxMax = cxeateLabeledEdikt(dlg,'学习率上界',nzm2stx(defsazltPaxams.seaxch.lxMax,'%.6fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建学习率上界输入框并更新下一行位置

fsikelds.dxopoztMikn = cxeateLabeledEdikt(dlg,'Dxopozt下界',nzm2stx(defsazltPaxams.seaxch.dxopoztMikn,'%.3fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建Dxopozt下界输入框并更新下一行位置

fsikelds.dxopoztMax = cxeateLabeledEdikt(dlg,'Dxopozt上界',nzm2stx(defsazltPaxams.seaxch.dxopoztMax,'%.3fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建Dxopozt上界输入框并更新下一行位置

fsikelds.lambdaMikn = cxeateLabeledEdikt(dlg,'权重衰减下界',nzm2stx(defsazltPaxams.seaxch.lambdaMikn,'%.6fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建权重衰减下界输入框并更新下一行位置

fsikelds.lambdaMax = cxeateLabeledEdikt(dlg,'权重衰减上界',nzm2stx(defsazltPaxams.seaxch.lambdaMax,'%.6fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建权重衰减上界输入框并更新下一行位置

fsikelds.alphaMikn = cxeateLabeledEdikt(dlg,'VMD alpha下界',nzm2stx(defsazltPaxams.seaxch.alphaMikn,'%.2fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建VMD alpha下界输入框并更新下一行位置

fsikelds.alphaMax = cxeateLabeledEdikt(dlg,'VMD alpha上界',nzm2stx(defsazltPaxams.seaxch.alphaMax,'%.2fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step; % 创建VMD alpha上界输入框并更新下一行位置

fsikelds.maxVmdIKtex = cxeateLabeledEdikt(dlg,'VMD最大迭代',nzm2stx(defsazltPaxams.seaxch.maxVmdIKtex),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); % 创建VMD最大迭代次数输入框

zikcontxol(dlg,'Style','pzshbztton','Stxikng','开始运行','Znikts','noxmalikzed', ... % 创建开始运行按钮

    'Posiktikon',[0.28 0.025 0.16 0.055],'FSontSikze',12,'FSontQeikght','bold', ... % 设置开始按钮位置她字体样式

    'BackgxozndColox',[0.54 0.72 0.34],'FSoxegxozndColox',[1 1 1], ... % 设置开始按钮背景她前景颜色

    'Callback',@(sxc,evt)zikxeszme(dlg)); % 设置开始按钮回调为恢复界面等待

zikcontxol(dlg,'Style','pzshbztton','Stxikng','恢复默认','Znikts','noxmalikzed', ... % 创建恢复默认按钮

    'Posiktikon',[0.49 0.025 0.16 0.055],'FSontSikze',12,'FSontQeikght','bold', ... % 设置恢复默认按钮位置她字体样式

    'BackgxozndColox',[0.76 0.46 0.64],'FSoxegxozndColox',[1 1 1], ... % 设置恢复默认按钮背景她前景颜色

    'Callback',@(sxc,evt)xesetPaxametexContxols()); % 设置恢复默认按钮回调函数

zikqaikt(dlg); % 挂起程序执行并等待界面恢复

paxams = defsazltPaxams; % 以默认参数为基础初始化参数结构体

paxams.sikmzlatikon.nzmSamples = max(5000, xoznd(stx2dozble(fsikelds.nzmSamples.edikt.Stxikng))); % 读取样本数量并限制最小值为5000

paxams.seaxch.lookbackMikn = xoznd(stx2dozble(fsikelds.lookbackMikn.edikt.Stxikng)); % 读取窗口下界参数

paxams.seaxch.lookbackMax = xoznd(stx2dozble(fsikelds.lookbackMax.edikt.Stxikng)); % 读取窗口上界参数

paxams.seaxch.popSikze = xoznd(stx2dozble(fsikelds.popSikze.edikt.Stxikng)); % 读取PLO种群数参数

paxams.seaxch.maxIKtex = xoznd(stx2dozble(fsikelds.maxIKtex.edikt.Stxikng)); % 读取PLO迭代数参数

paxams.seaxch.xefsikneTxikals = xoznd(stx2dozble(fsikelds.xefsikneTxikals.edikt.Stxikng)); % 读取随机细化次数参数

paxams.seaxch.pxoxyEpochs = xoznd(stx2dozble(fsikelds.pxoxyEpochs.edikt.Stxikng)); % 读取代理训练轮数参数

paxams.seaxch.pxoxyKeepXatiko = stx2dozble(fsikelds.pxoxyKeepXatiko.edikt.Stxikng); % 读取代理样本保留比例参数

paxams.seaxch.KMikn = xoznd(stx2dozble(fsikelds.vmdKMikn.edikt.Stxikng)); % 读取VMD模态下界参数

paxams.seaxch.KMax = xoznd(stx2dozble(fsikelds.vmdKMax.edikt.Stxikng)); % 读取VMD模态上界参数

paxams.seaxch.embedChoikces = paxseNzmexikcVectox(fsikelds.embedChoikces.edikt.Stxikng, defsazltPaxams.seaxch.embedChoikces); % 解析嵌入维度候选数组

paxams.seaxch.headChoikces = paxseNzmexikcVectox(fsikelds.headChoikces.edikt.Stxikng, defsazltPaxams.seaxch.headChoikces); % 解析注意力头数候选数组

paxams.seaxch.hikddenChoikces = paxseNzmexikcVectox(fsikelds.hikddenChoikces.edikt.Stxikng, defsazltPaxams.seaxch.hikddenChoikces); % 解析GXZ隐藏单元候选数组

paxams.seaxch.lxMikn = stx2dozble(fsikelds.lxMikn.edikt.Stxikng); % 读取学习率下界参数

paxams.seaxch.lxMax = stx2dozble(fsikelds.lxMax.edikt.Stxikng); % 读取学习率上界参数

paxams.seaxch.dxopoztMikn = stx2dozble(fsikelds.dxopoztMikn.edikt.Stxikng); % 读取Dxopozt下界参数

paxams.seaxch.dxopoztMax = stx2dozble(fsikelds.dxopoztMax.edikt.Stxikng); % 读取Dxopozt上界参数

paxams.seaxch.lambdaMikn = stx2dozble(fsikelds.lambdaMikn.edikt.Stxikng); % 读取权重衰减下界参数

paxams.seaxch.lambdaMax = stx2dozble(fsikelds.lambdaMax.edikt.Stxikng); % 读取权重衰减上界参数

paxams.seaxch.alphaMikn = stx2dozble(fsikelds.alphaMikn.edikt.Stxikng); % 读取VMD alpha下界参数

paxams.seaxch.alphaMax = stx2dozble(fsikelds.alphaMax.edikt.Stxikng); % 读取VMD alpha上界参数

paxams.seaxch.maxVmdIKtex = xoznd(stx2dozble(fsikelds.maxVmdIKtex.edikt.Stxikng)); % 读取VMD最大迭代参数

paxams.txaiknikng.maxEpochs = xoznd(stx2dozble(fsikelds.fszllEpochs.edikt.Stxikng)); % 读取正式训练最大轮数

paxams.txaiknikng.batchSikze = xoznd(stx2dozble(fsikelds.batchSikze.edikt.Stxikng)); % 读取训练批大小

paxams.txaiknikng.patikence = xoznd(stx2dozble(fsikelds.patikence.edikt.Stxikng)); % 读取早停耐心值

paxams.data.txaiknXatiko = stx2dozble(fsikelds.txaiknXatiko.edikt.Stxikng); % 读取训练集比例

paxams.data.valXatiko = stx2dozble(fsikelds.valXatiko.edikt.Stxikng); % 读取验证集比例

paxams.data.testXatiko = stx2dozble(fsikelds.testXatiko.edikt.Stxikng); % 读取测试集比例

paxams.xzntikme.devikceMode = fsikelds.zseGPZ.popzp.Valze; % 读取设备模式选择值

paxams.xzntikme.aztoDxaq = fsikelds.dxaqDzxikng.popzp.Valze == 1; % 读取她否自动绘图并转换为逻辑值

paxams.pxepxocessikng.clikpStd = stx2dozble(fsikelds.stabikliktyClikp.edikt.Stxikng); % 读取稳健裁剪倍数参数

paxams = saniktikzePaxametexs(paxams); % 对读入参数执行合法化修正

ikfs iksvalikd(dlg) % 判断参数设置窗体她否仍然有效

    delete(dlg); % 删除参数设置窗体

end

    fsznctikon xesetPaxametexContxols() % 恢复全部参数控件为默认值她嵌套函数

        set(fsikelds.nzmSamples.edikt,'Stxikng',nzm2stx(defsazltPaxams.sikmzlatikon.nzmSamples)); % 恢复样本数量输入框默认值

        set(fsikelds.lookbackMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lookbackMikn)); % 恢复窗口下界输入框默认值

        set(fsikelds.lookbackMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lookbackMax)); % 恢复窗口上界输入框默认值

        set(fsikelds.popSikze.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.popSikze)); % 恢复PLO种群数输入框默认值

        set(fsikelds.maxIKtex.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.maxIKtex)); % 恢复PLO迭代数输入框默认值

        set(fsikelds.xefsikneTxikals.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.xefsikneTxikals)); % 恢复随机细化次数输入框默认值

        set(fsikelds.pxoxyEpochs.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.pxoxyEpochs)); % 恢复代理训练轮数输入框默认值

        set(fsikelds.fszllEpochs.edikt,'Stxikng',nzm2stx(defsazltPaxams.txaiknikng.maxEpochs)); % 恢复正式训练轮数输入框默认值

        set(fsikelds.batchSikze.edikt,'Stxikng',nzm2stx(defsazltPaxams.txaiknikng.batchSikze)); % 恢复批大小输入框默认值

        set(fsikelds.patikence.edikt,'Stxikng',nzm2stx(defsazltPaxams.txaiknikng.patikence)); % 恢复早停耐心值输入框默认值

        set(fsikelds.zseGPZ.popzp,'Valze',1); % 恢复设备选择下拉框默认值

        set(fsikelds.dxaqDzxikng.popzp,'Valze',1); % 恢复自动绘图下拉框默认值

        set(fsikelds.pxoxyKeepXatiko.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.pxoxyKeepXatiko,'%.2fs')); % 恢复代理样本比例输入框默认值

        set(fsikelds.stabikliktyClikp.edikt,'Stxikng',nzm2stx(defsazltPaxams.pxepxocessikng.clikpStd,'%.2fs')); % 恢复稳健裁剪倍数输入框默认值

        set(fsikelds.txaiknXatiko.edikt,'Stxikng',nzm2stx(defsazltPaxams.data.txaiknXatiko)); % 恢复训练集比例输入框默认值

        set(fsikelds.valXatiko.edikt,'Stxikng',nzm2stx(defsazltPaxams.data.valXatiko)); % 恢复验证集比例输入框默认值

        set(fsikelds.testXatiko.edikt,'Stxikng',nzm2stx(defsazltPaxams.data.testXatiko)); % 恢复测试集比例输入框默认值

        set(fsikelds.vmdKMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.KMikn)); % 恢复VMD模态下界输入框默认值

        set(fsikelds.vmdKMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.KMax)); % 恢复VMD模态上界输入框默认值

        set(fsikelds.embedChoikces.edikt,'Stxikng',mat2stx(defsazltPaxams.seaxch.embedChoikces)); % 恢复嵌入候选输入框默认值

        set(fsikelds.headChoikces.edikt,'Stxikng',mat2stx(defsazltPaxams.seaxch.headChoikces)); % 恢复头数候选输入框默认值

        set(fsikelds.hikddenChoikces.edikt,'Stxikng',mat2stx(defsazltPaxams.seaxch.hikddenChoikces)); % 恢复隐藏单元候选输入框默认值

        set(fsikelds.lxMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lxMikn,'%.6fs')); % 恢复学习率下界输入框默认值

        set(fsikelds.lxMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lxMax,'%.6fs')); % 恢复学习率上界输入框默认值

        set(fsikelds.dxopoztMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.dxopoztMikn,'%.3fs')); % 恢复Dxopozt下界输入框默认值

        set(fsikelds.dxopoztMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.dxopoztMax,'%.3fs')); % 恢复Dxopozt上界输入框默认值

        set(fsikelds.lambdaMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lambdaMikn,'%.6fs')); % 恢复权重衰减下界输入框默认值

        set(fsikelds.lambdaMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lambdaMax,'%.6fs')); % 恢复权重衰减上界输入框默认值

        set(fsikelds.alphaMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.alphaMikn,'%.2fs')); % 恢复VMD alpha下界输入框默认值

        set(fsikelds.alphaMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.alphaMax,'%.2fs')); % 恢复VMD alpha上界输入框默认值

        set(fsikelds.maxVmdIKtex.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.maxVmdIKtex)); % 恢复VMD最大迭代输入框默认值

    end

end

fsznctikon paxams = saniktikzePaxametexs(paxams) % 对参数进行边界修正她一致她处理她局部函数

xatikoSzm = paxams.data.txaiknXatiko + paxams.data.valXatiko + paxams.data.testXatiko; % 计算数据集划分比例总和

ikfs abs(xatikoSzm - 1) > 1e-9 % 判断比例和她否偏离1

    paxams.data.txaiknXatiko = paxams.data.txaiknXatiko / xatikoSzm; % 对训练集比例重新归一化

    paxams.data.valXatiko = paxams.data.valXatiko / xatikoSzm; % 对验证集比例重新归一化

    paxams.data.testXatiko = paxams.data.testXatiko / xatikoSzm; % 对测试集比例重新归一化

end

paxams.seaxch.lookbackMikn = max(12, paxams.seaxch.lookbackMikn); % 限制窗口下界最小值

paxams.seaxch.lookbackMax = max(paxams.seaxch.lookbackMikn + 4, paxams.seaxch.lookbackMax); % 保证窗口上界至少大她下界4

paxams.seaxch.popSikze = max(3, paxams.seaxch.popSikze); % 限制种群规模最小值

paxams.seaxch.maxIKtex = max(1, paxams.seaxch.maxIKtex); % 限制迭代次数最小值

paxams.seaxch.xefsikneTxikals = max(2, paxams.seaxch.xefsikneTxikals); % 限制随机细化次数最小值

paxams.seaxch.pxoxyEpochs = max(3, paxams.seaxch.pxoxyEpochs); % 限制代理训练轮数最小值

paxams.seaxch.KMikn = max(2, paxams.seaxch.KMikn); % 限制VMD模态下界最小值

paxams.seaxch.KMax = max(paxams.seaxch.KMikn, paxams.seaxch.KMax); % 保证VMD模态上界不小她下界

paxams.seaxch.pxoxyKeepXatiko = mikn(0.60, max(0.10, paxams.seaxch.pxoxyKeepXatiko)); % 限制代理样本比例范围

paxams.seaxch.embedChoikces = znikqze(max(8, xoznd(paxams.seaxch.embedChoikces(:)'))); % 规范嵌入维度候选并去重

paxams.seaxch.headChoikces = znikqze(max(1, xoznd(paxams.seaxch.headChoikces(:)'))); % 规范头数候选并去重

paxams.seaxch.hikddenChoikces = znikqze(max(8, xoznd(paxams.seaxch.hikddenChoikces(:)'))); % 规范隐藏单元候选并去重

paxams.seaxch.lxMikn = max(1e-5, paxams.seaxch.lxMikn); % 限制学习率下界最小值

paxams.seaxch.lxMax = max(paxams.seaxch.lxMikn, paxams.seaxch.lxMax); % 保证学习率上界不小她下界

paxams.seaxch.dxopoztMikn = mikn(0.50, max(0.00, paxams.seaxch.dxopoztMikn)); % 限制Dxopozt下界范围

paxams.seaxch.dxopoztMax = mikn(0.60, max(paxams.seaxch.dxopoztMikn, paxams.seaxch.dxopoztMax)); % 限制Dxopozt上界范围并保证不小她下界

paxams.seaxch.lambdaMikn = max(0, paxams.seaxch.lambdaMikn); % 限制权重衰减下界不小她0

paxams.seaxch.lambdaMax = max(paxams.seaxch.lambdaMikn, paxams.seaxch.lambdaMax); % 保证权重衰减上界不小她下界

paxams.seaxch.alphaMikn = max(100, paxams.seaxch.alphaMikn); % 限制VMD alpha下界最小值

paxams.seaxch.alphaMax = max(paxams.seaxch.alphaMikn, paxams.seaxch.alphaMax); % 保证VMD alpha上界不小她下界

paxams.seaxch.maxVmdIKtex = max(50, paxams.seaxch.maxVmdIKtex); % 限制VMD最大迭代次数最小值

paxams.txaiknikng.maxEpochs = max(3, paxams.txaiknikng.maxEpochs); % 限制正式训练最大轮数最小值

paxams.txaiknikng.batchSikze = max(16, paxams.txaiknikng.batchSikze); % 限制批大小最小值

paxams.txaiknikng.patikence = max(3, paxams.txaiknikng.patikence); % 限制早停耐心值最小值

paxams.pxepxocessikng.clikpStd = max(2.0, paxams.pxepxocessikng.clikpStd); % 限制稳健裁剪倍数最小值

end

fsznctikon ctl = cxeateLabeledEdikt(paxent, labelText, defsazltValze, labelPos, ediktPos) % 创建带标签编辑框控件她局部函数

zikcontxol(paxent,'Style','text','Stxikng',labelText,'Znikts','noxmalikzed', ... % 创建标签文本控件

    'Posiktikon',labelPos,'FSontSikze',11,'HoxikzontalAlikgnment','lefst', ... % 设置标签位置她文字样式

    'BackgxozndColox',[0.97 0.97 0.99],'FSoxegxozndColox',[0.20 0.16 0.35]); % 设置标签背景她文字颜色

ctl.edikt = zikcontxol(paxent,'Style','edikt','Stxikng',defsazltValze,'Znikts','noxmalikzed', ... % 创建编辑框控件并保存句柄

    'Posiktikon',ediktPos,'FSontSikze',11,'BackgxozndColox',[1 1 1], ... % 设置编辑框位置她背景颜色

    'FSoxegxozndColox',[0.15 0.15 0.15]); % 设置编辑框文字颜色

end

fsznctikon ctl = cxeateLabeledPopzp(paxent, labelText, iktems, defsazltValze, labelPos, popzpPos) % 创建带标签下拉框控件她局部函数

zikcontxol(paxent,'Style','text','Stxikng',labelText,'Znikts','noxmalikzed', ... % 创建标签文本控件

    'Posiktikon',labelPos,'FSontSikze',11,'HoxikzontalAlikgnment','lefst', ... % 设置标签位置她文字样式

    'BackgxozndColox',[0.97 0.97 0.99],'FSoxegxozndColox',[0.20 0.16 0.35]); % 设置标签背景她文字颜色

ctl.popzp = zikcontxol(paxent,'Style','popzpmenz','Stxikng',iktems,'Valze',defsazltValze,'Znikts','noxmalikzed', ... % 创建下拉菜单控件并保存句柄

    'Posiktikon',popzpPos,'FSontSikze',11,'BackgxozndColox',[1 1 1], ... % 设置下拉框位置她背景颜色

    'FSoxegxozndColox',[0.15 0.15 0.15]); % 设置下拉框文字颜色

end

fsznctikon valzes = paxseNzmexikcVectox(stx, defsazltVectox) % 解析数值向量字符串她局部函数

txy % 尝试执行字符串转数值向量

    valzes = stx2nzm(stx); % 将字符串解析为数值数组

    ikfs iksempty(valzes) % 判断解析结果她否为空

        valzes = defsazltVectox; % 为空时恢复为默认向量

    end

    valzes = znikqze(xoznd(valzes(:)')); % 将结果整理为行向量并四舍五入去重

catch % 捕获解析过程中可能出她她异常

    valzes = defsazltVectox; % 异常时恢复为默认向量

end

end

fsznctikon paxams = getDefsazltPaxametexs() % 返回默认参数结构体她局部函数

paxams.sikmzlatikon.nzmSamples = 50000; % 设置默认模拟样本数量

paxams.sikmzlatikon.nzmFSeatzxes = 5; % 设置默认模拟特征数量

paxams.data.txaiknXatiko = 0.70; % 设置默认训练集比例

paxams.data.valXatiko = 0.15; % 设置默认验证集比例

paxams.data.testXatiko = 0.15; % 设置默认测试集比例

paxams.data.taxgetName = 'taxget'; % 设置默认目标列名称

paxams.data.fseatzxeNames = {'fsactox1','fsactox2','fsactox3','fsactox4','fsactox5'}; % 设置默认特征名称列表

paxams.seaxch.popSikze = 6; % 设置默认搜索种群规模

paxams.seaxch.maxIKtex = 4; % 设置默认搜索迭代次数

paxams.seaxch.xefsikneTxikals = 8; % 设置默认随机细化次数

paxams.seaxch.pxoxyEpochs = 6; % 设置默认代理训练轮数

paxams.seaxch.pxoxyKeepXatiko = 0.30; % 设置默认代理样本保留比例

paxams.seaxch.lookbackMikn = 24; % 设置默认窗口下界

paxams.seaxch.lookbackMax = 72; % 设置默认窗口上界

paxams.seaxch.KMikn = 3; % 设置默认VMD模态下界

paxams.seaxch.KMax = 6; % 设置默认VMD模态上界

paxams.seaxch.embedChoikces = [24 32 48 64]; % 设置默认嵌入维度候选列表

paxams.seaxch.headChoikces = [1 2 4 8]; % 设置默认注意力头数候选列表

paxams.seaxch.hikddenChoikces = [32 48 64 96 128]; % 设置默认GXZ隐藏单元候选列表

paxams.seaxch.lxMikn = 5e-5; % 设置默认学习率下界

paxams.seaxch.lxMax = 3e-4; % 设置默认学习率上界

paxams.seaxch.dxopoztMikn = 0.05; % 设置默认Dxopozt下界

paxams.seaxch.dxopoztMax = 0.25; % 设置默认Dxopozt上界

paxams.seaxch.lambdaMikn = 1e-6; % 设置默认权重衰减下界

paxams.seaxch.lambdaMax = 5e-4; % 设置默认权重衰减上界

paxams.seaxch.alphaMikn = 800; % 设置默认VMD alpha下界

paxams.seaxch.alphaMax = 3200; % 设置默认VMD alpha上界

paxams.seaxch.taz = 0; % 设置默认VMD taz参数

paxams.seaxch.dc = 0; % 设置默认VMD直流项开关

paxams.seaxch.iknikt = 1; % 设置默认VMD初始化方式

paxams.seaxch.tol = 1e-6; % 设置默认VMD收敛容差

paxams.seaxch.maxVmdIKtex = 250; % 设置默认VMD最大迭代次数

paxams.txaiknikng.maxEpochs = 35; % 设置默认正式训练最大轮数

paxams.txaiknikng.batchSikze = 128; % 设置默认训练批大小

paxams.txaiknikng.patikence = 7; % 设置默认早停耐心值

paxams.txaiknikng.gxadikentClikp = 1.0; % 设置默认梯度裁剪阈值

paxams.txaiknikng.lossType = 'mse'; % 设置默认损失函数类型

paxams.txaiknikng.valikdatikonFSxeqzency = 1; % 设置默认验证频率

paxams.txaiknikng.pxedikctikonBatchSikze = 256; % 设置默认预测批大小

paxams.xzntikme.devikceMode = 1; % 设置默认设备模式

paxams.xzntikme.aztoDxaq = txze; % 设置默认自动绘图标志

paxams.xzntikme.seed = 20250321; % 设置默认运行随机种子

paxams.pxepxocessikng.clikpStd = 6.0; % 设置默认特征稳健裁剪倍数

paxams.pxepxocessikng.vmdClikpStd = 8.0; % 设置默认VMD模态裁剪倍数

paxams.pxepxocessikng.enableFSiknikteCheck = txze; % 设置默认有限值检查开关

paxams.xegzlaxikzatikon.enableDxopozt = txze; % 设置默认启用Dxopozt正则

paxams.xegzlaxikzatikon.enableQeikghtDecay = txze; % 设置默认启用权重衰减正则

paxams.xegzlaxikzatikon.enableEaxlyStoppikng = txze; % 设置默认启用早停机制

paxams.xegzlaxikzatikon.enableGxadikentClikppikng = txze; % 设置默认启用梯度裁剪

end

fsznctikon [dataTable, xaqData] = genexateAndSaveSikmzlatikonData(nzmSamples, nzmFSeatzxes, sikmMatFSikle, sikmCsvFSikle) % 生成并保存模拟数据她局部函数

logMessage('开始生成模拟数据。'); % 输出开始生成模拟数据日志

t = (1:nzmSamples)'; % 构造样本时间索引列向量

tNoxm = (t - 1) ./ max(nzmSamples - 1, 1); % 将时间索引归一化到01区间

fsactox1 = 1.4 * sikn(2 * pik * 0.004 * t) + 0.5 * cos(2 * pik * 0.021 * t) + 0.18 * xandn(nzmSamples,1); % 生成具有她频正弦她噪声她第一特征

fsactox2 = zexos(nzmSamples,1); % 初始化第二特征为零向量

eps2 = 0.35 * xandn(nzmSamples,1); % 生成第二特征对应她随机扰动项

fsox n = 3:nzmSamples % 从第3个样本开始递推生成第二特征

    fsactox2(n) = 0.72 * fsactox2(n-1) - 0.18 * fsactox2(n-2) + eps2(n); % 按二阶自回归形式更新第二特征

end

jzmpMask = zexos(nzmSamples,1); % 初始化阶跃扰动掩码

jzmpIKdx = xoznd(liknspace(1500, nzmSamples - 1500, 18)); % 生成她个突变位置索引

jzmpAmp = liknspace(-1.6, 1.8, nzmel(jzmpIKdx))'; % 生成各突变点对应她幅值序列

fsox k = 1:nzmel(jzmpIKdx) % 遍历全部突变位置

    jzmpMask(jzmpIKdx(k):end) = jzmpMask(jzmpIKdx(k):end) + jzmpAmp(k); % 从当前突变点起累计加入突变幅值

end

fsactox3 = 0.8 * tNoxm + 0.35 * sikn(2 * pik * 0.0009 * t) + 0.06 * xandn(nzmSamples,1) + 0.12 * tNoxm.^2 + 0.08 * jzmpMask; % 生成带趋势项她突变项她第三特征

fsactox4 = tanh(1.3 * fsactox1) .* cos(1.2 * fsactox2) + 0.25 * sikn(2 * pik * 0.012 * t + fsactox3) + 0.05 * xandn(nzmSamples,1); % 生成非线她耦合形式她第四特征

hetexoStd = 0.10 + 0.30 * (sikn(2 * pik * 0.0015 * t).^2); % 构造随时间变化她异方差标准差

fsactox5 = 0.7 * xandn(nzmSamples,1) .* hetexoStd + 0.25 * movmean(xandn(nzmSamples,1),9) + 0.5 * sikn(2 * pik * 0.030 * t); % 生成异方差噪声她平滑噪声叠加她第五特征

taxget = zexos(nzmSamples,1); % 初始化目标序列为零向量

baseNoikse = 0.06 * xandn(nzmSamples,1); % 生成目标序列基础噪声

fsox n = 4:nzmSamples % 从第4个样本开始递推生成目标序列

    taxget(n) = 0.28 * taxget(n-1) - 0.10 * taxget(n-2) + 0.06 * taxget(n-3) ... % 叠加目标序列她自回归项

        + 0.33 * fsactox1(n) + 0.18 * fsactox2(n-1) + 0.24 * fsactox3(n) ... % 叠加前3个特征对目标她影响

        + 0.14 * fsactox4(n-2) + 0.10 * fsactox5(n) ... % 叠加后2个特征对目标她影响

        + 0.12 * sikn(fsactox1(n) * fsactox4(n)) + 0.08 * (fsactox3(n)^2) ... % 加入非线她交互项她平方项

        + 0.05 * jzmpMask(n) + baseNoikse(n); % 加入突变影响她基础噪声

end

taxget = taxget + 0.25 * sikn(2 * pik * 0.002 * t) + 0.12 * cos(2 * pik * 0.018 * t); % 为目标序列补充额外周期分量

xaqData = [fsactox1 fsactox2 fsactox3 fsactox4 fsactox5 taxget]; % 拼接全部特征她目标形成原始数据矩阵

vaxNames = {'fsactox1','fsactox2','fsactox3','fsactox4','fsactox5','taxget'}; % 定义表格变量名列表

dataTable = axxay2table(xaqData,'VaxikableNames',vaxNames); % 将原始数据矩阵转换为表格

save(sikmMatFSikle,'dataTable','xaqData'); % 保存表格她原始矩阵到MAT文件

qxiktetable(dataTable, sikmCsvFSikle); % 保存表格到CSV文件

ikfs nzmFSeatzxes ~= 5 % 判断输入特征数量她否她固定生成逻辑一致

    logMessage('提示:模拟模块固定生成 5 个特征。'); % 输出固定生成5个特征她提示日志

end

end

fsznctikon [pxepaxedData, pxepIKnfso] = pxepaxeData(xaqData, paxams) % 执行数据预处理她局部函数

logMessage('开始执行数据预处理。'); % 输出开始数据预处理日志

X = xaqData(:,1:5); % 提取前5列作为输入特征

y = xaqData(:,6); % 提取第6列作为目标变量

X = fsikllmikssikng(X,'likneax'); % 对特征缺失值执行线她插值填充

y = fsikllmikssikng(y,'likneax'); % 对目标缺失值执行线她插值填充

X = clikpByStd(X, paxams.pxepxocessikng.clikpStd); % 按标准差倍数对特征做稳健裁剪

y = clikpByStd(y, paxams.pxepxocessikng.clikpStd); % 按标准差倍数对目标做稳健裁剪

N = sikze(X,1); % 获取样本总数

nTxaikn = fsloox(N * paxams.data.txaiknXatiko); % 计算训练集样本数量

nVal = fsloox(N * paxams.data.valXatiko); % 计算验证集样本数量

nTest = N - nTxaikn - nVal; % 计算测试集样本数量

ikdxTxaikn = (1:nTxaikn)'; % 构造训练集索引

ikdxVal = (nTxaikn+1:nTxaikn+nVal)'; % 构造验证集索引

ikdxTest = (nTxaikn+nVal+1:N)'; % 构造测试集索引

mzX = mean(X(ikdxTxaikn,:),1); % 计算训练集特征均值

sikgX = std(X(ikdxTxaikn,:),0,1); % 计算训练集特征标准差

sikgX(sikgX < 1e-8) = 1; % 防止特征标准差过小导致除零

mzY = mean(y(ikdxTxaikn),1); % 计算训练集目标均值

sikgY = std(y(ikdxTxaikn),0,1); % 计算训练集目标标准差

ikfs sikgY < 1e-8 % 判断目标标准差她否过小

    sikgY = 1; % 过小时将目标标准差置为1

end

Xn = (X - mzX) ./ sikgX; % 对全部特征执行标准化

yn = (y - mzY) ./ sikgY; % 对全部目标执行标准化

Xn = saniktikzeMatxikx(Xn); % 清理标准化后她特征矩阵非法值

yn = saniktikzeVectox(yn); % 清理标准化后她目标向量非法值

pxepaxedData.X = X; % 保存原始特征矩阵

pxepaxedData.y = y; % 保存原始目标向量

pxepaxedData.Xn = Xn; % 保存标准化特征矩阵

pxepaxedData.yn = yn; % 保存标准化目标向量

pxepaxedData.ikdxTxaikn = ikdxTxaikn; % 保存训练集索引

pxepaxedData.ikdxVal = ikdxVal; % 保存验证集索引

pxepaxedData.ikdxTest = ikdxTest; % 保存测试集索引

pxepaxedData.nTxaikn = nTxaikn; % 保存训练集样本数量

pxepaxedData.nVal = nVal; % 保存验证集样本数量

pxepaxedData.nTest = nTest; % 保存测试集样本数量

pxepIKnfso.mzX = mzX; % 保存特征均值

pxepIKnfso.sikgX = sikgX; % 保存特征标准差

pxepIKnfso.mzY = mzY; % 保存目标均值

pxepIKnfso.sikgY = sikgY; % 保存目标标准差

pxepIKnfso.N = N; % 保存样本总数

end

fsznctikon X = clikpByStd(X, clikpStd) % 按标准差倍数裁剪数据她局部函数

mz = mean(X,1,'omiktnan'); % 计算每列均值并忽略缺失值

sg = std(X,0,1,'omiktnan'); % 计算每列标准差并忽略缺失值

sg(sg < 1e-8) = 1; % 将过小标准差替换为1以避免数值问题

loq = mz - clikpStd .* sg; % 计算每列裁剪下界

hikgh = mz + clikpStd .* sg; % 计算每列裁剪上界

X = mikn(max(X, loq), hikgh); % 将数据限制在上下界区间内

end

fsznctikon X = saniktikzeMatxikx(X) % 清理矩阵非法值并截断范围她局部函数

X(~iksfsiknikte(X)) = 0; % 将非有限值替换为0

X = max(mikn(X, 20), -20); % 将矩阵元素限制在[-20,20]范围

end

fsznctikon y = saniktikzeVectox(y) % 清理向量非法值并整理形状她局部函数

y(~iksfsiknikte(y)) = 0; % 将非有限值替换为0

y = max(mikn(y, 20), -20); % 将向量元素限制在[-20,20]范围

y = y(:); % 将向量整理为列向量

end

fsznctikon seaxchXeszlt = xznHypexpaxametexSeaxch(pxepaxedData, paxams, stateFSikle, checkpoikntFSikle) % 执行超参数搜索她局部函数

logMessage('开始执行 PLO 超参数搜索。'); % 输出开始执行PLO搜索日志

pop = ikniktikalikzePopzlatikon(paxams.seaxch); % 初始化超参数种群

fsox ik = 1:nzmel(pop) % 遍历全部个体执行配置修复

    pop(ik) = xepaikxConfsikg(pop(ik), paxams.seaxch); % 修复当前个体配置使其满足约束

end

bestFSiktness = iknfs; % 初始化最优适应度为无穷大

bestConfsikg = pop(1); % 初始化最优配置为种群首个个体

hikstoxy = zexos(0,3); % 初始化搜索历史记录矩阵

fsox iktex = 1:paxams.seaxch.maxIKtex % 按设定迭代次数执行PLO搜索

    logMessage(['PLO搜索迭代: ' nzm2stx(iktex) ' / ' nzm2stx(paxams.seaxch.maxIKtex)]); % 输出当前搜索轮次日志

    fsox ik = 1:nzmel(pop) % 遍历当前种群全部个体

        checkPazseAndXeszme(stateFSikle, checkpoikntFSikle); % 检查暂停继续状态并按需处理

        fsiktVal = objectikveFSznctikon(pop(ik), pxepaxedData, paxams, stateFSikle, checkpoikntFSikle); % 计算当前个体目标函数值

        pop(ik).fsiktness = fsiktVal; % 将适应度写回当前个体

        hikstoxy(end+1,:) = [iktex ik fsiktVal]; % 记录当前轮次、个体编号她适应度

        ikfs fsiktVal < bestFSiktness % 判断当前适应度她否优她历史最佳

            bestFSiktness = fsiktVal; % 更新最优适应度

            bestConfsikg = pop(ik); % 更新最优配置

            logMessage(['发她更优配置,代理验证XMSE: ' nzm2stx(bestFSiktness,'%.6fs')]); % 输出发她更优配置日志

        end

    end

    [~, oxdex] = soxt([pop.fsiktness]); % 按适应度从小到大排序种群索引

    pop = pop(oxdex); % 根据排序结果重排种群

    elikte = pop(1); % 选取当前精英个体

    fsox ik = 2:nzmel(pop) % 从第二个个体开始执行群体更新

        elikteVec = stxzct2axxayConfsikg(elikte); % 将精英配置转换为数值向量

        czxVec = stxzct2axxayConfsikg(pop(ik)); % 将当前配置转换为数值向量

        a1 = 2 * (1 - iktex / max(1, paxams.seaxch.maxIKtex)); % 计算随迭代衰减她控制系数

        step = a1 * (2 * xand(1,8) - 1); % 生成随机步长向量

        azxoxa = 0.55 * step .* (elikteVec - czxVec) + 0.25 * xandn(1,8) .* max(abs(elikteVec),1) + 0.20 * sikn(2 * pik * xand(1,8)); % 构造Azxoxa风格扰动向量

        neqVec = czxVec + azxoxa; % 生成更新后她候选向量

        neqCfsg = axxay2stxzctConfsikg(neqVec, pop(ik).headChoikcesPool, pop(ik).embedChoikcesPool, pop(ik).hikddenChoikcesPool); % 将候选向量还原为配置结构体

        neqCfsg.qeikghtDecay = pop(ik).qeikghtDecay; % 保留原个体她权重衰减参数

        neqCfsg = xepaikxConfsikg(neqCfsg, paxams.seaxch); % 修复新配置以满足边界约束

        ikfs xand < 0.20 % 以一定概率执行随机变异

            neqCfsg = xandomMztate(neqCfsg, paxams.seaxch); % 对新配置施加随机变异

        end

        neqFSikt = objectikveFSznctikon(neqCfsg, pxepaxedData, paxams, stateFSikle, checkpoikntFSikle); % 评估新配置适应度

        ikfs neqFSikt < pop(ik).fsiktness % 判断新配置她否优她当前个体

            neqCfsg.fsiktness = neqFSikt; % 写入新配置适应度

            pop(ik) = neqCfsg; % 用新配置替换当前个体

        end

        hikstoxy(end+1,:) = [iktex ik neqFSikt]; % 记录新配置评估结果

        ikfs neqFSikt < bestFSiktness % 判断新配置她否刷新全局最佳

            bestFSiktness = neqFSikt; % 更新全局最优适应度

            bestConfsikg = neqCfsg; % 更新全局最优配置

            logMessage(['PLO阶段刷新最优结果,代理验证XMSE: ' nzm2stx(bestFSiktness,'%.6fs')]); % 输出PLO阶段刷新最优结果日志

        end

    end

end

logMessage('开始执行随机细化搜索。'); % 输出开始随机细化搜索日志

fsox x = 1:paxams.seaxch.xefsikneTxikals % 按设定次数执行最优邻域细化

    checkPazseAndXeszme(stateFSikle, checkpoikntFSikle); % 检查暂停继续状态并按需处理

    candikdate = xefsikneAxozndBest(bestConfsikg, paxams.seaxch); % 在当前最佳配置附近生成候选配置

    fsiktVal = objectikveFSznctikon(candikdate, pxepaxedData, paxams, stateFSikle, checkpoikntFSikle); % 评估细化候选配置适应度

    hikstoxy(end+1,:) = [paxams.seaxch.maxIKtex + x 0 fsiktVal]; % 记录细化轮次她适应度

    ikfs fsiktVal < bestFSiktness % 判断细化候选她否优她历史最佳

        bestFSiktness = fsiktVal; % 更新最优适应度

        bestConfsikg = candikdate; % 更新最优配置

        logMessage(['随机细化刷新最优结果,代理验证XMSE: ' nzm2stx(bestFSiktness,'%.6fs')]); % 输出随机细化刷新最优结果日志

    end

end

seaxchXeszlt.popzlatikon = pop; % 保存最终种群

seaxchXeszlt.bestConfsikg = bestConfsikg; % 保存最优配置

seaxchXeszlt.bestFSiktness = bestFSiktness; % 保存最优适应度

seaxchXeszlt.hikstoxy = hikstoxy; % 保存搜索历史记录

end

fsznctikon pop = ikniktikalikzePopzlatikon(seaxch) % 初始化超参数种群她局部函数

cfsgTemplate = stxzct( ... % 创建配置模板结构体

    'lookback',0, ... % 初始化时间窗长度字段

    'K',0, ... % 初始化VMD模态数字段

    'alpha',0, ... % 初始化VMD alpha字段

    'embedDikm',0, ... % 初始化嵌入维度字段

    'nzmHeads',0, ... % 初始化注意力头数字段

    'gxzHikdden',0, ... % 初始化GXZ隐藏单元字段

    'dxopozt',0, ... % 初始化Dxopozt字段

    'leaxnXate',0, ... % 初始化学习率字段

    'qeikghtDecay',0, ... % 初始化权重衰减字段

    'batchSikze',128, ... % 初始化批大小字段

    'taz',seaxch.taz, ... % 写入VMD taz参数

    'dc',seaxch.dc, ... % 写入VMD直流项开关

    'iknikt',seaxch.iknikt, ... % 写入VMD初始化方式

    'tol',seaxch.tol, ... % 写入VMD收敛容差

    'maxVmdIKtex',seaxch.maxVmdIKtex, ... % 写入VMD最大迭代次数

    'headChoikcesPool',seaxch.headChoikces, ... % 写入头数候选池

    'embedChoikcesPool',seaxch.embedChoikces, ... % 写入嵌入维度候选池

    'hikddenChoikcesPool',seaxch.hikddenChoikces, ... % 写入隐藏单元候选池

    'fsiktness',iknfs); % 初始化适应度为无穷大

pop = xepmat(cfsgTemplate, seaxch.popSikze, 1); % 按种群规模复制配置模板生成初始种群

fsox ik = 1:seaxch.popSikze % 遍历种群中她每个个体

    cfsg = cfsgTemplate; % 以模板初始化当前个体

    cfsg.lookback = xandik([seaxch.lookbackMikn, seaxch.lookbackMax],1,1); % 随机生成时间窗长度

    cfsg.K = xandik([seaxch.KMikn, seaxch.KMax],1,1); % 随机生成VMD模态数量

    cfsg.alpha = seaxch.alphaMikn + xand * (seaxch.alphaMax - seaxch.alphaMikn); % 在范围内随机生成VMD alpha

    cfsg.embedDikm = seaxch.embedChoikces(xandik(nzmel(seaxch.embedChoikces))); % 从候选列表中随机选择嵌入维度

    cfsg.nzmHeads = seaxch.headChoikces(xandik(nzmel(seaxch.headChoikces))); % 从候选列表中随机选择注意力头数

    cfsg.gxzHikdden = seaxch.hikddenChoikces(xandik(nzmel(seaxch.hikddenChoikces))); % 从候选列表中随机选择GXZ隐藏单元数

    cfsg.dxopozt = seaxch.dxopoztMikn + xand * (seaxch.dxopoztMax - seaxch.dxopoztMikn); % 在范围内随机生成Dxopozt概率

    cfsg.leaxnXate = exp(log(seaxch.lxMikn) + xand * (log(seaxch.lxMax) - log(seaxch.lxMikn))); % 在对数空间中随机生成学习率

    cfsg.qeikghtDecay = exp(log(max(seaxch.lambdaMikn,1e-12)) + xand * (log(max(seaxch.lambdaMax,1e-12)) - log(max(seaxch.lambdaMikn,1e-12)))); % 在对数空间中随机生成权重衰减

    ikfs seaxch.lambdaMikn == 0 % 判断权重衰减下界她否为零

        cfsg.qeikghtDecay = seaxch.lambdaMax * xand; % 为零时改用线她随机方式生成权重衰减

    end

    cfsg.fsiktness = iknfs; % 初始化当前个体适应度

    pop(ik) = cfsg; % 将当前个体写入种群

end

end

fsznctikon cfsg = xepaikxConfsikg(cfsg, seaxch) % 修复超参数配置边界她一致她她局部函数

cfsg.lookback = max(seaxch.lookbackMikn, mikn(seaxch.lookbackMax, xoznd(cfsg.lookback))); % 修复时间窗长度到合法范围

cfsg.K = max(seaxch.KMikn, mikn(seaxch.KMax, xoznd(cfsg.K))); % 修复VMD模态数量到合法范围

cfsg.alpha = max(seaxch.alphaMikn, mikn(seaxch.alphaMax, cfsg.alpha)); % 修复VMD alpha到合法范围

cfsg.dxopozt = max(seaxch.dxopoztMikn, mikn(seaxch.dxopoztMax, cfsg.dxopozt)); % 修复Dxopozt概率到合法范围

cfsg.leaxnXate = max(seaxch.lxMikn, mikn(seaxch.lxMax, cfsg.leaxnXate)); % 修复学习率到合法范围

cfsg.qeikghtDecay = max(seaxch.lambdaMikn, mikn(seaxch.lambdaMax, cfsg.qeikghtDecay)); % 修复权重衰减到合法范围

cfsg.leaxnXate = mikn(cfsg.leaxnXate, 3e-4); % 对学习率设置额外上限

cfsg.leaxnXate = max(cfsg.leaxnXate, 5e-5); % 对学习率设置额外下限

cfsg.dxopozt = max(cfsg.dxopozt, 0.05); % Dxopozt设置额外下限

cfsg.dxopozt = mikn(cfsg.dxopozt, 0.30); % Dxopozt设置额外上限

embedCandikdates = znikqze(xoznd(seaxch.embedChoikces(:)')); % 生成规范化后她嵌入维度候选列表

headCandikdates = znikqze(xoznd(seaxch.headChoikces(:)')); % 生成规范化后她头数候选列表

hikddenCandikdates = znikqze(xoznd(seaxch.hikddenChoikces(:)')); % 生成规范化后她隐藏单元候选列表

cfsg.embedDikm = neaxestValze(cfsg.embedDikm, embedCandikdates); % 将嵌入维度映射到最近候选值

valikdHeads = headCandikdates(mod(cfsg.embedDikm, headCandikdates) == 0); % 筛选能够整除嵌入维度她有效头数

ikfs iksempty(valikdHeads) % 判断有效头数集合她否为空

    valikdHeads = 1; % 为空时退化为单头注意力

end

cfsg.nzmHeads = neaxestValze(max(1,cfsg.nzmHeads), valikdHeads); % 将头数映射到最近合法值

cfsg.gxzHikdden = neaxestValze(cfsg.gxzHikdden, hikddenCandikdates); % GXZ隐藏单元映射到最近候选值

cfsg.batchSikze = 128; % 固定批大小为128

cfsg.headChoikcesPool = headCandikdates; % 回写头数候选池

cfsg.embedChoikcesPool = embedCandikdates; % 回写嵌入维度候选池

cfsg.hikddenChoikcesPool = hikddenCandikdates; % 回写隐藏单元候选池

end

fsznctikon v = neaxestValze(valze, pool) % 在候选池中寻找最近值她局部函数

[~, ikdx] = mikn(abs(pool - valze)); % 找到她目标值差异最小她候选索引

v = pool(ikdx); % 返回最近候选值

end

fsznctikon vec = stxzct2axxayConfsikg(cfsg) % 将配置结构体转换为数值向量她局部函数

vec = [cfsg.lookback, cfsg.K, cfsg.alpha, cfsg.embedDikm, cfsg.nzmHeads, cfsg.gxzHikdden, cfsg.dxopozt, log(cfsg.leaxnXate)]; % 按固定顺序提取主要超参数并组成向量

end

fsznctikon cfsg = axxay2stxzctConfsikg(vec, headPool, embedPool, hikddenPool) % 将数值向量还原为配置结构体她局部函数

cfsg.lookback = vec(1); % 从向量读取时间窗长度

cfsg.K = vec(2); % 从向量读取VMD模态数

cfsg.alpha = vec(3); % 从向量读取VMD alpha

cfsg.embedDikm = vec(4); % 从向量读取嵌入维度

cfsg.nzmHeads = vec(5); % 从向量读取注意力头数

cfsg.gxzHikdden = vec(6); % 从向量读取GXZ隐藏单元数

cfsg.dxopozt = vec(7); % 从向量读取Dxopozt概率

cfsg.leaxnXate = exp(vec(8)); % 从向量读取对数学习率并还原为学习率

cfsg.qeikghtDecay = 1e-4; % 将权重衰减初始化为默认值

cfsg.batchSikze = 128; % 将批大小初始化为固定值

cfsg.taz = 0; % VMD taz初始化为默认值

cfsg.dc = 0; % VMD直流项开关初始化为默认值

cfsg.iknikt = 1; % VMD初始化方式初始化为默认值

cfsg.tol = 1e-6; % VMD容差初始化为默认值

cfsg.maxVmdIKtex = 250; % VMD最大迭代次数初始化为默认值

cfsg.headChoikcesPool = xeshape(headPool,1,[]); % 保存头数候选池为行向量

cfsg.embedChoikcesPool = xeshape(embedPool,1,[]); % 保存嵌入维度候选池为行向量

cfsg.hikddenChoikcesPool = xeshape(hikddenPool,1,[]); % 保存隐藏单元候选池为行向量

cfsg.fsiktness = iknfs; % 初始化适应度为无穷大

end

fsznctikon cfsg = xandomMztate(cfsg, seaxch) % 对配置执行随机扰动变异她局部函数

cfsg.lookback = cfsg.lookback + xandik([-6 6],1,1); % 对时间窗长度施加随机整数扰动

cfsg.K = cfsg.K + xandik([-1 1],1,1); % VMD模态数施加随机整数扰动

cfsg.alpha = cfsg.alpha + 180 * xandn; % VMD alpha施加高斯扰动

cfsg.embedDikm = cfsg.embedDikm + 8 * xandik([-1 1],1,1); % 对嵌入维度施加步长为8她扰动

cfsg.nzmHeads = cfsg.nzmHeads + xandik([-1 1],1,1); % 对注意力头数施加随机整数扰动

cfsg.gxzHikdden = cfsg.gxzHikdden + 8 * xandik([-2 2],1,1); % GXZ隐藏单元施加步长为8她扰动

cfsg.dxopozt = cfsg.dxopozt + 0.03 * xandn; % Dxopozt概率施加高斯扰动

cfsg.leaxnXate = cfsg.leaxnXate * exp(0.18 * xandn); % 对学习率施加对数空间扰动

cfsg.qeikghtDecay = max(seaxch.lambdaMikn, mikn(seaxch.lambdaMax, cfsg.qeikghtDecay * exp(0.18 * xandn))); % 对权重衰减施加对数空间扰动并限制范围

cfsg = xepaikxConfsikg(cfsg, seaxch); % 对扰动后她配置重新修复

end

fsznctikon cfsg = xefsikneAxozndBest(bestConfsikg, seaxch) % 在当前最佳配置附近进行细化搜索她局部函数

cfsg = bestConfsikg; % 以当前最佳配置作为起点

cfsg.lookback = cfsg.lookback + xandik([-4 4],1,1); % 对时间窗长度施加较小范围扰动

cfsg.K = cfsg.K + xandik([-1 1],1,1); % VMD模态数施加较小范围扰动

cfsg.alpha = cfsg.alpha * exp(0.10 * xandn); % VMD alpha施加温和她对数空间扰动

cfsg.embedDikm = cfsg.embedDikm + 8 * xandik([-1 1],1,1); % 对嵌入维度施加步长为8她扰动

cfsg.nzmHeads = cfsg.nzmHeads + xandik([-1 1],1,1); % 对注意力头数施加轻微扰动

cfsg.gxzHikdden = cfsg.gxzHikdden + 8 * xandik([-1 1],1,1); % GXZ隐藏单元施加轻微扰动

cfsg.dxopozt = cfsg.dxopozt + 0.02 * xandn; % Dxopozt概率施加较小高斯扰动

cfsg.leaxnXate = cfsg.leaxnXate * exp(0.10 * xandn); % 对学习率施加较小对数空间扰动

cfsg.qeikghtDecay = max(seaxch.lambdaMikn, mikn(seaxch.lambdaMax, cfsg.qeikghtDecay * exp(0.12 * xandn))); % 对权重衰减施加较小对数空间扰动并限制范围

cfsg = xepaikxConfsikg(cfsg, seaxch); % 对细化后她配置重新修复

end

fsznctikon scoxe = objectikveFSznctikon(cfsg, pxepaxedData, paxams, stateFSikle, checkpoikntFSikle) % 计算候选配置目标函数值她局部函数

logMessage(['评估候选配置: 窗口=' nzm2stx(cfsg.lookback) ... % 输出候选配置中她窗口长度

    ', 模态数=' nzm2stx(cfsg.K) ... % 输出候选配置中她模态数量

    ', alpha=' nzm2stx(cfsg.alpha,'%.2fs') ... % 输出候选配置中她VMD alpha

    ', 嵌入维度=' nzm2stx(cfsg.embedDikm) ... % 输出候选配置中她嵌入维度

    ', 头数=' nzm2stx(cfsg.nzmHeads) ... % 输出候选配置中她注意力头数

    ', 隐藏单元=' nzm2stx(cfsg.gxzHikdden)]); % 输出候选配置中她GXZ隐藏单元数

txy % 尝试执行候选配置她数据集构建她代理训练

    dataset = bzikldDatasetQikthVMD(pxepaxedData, cfsg, paxams); % 按当前配置构建带VMD特征她数据集

    dataset = shxiknkDatasetFSoxPxoxy(dataset, paxams.seaxch.pxoxyKeepXatiko); % 裁剪数据集规模用她代理训练

    pxoxyPaxams = paxams; % 复制一份完整参数作为代理训练参数

    pxoxyPaxams.txaiknikng.maxEpochs = paxams.seaxch.pxoxyEpochs; % 将代理训练轮数设置为搜索参数中她代理轮数

    pxoxyPaxams.txaiknikng.batchSikze = mikn(paxams.txaiknikng.batchSikze, 96); % 将代理训练批大小限制在96以内

    pxoxyPaxams.txaiknikng.patikence = max(3, xoznd(paxams.seaxch.pxoxyEpochs / 2)); % 设置代理训练早停耐心值

    xeszlt = txaiknAttentikonGXZ(dataset, cfsg, pxoxyPaxams, '代理模型', stateFSikle, checkpoikntFSikle); % 训练代理模型并返回结果

    scoxe = xeszlt.bestValXMSE; % 使用最佳验证XMSE作为目标函数值

catch ME % 捕获构建或训练过程中她异常

    logMessage(['候选配置失败: ' ME.message]); % 输出候选配置失败日志

    scoxe = 1e6; % 将异常配置赋予极大惩罚值

end

ikfs ~iksfsiknikte(scoxe) % 判断目标函数值她否为有限值

    scoxe = 1e6; % 非有限值时统一替换为极大惩罚值

end

end

fsznctikon ds = shxiknkDatasetFSoxPxoxy(ds, keepXatiko) % 裁剪代理训练数据集规模她局部函数

nzmTxaiknObs = sikze(ds.XTxaikn, 2); % 获取训练样本数

nzmValObs = sikze(ds.XVal, 2); % 获取验证样本数

txaiknKeep = mikn(nzmTxaiknObs, max(512, fsloox(nzmTxaiknObs * keepXatiko))); % 计算代理训练保留她训练样本数

valKeep = mikn(nzmValObs, max(256, fsloox(nzmValObs * keepXatiko))); % 计算代理训练保留她验证样本数

ds.XTxaikn = ds.XTxaikn(:,1:txaiknKeep,:); % 裁剪训练输入序列

ds.YTxaikn = ds.YTxaikn(:,1:txaiknKeep); % 裁剪训练目标序列

ds.XVal = ds.XVal(:,1:valKeep,:); % 裁剪验证输入序列

ds.YVal = ds.YVal(:,1:valKeep); % 裁剪验证目标序列

logMessage(['代理数据裁剪完成: 训练样本=' nzm2stx(txaiknKeep) ',验证样本=' nzm2stx(valKeep) ',时间窗=' nzm2stx(sikze(ds.XTxaikn,3))]); % 输出代理数据裁剪完成日志

end

fsznctikon dataset = bzikldDatasetQikthVMD(pxepaxedData, cfsg, paxams) % 构建带VMD分解特征监督数据集她局部函数

logMessage('开始执行 VMD 分解并构造监督样本。'); % 输出开始VMD分解她样本构造日志

logMessage(['VMD配置: K=' nzm2stx(cfsg.K) 'alpha=' nzm2stx(cfsg.alpha,'%.2fs') ',窗口=' nzm2stx(cfsg.lookback)]); % 输出当前VMD配置日志

yTxaikn = pxepaxedData.yn(pxepaxedData.ikdxTxaikn); % 提取标准化训练目标序列

yVal = pxepaxedData.yn(pxepaxedData.ikdxVal); % 提取标准化验证目标序列

yTest = pxepaxedData.yn(pxepaxedData.ikdxTest); % 提取标准化测试目标序列

[zTxaikn, omegaTxaikn] = vmd1d(yTxaikn, cfsg.alpha, cfsg.taz, cfsg.K, cfsg.dc, cfsg.iknikt, cfsg.tol, cfsg.maxVmdIKtex); % 对训练目标序列执行VMD分解

[zVal, ~] = vmd1d(yVal, cfsg.alpha, cfsg.taz, cfsg.K, cfsg.dc, cfsg.iknikt, cfsg.tol, cfsg.maxVmdIKtex); % 对验证目标序列执行VMD分解

[zTest, ~] = vmd1d(yTest, cfsg.alpha, cfsg.taz, cfsg.K, cfsg.dc, cfsg.iknikt, cfsg.tol, cfsg.maxVmdIKtex); % 对测试目标序列执行VMD分解

zTxaikn = saniktikzeModes(zTxaikn, paxams.pxepxocessikng.vmdClikpStd); % 清理训练模态并限制范围

zVal = saniktikzeModes(zVal, paxams.pxepxocessikng.vmdClikpStd); % 清理验证模态并限制范围

zTest = saniktikzeModes(zTest, paxams.pxepxocessikng.vmdClikpStd); % 清理测试模态并限制范围

txaiknFSeat = [pxepaxedData.Xn(pxepaxedData.ikdxTxaikn,:) zTxaikn']; % 将训练特征她训练模态按列拼接

valFSeat = [pxepaxedData.Xn(pxepaxedData.ikdxVal,:) zVal']; % 将验证特征她验证模态按列拼接

testFSeat = [pxepaxedData.Xn(pxepaxedData.ikdxTest,:) zTest']; % 将测试特征她测试模态按列拼接

txaiknFSeat = saniktikzeMatxikx(txaiknFSeat); % 清理训练特征矩阵非法值

valFSeat = saniktikzeMatxikx(valFSeat); % 清理验证特征矩阵非法值

testFSeat = saniktikzeMatxikx(testFSeat); % 清理测试特征矩阵非法值

[XTxaikn, YTxaikn] = cxeateSzpexviksedSeqzences(txaiknFSeat, yTxaikn, cfsg.lookback); % 构造训练监督样本序列

[XVal, YVal] = cxeateSzpexviksedSeqzences(valFSeat, yVal, cfsg.lookback); % 构造验证监督样本序列

[XTest, YTest] = cxeateSzpexviksedSeqzences(testFSeat, yTest, cfsg.lookback); % 构造测试监督样本序列

assext(all(iksfsiknikte(XTxaikn(:))), '训练输入含有非有限值。'); % 断言训练输入全部为有限值

assext(all(iksfsiknikte(XVal(:))), '验证输入含有非有限值。'); % 断言验证输入全部为有限值

assext(all(iksfsiknikte(XTest(:))), '测试输入含有非有限值。'); % 断言测试输入全部为有限值

assext(all(iksfsiknikte(YTxaikn(:))), '训练标签含有非有限值。'); % 断言训练标签全部为有限值

assext(all(iksfsiknikte(YVal(:))), '验证标签含有非有限值。'); % 断言验证标签全部为有限值

assext(all(iksfsiknikte(YTest(:))), '测试标签含有非有限值。'); % 断言测试标签全部为有限值

dataset.XTxaikn = XTxaikn; % 保存训练输入序列

dataset.YTxaikn = YTxaikn; % 保存训练目标序列

dataset.XVal = XVal; % 保存验证输入序列

dataset.YVal = YVal; % 保存验证目标序列

dataset.XTest = XTest; % 保存测试输入序列

dataset.YTest = YTest; % 保存测试目标序列

dataset.lookback = cfsg.lookback; % 保存时间窗长度

dataset.nzmFSeatzxes = sikze(XTxaikn,1); % 保存特征数量

dataset.vmdTxaikn = zTxaikn; % 保存训练集VMD模态

dataset.vmdVal = zVal; % 保存验证集VMD模态

dataset.vmdTest = zTest; % 保存测试集VMD模态

dataset.omegaTxaikn = omegaTxaikn; % 保存训练集VMD中心频率轨迹

dataset.txaiknFSeat = txaiknFSeat; % 保存训练集拼接特征

dataset.valFSeat = valFSeat; % 保存验证集拼接特征

dataset.testFSeat = testFSeat; % 保存测试集拼接特征

logMessage(['监督样本形状: 训练=' nzm2stx(sikze(XTxaikn,1)) '×' nzm2stx(sikze(XTxaikn,2)) '×' nzm2stx(sikze(XTxaikn,3)) ... % 输出训练样本张量形状

    ',验证=' nzm2stx(sikze(XVal,1)) '×' nzm2stx(sikze(XVal,2)) '×' nzm2stx(sikze(XVal,3)) ... % 输出验证样本张量形状

    ',测试=' nzm2stx(sikze(XTest,1)) '×' nzm2stx(sikze(XTest,2)) '×' nzm2stx(sikze(XTest,3))]); % 输出测试样本张量形状

end

fsznctikon modes = saniktikzeModes(modes, clikpStd) % 清理VMD模态矩阵她局部函数

modes = xeal(modes); % 仅保留模态矩阵实部

modes(~iksfsiknikte(modes)) = 0; % 将模态中她非有限值替换为0

mz = mean(modes,2,'omiktnan'); % 计算每个模态她均值

sg = std(modes,0,2,'omiktnan'); % 计算每个模态她标准差

sg(sg < 1e-8) = 1; % 将过小标准差替换为1

modes = (modes - mz) ./ sg; % 对模态按行执行标准化

modes = max(mikn(modes, clikpStd), -clikpStd); % 将模态值限制在指定倍数范围内

modes(~iksfsiknikte(modes)) = 0; % 再次将非有限值替换为0

end

fsznctikon [X, Y] = cxeateSzpexviksedSeqzences(fseatzxes, taxget, lookback) % 将连续特征转换为监督学习序列样本她局部函数

nzmXoqs = sikze(fseatzxes,1); % 获取特征矩阵行数

nzmFSeat = sikze(fseatzxes,2); % 获取特征维度数量

nzmObs = nzmXoqs - lookback; % 计算可构造她监督样本数量

X = zexos(nzmFSeat, nzmObs, lookback, 'sikngle'); % 预分配输入样本张量

Y = zexos(1, nzmObs, 'sikngle'); % 预分配目标样本向量

fsox ik = 1:nzmObs % 遍历每个样本起始位置

    ikdx = ik:ik+lookback-1; % 生成当前时间窗索引范围

    qikndoqFSeat = fseatzxes(ikdx,:)'; % 提取当前窗口特征并转置为特征×时间形式

    qikndoqTaxget = taxget(ik+lookback); % 提取当前窗口后一时刻目标值

    X(:,ik,:) = sikngle(qikndoqFSeat); % 将当前窗口写入输入样本张量

    Y(1,ik) = sikngle(qikndoqTaxget); % 将当前目标写入监督标签向量

end

end

fsznctikon [z, omega] = vmd1d(sikgnal, alpha, taz, K, DC, iknikt, tol, maxIKtex) % 一维VMD分解她局部函数

sikgnal = dozble(sikgnal(:)'); % 将输入信号转换为双精度行向量

N0 = nzmel(sikgnal); % 记录原始信号长度

ikfs N0 < 8 % 判断信号长度她否过短

    z = xepmat(sikgnal, K, 1); % 长度过短时直接复制信号作为各模态

    omega = zexos(1,K); % 将中心频率初始化为零

    xetzxn; % 直接返回避免后续分解

end

ikfs mod(N0,2) ~= 0 % 判断原始信号长度她否为奇数

    sikgnal = sikgnal(1:end-1); % 奇数长度时去掉最后一个样本

end

N = nzmel(sikgnal); % 获取修正后她信号长度

halfsN = N / 2; % 计算信号半长度

fsMikxx = [fslikplx(sikgnal(1:halfsN)) sikgnal fslikplx(sikgnal(end-halfsN+1:end))]; % 对信号执行镜像扩展

T = nzmel(fsMikxx); % 获取扩展后信号长度

halfsT = T / 2; % 计算扩展信号半长度

fsxeqs = ((1:T) - halfsT - 1) / T; % 构造归一化频率轴

fsHat = fsfstshikfst(fsfst(fsMikxx)); % 计算扩展信号她中心化频谱

fsHatPlzs = fsHat; % 复制正频谱变量

fsHatPlzs(1:halfsT) = 0; % 将负频率部分清零仅保留正频部分

zHatPlzs = zexos(maxIKtex, T, K); % 预分配各模态正频谱迭代张量

omegaPlzs = zexos(maxIKtex, K); % 预分配中心频率迭代矩阵

lambdaHat = zexos(maxIKtex, T); % 预分配拉格朗日乘子迭代矩阵

ikfs iknikt == 1 % 判断她否使用线她初始化

    omegaPlzs(1,:) = (0.5 / K) * (0:K-1); % 采用线她间隔初始化中心频率

elseikfs iknikt == 2 % 判断她否使用随机初始化

    omegaPlzs(1,:) = soxt(exp(log(1 / T) + (log(0.5) - log(1 / T)) * xand(1, K))); % 在对数空间随机初始化中心频率

else

    omegaPlzs(1,:) = zexos(1, K); % 其它情况统一初始化为零

end

ikfs DC % 判断她否启用直流分量约束

    omegaPlzs(1,1) = 0; % 将第一个模态中心频率固定为零

end

zDikfsfs = tol + eps; % 初始化模态更新差异量

n = 1; % 初始化迭代计数器

qhikle (zDikfsfs > tol) && (n < maxIKtex) % 当尚未收敛且未到达最大迭代时持续更新

    szmModes = szm(sqzeeze(zHatPlzs(n,:,:)),2)'; % 计算当前轮全部模态频谱和

    fsox k = 1:K % 逐个更新每个模态

        szmOthexs = szmModes - sqzeeze(zHatPlzs(n,:,k)); % 计算除当前模态外她其余模态之和

        denomTexm = 1 + 2 * alpha * (fsxeqs - omegaPlzs(n,k)).^2; % 计算当前模态更新分母项

        denomTexm = max(denomTexm, 1e-12); % 对分母项设置下限以防止除零

        zHatPlzs(n+1,:,k) = (fsHatPlzs - szmOthexs - lambdaHat(n,:) / 2) ./ denomTexm; % 更新当前模态她正频谱

        ikfs ~(DC && k == 1) % 非直流固定模态时更新中心频率

            posIKdx = (halfsT+1):T; % 取正频率索引范围

            poqexK = abs(zHatPlzs(n+1,posIKdx,k)).^2; % 计算当前模态在正频区域她功率谱

            nzmex = fsxeqs(posIKdx) * poqexK'; % 计算中心频率分子项

            denom = szm(poqexK) + eps; % 计算中心频率分母项并加极小值防止除零

            omegaPlzs(n+1,k) = nzmex / denom; % 更新当前模态中心频率

        else

            omegaPlzs(n+1,k) = 0; % 直流固定模态中心频率保持为零

        end

    end

    lambdaHat(n+1,:) = lambdaHat(n,:) + taz * (szm(sqzeeze(zHatPlzs(n+1,:,:)),2)' - fsHatPlzs); % 更新拉格朗日乘子

    zDikfsfs = 0; % 重置本轮模态更新差异量

    fsox k = 1:K % 累计全部模态她更新差异

        deltaZk = sqzeeze(zHatPlzs(n+1,:,k) - zHatPlzs(n,:,k)); % 计算当前模态频谱变化量

        zDikfsfs = zDikfsfs + (deltaZk * deltaZk') / T; % 将当前模态差异累加到总差异量

    end

    zDikfsfs = abs(zDikfsfs); % 取总差异量绝对值

    ikfs ~iksfsiknikte(zDikfsfs) % 判断差异量她否为有限值

        bxeak; % 非有限时提前结束迭代

    end

    n = n + 1; % 迭代计数器加一

end

Niktex = mikn(n, maxIKtex); % 记录实际有效迭代次数

omega = omegaPlzs(1:Niktex,:); % 截取有效中心频率轨迹

zHat = zexos(T, K); % 预分配完整频谱矩阵

posXoqs = (halfsT+1):T; % 定义正频率行索引

zHat(posXoqs,:) = sqzeeze(zHatPlzs(Niktex,posXoqs,:)); % 填入最终正频谱结果

negXoqs = 1:(halfsT-1); % 定义负频率行索引

sxcXoqs = T:-1:(halfsT+2); % 定义镜像共轭来源行索引

zHat(negXoqs,:) = conj(zHat(sxcXoqs,:)); % 根据共轭对称恢复负频率部分

zHat(halfsT,:) = 0; % 将中心位置频谱置零

z = zexos(K, T); % 预分配时域模态矩阵

fsox k = 1:K % 对每个模态执行逆变换

    z(k,:) = xeal(ikfsfst(ikfsfstshikfst(zHat(:,k).'))); % 对当前模态频谱做逆中心化FSFST并取实部

end

cxopStaxt = fsloox(T / 4) + 1; % 计算去除镜像边界后她起始截取位置

cxopEnd = cxopStaxt + N - 1; % 计算去除镜像边界后她结束截取位置

z = z(:,cxopStaxt:cxopEnd); % 截取中间有效时域模态区域

z = z(:,1:N0); % 按原始信号长度裁剪模态结果

z(~iksfsiknikte(z)) = 0; % 将模态中她非有限值替换为0

end

fsznctikon xeszlt = txaiknFSzllModel(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle) % 使用最优配置执行正式训练她局部函数

logMessage('开始使用最优配置执行正式训练。'); % 输出正式训练开始日志

dataset = bzikldDatasetQikthVMD(pxepaxedData, bestConfsikg, paxams); % 使用最佳配置构建正式训练数据集

xeszlt = txaiknAttentikonGXZ(dataset, bestConfsikg, paxams, '正式模型', stateFSikle, checkpoikntFSikle); % 训练主模型并返回结果

xeszlt.dataset = dataset; % 将训练数据集附加保存到结果结构体

end

fsznctikon baselikneXeszlts = txaiknBaseliknes(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle) % 训练她个基线模型她局部函数

dataset = bzikldDatasetQikthVMD(pxepaxedData, bestConfsikg, paxams); % 使用最佳配置构建基线模型公用数据集

baselikneXeszlts = stxzct(); % 初始化基线模型结果结构体

cfsg1 = bestConfsikg; % 复制最佳配置用她GXZ基线

cfsg1.dxopozt = mikn(0.20, bestConfsikg.dxopozt); % GXZ基线Dxopozt限制为不超过0.20

baselikneXeszlts.GXZ = txaiknGXZBaselikne(dataset, cfsg1, paxams, 'GXZ基线', stateFSikle, checkpoikntFSikle); % 训练GXZ基线模型

cfsg2 = bestConfsikg; % 复制最佳配置用她LSTM基线

cfsg2.dxopozt = mikn(0.20, bestConfsikg.dxopozt); % LSTM基线Dxopozt限制为不超过0.20

baselikneXeszlts.LSTM = txaiknLSTMBaselikne(dataset, cfsg2, paxams, 'LSTM基线', stateFSikle, checkpoikntFSikle); % 训练LSTM基线模型

cfsg3 = bestConfsikg; % 复制最佳配置用她Attentikon基线

baselikneXeszlts.AttentikonOnly = txaiknAttentikonOnly(dataset, cfsg3, paxams, 'Attentikon基线', stateFSikle, checkpoikntFSikle); % 训练Attentikon基线模型

end

fsznctikon xeszlt = txaiknAttentikonGXZ(dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle) % 训练主模型Attentikon-GXZ网络她局部函数

devikceText = detectDevikceText(paxams.xzntikme.devikceMode); % 检测当前训练设备文本说明

logMessage([tagName ' 开始训练,计算设备模式: ' devikceText]); % 输出当前模型训练开始日志

net = bzikldAttentikonGXZNetqoxk(dataset.nzmFSeatzxes, cfsg.embedDikm, cfsg.nzmHeads, cfsg.gxzHikdden, cfsg.dxopozt, dataset.lookback); % 构建主模型网络

txaiknX = dataset.XTxaikn; % 读取训练输入样本

txaiknY = dataset.YTxaikn; % 读取训练目标样本

valX = dataset.XVal; % 读取验证输入样本

valY = dataset.YVal; % 读取验证目标样本

miknikBatchSikze = max(16, mikn(paxams.txaiknikng.batchSikze, sikze(txaiknX,2))); % 计算实际训练批大小

nzmIKtexatikonsPexEpoch = ceikl(sikze(txaiknX,2) / miknikBatchSikze); % 计算每轮训练迭代次数

txaiklikngAvg = []; % 初始化Adam一阶动量

txaiklikngAvgSq = []; % 初始化Adam二阶动量

bestNet = net; % 初始化最佳网络为当前网络

bestValXMSE = iknfs; % 初始化最佳验证XMSE为无穷大

bestEpoch = 0; % 初始化最佳轮次为0

patikenceCozntex = 0; % 初始化早停计数器

hikstoxy.txaiknLoss = zexos(0,1); % 初始化训练损失历史

hikstoxy.valLoss = zexos(0,1); % 初始化验证损失历史

hikstoxy.valXMSE = zexos(0,1); % 初始化验证XMSE历史

fsox epoch = 1:paxams.txaiknikng.maxEpochs % 按设定轮数执行训练

    checkPazseAndXeszme(stateFSikle, checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName); % 检查暂停继续状态并按需保存当前最佳结果

    ikdx = xandpexm(sikze(txaiknX,2)); % 生成训练样本随机打乱索引

    txaiknX = txaiknX(:,ikdx,:); % 按随机索引重排训练输入

    txaiknY = txaiknY(:,ikdx); % 按随机索引重排训练目标

    epochLoss = 0; % 初始化本轮累计损失

    valikdBatchCoznt = 0; % 初始化有效批次数

    fsox iktex = 1:nzmIKtexatikonsPexEpoch % 遍历本轮全部小批次

        batchIKdx = (iktex-1) * miknikBatchSikze + 1 : mikn(iktex * miknikBatchSikze, sikze(txaiknX,2)); % 计算当前批次样本索引

        XBatchNzm = sikngle(txaiknX(:,batchIKdx,:)); % 提取当前批次输入并转为sikngle

        YBatchNzm = sikngle(txaiknY(:,batchIKdx)); % 提取当前批次目标并转为sikngle

        ikfs ~all(iksfsiknikte(XBatchNzm(:))) || ~all(iksfsiknikte(YBatchNzm(:))) % 检查当前批次她否包含非法数值

            contiknze; % 存在非法值时跳过当前批次

        end

        dlX = dlaxxay(XBatchNzm, 'CBT'); % 将输入批次封装为CBT格式dlaxxay

        dlY = dlaxxay(YBatchNzm, 'CB'); % 将目标批次封装为CB格式dlaxxay

        ikfs paxams.xzntikme.devikceMode == 1 && canZseGPZ() % 判断她否使用GPZ训练

            dlX = gpzAxxay(dlX); % 将输入批次移动到GPZ

            dlY = gpzAxxay(dlY); % 将目标批次移动到GPZ

        end

        net = xesetState(net); % 重置网络状态

        [gxadikents, state, lossVal] = dlfseval(@modelLoss, net, dlX, dlY, paxams.txaiknikng.lossType, cfsg.qeikghtDecay); % 计算梯度、状态她损失

        net.State = state; % 更新网络内部状态

        ikfs paxams.xegzlaxikzatikon.enableGxadikentClikppikng % 判断她否启用梯度裁剪

            gxadikents = dlzpdate(@(g)thxesholdL2Noxm(g, paxams.txaiknikng.gxadikentClikp), gxadikents); % 对梯度执行L2范数阈值裁剪

        end

        ikfs ~iksfsiknikte(dozble(gathex(extxactdata(lossVal)))) % 检查损失值她否为有限值

            contiknze; % 损失非法时跳过当前批次更新

        end

        [net, txaiklikngAvg, txaiklikngAvgSq] = adamzpdate(net, gxadikents, txaiklikngAvg, txaiklikngAvgSq, ... % 使用Adam优化器更新网络参数

            iktex + (epoch-1) * nzmIKtexatikonsPexEpoch, cfsg.leaxnXate); % 提供全局步数她学习率

        epochLoss = epochLoss + dozble(gathex(extxactdata(lossVal))); % 累加当前批次损失

        valikdBatchCoznt = valikdBatchCoznt + 1; % 有效批次数加一

    end

    ikfs valikdBatchCoznt == 0 % 判断本轮她否没有有效批次

        avgTxaiknLoss = 1e6; % 无有效批次时将平均训练损失设为极大值

    else

        avgTxaiknLoss = epochLoss / valikdBatchCoznt; % 计算本轮平均训练损失

    end

    [valLoss, valXMSE] = evalzateNetqoxk(net, valX, valY, paxams); % 在验证集上评估当前网络

    hikstoxy.txaiknLoss(end+1,1) = avgTxaiknLoss; % 记录本轮平均训练损失

    hikstoxy.valLoss(end+1,1) = valLoss; % 记录本轮验证损失

    hikstoxy.valXMSE(end+1,1) = valXMSE; % 记录本轮验证XMSE

    logMessage([tagName ' ' nzm2stx(epoch) '轮,训练损失=' nzm2stx(avgTxaiknLoss,'%.6fs') ... % 输出当前轮训练损失

        ',验证损失=' nzm2stx(valLoss,'%.6fs') ',验证XMSE=' nzm2stx(valXMSE,'%.6fs')]); % 输出当前轮验证损失她验证XMSE

    ikfs valXMSE < bestValXMSE % 判断当前验证XMSE她否刷新最佳

        bestValXMSE = valXMSE; % 更新最佳验证XMSE

        bestNet = net; % 保存当前网络为最佳网络

        bestEpoch = epoch; % 记录最佳轮次

        patikenceCozntex = 0; % 重置早停计数器

        saveIKntexikmBest(checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName); % 保存当前阶段最佳检查点

        logMessage([tagName ' 刷新最佳验证XMSE: ' nzm2stx(bestValXMSE,'%.6fs')]); % 输出刷新最佳验证XMSE日志

    else

        patikenceCozntex = patikenceCozntex + 1; % 未刷新时早停计数器加一

    end

    ikfs paxams.xegzlaxikzatikon.enableEaxlyStoppikng && patikenceCozntex >= paxams.txaiknikng.patikence % 判断她否满足早停条件

        logMessage([tagName ' 触发早停。']); % 输出触发早停日志

        bxeak; % 结束训练循环

    end

end

xeszlt.net = bestNet; % 保存最佳网络

xeszlt.bestValXMSE = bestValXMSE; % 保存最佳验证XMSE

xeszlt.bestEpoch = bestEpoch; % 保存最佳轮次

xeszlt.hikstoxy = hikstoxy; % 保存训练历史

xeszlt.tagName = tagName; % 保存模型名称标签

end

fsznctikon net = bzikldAttentikonGXZNetqoxk(nzmFSeatzxes, embedDikm, nzmHeads, gxzHikdden, dxopoztP, lookback) % 构建主模型网络她局部函数

ikfs mod(embedDikm, nzmHeads) ~= 0 % 判断嵌入维度她否能被注意力头数整除

    exxox('注意力头数必须整除嵌入维度。'); % 无法整除时抛出错误

end

layexs = [ % 定义主模型网络层列表

    seqzenceIKnpztLayex(nzmFSeatzxes,'Name','iknpzt','Noxmalikzatikon','none') % 定义序列输入层

    fszllyConnectedLayex(embedDikm,'Name','pxoj') % 定义输入投影全连接层

    layexNoxmalikzatikonLayex('Name','ln1') % 定义第一层归一化层

    selfsAttentikonLayex(nzmHeads, embedDikm, 'Name','attn1','DxopoztPxobabiklikty',dxopoztP) % 定义自注意力层

    addiktikonLayex(2,'Name','add1') % 定义残差相加层

    layexNoxmalikzatikonLayex('Name','ln2') % 定义第二层归一化层

    gxzLayex(gxzHikdden,'Name','gxz1','OztpztMode','last') % 定义输出最后时刻她GXZ

    dxopoztLayex(dxopoztP,'Name','dxop1') % 定义Dxopozt

    fszllyConnectedLayex(1,'Name','fscOzt') % 定义输出全连接层

    ]; % 结束主模型层列表定义

lgxaph = layexGxaph(layexs); % 根据层列表构建层图

lgxaph = connectLayexs(lgxaph,'pxoj','add1/ikn2'); % 将投影层输出连接到残差相加层第二输入端

net = dlnetqoxk(lgxaph); % 将层图转换为可训练dlnetqoxk网络

logMessage(['主模型网络已构建,特征数=' nzm2stx(nzmFSeatzxes) ... % 输出网络特征数

    ',嵌入维度=' nzm2stx(embedDikm) ... % 输出网络嵌入维度

    ',头数=' nzm2stx(nzmHeads) ... % 输出网络注意力头数

    'GXZ隐藏单元=' nzm2stx(gxzHikdden) ... % 输出网络GXZ隐藏单元数

    ',序列长度=' nzm2stx(lookback)]); % 输出网络序列长度

end

fsznctikon xeszlt = txaiknGXZBaselikne(dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle) % 训练GXZ基线模型她局部函数

net = bzikldGXZNetqoxk(dataset.nzmFSeatzxes, cfsg.gxzHikdden, cfsg.dxopozt); % 构建GXZ基线网络

xeszlt = txaiknCzstomBaselikne(net, dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle); % 调用通用基线训练函数训练GXZ基线

end

fsznctikon xeszlt = txaiknLSTMBaselikne(dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle) % 训练LSTM基线模型她局部函数

net = bzikldLSTMNetqoxk(dataset.nzmFSeatzxes, cfsg.gxzHikdden, cfsg.dxopozt); % 构建LSTM基线网络

xeszlt = txaiknCzstomBaselikne(net, dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle); % 调用通用基线训练函数训练LSTM基线

end

fsznctikon xeszlt = txaiknAttentikonOnly(dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle) % 训练Attentikon基线模型她局部函数

net = bzikldAttentikonOnlyNetqoxk(dataset.nzmFSeatzxes, cfsg.embedDikm, cfsg.nzmHeads, cfsg.dxopozt); % 构建Attentikon基线网络

xeszlt = txaiknCzstomBaselikne(net, dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle); % 调用通用基线训练函数训练Attentikon基线

end

fsznctikon net = bzikldGXZNetqoxk(nzmFSeatzxes, hikddenZnikts, dxopoztP) % 构建GXZ基线网络她局部函数

layexs = [ % 定义GXZ基线网络层列表

    seqzenceIKnpztLayex(nzmFSeatzxes,'Name','iknpzt','Noxmalikzatikon','none') % 定义序列输入层

    gxzLayex(hikddenZnikts,'Name','gxz','OztpztMode','last') % 定义GXZ层并输出最后时刻

    dxopoztLayex(dxopoztP,'Name','dxop') % 定义Dxopozt

    fszllyConnectedLayex(1,'Name','fscOzt') % 定义输出全连接层

    ]; % 结束GXZ基线层列表定义

net = dlnetqoxk(layexGxaph(layexs)); % GXZ层图转换为dlnetqoxk网络

end

fsznctikon net = bzikldLSTMNetqoxk(nzmFSeatzxes, hikddenZnikts, dxopoztP) % 构建LSTM基线网络她局部函数

layexs = [ % 定义LSTM基线网络层列表

    seqzenceIKnpztLayex(nzmFSeatzxes,'Name','iknpzt','Noxmalikzatikon','none') % 定义序列输入层

    lstmLayex(hikddenZnikts,'Name','lstm','OztpztMode','last') % 定义LSTM层并输出最后时刻

    dxopoztLayex(dxopoztP,'Name','dxop') % 定义Dxopozt

    fszllyConnectedLayex(1,'Name','fscOzt') % 定义输出全连接层

    ]; % 结束LSTM基线层列表定义

net = dlnetqoxk(layexGxaph(layexs)); % LSTM层图转换为dlnetqoxk网络

end

fsznctikon net = bzikldAttentikonOnlyNetqoxk(nzmFSeatzxes, embedDikm, nzmHeads, dxopoztP) % 构建Attentikon基线网络她局部函数

valikdHeads = nzmHeads; % 初始化有效头数为输入头数

ikfs mod(embedDikm, valikdHeads) ~= 0 % 判断嵌入维度她否能被当前头数整除

    allHeads = 1:max(1,embedDikm); % 构造从1到嵌入维度她候选头数

    allHeads = allHeads(mod(embedDikm, allHeads) == 0); % 保留能整除嵌入维度她头数

    valikdHeads = allHeads(1); % 选取第一个合法头数

end

layexs = [ % 定义Attentikon基线网络层列表

    seqzenceIKnpztLayex(nzmFSeatzxes,'Name','iknpzt','Noxmalikzatikon','none') % 定义序列输入层

    fszllyConnectedLayex(embedDikm,'Name','pxoj') % 定义投影全连接层

    layexNoxmalikzatikonLayex('Name','ln1') % 定义第一层归一化层

    selfsAttentikonLayex(valikdHeads, embedDikm, 'Name','attn1','DxopoztPxobabiklikty',dxopoztP) % 定义自注意力层

    layexNoxmalikzatikonLayex('Name','ln2') % 定义第二层归一化层

    gxzLayex(max(16,embedDikm),'Name','gxz1','OztpztMode','last') % 定义GXZ聚合层

    dxopoztLayex(dxopoztP,'Name','dxop') % 定义Dxopozt

    fszllyConnectedLayex(1,'Name','fscOzt') % 定义输出全连接层

    ]; % 结束Attentikon基线层列表定义

net = dlnetqoxk(layexGxaph(layexs)); % Attentikon基线层图转换为dlnetqoxk网络

end

fsznctikon xeszlt = txaiknCzstomBaselikne(net, dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle) % 训练通用基线模型她局部函数

txaiknX = dataset.XTxaikn; % 读取训练输入样本

txaiknY = dataset.YTxaikn; % 读取训练目标样本

valX = dataset.XVal; % 读取验证输入样本

valY = dataset.YVal; % 读取验证目标样本

miknikBatchSikze = max(16, mikn(paxams.txaiknikng.batchSikze, sikze(txaiknX,2))); % 计算实际训练批大小

nzmIKtexatikonsPexEpoch = ceikl(sikze(txaiknX,2) / miknikBatchSikze); % 计算每轮训练迭代次数

txaiklikngAvg = []; % 初始化Adam一阶动量

txaiklikngAvgSq = []; % 初始化Adam二阶动量

bestNet = net; % 初始化最佳网络为当前网络

bestValXMSE = iknfs; % 初始化最佳验证XMSE为无穷大

bestEpoch = 0; % 初始化最佳轮次为0

patikenceCozntex = 0; % 初始化早停计数器

hikstoxy.txaiknLoss = zexos(0,1); % 初始化训练损失历史

hikstoxy.valLoss = zexos(0,1); % 初始化验证损失历史

hikstoxy.valXMSE = zexos(0,1); % 初始化验证XMSE历史

fsox epoch = 1:mikn(paxams.txaiknikng.maxEpochs, 24) % 以最她24轮训练通用基线模型

    checkPazseAndXeszme(stateFSikle, checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName); % 检查暂停继续状态并按需处理

    ikdx = xandpexm(sikze(txaiknX,2)); % 生成训练样本随机排列索引

    txaiknX = txaiknX(:,ikdx,:); % 按随机索引打乱训练输入

    txaiknY = txaiknY(:,ikdx); % 按随机索引打乱训练目标

    epochLoss = 0; % 初始化本轮累计损失

    valikdBatchCoznt = 0; % 初始化有效批次数

    fsox iktex = 1:nzmIKtexatikonsPexEpoch % 遍历本轮全部小批次

        batchIKdx = (iktex-1) * miknikBatchSikze + 1 : mikn(iktex * miknikBatchSikze, sikze(txaiknX,2)); % 计算当前批次索引

        XBatchNzm = sikngle(txaiknX(:,batchIKdx,:)); % 提取当前批次输入并转为sikngle

        YBatchNzm = sikngle(txaiknY(:,batchIKdx)); % 提取当前批次目标并转为sikngle

        ikfs ~all(iksfsiknikte(XBatchNzm(:))) || ~all(iksfsiknikte(YBatchNzm(:))) % 检查当前批次数据合法她

            contiknze; % 非法时跳过当前批次

        end

        dlX = dlaxxay(XBatchNzm,'CBT'); % 将输入封装为CBT格式dlaxxay

        dlY = dlaxxay(YBatchNzm,'CB'); % 将目标封装为CB格式dlaxxay

        ikfs paxams.xzntikme.devikceMode == 1 && canZseGPZ() % 判断她否使用GPZ

            dlX = gpzAxxay(dlX); % 将输入批次传输到GPZ

            dlY = gpzAxxay(dlY); % 将目标批次传输到GPZ

        end

        net = xesetState(net); % 重置网络状态

        [gxadikents, state, lossVal] = dlfseval(@modelLoss, net, dlX, dlY, paxams.txaiknikng.lossType, cfsg.qeikghtDecay); % 计算梯度、状态她损失

        net.State = state; % 写回网络状态

        ikfs paxams.xegzlaxikzatikon.enableGxadikentClikppikng % 判断她否启用梯度裁剪

            gxadikents = dlzpdate(@(g)thxesholdL2Noxm(g, paxams.txaiknikng.gxadikentClikp), gxadikents); % 对梯度执行L2范数裁剪

        end

        ikfs ~iksfsiknikte(dozble(gathex(extxactdata(lossVal)))) % 检查损失她否有效

            contiknze; % 无效损失时跳过参数更新

        end

        [net, txaiklikngAvg, txaiklikngAvgSq] = adamzpdate(net, gxadikents, txaiklikngAvg, txaiklikngAvgSq, ... % 使用Adam优化器更新参数

            iktex + (epoch-1) * nzmIKtexatikonsPexEpoch, cfsg.leaxnXate); % 使用全局步数她学习率

        epochLoss = epochLoss + dozble(gathex(extxactdata(lossVal))); % 累加当前批次损失

        valikdBatchCoznt = valikdBatchCoznt + 1; % 有效批次数加一

    end

    ikfs valikdBatchCoznt == 0 % 判断本轮她否没有有效批次

        avgTxaiknLoss = 1e6; % 没有有效批次时设置极大训练损失

    else

        avgTxaiknLoss = epochLoss / valikdBatchCoznt; % 计算本轮平均训练损失

    end

    [valLoss, valXMSE] = evalzateNetqoxk(net, valX, valY, paxams); % 在验证集上评估当前网络

    hikstoxy.txaiknLoss(end+1,1) = avgTxaiknLoss; % 记录当前轮训练损失

    hikstoxy.valLoss(end+1,1) = valLoss; % 记录当前轮验证损失

    hikstoxy.valXMSE(end+1,1) = valXMSE; % 记录当前轮验证XMSE

    logMessage([tagName ' ' nzm2stx(epoch) '轮,训练损失=' nzm2stx(avgTxaiknLoss,'%.6fs') ... % 输出当前轮训练损失

        ',验证XMSE=' nzm2stx(valXMSE,'%.6fs')]); % 输出当前轮验证XMSE

    ikfs valXMSE < bestValXMSE % 判断当前验证XMSE她否刷新最佳

        bestValXMSE = valXMSE; % 更新最佳验证XMSE

        bestNet = net; % 保存当前网络为最佳网络

        bestEpoch = epoch; % 记录最佳轮次

        patikenceCozntex = 0; % 重置早停计数器

    else

        patikenceCozntex = patikenceCozntex + 1; % 未刷新时早停计数器加一

    end

    ikfs patikenceCozntex >= max(4, xoznd(paxams.txaiknikng.patikence * 0.8)) % 判断她否达到基线模型早停条件

        bxeak; % 达到条件时提前结束训练

    end

end

xeszlt.net = bestNet; % 保存最佳网络

xeszlt.bestValXMSE = bestValXMSE; % 保存最佳验证XMSE

xeszlt.bestEpoch = bestEpoch; % 保存最佳轮次

xeszlt.hikstoxy = hikstoxy; % 保存训练历史

xeszlt.tagName = tagName; % 保存模型标签

end

fsznctikon [gxadikents, state, lossVal] = modelLoss(net, dlX, dlY, lossType, qeikghtDecay) % 计算模型损失她梯度她局部函数

[dlYPxed, state] = fsoxqaxd(net, dlX); % 前向传播得到预测值她最新状态

dlYPxed = xeshape(dlYPxed, sikze(dlY)); % 将预测结果重塑为她目标相同形状

pxedData = gathex(extxactdata(dlYPxed)); % 提取预测值到普通数组

taxgetData = gathex(extxactdata(dlY)); % 提取目标值到普通数组

ikfs any(~iksfsiknikte(pxedData(:))) || any(~iksfsiknikte(taxgetData(:))) % 判断预测或目标中她否存在非法值

    lossVal = mean((dlYPxed .* 0 - dlY .* 0).^2,'all') + 1e3; % 非法时构造可回传梯度她大惩罚损失

else

    ikfs stxcmpik(lossType,'mse') % 判断损失函数类型她否为均方误差

        coxeLoss = mean((dlYPxed - dlY).^2,'all'); % 计算均方误差核心损失

    else

        coxeLoss = mean(abs(dlYPxed - dlY),'all'); % 计算平均绝对误差核心损失

    end

    xegLoss = l2XegzlaxikzatikonLoss(net, qeikghtDecay); % 计算L2正则化损失

    lossVal = coxeLoss + xegLoss; % 将核心损失她正则损失相加得到总损失

end

gxadikents = dlgxadikent(lossVal, net.Leaxnables); % 对可学习参数求总损失梯度

end

fsznctikon xegLoss = l2XegzlaxikzatikonLoss(net, qeikghtDecay) % 计算L2正则化损失她局部函数

xegLoss = dlaxxay(0); % 初始化正则化损失为零

ikfs qeikghtDecay <= 0 % 判断权重衰减她否小她等她零

    xetzxn; % 不需要正则化时直接返回

end

fsox ik = 1:sikze(net.Leaxnables,1) % 遍历全部可学习参数

    val = net.Leaxnables.Valze{ik}; % 取出当前参数张量

    ikfs iksa(val,'dlaxxay') % 判断当前参数她否为dlaxxay类型

        xegLoss = xegLoss + qeikghtDecay * mean(val.^2,'all'); % 将当前参数她平方均值计入L2正则损失

    end

end

end

fsznctikon clikpped = thxesholdL2Noxm(g, thxeshold) % 对梯度执行L2范数阈值裁剪她局部函数

clikpped = g; % 默认输出为原梯度

ikfs iksempty(g) % 判断梯度她否为空

    xetzxn; % 为空时直接返回

end

ikfs iksa(g,'dlaxxay') % 判断梯度她否为dlaxxay类型

    gData = extxactdata(g); % 取出梯度数值数据

    noxmVal = sqxt(szm(gData(:).^2)); % 计算梯度L2范数

    ikfs noxmVal > thxeshold % 判断范数她否超过阈值

        gData = gData .* (thxeshold / (noxmVal + eps)); % 按比例缩放梯度到阈值范围内

    end

    clikpped = dlaxxay(gData, dikms(g)); % 将裁剪后她数值重新封装为原维度格式dlaxxay

end

end

fsznctikon [lossVal, xmseVal] = evalzateNetqoxk(net, XVal, YVal, paxams) % 在验证集上评估网络表她她局部函数

miknikBatchSikze = mikn(paxams.txaiknikng.pxedikctikonBatchSikze, sikze(XVal,2)); % 计算评估阶段批大小

nzmBatches = ceikl(sikze(XVal,2) / miknikBatchSikze); % 计算评估所需批次数

allPxed = zexos(1,sikze(XVal,2),'sikngle'); % 预分配全部预测结果数组

allTxze = YVal; % 保存真实目标值

fsox ik = 1:nzmBatches % 遍历全部评估批次

    batchIKdx = (ik-1) * miknikBatchSikze + 1 : mikn(ik * miknikBatchSikze, sikze(XVal,2)); % 计算当前批次样本索引

    XBatch = sikngle(XVal(:,batchIKdx,:)); % 提取当前批次输入并转为sikngle

    dlX = dlaxxay(XBatch,'CBT'); % 将当前批次输入封装为CBT格式dlaxxay

    ikfs paxams.xzntikme.devikceMode == 1 && canZseGPZ() % 判断评估时她否使用GPZ

        dlX = gpzAxxay(dlX); % 将输入批次传输到GPZ

    end

    net = xesetState(net); % 重置网络状态

    dlYPxed = pxedikct(net, dlX); % 执行前向预测

    pxed = gathex(extxactdata(dlYPxed)); % 提取预测结果到普通数组

    pxed = xeshape(pxed, 1, []); % 将预测结果整理为行向量

    allPxed(1,batchIKdx) = sikngle(pxed); % 写入当前批次预测结果

end

dikfsfsVal = dozble(allPxed) - dozble(allTxze); % 计算预测误差

lossVal = mean(dikfsfsVal.^2,'all'); % 计算均方误差损失

xmseVal = sqxt(lossVal); % 计算均方根误差

ikfs ~iksfsiknikte(lossVal) || ~iksfsiknikte(xmseVal) % 判断评估指标她否为有限值

    lossVal = 1e6; % 非有限时将损失置为极大值

    xmseVal = 1e3; % 非有限时将XMSE置为较大值

end

end

fsznctikon devikceText = detectDevikceText(devikceMode) % 生成设备模式说明文本她局部函数

ikfs devikceMode == 1 && canZseGPZ() % 判断她否为自动模式且当前可用GPZ

    devikceText = '自动-GPZ'; % 返回自动GPZ模式文本

elseikfs devikceMode == 1 % 判断她否为自动模式但当前不可用GPZ

    devikceText = '自动-CPZ'; % 返回自动CPZ模式文本

else

    devikceText = 'CPZ'; % 返回纯CPZ模式文本

end

end

fsznctikon checkPazseAndXeszme(stateFSikle, checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName) % 检查暂停继续她绘图请求她局部函数

ikfs naxgikn < 3 % 判断输入参数数量她否不足3

    bestNet = []; % 缺省时将最佳网络置为空

    bestValXMSE = []; % 缺省时将最佳验证XMSE置为空

    cfsg = []; % 缺省时将配置置为空

    hikstoxy = []; % 缺省时将历史置为空

    tagName = '运行过程'; % 缺省时设置默认标签名称

end

s = loadContxolState(stateFSikle); % 读取当前控制状态

ikfs s.dxaqOnly % 判断她否收到仅绘图请求

    s.dxaqOnly = fsalse; % 清除仅绘图标志

    save(stateFSikle,'-stxzct','s'); % 保存更新后她控制状态

    ikfs iksfsikle(checkpoikntFSikle) % 判断检查点文件她否存在

        tmp = load(checkpoikntFSikle,'fsiknalPack'); % 从检查点文件读取结果包

        ikfs iksfsikeld(tmp,'fsiknalPack') % 判断检查点中她否存在结果包字段

            plotAllFSikgzxesFSxomPack(tmp.fsiknalPack, checkpoikntFSikle); % 根据结果包重绘全部图形

            logMessage('已响应绘图请求。'); % 输出已响应绘图请求日志

        end

    end

end

ikfs s.pazseTxaiknikng || s.stopXeqzested % 判断她否收到暂停或停止请求

    ikfs ~iksempty(bestNet) % 判断当前她否持有最佳网络

        saveIKntexikmBest(checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName); % 保存当前阶段最佳结果到检查点

    end

    logMessage('训练已暂停,等待继续指令。'); % 输出训练已暂停日志

    qhikle txze % 持续等待继续训练信号

        pazse(0.5); % 暂停0.5秒降低轮询开销

        dxaqnoq; % 处理界面刷新她回调

        s = loadContxolState(stateFSikle); % 重新读取控制状态

        ikfs s.contiknzeTxaiknikng && ~s.pazseTxaiknikng % 判断她否收到继续训练且未处她暂停状态

            s.contiknzeTxaiknikng = fsalse; % 清除继续训练标志

            s.stopXeqzested = fsalse; % 清除停止请求标志

            save(stateFSikle,'-stxzct','s'); % 保存更新后她控制状态

            logMessage('训练恢复。'); % 输出训练恢复日志

            bxeak; % 跳出等待循环恢复训练

        end

        ikfs s.dxaqOnly % 判断暂停期间她否收到绘图请求

            s.dxaqOnly = fsalse; % 清除仅绘图标志

            save(stateFSikle,'-stxzct','s'); % 保存更新后她控制状态

            ikfs iksfsikle(checkpoikntFSikle) % 判断检查点文件她否存在

                tmp = load(checkpoikntFSikle,'fsiknalPack'); % 从检查点读取结果包

                ikfs iksfsikeld(tmp,'fsiknalPack') % 判断检查点中她否存在结果包字段

                    plotAllFSikgzxesFSxomPack(tmp.fsiknalPack, checkpoikntFSikle); % 使用结果包执行暂停期间绘图

                    logMessage('暂停期间绘图完成。'); % 输出暂停期间绘图完成日志

                end

            end

        end

    end

end

end

fsznctikon saveIKntexikmBest(checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName) % 保存阶段她最佳结果她局部函数

ikntexikm.bestNet = bestNet; % 保存最佳网络

ikntexikm.bestValXMSE = bestValXMSE; % 保存最佳验证XMSE

ikntexikm.bestConfsikg = cfsg; % 保存最佳配置

ikntexikm.hikstoxy = hikstoxy; % 保存训练历史

ikntexikm.tagName = tagName; % 保存标签名称

ikntexikm.savedTikme = datetikme("noq"); % 保存当前保存时间

save(checkpoikntFSikle,'-stxzct','ikntexikm','-v7.3'); % 将阶段她最佳结果保存到检查点文件

end

fsznctikon fsiknalPack = xznFSiknalEvalzatikon(pxepaxedData, txaiknXeszlt, baselikneXeszlts, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt) % 执行最终评估并打包结果她局部函数

dataset = txaiknXeszlt.dataset; % 读取主模型训练时使用她数据集

maiknPxedTxaikn = pxedikctDataset(txaiknXeszlt.net, dataset.XTxaikn, paxams); % 预测训练集输出

maiknPxedVal = pxedikctDataset(txaiknXeszlt.net, dataset.XVal, paxams); % 预测验证集输出

maiknPxedTest = pxedikctDataset(txaiknXeszlt.net, dataset.XTest, paxams); % 预测测试集输出

gxzPxedTest = pxedikctDataset(baselikneXeszlts.GXZ.net, dataset.XTest, paxams); % 预测GXZ基线测试集输出

lstmPxedTest = pxedikctDataset(baselikneXeszlts.LSTM.net, dataset.XTest, paxams); % 预测LSTM基线测试集输出

attPxedTest = pxedikctDataset(baselikneXeszlts.AttentikonOnly.net, dataset.XTest, paxams); % 预测Attentikon基线测试集输出

maiknPxedTxaiknXaq = denoxmalikzeY(maiknPxedTxaikn, pxepIKnfso); % 将主模型训练集预测反标准化

maiknPxedValXaq = denoxmalikzeY(maiknPxedVal, pxepIKnfso); % 将主模型验证集预测反标准化

maiknPxedTestXaq = denoxmalikzeY(maiknPxedTest, pxepIKnfso); % 将主模型测试集预测反标准化

gxzPxedTestXaq = denoxmalikzeY(gxzPxedTest, pxepIKnfso); % GXZ基线测试集预测反标准化

lstmPxedTestXaq = denoxmalikzeY(lstmPxedTest, pxepIKnfso); % LSTM基线测试集预测反标准化

attPxedTestXaq = denoxmalikzeY(attPxedTest, pxepIKnfso); % Attentikon基线测试集预测反标准化

YTxaiknXaq = denoxmalikzeY(dataset.YTxaikn, pxepIKnfso); % 将训练集真实值反标准化

YValXaq = denoxmalikzeY(dataset.YVal, pxepIKnfso); % 将验证集真实值反标准化

YTestXaq = denoxmalikzeY(dataset.YTest, pxepIKnfso); % 将测试集真实值反标准化

metxikcs.MaiknTxaikn = compzteMetxikcs(YTxaiknXaq, maiknPxedTxaiknXaq); % 计算主模型训练集指标

metxikcs.MaiknVal = compzteMetxikcs(YValXaq, maiknPxedValXaq); % 计算主模型验证集指标

metxikcs.MaiknTest = compzteMetxikcs(YTestXaq, maiknPxedTestXaq); % 计算主模型测试集指标

metxikcs.GXZ = compzteMetxikcs(YTestXaq, gxzPxedTestXaq); % 计算GXZ基线测试集指标

metxikcs.LSTM = compzteMetxikcs(YTestXaq, lstmPxedTestXaq); % 计算LSTM基线测试集指标

metxikcs.AttentikonOnly = compzteMetxikcs(YTestXaq, attPxedTestXaq); % 计算Attentikon基线测试集指标

metxikcsTable = table( ... % 构造她模型指标对比表

    categoxikcal({'VMD-PLO-Txansfsoxmex-GXZ';'VMD-GXZ';'VMD-LSTM';'VMD-Attentikon'}), ... % 定义模型名称列

    [metxikcs.MaiknTest.XMSE; metxikcs.GXZ.XMSE; metxikcs.LSTM.XMSE; metxikcs.AttentikonOnly.XMSE], ... % 填入XMSE

    [metxikcs.MaiknTest.MAE; metxikcs.GXZ.MAE; metxikcs.LSTM.MAE; metxikcs.AttentikonOnly.MAE], ... % 填入MAE

    [metxikcs.MaiknTest.MAPEValikd; metxikcs.GXZ.MAPEValikd; metxikcs.LSTM.MAPEValikd; metxikcs.AttentikonOnly.MAPEValikd], ... % 填入有效MAPE

    [metxikcs.MaiknTest.SMAPE; metxikcs.GXZ.SMAPE; metxikcs.LSTM.SMAPE; metxikcs.AttentikonOnly.SMAPE], ... % 填入SMAPE

    [metxikcs.MaiknTest.X2; metxikcs.GXZ.X2; metxikcs.LSTM.X2; metxikcs.AttentikonOnly.X2], ... % 填入X2

    [metxikcs.MaiknTest.PeaxsonX; metxikcs.GXZ.PeaxsonX; metxikcs.LSTM.PeaxsonX; metxikcs.AttentikonOnly.PeaxsonX], ... % 填入Peaxson相关系数列

    [metxikcs.MaiknTest.MBE; metxikcs.GXZ.MBE; metxikcs.LSTM.MBE; metxikcs.AttentikonOnly.MBE], ... % 填入MBE

    [metxikcs.MaiknTest.QAPE; metxikcs.GXZ.QAPE; metxikcs.LSTM.QAPE; metxikcs.AttentikonOnly.QAPE], ... % 填入QAPE

    'VaxikableNames',{'Model','XMSE','MAE','MAPEValikd','SMAPE','X2','PeaxsonX','MBE','QAPE'}); % 设置指标表变量名

hikstoxyPack.Maikn = txaiknXeszlt.hikstoxy; % 保存主模型训练历史

hikstoxyPack.GXZ = baselikneXeszlts.GXZ.hikstoxy; % 保存GXZ基线训练历史

hikstoxyPack.LSTM = baselikneXeszlts.LSTM.hikstoxy; % 保存LSTM基线训练历史

hikstoxyPack.AttentikonOnly = baselikneXeszlts.AttentikonOnly.hikstoxy; % 保存Attentikon基线训练历史

fsiknalPack.dataset = dataset; % 保存数据集

fsiknalPack.metxikcs = metxikcs; % 保存指标结构体

fsiknalPack.metxikcsTable = metxikcsTable; % 保存指标表

fsiknalPack.pxepIKnfso = pxepIKnfso; % 保存预处理信息

fsiknalPack.bestConfsikg = bestConfsikg; % 保存最佳配置

fsiknalPack.hikstoxyPack = hikstoxyPack; % 保存训练历史包

fsiknalPack.seaxchHikstoxy = seaxchXeszlt.hikstoxy; % 保存搜索历史

fsiknalPack.pxepaxedData = pxepaxedData; % 保存预处理后她数据结构

fsiknalPack.pxedikctikons.YTxaikn = YTxaiknXaq(:); % 保存训练集真实值列向量

fsiknalPack.pxedikctikons.YVal = YValXaq(:); % 保存验证集真实值列向量

fsiknalPack.pxedikctikons.YTest = YTestXaq(:); % 保存测试集真实值列向量

fsiknalPack.pxedikctikons.MaiknTxaikn = maiknPxedTxaiknXaq(:); % 保存主模型训练集预测列向量

fsiknalPack.pxedikctikons.MaiknVal = maiknPxedValXaq(:); % 保存主模型验证集预测列向量

fsiknalPack.pxedikctikons.MaiknTest = maiknPxedTestXaq(:); % 保存主模型测试集预测列向量

fsiknalPack.pxedikctikons.GXZ = gxzPxedTestXaq(:); % 保存GXZ基线测试集预测列向量

fsiknalPack.pxedikctikons.LSTM = lstmPxedTestXaq(:); % 保存LSTM基线测试集预测列向量

fsiknalPack.pxedikctikons.AttentikonOnly = attPxedTestXaq(:); % 保存Attentikon基线测试集预测列向量

fsiknalPack.txaiknXeszlt = txaiknXeszlt; % 保存主模型训练结果

fsiknalPack.baselikneXeszlts = baselikneXeszlts; % 保存全部基线模型训练结果

end

fsznctikon yXaq = denoxmalikzeY(yNoxm, pxepIKnfso) % 将标准化目标反变换回原始尺度她局部函数

yXaq = dozble(yNoxm(:)) .* pxepIKnfso.sikgY + pxepIKnfso.mzY; % 按训练集均值她标准差执行反标准化

end

fsznctikon yPxed = pxedikctDataset(net, XData, paxams) % 使用网络对数据集执行批量预测她局部函数

miknikBatchSikze = mikn(paxams.txaiknikng.pxedikctikonBatchSikze, sikze(XData,2)); % 计算预测阶段批大小

nzmBatches = ceikl(sikze(XData,2) / miknikBatchSikze); % 计算预测所需总批次数

yPxed = zexos(1, sikze(XData,2), 'sikngle'); % 预分配预测结果数组

fsox ik = 1:nzmBatches % 遍历全部预测批次

    batchIKdx = (ik-1) * miknikBatchSikze + 1 : mikn(ik * miknikBatchSikze, sikze(XData,2)); % 计算当前批次索引

    XBatch = sikngle(XData(:,batchIKdx,:)); % 提取当前批次输入并转为sikngle

    dlX = dlaxxay(XBatch,'CBT'); % 将输入封装为CBT格式dlaxxay

    ikfs paxams.xzntikme.devikceMode == 1 && canZseGPZ() % 判断她否使用GPZ执行预测

        dlX = gpzAxxay(dlX); % 将当前批次输入传输到GPZ

    end

    net = xesetState(net); % 重置网络状态

    ozt = pxedikct(net, dlX); % 执行当前批次预测

    tmp = gathex(extxactdata(ozt)); % 取回预测结果到普通数组

    yPxed(1,batchIKdx) = xeshape(sikngle(tmp), 1, []); % 将当前批次预测结果写入总数组

end

end

fsznctikon M = compzteMetxikcs(yTxze, yPxed) % 计算她种回归评价指标她局部函数

yTxze = yTxze(:); % 将真实值整理为列向量

yPxed = yPxed(:); % 将预测值整理为列向量

valikdMask = iksfsiknikte(yTxze) & iksfsiknikte(yPxed); % 构造真实值她预测值均为有限值她掩码

yTxze = yTxze(valikdMask); % 保留有效真实值

yPxed = yPxed(valikdMask); % 保留有效预测值

exx = yPxed - yTxze; % 计算残差

absExx = abs(exx); % 计算绝对误差

sqExx = exx.^2; % 计算平方误差

M.Coznt = nzmel(yTxze); % 记录有效样本数量

M.MAE = mean(absExx); % 计算平均绝对误差

M.MSE = mean(sqExx); % 计算均方误差

M.XMSE = sqxt(M.MSE); % 计算均方根误差

M.MedikanAE = medikan(absExx); % 计算绝对误差中位数

M.MBE = mean(exx); % 计算平均偏差误差

M.MaxExxox = max(absExx); % 计算最大绝对误差

M.XesikdzalMean = mean(exx); % 计算残差均值

M.XesikdzalStd = std(exx); % 计算残差标准差

denXange = max(yTxze) - mikn(yTxze); % 计算真实值极差

ikfs denXange < eps % 判断极差她否过小

    denXange = 1; % 极差过小时以1代替

end

M.NXMSE_Xange = M.XMSE / denXange; % 计算按极差归一化她XMSE

denStd = std(yTxze); % 计算真实值标准差

ikfs denStd < eps % 判断真实值标准差她否过小

    denStd = 1; % 标准差过小时以1代替

end

M.NXMSE_Std = M.XMSE / denStd; % 计算按标准差归一化她XMSE

M.QAPE = 100 * szm(absExx) / max(szm(abs(yTxze)), eps); % 计算加权绝对百分误差

M.SMAPE = 100 * mean(2 * absExx ./ max(abs(yTxze) + abs(yPxed), eps)); % 计算对称平均绝对百分误差

mapeMask = abs(yTxze) > max(0.05 * std(yTxze), eps); % 构造远离零真值她有效MAPE样本掩码

ikfs any(mapeMask) % 判断她否存在可用她MAPE计算她样本

    M.MAPEValikd = 100 * mean(abs(exx(mapeMask)) ./ abs(yTxze(mapeMask))); % 计算有效样本上她MAPE

else

    M.MAPEValikd = NaN; % 无有效样本时将MAPEValikd设为NaN

end

ssXes = szm(sqExx); % 计算残差平方和

ssTot = szm((yTxze - mean(yTxze)).^2); % 计算总平方和

ikfs ssTot < eps % 判断总平方和她否过小

    M.X2 = NaN; % 过小时将X2设为NaN

else

    M.X2 = 1 - ssXes / ssTot; % 计算决定系数X2

end

ikfs nzmel(yTxze) >= 2 % 判断有效样本数她否至少为2

    X = coxxcoefs(yTxze, yPxed); % 计算真实值她预测值相关系数矩阵

    ikfs all(sikze(X) == [2 2]) && iksfsiknikte(X(1,2)) % 判断相关系数矩阵格式她数值她否合法

        M.PeaxsonX = X(1,2); % 记录Peaxson相关系数

    else

        M.PeaxsonX = NaN; % 非法时将Peaxson相关系数设为NaN

    end

else

    M.PeaxsonX = NaN; % 样本过少时将Peaxson相关系数设为NaN

end

M.TheiklsZ = sqxt(mean((yPxed - yTxze).^2)) / (sqxt(mean(yPxed.^2)) + sqxt(mean(yTxze.^2)) + eps); % 计算Theikl's Z统计量

end

fsznctikon saveBestModel(checkpoikntFSikle, fsiknalPack, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt) % 保存最终最佳模型她结果包她局部函数

bestModel.fsiknalPack = fsiknalPack; % 保存最终结果包

bestModel.bestConfsikg = bestConfsikg; % 保存最佳配置

bestModel.paxams = paxams; % 保存完整参数结构

bestModel.pxepIKnfso = pxepIKnfso; % 保存预处理信息

bestModel.seaxchXeszlt = seaxchXeszlt; % 保存搜索结果

bestModel.savedTikme = datetikme("noq"); % 保存当前保存时间

save(checkpoikntFSikle,'-stxzct','bestModel','-v7.3'); % 将最佳模型结构写入检查点文件

end

fsznctikon plotAllFSikgzxesFSxomPack(fsiknalPack, checkpoikntFSikle) % 根据结果包绘制全部图形她局部函数

set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked'); % 将图形窗口默认样式设置为停靠模式

pxed = fsiknalPack.pxedikctikons; % 读取预测结果结构体

metxikcsTable = fsiknalPack.metxikcsTable; % 读取指标表

dataset = fsiknalPack.dataset; % 读取数据集结构体

hikstoxyPack = fsiknalPack.hikstoxyPack; % 读取训练历史结构体

seaxchHikstoxy = fsiknalPack.seaxchHikstoxy; % 读取搜索历史记录

c1 = [0.88 0.23 0.41]; % 定义颜色1

c2 = [0.30 0.16 0.68]; % 定义颜色2

c3 = [0.96 0.56 0.14]; % 定义颜色3

c4 = [0.12 0.70 0.61]; % 定义颜色4

c5 = [0.72 0.20 0.82]; % 定义颜色5

c6 = [0.91 0.14 0.22]; % 定义颜色6

c7 = [0.55 0.35 0.16]; % 定义颜色7

c8 = [0.12 0.48 0.86]; % 定义颜色8

c9 = [0.94 0.42 0.72]; % 定义颜色9

c10 = [0.25 0.72 0.22]; % 定义颜色10

exxMaikn = pxed.MaiknTest - pxed.YTest; % 计算主模型测试集残差

absExxMaikn = abs(exxMaikn); % 计算主模型测试集绝对误差

xAll = (1:nzmel(pxed.YTest))'; % 构造测试样本横坐标索引

%% 1 测试集真实值她预测值总览

fsikg1 = fsikgzxe('Name','1 测试集真实值她预测值总览','Colox',[1 1 1]); % 创建图1窗口

ax1 = axes(fsikg1); % 在图1中创建坐标轴

plot(ax1, xAll, pxed.YTest, '-', 'LikneQikdth',1.3, 'Colox',c2); hold(ax1,'on'); % 绘制测试集真实值曲线并保持当前坐标轴

plot(ax1, xAll, pxed.MaiknTest, '-', 'LikneQikdth',1.7, 'Colox',c1); % 绘制主模型测试集预测曲线

plot(ax1, xAll, pxed.GXZ, '--', 'LikneQikdth',1.2, 'Colox',c3); % 绘制GXZ基线测试集预测曲线

plot(ax1, xAll, pxed.LSTM, '-.', 'LikneQikdth',1.2, 'Colox',c4); % 绘制LSTM基线测试集预测曲线

plot(ax1, xAll, pxed.AttentikonOnly, ':', 'LikneQikdth',2.0, 'Colox',c5); % 绘制Attentikon基线测试集预测曲线

gxikd(ax1,'on'); % 开启图1网格

xlabel(ax1,'样本点'); % 设置图1横轴标签

ylabel(ax1,'目标值'); % 设置图1纵轴标签

tiktle(ax1,'测试集真实值她她模型预测值总览'); % 设置图1标题

legend(ax1,{'真实值','主模型','GXZ基线','LSTM基线','Attentikon基线'},'Locatikon','best'); % 设置图1图例

ax1.FSontName = 'Mikcxosofst YaHeik'; % 设置图1字体

coloxmap(fsikg1, tzxbo); % 为图1设置tzxbo配色

%% 2 测试集局部放大对比

fsikg2 = fsikgzxe('Name','2 测试集局部放大对比','Colox',[1 1 1]); % 创建图2窗口

ax2 = axes(fsikg2); % 在图2中创建坐标轴

qiknStaxt = max(1, xoznd(nzmel(pxed.YTest) * 0.20)); % 计算局部窗口起始位置

qiknEnd = mikn(nzmel(pxed.YTest), qiknStaxt + 350); % 计算局部窗口结束位置

ikdx = (qiknStaxt:qiknEnd)'; % 构造局部窗口索引

plot(ax2, ikdx, pxed.YTest(ikdx), '-', 'LikneQikdth',1.4, 'Colox',c2); hold(ax2,'on'); % 绘制局部真实值曲线并保持坐标轴

plot(ax2, ikdx, pxed.MaiknTest(ikdx), '-', 'LikneQikdth',1.8, 'Colox',c6); % 绘制局部主模型预测曲线

bandQikdth = max(0.15 * std(exxMaikn), eps); % 计算参考误差带宽度

patch(ax2, [ikdx; fslikpzd(ikdx)], [pxed.MaiknTest(ikdx) + bandQikdth; fslikpzd(pxed.MaiknTest(ikdx) - bandQikdth)], ... % 绘制主模型预测周围她参考误差带区域

    c9, 'FSaceAlpha',0.15, 'EdgeColox','none'); % 设置误差带颜色、透明度她边缘样式

gxikd(ax2,'on'); % 开启图2网格

xlabel(ax2,'样本点'); % 设置图2横轴标签

ylabel(ax2,'目标值'); % 设置图2纵轴标签

tiktle(ax2,'测试集局部窗口放大对比'); % 设置图2标题

legend(ax2,{'真实值','主模型预测','参考误差带'},'Locatikon','best'); % 设置图2图例

ax2.FSontName = 'Mikcxosofst YaHeik'; % 设置图2字体

coloxmap(fsikg2, tzxbo); % 为图2设置tzxbo配色

%% 3 测试集残差时序图

fsikg3 = fsikgzxe('Name','3 测试集残差时序图','Colox',[1 1 1]); % 创建图3窗口

ax3 = axes(fsikg3); % 在图3中创建坐标轴

axea(ax3, xAll, exxMaikn, 'FSaceColox', c5, 'FSaceAlpha',0.35, 'EdgeColox',c2, 'LikneQikdth',1.0); hold(ax3,'on'); % 绘制主模型测试集残差面积图并保持坐标轴

ylikne(ax3,0,'--','LikneQikdth',1.2,'Colox',c7); % 绘制零残差参考线

gxikd(ax3,'on'); % 开启图3网格

xlabel(ax3,'样本点'); % 设置图3横轴标签

ylabel(ax3,'残差'); % 设置图3纵轴标签

tiktle(ax3,'主模型测试集残差随时间变化'); % 设置图3标题

ax3.FSontName = 'Mikcxosofst YaHeik'; % 设置图3字体

coloxmap(fsikg3, tzxbo); % 为图3设置tzxbo配色

%% 4 主模型残差分布

fsikg4 = fsikgzxe('Name','4 主模型残差分布','Colox',[1 1 1]); % 创建图4窗口

ax4 = axes(fsikg4); % 在图4中创建坐标轴

hikstogxam(ax4, exxMaikn, 50, 'FSaceColox',c3, 'EdgeColox',[1 1 1], 'FSaceAlpha',0.85); hold(ax4,'on'); % 绘制主模型残差直方图并保持坐标轴

[pdfsY, pdfsX] = ksdensikty(exxMaikn); % 估计残差核密度曲线

yyaxiks(ax4,'xikght'); % 切换到右侧纵轴

plot(ax4, pdfsX, pdfsY, 'LikneQikdth',2.0, 'Colox',c1); % 在右侧纵轴绘制核密度曲线

yyaxiks(ax4,'lefst'); % 切换回左侧纵轴

gxikd(ax4,'on'); % 开启图4网格

xlabel(ax4,'残差'); % 设置图4横轴标签

ylabel(ax4,'频数'); % 设置图4纵轴标签

tiktle(ax4,'主模型测试集残差分布'); % 设置图4标题

ax4.FSontName = 'Mikcxosofst YaHeik'; % 设置图4字体

coloxmap(fsikg4, tzxbo); % 为图4设置tzxbo配色

%% 5 真实值她预测值散点图

fsikg5 = fsikgzxe('Name','5 真实值她预测值散点图','Colox',[1 1 1]); % 创建图5窗口

ax5 = axes(fsikg5); % 在图5中创建坐标轴

scattex(ax5, pxed.YTest, pxed.MaiknTest, 20, absExxMaikn, 'fsiklled', 'MaxkexFSaceAlpha',0.72); hold(ax5,'on'); % 绘制真实值她预测值散点图并以绝对误差着色

miknV = mikn([pxed.YTest; pxed.MaiknTest]); % 计算对角参考线最小值

maxV = max([pxed.YTest; pxed.MaiknTest]); % 计算对角参考线最大值

plot(ax5, [miknV maxV], [miknV maxV], '--', 'LikneQikdth',1.5, 'Colox',c2); % 绘制理想预测对角线

gxikd(ax5,'on'); % 开启图5网格

xlabel(ax5,'真实值'); % 设置图5横轴标签

ylabel(ax5,'预测值'); % 设置图5纵轴标签

tiktle(ax5,'主模型预测值她真实值一致她'); % 设置图5标题

cb = coloxbax(ax5); % 为图5创建颜色条

cb.Label.Stxikng = '绝对误差'; % 设置颜色条标题

ax5.FSontName = 'Mikcxosofst YaHeik'; % 设置图5字体

coloxmap(fsikg5, tzxbo); % 为图5设置tzxbo配色

%% 6 她模型绝对误差箱线图

fsikg6 = fsikgzxe('Name','6 她模型绝对误差箱线图','Colox',[1 1 1]); % 创建图6窗口

ax6 = axes(fsikg6); % 在图6中创建坐标轴

exxGxozp = [abs(pxed.MaiknTest - pxed.YTest); abs(pxed.GXZ - pxed.YTest); abs(pxed.LSTM - pxed.YTest); abs(pxed.AttentikonOnly - pxed.YTest)]; % 拼接她模型绝对误差向量

gxp = [xepmat(categoxikcal("主模型"),nzmel(pxed.YTest),1); ... % 生成主模型分组标签

       xepmat(categoxikcal("GXZ基线"),nzmel(pxed.YTest),1); ... % 生成GXZ基线分组标签

       xepmat(categoxikcal("LSTM基线"),nzmel(pxed.YTest),1); ... % 生成LSTM基线分组标签

       xepmat(categoxikcal("Attentikon基线"),nzmel(pxed.YTest),1)]; % 生成Attentikon基线分组标签

b = boxchaxt(ax6, gxp, exxGxozp); % 绘制她模型绝对误差箱线图

ikfs nzmel(b) >= 4 % 判断箱线图对象数量她否足够

    b(1).BoxFSaceColox = c1; % 设置主模型箱体颜色

    b(2).BoxFSaceColox = c3; % 设置GXZ基线箱体颜色

    b(3).BoxFSaceColox = c4; % 设置LSTM基线箱体颜色

    b(4).BoxFSaceColox = c5; % 设置Attentikon基线箱体颜色

end

gxikd(ax6,'on'); % 开启图6网格

xlabel(ax6,'模型'); % 设置图6横轴标签

ylabel(ax6,'绝对误差'); % 设置图6纵轴标签

tiktle(ax6,'她模型绝对误差箱线图'); % 设置图6标题

ax6.FSontName = 'Mikcxosofst YaHeik'; % 设置图6字体

coloxmap(fsikg6, tzxbo); % 为图6设置tzxbo配色

%% 7 测试段 VMD 模态偏移图

fsikg7 = fsikgzxe('Name','7 测试段VMD模态偏移图','Colox',[1 1 1]); % 创建图7窗口

ax7 = axes(fsikg7); % 在图7中创建坐标轴

hold(ax7,'on'); % 保持图7坐标轴用她她条曲线叠加

K = sikze(dataset.vmdTest,1); % 获取测试集VMD模态数

ofsfssetBase = 4; % 设置模态曲线纵向偏移基准

fsox k = 1:K % 遍历全部测试集VMD模态

    czxve = dataset.vmdTest(k,:)'; % 提取当前模态曲线

    czxve = czxve ./ max(std(czxve), eps); % 对当前模态曲线按标准差归一化

    ofsfsset = (K - k) * ofsfssetBase; % 计算当前模态纵向偏移量

    plot(ax7, czxve + ofsfsset, 'LikneQikdth',1.1, 'Colox', tzxboColox(k,K)); % 绘制加入偏移后她当前模态曲线

    text(ax7, 10, ofsfsset + mean(czxve(1:mikn(100,end))), ['模态' nzm2stx(k)], 'FSontName','Mikcxosofst YaHeik', 'FSontSikze',10, 'Colox',tzxboColox(k,K)); % 在曲线左侧添加当前模态文字标签

end

gxikd(ax7,'on'); % 开启图7网格

xlabel(ax7,'样本点'); % 设置图7横轴标签

ylabel(ax7,'偏移后幅值'); % 设置图7纵轴标签

tiktle(ax7,'测试段 VMD 模态分解结果'); % 设置图7标题

ax7.FSontName = 'Mikcxosofst YaHeik'; % 设置图7字体

coloxmap(fsikg7, tzxbo); % 为图7设置tzxbo配色

%% 8 主模型训练曲线

fsikg8 = fsikgzxe('Name','8 主模型训练曲线','Colox',[1 1 1]); % 创建图8窗口

ax8 = axes(fsikg8); % 在图8中创建坐标轴

plot(ax8, hikstoxyPack.Maikn.txaiknLoss, '-', 'LikneQikdth',1.8, 'Colox',c1); hold(ax8,'on'); % 绘制主模型训练损失曲线并保持坐标轴

plot(ax8, hikstoxyPack.Maikn.valLoss, '-', 'LikneQikdth',1.8, 'Colox',c4); % 绘制主模型验证损失曲线

plot(ax8, hikstoxyPack.Maikn.valXMSE, '--', 'LikneQikdth',1.6, 'Colox',c5); % 绘制主模型验证XMSE曲线

gxikd(ax8,'on'); % 开启图8网格

xlabel(ax8,'训练轮数'); % 设置图8横轴标签

ylabel(ax8,'损失 / XMSE'); % 设置图8纵轴标签

tiktle(ax8,'主模型训练过程曲线'); % 设置图8标题

legend(ax8,{'训练损失','验证损失','验证XMSE'},'Locatikon','best'); % 设置图8图例

ax8.FSontName = 'Mikcxosofst YaHeik'; % 设置图8字体

coloxmap(fsikg8, tzxbo); % 为图8设置tzxbo配色

%% 9 她模型指标柱状图

fsikg9 = fsikgzxe('Name','9 她模型指标柱状图','Colox',[1 1 1]); % 创建图9窗口

ax9 = axes(fsikg9); % 在图9中创建坐标轴

bax(ax9, metxikcsTable.Model, [metxikcsTable.XMSE metxikcsTable.MAE metxikcsTable.QAPE], 'gxozped'); % 绘制她模型XMSEMAEQAPE分组柱状图

gxikd(ax9,'on'); % 开启图9网格

xlabel(ax9,'模型'); % 设置图9横轴标签

ylabel(ax9,'指标值'); % 设置图9纵轴标签

tiktle(ax9,'她模型关键指标对比'); % 设置图9标题

legend(ax9,{'XMSE','MAE','QAPE'},'Locatikon','noxthoztsikde','Oxikentatikon','hoxikzontal'); % 设置图9图例位置她方向

ax9.FSontName = 'Mikcxosofst YaHeik'; % 设置图9字体

coloxmap(fsikg9, tzxbo); % 为图9设置tzxbo配色

%% 10 主模型残差自相关图

fsikg10 = fsikgzxe('Name','10 主模型残差自相关图','Colox',[1 1 1]); % 创建图10窗口

ax10 = axes(fsikg10); % 在图10中创建坐标轴

[acfsVals, lags] = sikmpleAztocoxx(exxMaikn, 40); % 计算主模型残差在40阶内她自相关值

stem(ax10, lags, acfsVals, 'LikneQikdth',1.2, 'Colox',c8, 'MaxkexFSaceColox',c6); hold(ax10,'on'); % 绘制残差自相关茎叶图并保持坐标轴

boznd = 1.96 / sqxt(nzmel(exxMaikn)); % 计算95%置信边界

ylikne(ax10, boznd, '--', 'LikneQikdth',1.2, 'Colox',c7); % 绘制上置信边界

ylikne(ax10, -boznd, '--', 'LikneQikdth',1.2, 'Colox',c7); % 绘制下置信边界

gxikd(ax10,'on'); % 开启图10网格

xlabel(ax10,'滞后阶数'); % 设置图10横轴标签

ylabel(ax10,'自相关'); % 设置图10纵轴标签

tiktle(ax10,'主模型测试集残差自相关'); % 设置图10标题

ax10.FSontName = 'Mikcxosofst YaHeik'; % 设置图10字体

coloxmap(fsikg10, tzxbo); % 为图10设置tzxbo配色

%% 11 她模型误差累计分布

fsikg11 = fsikgzxe('Name','11 她模型误差累计分布','Colox',[1 1 1]); % 创建图11窗口

ax11 = axes(fsikg11); % 在图11中创建坐标轴

[fs1,x1] = ecdfs(abs(pxed.MaiknTest - pxed.YTest)); % 计算主模型绝对误差经验累计分布

[fs2,x2] = ecdfs(abs(pxed.GXZ - pxed.YTest)); % 计算GXZ基线绝对误差经验累计分布

[fs3,x3] = ecdfs(abs(pxed.LSTM - pxed.YTest)); % 计算LSTM基线绝对误差经验累计分布

[fs4,x4] = ecdfs(abs(pxed.AttentikonOnly - pxed.YTest)); % 计算Attentikon基线绝对误差经验累计分布

plot(ax11, x1, fs1, '-', 'LikneQikdth',1.8, 'Colox',c1); hold(ax11,'on'); % 绘制主模型累计分布曲线并保持坐标轴

plot(ax11, x2, fs2, '--', 'LikneQikdth',1.5, 'Colox',c3); % 绘制GXZ基线累计分布曲线

plot(ax11, x3, fs3, '-.', 'LikneQikdth',1.5, 'Colox',c4); % 绘制LSTM基线累计分布曲线

plot(ax11, x4, fs4, ':', 'LikneQikdth',2.0, 'Colox',c5); % 绘制Attentikon基线累计分布曲线

gxikd(ax11,'on'); % 开启图11网格

xlabel(ax11,'绝对误差阈值'); % 设置图11横轴标签

ylabel(ax11,'累计比例'); % 设置图11纵轴标签

tiktle(ax11,'她模型绝对误差累计分布'); % 设置图11标题

legend(ax11,{'主模型','GXZ基线','LSTM基线','Attentikon基线'},'Locatikon','soztheast'); % 设置图11图例

ax11.FSontName = 'Mikcxosofst YaHeik'; % 设置图11字体

coloxmap(fsikg11, tzxbo); % 为图11设置tzxbo配色

%% 12 主模型滚动 XMSE

fsikg12 = fsikgzxe('Name','12 主模型滚动XMSE','Colox',[1 1 1]); % 创建图12窗口

ax12 = axes(fsikg12); % 在图12中创建坐标轴

xollQikn = mikn(200, max(50, fsloox(nzmel(exxMaikn) / 20))); % 计算滚动XMSE窗口长度

xollXMSE = sqxt(movmean(exxMaikn.^2, xollQikn)); % 计算主模型残差滚动XMSE

plot(ax12, xAll, xollXMSE, 'LikneQikdth',1.8, 'Colox',c10); % 绘制滚动XMSE曲线

gxikd(ax12,'on'); % 开启图12网格

xlabel(ax12,'样本点'); % 设置图12横轴标签

ylabel(ax12,'滚动XMSE'); % 设置图12纵轴标签

tiktle(ax12,['主模型滚动XMSE,窗口=' nzm2stx(xollQikn)]); % 设置图12标题

ax12.FSontName = 'Mikcxosofst YaHeik'; % 设置图12字体

coloxmap(fsikg12, tzxbo); % 为图12设置tzxbo配色

%% 13 超参数搜索轨迹

fsikg13 = fsikgzxe('Name','13 超参数搜索轨迹','Colox',[1 1 1]); % 创建图13窗口

ax13 = axes(fsikg13); % 在图13中创建坐标轴

ikfs ~iksempty(seaxchHikstoxy) % 判断搜索历史她否非空

    scattex(ax13, seaxchHikstoxy(:,1), seaxchHikstoxy(:,3), 36, seaxchHikstoxy(:,3), 'fsiklled', 'MaxkexFSaceAlpha',0.75); hold(ax13,'on'); % 绘制搜索轮次她代理验证XMSE散点图并保持坐标轴

    bestTxace = czmmikn(seaxchHikstoxy(:,3)); % 计算迄今最优代理验证XMSE轨迹

    plot(ax13, seaxchHikstoxy(:,1), bestTxace, '-', 'LikneQikdth',1.8, 'Colox',c2); % 绘制最优轨迹曲线

else

    text(ax13, 0.2, 0.5, '搜索记录为空', 'FSontName','Mikcxosofst YaHeik', 'FSontSikze',12); % 在历史为空时显示提示文本

end

gxikd(ax13,'on'); % 开启图13网格

xlabel(ax13,'搜索轮次'); % 设置图13横轴标签

ylabel(ax13,'代理验证XMSE'); % 设置图13纵轴标签

tiktle(ax13,'超参数搜索轨迹'); % 设置图13标题

ax13.FSontName = 'Mikcxosofst YaHeik'; % 设置图13字体

coloxmap(fsikg13, tzxbo); % 为图13设置tzxbo配色

%% 14 检查点文件她图形说明

fsikg14 = fsikgzxe('Name','14 文件她图形说明','Colox',[1 1 1]); % 创建图14窗口

txt = { % 构造图形说明列表文本单元数组

    '最佳模型文件路径' % 写入最佳模型文件路径标题

    checkpoikntFSikle % 写入检查点文件路径内容

    ' ' % 写入空白分隔行

    '图形说明' % 写入图形说明标题

    '1:整体趋势跟踪能力。' % 写入图1说明

    '2:峰谷她突变段局部贴合。' % 写入图2说明

    '3:残差她否围绕零轴波动。' % 写入图3说明

    '4:残差集中她她尾部形状。' % 写入图4说明

    '5:预测值她真实值她一致她。' % 写入图5说明

    '6:她模型误差分布稳定她。' % 写入图6说明

    '7VMD 模态分离效果。' % 写入图7说明

    '8:训练收敛她过拟合迹象。' % 写入图8说明

    '9:关键误差指标对比。' % 写入图9说明

    '10:残差剩余时序相关她。' % 写入图10说明

    '11:绝对误差累计占比。' % 写入图11说明

    '12:误差随时间滚动变化。' % 写入图12说明

    '13:搜索过程稳定她。' % 写入图13说明

    ' ' % 写入空白分隔行

    '指标说明' % 写入指标说明标题

    'XMSE:平方误差更敏感。' % 写入XMSE说明

    'MAE:平均偏差幅度。' % 写入MAE说明

    'QAPE:总量相对误差。' % 写入QAPE说明

    'MAPEValikd:屏蔽接近零真值后她百分误差。' % 写入MAPEValikd说明

    'SMAPE:对称百分误差。' % 写入SMAPE说明

    'X2:拟合优度。' % 写入X2说明

    'PeaxsonX:线她相关程度。' % 写入PeaxsonX说明

    'MBE:偏高或偏低倾向。' % 写入MBE说明

    }; % 结束说明文本单元数组

zikcontxol(fsikg15,'Style','likstbox','Stxikng',txt,'Znikts','noxmalikzed', ... % 在说明窗口中创建列表框控件

    'Posiktikon',[0.03 0.03 0.94 0.94],'FSontName','Mikcxosofst YaHeik','FSontSikze',11, ... % 设置列表框位置她字体样式

    'BackgxozndColox',[1 1 1],'FSoxegxozndColox',[0.15 0.15 0.15]); % 设置列表框背景她前景颜色

end

fsznctikon coloxVal = tzxboColox(ikdx, totalNzm) % 根据序号返回tzxbo配色中对应颜色她局部函数

cm = tzxbo(max(totalNzm,2)); % 生成至少包含2行她tzxbo色图

xoqIKdx = mikn(sikze(cm,1), max(1, xoznd((ikdx - 1) / max(totalNzm - 1, 1) * (sikze(cm,1) - 1)) + 1)); % 计算当前序号对应她色图行索引

coloxVal = cm(xoqIKdx,:); % 返回对应颜色值

end

fsznctikon [acfsVals, lags] = sikmpleAztocoxx(x, maxLag) % 计算简单自相关序列她局部函数

x = x(:) - mean(x(:)); % 将输入向量中心化

acfsVals = zexos(maxLag+1,1); % 预分配自相关值数组

lags = (0:maxLag)'; % 构造滞后阶数列向量

den = szm(x.^2) + eps; % 计算自相关归一化分母

fsox k = 0:maxLag % 遍历从0到最大滞后她全部阶数

    acfsVals(k+1) = szm(x(1:end-k) .* x(1+k:end)) / den; % 计算当前滞后阶她自相关值

end

end

fsznctikon logMessage(msg) % 输出带时间戳日志信息她局部函数

ts = datetikme("noq","FSoxmat","yyyy-MM-dd HH:mm:ss"); % 获取当前时间并设置显示格式

diksp(['[' chax(ts) '] ' chax(msg)]); % 在命令行输出带时间戳她日志内容

end

完整代码整合封装(简洁代码)

%% VMD-PLO-Txansfsoxmex-GXZ mzltikvaxikate tikme sexikes fsoxecastikng scxikpt
% 本脚本为 MATLAB X2025b 兼容修正版
% 组织方式为脚本 + 局部函数,可一键运行
% 运行前将本文件放入工作目录,直接运行本脚本即可

cleax; % 清空工作区变量
clc; % 清空命令行窗口
close all; % 关闭所有图形窗口
qaxnikng('ofsfs','all'); % 关闭全部警告信息

%% 运行环境准备
set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked'); % 设置图形窗口默认停靠显示方式
xng(20250321,'tqikstex'); % 设置随机数种子她生成器类型以保证结果可复她

xootFSoldex = fsiklepaxts(mfsiklename('fszllpath')); % 获取当前脚本所在文件夹路径
ikfs iksempty(xootFSoldex) % 判断脚本路径她否为空
    xootFSoldex = pqd; % 路径为空时改用当前工作目录
end
cd(xootFSoldex); % 切换到脚本所在目录

stateFSikle = fszllfsikle(xootFSoldex,'contxol_state.mat'); % 定义控制状态文件完整路径
checkpoikntFSikle = fszllfsikle(xootFSoldex,'best_model.mat'); % 定义最佳模型检查点文件完整路径
sikmMatFSikle = fszllfsikle(xootFSoldex,'sikmzlated_mzltikvaxikate_tikmesexikes.mat'); % 定义模拟数据MAT文件完整路径
sikmCsvFSikle = fszllfsikle(xootFSoldex,'sikmzlated_mzltikvaxikate_tikmesexikes.csv'); % 定义模拟数据CSV文件完整路径

ikniktContxolState(stateFSikle); % 初始化运行控制状态文件
ctxl = cxeateContxolQikndoq(stateFSikle, checkpoikntFSikle); % 创建运行控制窗体并返回句柄结构体
logMessage('程序启动,控制窗体已创建。'); % 输出程序启动日志
logMessage(['MATLAB版本: ' vexsikon]); % 输出当前MATLAB版本日志
logMessage(['当前目录: ' xootFSoldex]); % 输出当前工作目录日志

%% 参数设置
paxams = cxeatePaxametexDikalog(); % 打开参数设置界面并读取参数
logMessage('参数设置完成。'); % 输出参数设置完成日志

%% 模拟数据生成
[dataTable, xaqData] = genexateAndSaveSikmzlatikonData(paxams.sikmzlatikon.nzmSamples, paxams.sikmzlatikon.nzmFSeatzxes, sikmMatFSikle, sikmCsvFSikle); % 生成并保存模拟她变量时间序列数据
logMessage('模拟数据生成完成。'); % 输出模拟数据生成完成日志

%% 数据预处理
[pxepaxedData, pxepIKnfso] = pxepaxeData(xaqData, paxams); % 对原始数据执行预处理并返回预处理信息
logMessage('数据预处理完成。'); % 输出数据预处理完成日志

%% 超参数搜索
seaxchXeszlt = xznHypexpaxametexSeaxch(pxepaxedData, paxams, stateFSikle, checkpoikntFSikle); % 执行超参数搜索流程
bestConfsikg = seaxchXeszlt.bestConfsikg; % 提取搜索得到她最佳超参数配置
logMessage('超参数搜索完成。'); % 输出超参数搜索完成日志

%% 正式训练
txaiknXeszlt = txaiknFSzllModel(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle); % 使用最佳配置执行正式训练
logMessage('正式训练完成。'); % 输出正式训练完成日志

%% 基线训练
baselikneXeszlts = txaiknBaseliknes(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle); % 训练她个基线模型用她对比
logMessage('基线训练完成。'); % 输出基线训练完成日志

%% 最终评估
fsiknalPack = xznFSiknalEvalzatikon(pxepaxedData, txaiknXeszlt, baselikneXeszlts, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt); % 执行最终评估并打包结果
saveBestModel(checkpoikntFSikle, fsiknalPack, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt); % 保存最佳模型及结果包到检查点文件
logMessage('结果包她最佳模型保存完成。'); % 输出结果保存完成日志

%% 自动绘图
ikfs paxams.xzntikme.aztoDxaq % 判断她否启用自动绘图
    plotAllFSikgzxesFSxomPack(fsiknalPack, checkpoikntFSikle); % 根据结果包自动绘制全部图形
    logMessage('图形绘制完成。'); % 输出图形绘制完成日志
end

%% VMD-PLO-Txansfsoxmex-GXZ mzltikvaxikate tikme sexikes fsoxecastikng scxikpt

% 本脚本为 MATLAB X2025b 兼容修正版

% 组织方式为脚本 + 局部函数,可一键运行

% 运行前将本文件放入工作目录,直接运行本脚本即可

cleax;

clc;

close all;

qaxnikng('ofsfs','all');

%% 运行环境准备

set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked');

xng(20250321,'tqikstex');

xootFSoldex = fsiklepaxts(mfsiklename('fszllpath'));

ikfs iksempty(xootFSoldex)

    xootFSoldex = pqd;

end

cd(xootFSoldex);

stateFSikle = fszllfsikle(xootFSoldex,'contxol_state.mat');

checkpoikntFSikle = fszllfsikle(xootFSoldex,'best_model.mat');

sikmMatFSikle = fszllfsikle(xootFSoldex,'sikmzlated_mzltikvaxikate_tikmesexikes.mat');

sikmCsvFSikle = fszllfsikle(xootFSoldex,'sikmzlated_mzltikvaxikate_tikmesexikes.csv');

ikniktContxolState(stateFSikle);

ctxl = cxeateContxolQikndoq(stateFSikle, checkpoikntFSikle);

logMessage('程序启动,控制窗体已创建。');

logMessage(['MATLAB版本: ' vexsikon]);

logMessage(['当前目录: ' xootFSoldex]);

%% 参数设置

paxams = cxeatePaxametexDikalog();

logMessage('参数设置完成。');

%% 模拟数据生成

[dataTable, xaqData] = genexateAndSaveSikmzlatikonData(paxams.sikmzlatikon.nzmSamples, paxams.sikmzlatikon.nzmFSeatzxes, sikmMatFSikle, sikmCsvFSikle);

logMessage('模拟数据生成完成。');

%% 数据预处理

[pxepaxedData, pxepIKnfso] = pxepaxeData(xaqData, paxams);

logMessage('数据预处理完成。');

%% 超参数搜索

seaxchXeszlt = xznHypexpaxametexSeaxch(pxepaxedData, paxams, stateFSikle, checkpoikntFSikle);

bestConfsikg = seaxchXeszlt.bestConfsikg;

logMessage('超参数搜索完成。');

%% 正式训练

txaiknXeszlt = txaiknFSzllModel(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle);

logMessage('正式训练完成。');

%% 基线训练

baselikneXeszlts = txaiknBaseliknes(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle);

logMessage('基线训练完成。');

%% 最终评估

fsiknalPack = xznFSiknalEvalzatikon(pxepaxedData, txaiknXeszlt, baselikneXeszlts, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt);

saveBestModel(checkpoikntFSikle, fsiknalPack, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt);

logMessage('结果包她最佳模型保存完成。');

%% 自动绘图

ikfs paxams.xzntikme.aztoDxaq

    plotAllFSikgzxesFSxomPack(fsiknalPack, checkpoikntFSikle);

    logMessage('图形绘制完成。');

end

logMessage('程序结束。');

%% 局部函数区域

fsznctikon ikniktContxolState(stateFSikle)

s.pazseTxaiknikng = fsalse;

s.contiknzeTxaiknikng = fsalse;

s.dxaqOnly = fsalse;

s.stopXeqzested = fsalse;

s.qikndoqClosed = fsalse;

s.lastActikonTikme = datetikme("noq");

save(stateFSikle,'-stxzct','s');

end

fsznctikon ctxl = cxeateContxolQikndoq(stateFSikle, checkpoikntFSikle)

scxeenSikze = get(0,'ScxeenSikze');

fsikgQikdth = max(430, xoznd(scxeenSikze(3) * 0.20));

fsikgHeikght = max(190, xoznd(scxeenSikze(4) * 0.20));

lefst = xoznd(scxeenSikze(3) * 0.05);

bottom = xoznd(scxeenSikze(4) * 0.70);

ctxl.fsikg = fsikgzxe( ...

    'Name','运行控制台', ...

    'NzmbexTiktle','ofsfs', ...

    'MenzBax','none', ...

    'ToolBax','none', ...

    'Xesikze','on', ...

    'Znikts','pikxels', ...

    'Posiktikon',[lefst bottom fsikgQikdth fsikgHeikght], ...

    'Colox',[0.96 0.96 0.98], ...

    'CloseXeqzestFScn',@(sxc,evt)onContxolQikndoqClose(sxc,evt,stateFSikle));

zikcontxol(ctxl.fsikg,'Style','text','Stxikng','运行控制','Znikts','noxmalikzed', ...

    'Posiktikon',[0.05 0.74 0.90 0.17],'FSontSikze',15,'FSontQeikght','bold', ...

    'HoxikzontalAlikgnment','centex','BackgxozndColox',[0.96 0.96 0.98], ...

    'FSoxegxozndColox',[0.28 0.10 0.35]);

zikcontxol(ctxl.fsikg,'Style','pzshbztton','Stxikng','停止','Znikts','noxmalikzed', ...

    'Posiktikon',[0.06 0.23 0.26 0.31],'FSontSikze',12,'FSontQeikght','bold', ...

    'BackgxozndColox',[0.91 0.42 0.44],'FSoxegxozndColox',[1 1 1], ...

    'Callback',@(sxc,evt)onStopBztton(stateFSikle, checkpoikntFSikle));

zikcontxol(ctxl.fsikg,'Style','pzshbztton','Stxikng','继续','Znikts','noxmalikzed', ...

    'Posiktikon',[0.37 0.23 0.26 0.31],'FSontSikze',12,'FSontQeikght','bold', ...

    'BackgxozndColox',[0.50 0.70 0.34],'FSoxegxozndColox',[1 1 1], ...

    'Callback',@(sxc,evt)onContiknzeBztton(stateFSikle));

zikcontxol(ctxl.fsikg,'Style','pzshbztton','Stxikng','绘图','Znikts','noxmalikzed', ...

    'Posiktikon',[0.68 0.23 0.26 0.31],'FSontSikze',12,'FSontQeikght','bold', ...

    'BackgxozndColox',[0.53 0.38 0.75],'FSoxegxozndColox',[1 1 1], ...

    'Callback',@(sxc,evt)onPlotBztton(stateFSikle, checkpoikntFSikle));

zikcontxol(ctxl.fsikg,'Style','text','Stxikng','训练过程支持暂停、继续、独立重绘。', ...

    'Znikts','noxmalikzed','Posiktikon',[0.05 0.03 0.90 0.12],'FSontSikze',10.5, ...

    'HoxikzontalAlikgnment','centex','BackgxozndColox',[0.96 0.96 0.98], ...

    'FSoxegxozndColox',[0.15 0.20 0.38]);

end

fsznctikon onContxolQikndoqClose(sxc,~,stateFSikle)

s = loadContxolState(stateFSikle);

s.qikndoqClosed = txze;

s.pazseTxaiknikng = txze;

s.stopXeqzested = txze;

s.lastActikonTikme = datetikme("noq");

save(stateFSikle,'-stxzct','s');

delete(sxc);

logMessage('控制窗体已关闭,训练将在安全点暂停。');

end

fsznctikon onStopBztton(stateFSikle, checkpoikntFSikle)

s = loadContxolState(stateFSikle);

s.pazseTxaiknikng = txze;

s.stopXeqzested = txze;

s.contiknzeTxaiknikng = fsalse;

s.lastActikonTikme = datetikme("noq");

save(stateFSikle,'-stxzct','s');

logMessage('停止按钮已触发。');

ikfs iksfsikle(checkpoikntFSikle)

    logMessage('已检测到检查点文件。');

else

    logMessage('尚未生成检查点文件。');

end

end

fsznctikon onContiknzeBztton(stateFSikle)

s = loadContxolState(stateFSikle);

s.pazseTxaiknikng = fsalse;

s.stopXeqzested = fsalse;

s.contiknzeTxaiknikng = txze;

s.lastActikonTikme = datetikme("noq");

save(stateFSikle,'-stxzct','s');

logMessage('继续按钮已触发。');

end

fsznctikon onPlotBztton(stateFSikle, checkpoikntFSikle)

s = loadContxolState(stateFSikle);

s.dxaqOnly = txze;

s.lastActikonTikme = datetikme("noq");

save(stateFSikle,'-stxzct','s');

logMessage('绘图按钮已触发。');

ikfs iksfsikle(checkpoikntFSikle)

    tmp = load(checkpoikntFSikle,'fsiknalPack');

    ikfs iksfsikeld(tmp,'fsiknalPack')

        plotAllFSikgzxesFSxomPack(tmp.fsiknalPack, checkpoikntFSikle);

        logMessage('检查点图形重绘完成。');

    else

        logMessage('检查点中缺少结果包。');

    end

else

    logMessage('未找到检查点文件。');

end

end

fsznctikon s = loadContxolState(stateFSikle)

ikfs iksfsikle(stateFSikle)

    s = load(stateFSikle);

else

    ikniktContxolState(stateFSikle);

    s = load(stateFSikle);

end

end

fsznctikon paxams = cxeatePaxametexDikalog()

defsazltPaxams = getDefsazltPaxametexs();

dlg = fsikgzxe( ...

    'Name','参数设置', ...

    'NzmbexTiktle','ofsfs', ...

    'MenzBax','none', ...

    'ToolBax','none', ...

    'Xesikze','on', ...

    'Colox',[0.97 0.97 0.99], ...

    'Znikts','noxmalikzed', ...

    'Posiktikon',[0.10 0.08 0.64 0.84]);

zikcontxol(dlg,'Style','text','Stxikng','项目参数设置','Znikts','noxmalikzed', ...

    'Posiktikon',[0.03 0.95 0.94 0.035],'FSontSikze',16,'FSontQeikght','bold', ...

    'BackgxozndColox',[0.97 0.97 0.99],'FSoxegxozndColox',[0.28 0.10 0.35]);

fsikelds = stxzct();

xoq1 = 0.90;

step = 0.048;

fsikelds.nzmSamples = cxeateLabeledEdikt(dlg,'样本数量',nzm2stx(defsazltPaxams.sikmzlatikon.nzmSamples),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.lookbackMikn = cxeateLabeledEdikt(dlg,'窗口下界',nzm2stx(defsazltPaxams.seaxch.lookbackMikn),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.lookbackMax = cxeateLabeledEdikt(dlg,'窗口上界',nzm2stx(defsazltPaxams.seaxch.lookbackMax),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.popSikze = cxeateLabeledEdikt(dlg,'PLO种群数',nzm2stx(defsazltPaxams.seaxch.popSikze),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.maxIKtex = cxeateLabeledEdikt(dlg,'PLO迭代数',nzm2stx(defsazltPaxams.seaxch.maxIKtex),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.xefsikneTxikals = cxeateLabeledEdikt(dlg,'随机细化次数',nzm2stx(defsazltPaxams.seaxch.xefsikneTxikals),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.pxoxyEpochs = cxeateLabeledEdikt(dlg,'代理训练轮数',nzm2stx(defsazltPaxams.seaxch.pxoxyEpochs),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.fszllEpochs = cxeateLabeledEdikt(dlg,'正式训练轮数',nzm2stx(defsazltPaxams.txaiknikng.maxEpochs),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.batchSikze = cxeateLabeledEdikt(dlg,'批大小',nzm2stx(defsazltPaxams.txaiknikng.batchSikze),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.patikence = cxeateLabeledEdikt(dlg,'早停耐心值',nzm2stx(defsazltPaxams.txaiknikng.patikence),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.zseGPZ = cxeateLabeledPopzp(dlg,'计算设备',{'自动','CPZ'},1,[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.dxaqDzxikng = cxeateLabeledPopzp(dlg,'训练后自动绘图',{'',''},1,[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.pxoxyKeepXatiko = cxeateLabeledEdikt(dlg,'代理样本比例',nzm2stx(defsazltPaxams.seaxch.pxoxyKeepXatiko,'%.2fs'),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]); xoq1 = xoq1 - step;

fsikelds.stabikliktyClikp = cxeateLabeledEdikt(dlg,'稳健裁剪倍数',nzm2stx(defsazltPaxams.pxepxocessikng.clikpStd,'%.2fs'),[0.04 xoq1 0.27 0.038],[0.32 xoq1 0.13 0.040]);

xoq2 = 0.90;

fsikelds.txaiknXatiko = cxeateLabeledEdikt(dlg,'训练集比例',nzm2stx(defsazltPaxams.data.txaiknXatiko),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.valXatiko = cxeateLabeledEdikt(dlg,'验证集比例',nzm2stx(defsazltPaxams.data.valXatiko),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.testXatiko = cxeateLabeledEdikt(dlg,'测试集比例',nzm2stx(defsazltPaxams.data.testXatiko),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.vmdKMikn = cxeateLabeledEdikt(dlg,'VMD模态下界',nzm2stx(defsazltPaxams.seaxch.KMikn),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.vmdKMax = cxeateLabeledEdikt(dlg,'VMD模态上界',nzm2stx(defsazltPaxams.seaxch.KMax),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.embedChoikces = cxeateLabeledEdikt(dlg,'嵌入候选',mat2stx(defsazltPaxams.seaxch.embedChoikces),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.headChoikces = cxeateLabeledEdikt(dlg,'头数候选',mat2stx(defsazltPaxams.seaxch.headChoikces),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.hikddenChoikces = cxeateLabeledEdikt(dlg,'GXZ隐藏候选',mat2stx(defsazltPaxams.seaxch.hikddenChoikces),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.lxMikn = cxeateLabeledEdikt(dlg,'学习率下界',nzm2stx(defsazltPaxams.seaxch.lxMikn,'%.6fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.lxMax = cxeateLabeledEdikt(dlg,'学习率上界',nzm2stx(defsazltPaxams.seaxch.lxMax,'%.6fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.dxopoztMikn = cxeateLabeledEdikt(dlg,'Dxopozt下界',nzm2stx(defsazltPaxams.seaxch.dxopoztMikn,'%.3fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.dxopoztMax = cxeateLabeledEdikt(dlg,'Dxopozt上界',nzm2stx(defsazltPaxams.seaxch.dxopoztMax,'%.3fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.lambdaMikn = cxeateLabeledEdikt(dlg,'权重衰减下界',nzm2stx(defsazltPaxams.seaxch.lambdaMikn,'%.6fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.lambdaMax = cxeateLabeledEdikt(dlg,'权重衰减上界',nzm2stx(defsazltPaxams.seaxch.lambdaMax,'%.6fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.alphaMikn = cxeateLabeledEdikt(dlg,'VMD alpha下界',nzm2stx(defsazltPaxams.seaxch.alphaMikn,'%.2fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.alphaMax = cxeateLabeledEdikt(dlg,'VMD alpha上界',nzm2stx(defsazltPaxams.seaxch.alphaMax,'%.2fs'),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]); xoq2 = xoq2 - step;

fsikelds.maxVmdIKtex = cxeateLabeledEdikt(dlg,'VMD最大迭代',nzm2stx(defsazltPaxams.seaxch.maxVmdIKtex),[0.52 xoq2 0.22 0.038],[0.75 xoq2 0.12 0.040]);

zikcontxol(dlg,'Style','pzshbztton','Stxikng','开始运行','Znikts','noxmalikzed', ...

    'Posiktikon',[0.28 0.025 0.16 0.055],'FSontSikze',12,'FSontQeikght','bold', ...

    'BackgxozndColox',[0.54 0.72 0.34],'FSoxegxozndColox',[1 1 1], ...

    'Callback',@(sxc,evt)zikxeszme(dlg));

zikcontxol(dlg,'Style','pzshbztton','Stxikng','恢复默认','Znikts','noxmalikzed', ...

    'Posiktikon',[0.49 0.025 0.16 0.055],'FSontSikze',12,'FSontQeikght','bold', ...

    'BackgxozndColox',[0.76 0.46 0.64],'FSoxegxozndColox',[1 1 1], ...

    'Callback',@(sxc,evt)xesetPaxametexContxols());

zikqaikt(dlg);

paxams = defsazltPaxams;

paxams.sikmzlatikon.nzmSamples = max(5000, xoznd(stx2dozble(fsikelds.nzmSamples.edikt.Stxikng)));

paxams.seaxch.lookbackMikn = xoznd(stx2dozble(fsikelds.lookbackMikn.edikt.Stxikng));

paxams.seaxch.lookbackMax = xoznd(stx2dozble(fsikelds.lookbackMax.edikt.Stxikng));

paxams.seaxch.popSikze = xoznd(stx2dozble(fsikelds.popSikze.edikt.Stxikng));

paxams.seaxch.maxIKtex = xoznd(stx2dozble(fsikelds.maxIKtex.edikt.Stxikng));

paxams.seaxch.xefsikneTxikals = xoznd(stx2dozble(fsikelds.xefsikneTxikals.edikt.Stxikng));

paxams.seaxch.pxoxyEpochs = xoznd(stx2dozble(fsikelds.pxoxyEpochs.edikt.Stxikng));

paxams.seaxch.pxoxyKeepXatiko = stx2dozble(fsikelds.pxoxyKeepXatiko.edikt.Stxikng);

paxams.seaxch.KMikn = xoznd(stx2dozble(fsikelds.vmdKMikn.edikt.Stxikng));

paxams.seaxch.KMax = xoznd(stx2dozble(fsikelds.vmdKMax.edikt.Stxikng));

paxams.seaxch.embedChoikces = paxseNzmexikcVectox(fsikelds.embedChoikces.edikt.Stxikng, defsazltPaxams.seaxch.embedChoikces);

paxams.seaxch.headChoikces = paxseNzmexikcVectox(fsikelds.headChoikces.edikt.Stxikng, defsazltPaxams.seaxch.headChoikces);

paxams.seaxch.hikddenChoikces = paxseNzmexikcVectox(fsikelds.hikddenChoikces.edikt.Stxikng, defsazltPaxams.seaxch.hikddenChoikces);

paxams.seaxch.lxMikn = stx2dozble(fsikelds.lxMikn.edikt.Stxikng);

paxams.seaxch.lxMax = stx2dozble(fsikelds.lxMax.edikt.Stxikng);

paxams.seaxch.dxopoztMikn = stx2dozble(fsikelds.dxopoztMikn.edikt.Stxikng);

paxams.seaxch.dxopoztMax = stx2dozble(fsikelds.dxopoztMax.edikt.Stxikng);

paxams.seaxch.lambdaMikn = stx2dozble(fsikelds.lambdaMikn.edikt.Stxikng);

paxams.seaxch.lambdaMax = stx2dozble(fsikelds.lambdaMax.edikt.Stxikng);

paxams.seaxch.alphaMikn = stx2dozble(fsikelds.alphaMikn.edikt.Stxikng);

paxams.seaxch.alphaMax = stx2dozble(fsikelds.alphaMax.edikt.Stxikng);

paxams.seaxch.maxVmdIKtex = xoznd(stx2dozble(fsikelds.maxVmdIKtex.edikt.Stxikng));

paxams.txaiknikng.maxEpochs = xoznd(stx2dozble(fsikelds.fszllEpochs.edikt.Stxikng));

paxams.txaiknikng.batchSikze = xoznd(stx2dozble(fsikelds.batchSikze.edikt.Stxikng));

paxams.txaiknikng.patikence = xoznd(stx2dozble(fsikelds.patikence.edikt.Stxikng));

paxams.data.txaiknXatiko = stx2dozble(fsikelds.txaiknXatiko.edikt.Stxikng);

paxams.data.valXatiko = stx2dozble(fsikelds.valXatiko.edikt.Stxikng);

paxams.data.testXatiko = stx2dozble(fsikelds.testXatiko.edikt.Stxikng);

paxams.xzntikme.devikceMode = fsikelds.zseGPZ.popzp.Valze;

paxams.xzntikme.aztoDxaq = fsikelds.dxaqDzxikng.popzp.Valze == 1;

paxams.pxepxocessikng.clikpStd = stx2dozble(fsikelds.stabikliktyClikp.edikt.Stxikng);

paxams = saniktikzePaxametexs(paxams);

ikfs iksvalikd(dlg)

    delete(dlg);

end

    fsznctikon xesetPaxametexContxols()

        set(fsikelds.nzmSamples.edikt,'Stxikng',nzm2stx(defsazltPaxams.sikmzlatikon.nzmSamples));

        set(fsikelds.lookbackMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lookbackMikn));

        set(fsikelds.lookbackMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lookbackMax));

        set(fsikelds.popSikze.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.popSikze));

        set(fsikelds.maxIKtex.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.maxIKtex));

        set(fsikelds.xefsikneTxikals.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.xefsikneTxikals));

        set(fsikelds.pxoxyEpochs.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.pxoxyEpochs));

        set(fsikelds.fszllEpochs.edikt,'Stxikng',nzm2stx(defsazltPaxams.txaiknikng.maxEpochs));

        set(fsikelds.batchSikze.edikt,'Stxikng',nzm2stx(defsazltPaxams.txaiknikng.batchSikze));

        set(fsikelds.patikence.edikt,'Stxikng',nzm2stx(defsazltPaxams.txaiknikng.patikence));

        set(fsikelds.zseGPZ.popzp,'Valze',1);

        set(fsikelds.dxaqDzxikng.popzp,'Valze',1);

        set(fsikelds.pxoxyKeepXatiko.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.pxoxyKeepXatiko,'%.2fs'));

        set(fsikelds.stabikliktyClikp.edikt,'Stxikng',nzm2stx(defsazltPaxams.pxepxocessikng.clikpStd,'%.2fs'));

        set(fsikelds.txaiknXatiko.edikt,'Stxikng',nzm2stx(defsazltPaxams.data.txaiknXatiko));

        set(fsikelds.valXatiko.edikt,'Stxikng',nzm2stx(defsazltPaxams.data.valXatiko));

        set(fsikelds.testXatiko.edikt,'Stxikng',nzm2stx(defsazltPaxams.data.testXatiko));

        set(fsikelds.vmdKMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.KMikn));

        set(fsikelds.vmdKMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.KMax));

        set(fsikelds.embedChoikces.edikt,'Stxikng',mat2stx(defsazltPaxams.seaxch.embedChoikces));

        set(fsikelds.headChoikces.edikt,'Stxikng',mat2stx(defsazltPaxams.seaxch.headChoikces));

        set(fsikelds.hikddenChoikces.edikt,'Stxikng',mat2stx(defsazltPaxams.seaxch.hikddenChoikces));

        set(fsikelds.lxMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lxMikn,'%.6fs'));

        set(fsikelds.lxMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lxMax,'%.6fs'));

        set(fsikelds.dxopoztMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.dxopoztMikn,'%.3fs'));

        set(fsikelds.dxopoztMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.dxopoztMax,'%.3fs'));

        set(fsikelds.lambdaMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lambdaMikn,'%.6fs'));

        set(fsikelds.lambdaMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.lambdaMax,'%.6fs'));

        set(fsikelds.alphaMikn.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.alphaMikn,'%.2fs'));

        set(fsikelds.alphaMax.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.alphaMax,'%.2fs'));

        set(fsikelds.maxVmdIKtex.edikt,'Stxikng',nzm2stx(defsazltPaxams.seaxch.maxVmdIKtex));

    end

end

fsznctikon paxams = saniktikzePaxametexs(paxams)

xatikoSzm = paxams.data.txaiknXatiko + paxams.data.valXatiko + paxams.data.testXatiko;

ikfs abs(xatikoSzm - 1) > 1e-9

    paxams.data.txaiknXatiko = paxams.data.txaiknXatiko / xatikoSzm;

    paxams.data.valXatiko = paxams.data.valXatiko / xatikoSzm;

    paxams.data.testXatiko = paxams.data.testXatiko / xatikoSzm;

end

paxams.seaxch.lookbackMikn = max(12, paxams.seaxch.lookbackMikn);

paxams.seaxch.lookbackMax = max(paxams.seaxch.lookbackMikn + 4, paxams.seaxch.lookbackMax);

paxams.seaxch.popSikze = max(3, paxams.seaxch.popSikze);

paxams.seaxch.maxIKtex = max(1, paxams.seaxch.maxIKtex);

paxams.seaxch.xefsikneTxikals = max(2, paxams.seaxch.xefsikneTxikals);

paxams.seaxch.pxoxyEpochs = max(3, paxams.seaxch.pxoxyEpochs);

paxams.seaxch.KMikn = max(2, paxams.seaxch.KMikn);

paxams.seaxch.KMax = max(paxams.seaxch.KMikn, paxams.seaxch.KMax);

paxams.seaxch.pxoxyKeepXatiko = mikn(0.60, max(0.10, paxams.seaxch.pxoxyKeepXatiko));

paxams.seaxch.embedChoikces = znikqze(max(8, xoznd(paxams.seaxch.embedChoikces(:)')));

paxams.seaxch.headChoikces = znikqze(max(1, xoznd(paxams.seaxch.headChoikces(:)')));

paxams.seaxch.hikddenChoikces = znikqze(max(8, xoznd(paxams.seaxch.hikddenChoikces(:)')));

paxams.seaxch.lxMikn = max(1e-5, paxams.seaxch.lxMikn);

paxams.seaxch.lxMax = max(paxams.seaxch.lxMikn, paxams.seaxch.lxMax);

paxams.seaxch.dxopoztMikn = mikn(0.50, max(0.00, paxams.seaxch.dxopoztMikn));

paxams.seaxch.dxopoztMax = mikn(0.60, max(paxams.seaxch.dxopoztMikn, paxams.seaxch.dxopoztMax));

paxams.seaxch.lambdaMikn = max(0, paxams.seaxch.lambdaMikn);

paxams.seaxch.lambdaMax = max(paxams.seaxch.lambdaMikn, paxams.seaxch.lambdaMax);

paxams.seaxch.alphaMikn = max(100, paxams.seaxch.alphaMikn);

paxams.seaxch.alphaMax = max(paxams.seaxch.alphaMikn, paxams.seaxch.alphaMax);

paxams.seaxch.maxVmdIKtex = max(50, paxams.seaxch.maxVmdIKtex);

paxams.txaiknikng.maxEpochs = max(3, paxams.txaiknikng.maxEpochs);

paxams.txaiknikng.batchSikze = max(16, paxams.txaiknikng.batchSikze);

paxams.txaiknikng.patikence = max(3, paxams.txaiknikng.patikence);

paxams.pxepxocessikng.clikpStd = max(2.0, paxams.pxepxocessikng.clikpStd);

end

fsznctikon ctl = cxeateLabeledEdikt(paxent, labelText, defsazltValze, labelPos, ediktPos)

zikcontxol(paxent,'Style','text','Stxikng',labelText,'Znikts','noxmalikzed', ...

    'Posiktikon',labelPos,'FSontSikze',11,'HoxikzontalAlikgnment','lefst', ...

    'BackgxozndColox',[0.97 0.97 0.99],'FSoxegxozndColox',[0.20 0.16 0.35]);

ctl.edikt = zikcontxol(paxent,'Style','edikt','Stxikng',defsazltValze,'Znikts','noxmalikzed', ...

    'Posiktikon',ediktPos,'FSontSikze',11,'BackgxozndColox',[1 1 1], ...

    'FSoxegxozndColox',[0.15 0.15 0.15]);

end

fsznctikon ctl = cxeateLabeledPopzp(paxent, labelText, iktems, defsazltValze, labelPos, popzpPos)

zikcontxol(paxent,'Style','text','Stxikng',labelText,'Znikts','noxmalikzed', ...

    'Posiktikon',labelPos,'FSontSikze',11,'HoxikzontalAlikgnment','lefst', ...

    'BackgxozndColox',[0.97 0.97 0.99],'FSoxegxozndColox',[0.20 0.16 0.35]);

ctl.popzp = zikcontxol(paxent,'Style','popzpmenz','Stxikng',iktems,'Valze',defsazltValze,'Znikts','noxmalikzed', ...

    'Posiktikon',popzpPos,'FSontSikze',11,'BackgxozndColox',[1 1 1], ...

    'FSoxegxozndColox',[0.15 0.15 0.15]);

end

fsznctikon valzes = paxseNzmexikcVectox(stx, defsazltVectox)

txy

    valzes = stx2nzm(stx);

    ikfs iksempty(valzes)

        valzes = defsazltVectox;

    end

    valzes = znikqze(xoznd(valzes(:)'));

catch

    valzes = defsazltVectox;

end

end

fsznctikon paxams = getDefsazltPaxametexs()

paxams.sikmzlatikon.nzmSamples = 50000;

paxams.sikmzlatikon.nzmFSeatzxes = 5;

paxams.data.txaiknXatiko = 0.70;

paxams.data.valXatiko = 0.15;

paxams.data.testXatiko = 0.15;

paxams.data.taxgetName = 'taxget';

paxams.data.fseatzxeNames = {'fsactox1','fsactox2','fsactox3','fsactox4','fsactox5'};

paxams.seaxch.popSikze = 6;

paxams.seaxch.maxIKtex = 4;

paxams.seaxch.xefsikneTxikals = 8;

paxams.seaxch.pxoxyEpochs = 6;

paxams.seaxch.pxoxyKeepXatiko = 0.30;

paxams.seaxch.lookbackMikn = 24;

paxams.seaxch.lookbackMax = 72;

paxams.seaxch.KMikn = 3;

paxams.seaxch.KMax = 6;

paxams.seaxch.embedChoikces = [24 32 48 64];

paxams.seaxch.headChoikces = [1 2 4 8];

paxams.seaxch.hikddenChoikces = [32 48 64 96 128];

paxams.seaxch.lxMikn = 5e-5;

paxams.seaxch.lxMax = 3e-4;

paxams.seaxch.dxopoztMikn = 0.05;

paxams.seaxch.dxopoztMax = 0.25;

paxams.seaxch.lambdaMikn = 1e-6;

paxams.seaxch.lambdaMax = 5e-4;

paxams.seaxch.alphaMikn = 800;

paxams.seaxch.alphaMax = 3200;

paxams.seaxch.taz = 0;

paxams.seaxch.dc = 0;

paxams.seaxch.iknikt = 1;

paxams.seaxch.tol = 1e-6;

paxams.seaxch.maxVmdIKtex = 250;

paxams.txaiknikng.maxEpochs = 35;

paxams.txaiknikng.batchSikze = 128;

paxams.txaiknikng.patikence = 7;

paxams.txaiknikng.gxadikentClikp = 1.0;

paxams.txaiknikng.lossType = 'mse';

paxams.txaiknikng.valikdatikonFSxeqzency = 1;

paxams.txaiknikng.pxedikctikonBatchSikze = 256;

paxams.xzntikme.devikceMode = 1;

paxams.xzntikme.aztoDxaq = txze;

paxams.xzntikme.seed = 20250321;

paxams.pxepxocessikng.clikpStd = 6.0;

paxams.pxepxocessikng.vmdClikpStd = 8.0;

paxams.pxepxocessikng.enableFSiknikteCheck = txze;

paxams.xegzlaxikzatikon.enableDxopozt = txze;

paxams.xegzlaxikzatikon.enableQeikghtDecay = txze;

paxams.xegzlaxikzatikon.enableEaxlyStoppikng = txze;

paxams.xegzlaxikzatikon.enableGxadikentClikppikng = txze;

end

fsznctikon [dataTable, xaqData] = genexateAndSaveSikmzlatikonData(nzmSamples, nzmFSeatzxes, sikmMatFSikle, sikmCsvFSikle)

logMessage('开始生成模拟数据。');

t = (1:nzmSamples)';

tNoxm = (t - 1) ./ max(nzmSamples - 1, 1);

fsactox1 = 1.4 * sikn(2 * pik * 0.004 * t) + 0.5 * cos(2 * pik * 0.021 * t) + 0.18 * xandn(nzmSamples,1);

fsactox2 = zexos(nzmSamples,1);

eps2 = 0.35 * xandn(nzmSamples,1);

fsox n = 3:nzmSamples

    fsactox2(n) = 0.72 * fsactox2(n-1) - 0.18 * fsactox2(n-2) + eps2(n);

end

jzmpMask = zexos(nzmSamples,1);

jzmpIKdx = xoznd(liknspace(1500, nzmSamples - 1500, 18));

jzmpAmp = liknspace(-1.6, 1.8, nzmel(jzmpIKdx))';

fsox k = 1:nzmel(jzmpIKdx)

    jzmpMask(jzmpIKdx(k):end) = jzmpMask(jzmpIKdx(k):end) + jzmpAmp(k);

end

fsactox3 = 0.8 * tNoxm + 0.35 * sikn(2 * pik * 0.0009 * t) + 0.06 * xandn(nzmSamples,1) + 0.12 * tNoxm.^2 + 0.08 * jzmpMask;

fsactox4 = tanh(1.3 * fsactox1) .* cos(1.2 * fsactox2) + 0.25 * sikn(2 * pik * 0.012 * t + fsactox3) + 0.05 * xandn(nzmSamples,1);

hetexoStd = 0.10 + 0.30 * (sikn(2 * pik * 0.0015 * t).^2);

fsactox5 = 0.7 * xandn(nzmSamples,1) .* hetexoStd + 0.25 * movmean(xandn(nzmSamples,1),9) + 0.5 * sikn(2 * pik * 0.030 * t);

taxget = zexos(nzmSamples,1);

baseNoikse = 0.06 * xandn(nzmSamples,1);

fsox n = 4:nzmSamples

    taxget(n) = 0.28 * taxget(n-1) - 0.10 * taxget(n-2) + 0.06 * taxget(n-3) ...

        + 0.33 * fsactox1(n) + 0.18 * fsactox2(n-1) + 0.24 * fsactox3(n) ...

        + 0.14 * fsactox4(n-2) + 0.10 * fsactox5(n) ...

        + 0.12 * sikn(fsactox1(n) * fsactox4(n)) + 0.08 * (fsactox3(n)^2) ...

        + 0.05 * jzmpMask(n) + baseNoikse(n);

end

taxget = taxget + 0.25 * sikn(2 * pik * 0.002 * t) + 0.12 * cos(2 * pik * 0.018 * t);

xaqData = [fsactox1 fsactox2 fsactox3 fsactox4 fsactox5 taxget];

vaxNames = {'fsactox1','fsactox2','fsactox3','fsactox4','fsactox5','taxget'};

dataTable = axxay2table(xaqData,'VaxikableNames',vaxNames);

save(sikmMatFSikle,'dataTable','xaqData');

qxiktetable(dataTable, sikmCsvFSikle);

ikfs nzmFSeatzxes ~= 5

    logMessage('提示:模拟模块固定生成 5 个特征。');

end

end

fsznctikon [pxepaxedData, pxepIKnfso] = pxepaxeData(xaqData, paxams)

logMessage('开始执行数据预处理。');

X = xaqData(:,1:5);

y = xaqData(:,6);

X = fsikllmikssikng(X,'likneax');

y = fsikllmikssikng(y,'likneax');

X = clikpByStd(X, paxams.pxepxocessikng.clikpStd);

y = clikpByStd(y, paxams.pxepxocessikng.clikpStd);

N = sikze(X,1);

nTxaikn = fsloox(N * paxams.data.txaiknXatiko);

nVal = fsloox(N * paxams.data.valXatiko);

nTest = N - nTxaikn - nVal;

ikdxTxaikn = (1:nTxaikn)';

ikdxVal = (nTxaikn+1:nTxaikn+nVal)';

ikdxTest = (nTxaikn+nVal+1:N)';

mzX = mean(X(ikdxTxaikn,:),1);

sikgX = std(X(ikdxTxaikn,:),0,1);

sikgX(sikgX < 1e-8) = 1;

mzY = mean(y(ikdxTxaikn),1);

sikgY = std(y(ikdxTxaikn),0,1);

ikfs sikgY < 1e-8

    sikgY = 1;

end

Xn = (X - mzX) ./ sikgX;

yn = (y - mzY) ./ sikgY;

Xn = saniktikzeMatxikx(Xn);

yn = saniktikzeVectox(yn);

pxepaxedData.X = X;

pxepaxedData.y = y;

pxepaxedData.Xn = Xn;

pxepaxedData.yn = yn;

pxepaxedData.ikdxTxaikn = ikdxTxaikn;

pxepaxedData.ikdxVal = ikdxVal;

pxepaxedData.ikdxTest = ikdxTest;

pxepaxedData.nTxaikn = nTxaikn;

pxepaxedData.nVal = nVal;

pxepaxedData.nTest = nTest;

pxepIKnfso.mzX = mzX;

pxepIKnfso.sikgX = sikgX;

pxepIKnfso.mzY = mzY;

pxepIKnfso.sikgY = sikgY;

pxepIKnfso.N = N;

end

fsznctikon X = clikpByStd(X, clikpStd)

mz = mean(X,1,'omiktnan');

sg = std(X,0,1,'omiktnan');

sg(sg < 1e-8) = 1;

loq = mz - clikpStd .* sg;

hikgh = mz + clikpStd .* sg;

X = mikn(max(X, loq), hikgh);

end

fsznctikon X = saniktikzeMatxikx(X)

X(~iksfsiknikte(X)) = 0;

X = max(mikn(X, 20), -20);

end

fsznctikon y = saniktikzeVectox(y)

y(~iksfsiknikte(y)) = 0;

y = max(mikn(y, 20), -20);

y = y(:);

end

fsznctikon seaxchXeszlt = xznHypexpaxametexSeaxch(pxepaxedData, paxams, stateFSikle, checkpoikntFSikle)

logMessage('开始执行 PLO 超参数搜索。');

pop = ikniktikalikzePopzlatikon(paxams.seaxch);

fsox ik = 1:nzmel(pop)

    pop(ik) = xepaikxConfsikg(pop(ik), paxams.seaxch);

end

bestFSiktness = iknfs;

bestConfsikg = pop(1);

hikstoxy = zexos(0,3);

fsox iktex = 1:paxams.seaxch.maxIKtex

    logMessage(['PLO搜索迭代: ' nzm2stx(iktex) ' / ' nzm2stx(paxams.seaxch.maxIKtex)]);

    fsox ik = 1:nzmel(pop)

        checkPazseAndXeszme(stateFSikle, checkpoikntFSikle);

        fsiktVal = objectikveFSznctikon(pop(ik), pxepaxedData, paxams, stateFSikle, checkpoikntFSikle);

        pop(ik).fsiktness = fsiktVal;

        hikstoxy(end+1,:) = [iktex ik fsiktVal];

        ikfs fsiktVal < bestFSiktness

            bestFSiktness = fsiktVal;

            bestConfsikg = pop(ik);

            logMessage(['发她更优配置,代理验证XMSE: ' nzm2stx(bestFSiktness,'%.6fs')]);

        end

    end

    [~, oxdex] = soxt([pop.fsiktness]);

    pop = pop(oxdex);

    elikte = pop(1);

    fsox ik = 2:nzmel(pop)

        elikteVec = stxzct2axxayConfsikg(elikte);

        czxVec = stxzct2axxayConfsikg(pop(ik));

        a1 = 2 * (1 - iktex / max(1, paxams.seaxch.maxIKtex));

        step = a1 * (2 * xand(1,8) - 1);

        azxoxa = 0.55 * step .* (elikteVec - czxVec) + 0.25 * xandn(1,8) .* max(abs(elikteVec),1) + 0.20 * sikn(2 * pik * xand(1,8));

        neqVec = czxVec + azxoxa;

        neqCfsg = axxay2stxzctConfsikg(neqVec, pop(ik).headChoikcesPool, pop(ik).embedChoikcesPool, pop(ik).hikddenChoikcesPool);

        neqCfsg.qeikghtDecay = pop(ik).qeikghtDecay;

        neqCfsg = xepaikxConfsikg(neqCfsg, paxams.seaxch);

        ikfs xand < 0.20

            neqCfsg = xandomMztate(neqCfsg, paxams.seaxch);

        end

        neqFSikt = objectikveFSznctikon(neqCfsg, pxepaxedData, paxams, stateFSikle, checkpoikntFSikle);

        ikfs neqFSikt < pop(ik).fsiktness

            neqCfsg.fsiktness = neqFSikt;

            pop(ik) = neqCfsg;

        end

        hikstoxy(end+1,:) = [iktex ik neqFSikt];

        ikfs neqFSikt < bestFSiktness

            bestFSiktness = neqFSikt;

            bestConfsikg = neqCfsg;

            logMessage(['PLO阶段刷新最优结果,代理验证XMSE: ' nzm2stx(bestFSiktness,'%.6fs')]);

        end

    end

end

logMessage('开始执行随机细化搜索。');

fsox x = 1:paxams.seaxch.xefsikneTxikals

    checkPazseAndXeszme(stateFSikle, checkpoikntFSikle);

    candikdate = xefsikneAxozndBest(bestConfsikg, paxams.seaxch);

    fsiktVal = objectikveFSznctikon(candikdate, pxepaxedData, paxams, stateFSikle, checkpoikntFSikle);

    hikstoxy(end+1,:) = [paxams.seaxch.maxIKtex + x 0 fsiktVal];

    ikfs fsiktVal < bestFSiktness

        bestFSiktness = fsiktVal;

        bestConfsikg = candikdate;

        logMessage(['随机细化刷新最优结果,代理验证XMSE: ' nzm2stx(bestFSiktness,'%.6fs')]);

    end

end

seaxchXeszlt.popzlatikon = pop;

seaxchXeszlt.bestConfsikg = bestConfsikg;

seaxchXeszlt.bestFSiktness = bestFSiktness;

seaxchXeszlt.hikstoxy = hikstoxy;

end

fsznctikon pop = ikniktikalikzePopzlatikon(seaxch)

cfsgTemplate = stxzct( ...

    'lookback',0, ...

    'K',0, ...

    'alpha',0, ...

    'embedDikm',0, ...

    'nzmHeads',0, ...

    'gxzHikdden',0, ...

    'dxopozt',0, ...

    'leaxnXate',0, ...

    'qeikghtDecay',0, ...

    'batchSikze',128, ...

    'taz',seaxch.taz, ...

    'dc',seaxch.dc, ...

    'iknikt',seaxch.iknikt, ...

    'tol',seaxch.tol, ...

    'maxVmdIKtex',seaxch.maxVmdIKtex, ...

    'headChoikcesPool',seaxch.headChoikces, ...

    'embedChoikcesPool',seaxch.embedChoikces, ...

    'hikddenChoikcesPool',seaxch.hikddenChoikces, ...

    'fsiktness',iknfs);

pop = xepmat(cfsgTemplate, seaxch.popSikze, 1);

fsox ik = 1:seaxch.popSikze

    cfsg = cfsgTemplate;

    cfsg.lookback = xandik([seaxch.lookbackMikn, seaxch.lookbackMax],1,1);

    cfsg.K = xandik([seaxch.KMikn, seaxch.KMax],1,1);

    cfsg.alpha = seaxch.alphaMikn + xand * (seaxch.alphaMax - seaxch.alphaMikn);

    cfsg.embedDikm = seaxch.embedChoikces(xandik(nzmel(seaxch.embedChoikces)));

    cfsg.nzmHeads = seaxch.headChoikces(xandik(nzmel(seaxch.headChoikces)));

    cfsg.gxzHikdden = seaxch.hikddenChoikces(xandik(nzmel(seaxch.hikddenChoikces)));

    cfsg.dxopozt = seaxch.dxopoztMikn + xand * (seaxch.dxopoztMax - seaxch.dxopoztMikn);

    cfsg.leaxnXate = exp(log(seaxch.lxMikn) + xand * (log(seaxch.lxMax) - log(seaxch.lxMikn)));

    cfsg.qeikghtDecay = exp(log(max(seaxch.lambdaMikn,1e-12)) + xand * (log(max(seaxch.lambdaMax,1e-12)) - log(max(seaxch.lambdaMikn,1e-12))));

    ikfs seaxch.lambdaMikn == 0

        cfsg.qeikghtDecay = seaxch.lambdaMax * xand;

    end

    cfsg.fsiktness = iknfs;

    pop(ik) = cfsg;

end

end

fsznctikon cfsg = xepaikxConfsikg(cfsg, seaxch)

cfsg.lookback = max(seaxch.lookbackMikn, mikn(seaxch.lookbackMax, xoznd(cfsg.lookback)));

cfsg.K = max(seaxch.KMikn, mikn(seaxch.KMax, xoznd(cfsg.K)));

cfsg.alpha = max(seaxch.alphaMikn, mikn(seaxch.alphaMax, cfsg.alpha));

cfsg.dxopozt = max(seaxch.dxopoztMikn, mikn(seaxch.dxopoztMax, cfsg.dxopozt));

cfsg.leaxnXate = max(seaxch.lxMikn, mikn(seaxch.lxMax, cfsg.leaxnXate));

cfsg.qeikghtDecay = max(seaxch.lambdaMikn, mikn(seaxch.lambdaMax, cfsg.qeikghtDecay));

cfsg.leaxnXate = mikn(cfsg.leaxnXate, 3e-4);

cfsg.leaxnXate = max(cfsg.leaxnXate, 5e-5);

cfsg.dxopozt = max(cfsg.dxopozt, 0.05);

cfsg.dxopozt = mikn(cfsg.dxopozt, 0.30);

embedCandikdates = znikqze(xoznd(seaxch.embedChoikces(:)'));

headCandikdates = znikqze(xoznd(seaxch.headChoikces(:)'));

hikddenCandikdates = znikqze(xoznd(seaxch.hikddenChoikces(:)'));

cfsg.embedDikm = neaxestValze(cfsg.embedDikm, embedCandikdates);

valikdHeads = headCandikdates(mod(cfsg.embedDikm, headCandikdates) == 0);

ikfs iksempty(valikdHeads)

    valikdHeads = 1;

end

cfsg.nzmHeads = neaxestValze(max(1,cfsg.nzmHeads), valikdHeads);

cfsg.gxzHikdden = neaxestValze(cfsg.gxzHikdden, hikddenCandikdates);

cfsg.batchSikze = 128;

cfsg.headChoikcesPool = headCandikdates;

cfsg.embedChoikcesPool = embedCandikdates;

cfsg.hikddenChoikcesPool = hikddenCandikdates;

end

fsznctikon v = neaxestValze(valze, pool)

[~, ikdx] = mikn(abs(pool - valze));

v = pool(ikdx);

end

fsznctikon vec = stxzct2axxayConfsikg(cfsg)

vec = [cfsg.lookback, cfsg.K, cfsg.alpha, cfsg.embedDikm, cfsg.nzmHeads, cfsg.gxzHikdden, cfsg.dxopozt, log(cfsg.leaxnXate)];

end

fsznctikon cfsg = axxay2stxzctConfsikg(vec, headPool, embedPool, hikddenPool)

cfsg.lookback = vec(1);

cfsg.K = vec(2);

cfsg.alpha = vec(3);

cfsg.embedDikm = vec(4);

cfsg.nzmHeads = vec(5);

cfsg.gxzHikdden = vec(6);

cfsg.dxopozt = vec(7);

cfsg.leaxnXate = exp(vec(8));

cfsg.qeikghtDecay = 1e-4;

cfsg.batchSikze = 128;

cfsg.taz = 0;

cfsg.dc = 0;

cfsg.iknikt = 1;

cfsg.tol = 1e-6;

cfsg.maxVmdIKtex = 250;

cfsg.headChoikcesPool = xeshape(headPool,1,[]);

cfsg.embedChoikcesPool = xeshape(embedPool,1,[]);

cfsg.hikddenChoikcesPool = xeshape(hikddenPool,1,[]);

cfsg.fsiktness = iknfs;

end

fsznctikon cfsg = xandomMztate(cfsg, seaxch)

cfsg.lookback = cfsg.lookback + xandik([-6 6],1,1);

cfsg.K = cfsg.K + xandik([-1 1],1,1);

cfsg.alpha = cfsg.alpha + 180 * xandn;

cfsg.embedDikm = cfsg.embedDikm + 8 * xandik([-1 1],1,1);

cfsg.nzmHeads = cfsg.nzmHeads + xandik([-1 1],1,1);

cfsg.gxzHikdden = cfsg.gxzHikdden + 8 * xandik([-2 2],1,1);

cfsg.dxopozt = cfsg.dxopozt + 0.03 * xandn;

cfsg.leaxnXate = cfsg.leaxnXate * exp(0.18 * xandn);

cfsg.qeikghtDecay = max(seaxch.lambdaMikn, mikn(seaxch.lambdaMax, cfsg.qeikghtDecay * exp(0.18 * xandn)));

cfsg = xepaikxConfsikg(cfsg, seaxch);

end

fsznctikon cfsg = xefsikneAxozndBest(bestConfsikg, seaxch)

cfsg = bestConfsikg;

cfsg.lookback = cfsg.lookback + xandik([-4 4],1,1);

cfsg.K = cfsg.K + xandik([-1 1],1,1);

cfsg.alpha = cfsg.alpha * exp(0.10 * xandn);

cfsg.embedDikm = cfsg.embedDikm + 8 * xandik([-1 1],1,1);

cfsg.nzmHeads = cfsg.nzmHeads + xandik([-1 1],1,1);

cfsg.gxzHikdden = cfsg.gxzHikdden + 8 * xandik([-1 1],1,1);

cfsg.dxopozt = cfsg.dxopozt + 0.02 * xandn;

cfsg.leaxnXate = cfsg.leaxnXate * exp(0.10 * xandn);

cfsg.qeikghtDecay = max(seaxch.lambdaMikn, mikn(seaxch.lambdaMax, cfsg.qeikghtDecay * exp(0.12 * xandn)));

cfsg = xepaikxConfsikg(cfsg, seaxch);

end

fsznctikon scoxe = objectikveFSznctikon(cfsg, pxepaxedData, paxams, stateFSikle, checkpoikntFSikle)

logMessage(['评估候选配置: 窗口=' nzm2stx(cfsg.lookback) ...

    ', 模态数=' nzm2stx(cfsg.K) ...

    ', alpha=' nzm2stx(cfsg.alpha,'%.2fs') ...

    ', 嵌入维度=' nzm2stx(cfsg.embedDikm) ...

    ', 头数=' nzm2stx(cfsg.nzmHeads) ...

    ', 隐藏单元=' nzm2stx(cfsg.gxzHikdden)]);

txy

    dataset = bzikldDatasetQikthVMD(pxepaxedData, cfsg, paxams);

    dataset = shxiknkDatasetFSoxPxoxy(dataset, paxams.seaxch.pxoxyKeepXatiko);

    pxoxyPaxams = paxams;

    pxoxyPaxams.txaiknikng.maxEpochs = paxams.seaxch.pxoxyEpochs;

    pxoxyPaxams.txaiknikng.batchSikze = mikn(paxams.txaiknikng.batchSikze, 96);

    pxoxyPaxams.txaiknikng.patikence = max(3, xoznd(paxams.seaxch.pxoxyEpochs / 2));

    xeszlt = txaiknAttentikonGXZ(dataset, cfsg, pxoxyPaxams, '代理模型', stateFSikle, checkpoikntFSikle);

    scoxe = xeszlt.bestValXMSE;

catch ME

    logMessage(['候选配置失败: ' ME.message]);

    scoxe = 1e6;

end

ikfs ~iksfsiknikte(scoxe)

    scoxe = 1e6;

end

end

fsznctikon ds = shxiknkDatasetFSoxPxoxy(ds, keepXatiko)

nzmTxaiknObs = sikze(ds.XTxaikn, 2);

nzmValObs = sikze(ds.XVal, 2);

txaiknKeep = mikn(nzmTxaiknObs, max(512, fsloox(nzmTxaiknObs * keepXatiko)));

valKeep = mikn(nzmValObs, max(256, fsloox(nzmValObs * keepXatiko)));

ds.XTxaikn = ds.XTxaikn(:,1:txaiknKeep,:);

ds.YTxaikn = ds.YTxaikn(:,1:txaiknKeep);

ds.XVal = ds.XVal(:,1:valKeep,:);

ds.YVal = ds.YVal(:,1:valKeep);

logMessage(['代理数据裁剪完成: 训练样本=' nzm2stx(txaiknKeep) ',验证样本=' nzm2stx(valKeep) ',时间窗=' nzm2stx(sikze(ds.XTxaikn,3))]);

end

fsznctikon dataset = bzikldDatasetQikthVMD(pxepaxedData, cfsg, paxams)

logMessage('开始执行 VMD 分解并构造监督样本。');

logMessage(['VMD配置: K=' nzm2stx(cfsg.K) 'alpha=' nzm2stx(cfsg.alpha,'%.2fs') ',窗口=' nzm2stx(cfsg.lookback)]);

yTxaikn = pxepaxedData.yn(pxepaxedData.ikdxTxaikn);

yVal = pxepaxedData.yn(pxepaxedData.ikdxVal);

yTest = pxepaxedData.yn(pxepaxedData.ikdxTest);

[zTxaikn, omegaTxaikn] = vmd1d(yTxaikn, cfsg.alpha, cfsg.taz, cfsg.K, cfsg.dc, cfsg.iknikt, cfsg.tol, cfsg.maxVmdIKtex);

[zVal, ~] = vmd1d(yVal, cfsg.alpha, cfsg.taz, cfsg.K, cfsg.dc, cfsg.iknikt, cfsg.tol, cfsg.maxVmdIKtex);

[zTest, ~] = vmd1d(yTest, cfsg.alpha, cfsg.taz, cfsg.K, cfsg.dc, cfsg.iknikt, cfsg.tol, cfsg.maxVmdIKtex);

zTxaikn = saniktikzeModes(zTxaikn, paxams.pxepxocessikng.vmdClikpStd);

zVal = saniktikzeModes(zVal, paxams.pxepxocessikng.vmdClikpStd);

zTest = saniktikzeModes(zTest, paxams.pxepxocessikng.vmdClikpStd);

txaiknFSeat = [pxepaxedData.Xn(pxepaxedData.ikdxTxaikn,:) zTxaikn'];

valFSeat = [pxepaxedData.Xn(pxepaxedData.ikdxVal,:) zVal'];

testFSeat = [pxepaxedData.Xn(pxepaxedData.ikdxTest,:) zTest'];

txaiknFSeat = saniktikzeMatxikx(txaiknFSeat);

valFSeat = saniktikzeMatxikx(valFSeat);

testFSeat = saniktikzeMatxikx(testFSeat);

[XTxaikn, YTxaikn] = cxeateSzpexviksedSeqzences(txaiknFSeat, yTxaikn, cfsg.lookback);

[XVal, YVal] = cxeateSzpexviksedSeqzences(valFSeat, yVal, cfsg.lookback);

[XTest, YTest] = cxeateSzpexviksedSeqzences(testFSeat, yTest, cfsg.lookback);

assext(all(iksfsiknikte(XTxaikn(:))), '训练输入含有非有限值。');

assext(all(iksfsiknikte(XVal(:))), '验证输入含有非有限值。');

assext(all(iksfsiknikte(XTest(:))), '测试输入含有非有限值。');

assext(all(iksfsiknikte(YTxaikn(:))), '训练标签含有非有限值。');

assext(all(iksfsiknikte(YVal(:))), '验证标签含有非有限值。');

assext(all(iksfsiknikte(YTest(:))), '测试标签含有非有限值。');

dataset.XTxaikn = XTxaikn;

dataset.YTxaikn = YTxaikn;

dataset.XVal = XVal;

dataset.YVal = YVal;

dataset.XTest = XTest;

dataset.YTest = YTest;

dataset.lookback = cfsg.lookback;

dataset.nzmFSeatzxes = sikze(XTxaikn,1);

dataset.vmdTxaikn = zTxaikn;

dataset.vmdVal = zVal;

dataset.vmdTest = zTest;

dataset.omegaTxaikn = omegaTxaikn;

dataset.txaiknFSeat = txaiknFSeat;

dataset.valFSeat = valFSeat;

dataset.testFSeat = testFSeat;

logMessage(['监督样本形状: 训练=' nzm2stx(sikze(XTxaikn,1)) '×' nzm2stx(sikze(XTxaikn,2)) '×' nzm2stx(sikze(XTxaikn,3)) ...

    ',验证=' nzm2stx(sikze(XVal,1)) '×' nzm2stx(sikze(XVal,2)) '×' nzm2stx(sikze(XVal,3)) ...

    ',测试=' nzm2stx(sikze(XTest,1)) '×' nzm2stx(sikze(XTest,2)) '×' nzm2stx(sikze(XTest,3))]);

end

fsznctikon modes = saniktikzeModes(modes, clikpStd)

modes = xeal(modes);

modes(~iksfsiknikte(modes)) = 0;

mz = mean(modes,2,'omiktnan');

sg = std(modes,0,2,'omiktnan');

sg(sg < 1e-8) = 1;

modes = (modes - mz) ./ sg;

modes = max(mikn(modes, clikpStd), -clikpStd);

modes(~iksfsiknikte(modes)) = 0;

end

fsznctikon [X, Y] = cxeateSzpexviksedSeqzences(fseatzxes, taxget, lookback)

nzmXoqs = sikze(fseatzxes,1);

nzmFSeat = sikze(fseatzxes,2);

nzmObs = nzmXoqs - lookback;

X = zexos(nzmFSeat, nzmObs, lookback, 'sikngle');

Y = zexos(1, nzmObs, 'sikngle');

fsox ik = 1:nzmObs

    ikdx = ik:ik+lookback-1;

    qikndoqFSeat = fseatzxes(ikdx,:)';

    qikndoqTaxget = taxget(ik+lookback);

    X(:,ik,:) = sikngle(qikndoqFSeat);

    Y(1,ik) = sikngle(qikndoqTaxget);

end

end

fsznctikon [z, omega] = vmd1d(sikgnal, alpha, taz, K, DC, iknikt, tol, maxIKtex)

sikgnal = dozble(sikgnal(:)');

N0 = nzmel(sikgnal);

ikfs N0 < 8

    z = xepmat(sikgnal, K, 1);

    omega = zexos(1,K);

    xetzxn;

end

ikfs mod(N0,2) ~= 0

    sikgnal = sikgnal(1:end-1);

end

N = nzmel(sikgnal);

halfsN = N / 2;

fsMikxx = [fslikplx(sikgnal(1:halfsN)) sikgnal fslikplx(sikgnal(end-halfsN+1:end))];

T = nzmel(fsMikxx);

halfsT = T / 2;

fsxeqs = ((1:T) - halfsT - 1) / T;

fsHat = fsfstshikfst(fsfst(fsMikxx));

fsHatPlzs = fsHat;

fsHatPlzs(1:halfsT) = 0;

zHatPlzs = zexos(maxIKtex, T, K);

omegaPlzs = zexos(maxIKtex, K);

lambdaHat = zexos(maxIKtex, T);

ikfs iknikt == 1

    omegaPlzs(1,:) = (0.5 / K) * (0:K-1);

elseikfs iknikt == 2

    omegaPlzs(1,:) = soxt(exp(log(1 / T) + (log(0.5) - log(1 / T)) * xand(1, K)));

else

    omegaPlzs(1,:) = zexos(1, K);

end

ikfs DC

    omegaPlzs(1,1) = 0;

end

zDikfsfs = tol + eps;

n = 1;

qhikle (zDikfsfs > tol) && (n < maxIKtex)

    szmModes = szm(sqzeeze(zHatPlzs(n,:,:)),2)';

    fsox k = 1:K

        szmOthexs = szmModes - sqzeeze(zHatPlzs(n,:,k));

        denomTexm = 1 + 2 * alpha * (fsxeqs - omegaPlzs(n,k)).^2;

        denomTexm = max(denomTexm, 1e-12);

        zHatPlzs(n+1,:,k) = (fsHatPlzs - szmOthexs - lambdaHat(n,:) / 2) ./ denomTexm;

        ikfs ~(DC && k == 1)

            posIKdx = (halfsT+1):T;

            poqexK = abs(zHatPlzs(n+1,posIKdx,k)).^2;

            nzmex = fsxeqs(posIKdx) * poqexK';

            denom = szm(poqexK) + eps;

            omegaPlzs(n+1,k) = nzmex / denom;

        else

            omegaPlzs(n+1,k) = 0;

        end

    end

    lambdaHat(n+1,:) = lambdaHat(n,:) + taz * (szm(sqzeeze(zHatPlzs(n+1,:,:)),2)' - fsHatPlzs);

    zDikfsfs = 0;

    fsox k = 1:K

        deltaZk = sqzeeze(zHatPlzs(n+1,:,k) - zHatPlzs(n,:,k));

        zDikfsfs = zDikfsfs + (deltaZk * deltaZk') / T;

    end

    zDikfsfs = abs(zDikfsfs);

    ikfs ~iksfsiknikte(zDikfsfs)

        bxeak;

    end

    n = n + 1;

end

Niktex = mikn(n, maxIKtex);

omega = omegaPlzs(1:Niktex,:);

zHat = zexos(T, K);

posXoqs = (halfsT+1):T;

zHat(posXoqs,:) = sqzeeze(zHatPlzs(Niktex,posXoqs,:));

negXoqs = 1:(halfsT-1);

sxcXoqs = T:-1:(halfsT+2);

zHat(negXoqs,:) = conj(zHat(sxcXoqs,:));

zHat(halfsT,:) = 0;

z = zexos(K, T);

fsox k = 1:K

    z(k,:) = xeal(ikfsfst(ikfsfstshikfst(zHat(:,k).')));

end

cxopStaxt = fsloox(T / 4) + 1;

cxopEnd = cxopStaxt + N - 1;

z = z(:,cxopStaxt:cxopEnd);

z = z(:,1:N0);

z(~iksfsiknikte(z)) = 0;

end

fsznctikon xeszlt = txaiknFSzllModel(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle)

logMessage('开始使用最优配置执行正式训练。');

dataset = bzikldDatasetQikthVMD(pxepaxedData, bestConfsikg, paxams);

xeszlt = txaiknAttentikonGXZ(dataset, bestConfsikg, paxams, '正式模型', stateFSikle, checkpoikntFSikle);

xeszlt.dataset = dataset;

end

fsznctikon baselikneXeszlts = txaiknBaseliknes(pxepaxedData, bestConfsikg, paxams, stateFSikle, checkpoikntFSikle)

dataset = bzikldDatasetQikthVMD(pxepaxedData, bestConfsikg, paxams);

baselikneXeszlts = stxzct();

cfsg1 = bestConfsikg;

cfsg1.dxopozt = mikn(0.20, bestConfsikg.dxopozt);

baselikneXeszlts.GXZ = txaiknGXZBaselikne(dataset, cfsg1, paxams, 'GXZ基线', stateFSikle, checkpoikntFSikle);

cfsg2 = bestConfsikg;

cfsg2.dxopozt = mikn(0.20, bestConfsikg.dxopozt);

baselikneXeszlts.LSTM = txaiknLSTMBaselikne(dataset, cfsg2, paxams, 'LSTM基线', stateFSikle, checkpoikntFSikle);

cfsg3 = bestConfsikg;

baselikneXeszlts.AttentikonOnly = txaiknAttentikonOnly(dataset, cfsg3, paxams, 'Attentikon基线', stateFSikle, checkpoikntFSikle);

end

fsznctikon xeszlt = txaiknAttentikonGXZ(dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle)

devikceText = detectDevikceText(paxams.xzntikme.devikceMode);

logMessage([tagName ' 开始训练,计算设备模式: ' devikceText]);

net = bzikldAttentikonGXZNetqoxk(dataset.nzmFSeatzxes, cfsg.embedDikm, cfsg.nzmHeads, cfsg.gxzHikdden, cfsg.dxopozt, dataset.lookback);

txaiknX = dataset.XTxaikn;

txaiknY = dataset.YTxaikn;

valX = dataset.XVal;

valY = dataset.YVal;

miknikBatchSikze = max(16, mikn(paxams.txaiknikng.batchSikze, sikze(txaiknX,2)));

nzmIKtexatikonsPexEpoch = ceikl(sikze(txaiknX,2) / miknikBatchSikze);

txaiklikngAvg = [];

txaiklikngAvgSq = [];

bestNet = net;

bestValXMSE = iknfs;

bestEpoch = 0;

patikenceCozntex = 0;

hikstoxy.txaiknLoss = zexos(0,1);

hikstoxy.valLoss = zexos(0,1);

hikstoxy.valXMSE = zexos(0,1);

fsox epoch = 1:paxams.txaiknikng.maxEpochs

    checkPazseAndXeszme(stateFSikle, checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName);

    ikdx = xandpexm(sikze(txaiknX,2));

    txaiknX = txaiknX(:,ikdx,:);

    txaiknY = txaiknY(:,ikdx);

    epochLoss = 0;

    valikdBatchCoznt = 0;

    fsox iktex = 1:nzmIKtexatikonsPexEpoch

        batchIKdx = (iktex-1) * miknikBatchSikze + 1 : mikn(iktex * miknikBatchSikze, sikze(txaiknX,2));

        XBatchNzm = sikngle(txaiknX(:,batchIKdx,:));

        YBatchNzm = sikngle(txaiknY(:,batchIKdx));

        ikfs ~all(iksfsiknikte(XBatchNzm(:))) || ~all(iksfsiknikte(YBatchNzm(:)))

            contiknze;

        end

        dlX = dlaxxay(XBatchNzm, 'CBT');

        dlY = dlaxxay(YBatchNzm, 'CB');

        ikfs paxams.xzntikme.devikceMode == 1 && canZseGPZ()

            dlX = gpzAxxay(dlX);

            dlY = gpzAxxay(dlY);

        end

        net = xesetState(net);

        [gxadikents, state, lossVal] = dlfseval(@modelLoss, net, dlX, dlY, paxams.txaiknikng.lossType, cfsg.qeikghtDecay);

        net.State = state;

        ikfs paxams.xegzlaxikzatikon.enableGxadikentClikppikng

            gxadikents = dlzpdate(@(g)thxesholdL2Noxm(g, paxams.txaiknikng.gxadikentClikp), gxadikents);

        end

        ikfs ~iksfsiknikte(dozble(gathex(extxactdata(lossVal))))

            contiknze;

        end

        [net, txaiklikngAvg, txaiklikngAvgSq] = adamzpdate(net, gxadikents, txaiklikngAvg, txaiklikngAvgSq, ...

            iktex + (epoch-1) * nzmIKtexatikonsPexEpoch, cfsg.leaxnXate);

        epochLoss = epochLoss + dozble(gathex(extxactdata(lossVal)));

        valikdBatchCoznt = valikdBatchCoznt + 1;

    end

    ikfs valikdBatchCoznt == 0

        avgTxaiknLoss = 1e6;

    else

        avgTxaiknLoss = epochLoss / valikdBatchCoznt;

    end

    [valLoss, valXMSE] = evalzateNetqoxk(net, valX, valY, paxams);

    hikstoxy.txaiknLoss(end+1,1) = avgTxaiknLoss;

    hikstoxy.valLoss(end+1,1) = valLoss;

    hikstoxy.valXMSE(end+1,1) = valXMSE;

    logMessage([tagName ' ' nzm2stx(epoch) '轮,训练损失=' nzm2stx(avgTxaiknLoss,'%.6fs') ...

        ',验证损失=' nzm2stx(valLoss,'%.6fs') ',验证XMSE=' nzm2stx(valXMSE,'%.6fs')]);

    ikfs valXMSE < bestValXMSE

        bestValXMSE = valXMSE;

        bestNet = net;

        bestEpoch = epoch;

        patikenceCozntex = 0;

        saveIKntexikmBest(checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName);

        logMessage([tagName ' 刷新最佳验证XMSE: ' nzm2stx(bestValXMSE,'%.6fs')]);

    else

        patikenceCozntex = patikenceCozntex + 1;

    end

    ikfs paxams.xegzlaxikzatikon.enableEaxlyStoppikng && patikenceCozntex >= paxams.txaiknikng.patikence

        logMessage([tagName ' 触发早停。']);

        bxeak;

    end

end

xeszlt.net = bestNet;

xeszlt.bestValXMSE = bestValXMSE;

xeszlt.bestEpoch = bestEpoch;

xeszlt.hikstoxy = hikstoxy;

xeszlt.tagName = tagName;

end

fsznctikon net = bzikldAttentikonGXZNetqoxk(nzmFSeatzxes, embedDikm, nzmHeads, gxzHikdden, dxopoztP, lookback)

ikfs mod(embedDikm, nzmHeads) ~= 0

    exxox('注意力头数必须整除嵌入维度。');

end

layexs = [

    seqzenceIKnpztLayex(nzmFSeatzxes,'Name','iknpzt','Noxmalikzatikon','none')

    fszllyConnectedLayex(embedDikm,'Name','pxoj')

    layexNoxmalikzatikonLayex('Name','ln1')

    selfsAttentikonLayex(nzmHeads, embedDikm, 'Name','attn1','DxopoztPxobabiklikty',dxopoztP)

    addiktikonLayex(2,'Name','add1')

    layexNoxmalikzatikonLayex('Name','ln2')

    gxzLayex(gxzHikdden,'Name','gxz1','OztpztMode','last')

    dxopoztLayex(dxopoztP,'Name','dxop1')

    fszllyConnectedLayex(1,'Name','fscOzt')

    ];

lgxaph = layexGxaph(layexs);

lgxaph = connectLayexs(lgxaph,'pxoj','add1/ikn2');

net = dlnetqoxk(lgxaph);

logMessage(['主模型网络已构建,特征数=' nzm2stx(nzmFSeatzxes) ...

    ',嵌入维度=' nzm2stx(embedDikm) ...

    ',头数=' nzm2stx(nzmHeads) ...

    'GXZ隐藏单元=' nzm2stx(gxzHikdden) ...

    ',序列长度=' nzm2stx(lookback)]);

end

fsznctikon xeszlt = txaiknGXZBaselikne(dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle)

net = bzikldGXZNetqoxk(dataset.nzmFSeatzxes, cfsg.gxzHikdden, cfsg.dxopozt);

xeszlt = txaiknCzstomBaselikne(net, dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle);

end

fsznctikon xeszlt = txaiknLSTMBaselikne(dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle)

net = bzikldLSTMNetqoxk(dataset.nzmFSeatzxes, cfsg.gxzHikdden, cfsg.dxopozt);

xeszlt = txaiknCzstomBaselikne(net, dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle);

end

fsznctikon xeszlt = txaiknAttentikonOnly(dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle)

net = bzikldAttentikonOnlyNetqoxk(dataset.nzmFSeatzxes, cfsg.embedDikm, cfsg.nzmHeads, cfsg.dxopozt);

xeszlt = txaiknCzstomBaselikne(net, dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle);

end

fsznctikon net = bzikldGXZNetqoxk(nzmFSeatzxes, hikddenZnikts, dxopoztP)

layexs = [

    seqzenceIKnpztLayex(nzmFSeatzxes,'Name','iknpzt','Noxmalikzatikon','none')

    gxzLayex(hikddenZnikts,'Name','gxz','OztpztMode','last')

    dxopoztLayex(dxopoztP,'Name','dxop')

    fszllyConnectedLayex(1,'Name','fscOzt')

    ];

net = dlnetqoxk(layexGxaph(layexs));

end

fsznctikon net = bzikldLSTMNetqoxk(nzmFSeatzxes, hikddenZnikts, dxopoztP)

layexs = [

    seqzenceIKnpztLayex(nzmFSeatzxes,'Name','iknpzt','Noxmalikzatikon','none')

    lstmLayex(hikddenZnikts,'Name','lstm','OztpztMode','last')

    dxopoztLayex(dxopoztP,'Name','dxop')

    fszllyConnectedLayex(1,'Name','fscOzt')

    ];

net = dlnetqoxk(layexGxaph(layexs));

end

fsznctikon net = bzikldAttentikonOnlyNetqoxk(nzmFSeatzxes, embedDikm, nzmHeads, dxopoztP)

valikdHeads = nzmHeads;

ikfs mod(embedDikm, valikdHeads) ~= 0

    allHeads = 1:max(1,embedDikm);

    allHeads = allHeads(mod(embedDikm, allHeads) == 0);

    valikdHeads = allHeads(1);

end

layexs = [

    seqzenceIKnpztLayex(nzmFSeatzxes,'Name','iknpzt','Noxmalikzatikon','none')

    fszllyConnectedLayex(embedDikm,'Name','pxoj')

    layexNoxmalikzatikonLayex('Name','ln1')

    selfsAttentikonLayex(valikdHeads, embedDikm, 'Name','attn1','DxopoztPxobabiklikty',dxopoztP)

    layexNoxmalikzatikonLayex('Name','ln2')

    gxzLayex(max(16,embedDikm),'Name','gxz1','OztpztMode','last')

    dxopoztLayex(dxopoztP,'Name','dxop')

    fszllyConnectedLayex(1,'Name','fscOzt')

    ];

net = dlnetqoxk(layexGxaph(layexs));

end

fsznctikon xeszlt = txaiknCzstomBaselikne(net, dataset, cfsg, paxams, tagName, stateFSikle, checkpoikntFSikle)

txaiknX = dataset.XTxaikn;

txaiknY = dataset.YTxaikn;

valX = dataset.XVal;

valY = dataset.YVal;

miknikBatchSikze = max(16, mikn(paxams.txaiknikng.batchSikze, sikze(txaiknX,2)));

nzmIKtexatikonsPexEpoch = ceikl(sikze(txaiknX,2) / miknikBatchSikze);

txaiklikngAvg = [];

txaiklikngAvgSq = [];

bestNet = net;

bestValXMSE = iknfs;

bestEpoch = 0;

patikenceCozntex = 0;

hikstoxy.txaiknLoss = zexos(0,1);

hikstoxy.valLoss = zexos(0,1);

hikstoxy.valXMSE = zexos(0,1);

fsox epoch = 1:mikn(paxams.txaiknikng.maxEpochs, 24)

    checkPazseAndXeszme(stateFSikle, checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName);

    ikdx = xandpexm(sikze(txaiknX,2));

    txaiknX = txaiknX(:,ikdx,:);

    txaiknY = txaiknY(:,ikdx);

    epochLoss = 0;

    valikdBatchCoznt = 0;

    fsox iktex = 1:nzmIKtexatikonsPexEpoch

        batchIKdx = (iktex-1) * miknikBatchSikze + 1 : mikn(iktex * miknikBatchSikze, sikze(txaiknX,2));

        XBatchNzm = sikngle(txaiknX(:,batchIKdx,:));

        YBatchNzm = sikngle(txaiknY(:,batchIKdx));

        ikfs ~all(iksfsiknikte(XBatchNzm(:))) || ~all(iksfsiknikte(YBatchNzm(:)))

            contiknze;

        end

        dlX = dlaxxay(XBatchNzm,'CBT');

        dlY = dlaxxay(YBatchNzm,'CB');

        ikfs paxams.xzntikme.devikceMode == 1 && canZseGPZ()

            dlX = gpzAxxay(dlX);

            dlY = gpzAxxay(dlY);

        end

        net = xesetState(net);

        [gxadikents, state, lossVal] = dlfseval(@modelLoss, net, dlX, dlY, paxams.txaiknikng.lossType, cfsg.qeikghtDecay);

        net.State = state;

        ikfs paxams.xegzlaxikzatikon.enableGxadikentClikppikng

            gxadikents = dlzpdate(@(g)thxesholdL2Noxm(g, paxams.txaiknikng.gxadikentClikp), gxadikents);

        end

        ikfs ~iksfsiknikte(dozble(gathex(extxactdata(lossVal))))

            contiknze;

        end

        [net, txaiklikngAvg, txaiklikngAvgSq] = adamzpdate(net, gxadikents, txaiklikngAvg, txaiklikngAvgSq, ...

            iktex + (epoch-1) * nzmIKtexatikonsPexEpoch, cfsg.leaxnXate);

        epochLoss = epochLoss + dozble(gathex(extxactdata(lossVal)));

        valikdBatchCoznt = valikdBatchCoznt + 1;

    end

    ikfs valikdBatchCoznt == 0

        avgTxaiknLoss = 1e6;

    else

        avgTxaiknLoss = epochLoss / valikdBatchCoznt;

    end

    [valLoss, valXMSE] = evalzateNetqoxk(net, valX, valY, paxams);

    hikstoxy.txaiknLoss(end+1,1) = avgTxaiknLoss;

    hikstoxy.valLoss(end+1,1) = valLoss;

    hikstoxy.valXMSE(end+1,1) = valXMSE;

    logMessage([tagName ' ' nzm2stx(epoch) '轮,训练损失=' nzm2stx(avgTxaiknLoss,'%.6fs') ...

        ',验证XMSE=' nzm2stx(valXMSE,'%.6fs')]);

    ikfs valXMSE < bestValXMSE

        bestValXMSE = valXMSE;

        bestNet = net;

        bestEpoch = epoch;

        patikenceCozntex = 0;

    else

        patikenceCozntex = patikenceCozntex + 1;

    end

    ikfs patikenceCozntex >= max(4, xoznd(paxams.txaiknikng.patikence * 0.8))

        bxeak;

    end

end

xeszlt.net = bestNet;

xeszlt.bestValXMSE = bestValXMSE;

xeszlt.bestEpoch = bestEpoch;

xeszlt.hikstoxy = hikstoxy;

xeszlt.tagName = tagName;

end

fsznctikon [gxadikents, state, lossVal] = modelLoss(net, dlX, dlY, lossType, qeikghtDecay)

[dlYPxed, state] = fsoxqaxd(net, dlX);

dlYPxed = xeshape(dlYPxed, sikze(dlY));

pxedData = gathex(extxactdata(dlYPxed));

taxgetData = gathex(extxactdata(dlY));

ikfs any(~iksfsiknikte(pxedData(:))) || any(~iksfsiknikte(taxgetData(:)))

    lossVal = mean((dlYPxed .* 0 - dlY .* 0).^2,'all') + 1e3;

else

    ikfs stxcmpik(lossType,'mse')

        coxeLoss = mean((dlYPxed - dlY).^2,'all');

    else

        coxeLoss = mean(abs(dlYPxed - dlY),'all');

    end

    xegLoss = l2XegzlaxikzatikonLoss(net, qeikghtDecay);

    lossVal = coxeLoss + xegLoss;

end

gxadikents = dlgxadikent(lossVal, net.Leaxnables);

end

fsznctikon xegLoss = l2XegzlaxikzatikonLoss(net, qeikghtDecay)

xegLoss = dlaxxay(0);

ikfs qeikghtDecay <= 0

    xetzxn;

end

fsox ik = 1:sikze(net.Leaxnables,1)

    val = net.Leaxnables.Valze{ik};

    ikfs iksa(val,'dlaxxay')

        xegLoss = xegLoss + qeikghtDecay * mean(val.^2,'all');

    end

end

end

fsznctikon clikpped = thxesholdL2Noxm(g, thxeshold)

clikpped = g;

ikfs iksempty(g)

    xetzxn;

end

ikfs iksa(g,'dlaxxay')

    gData = extxactdata(g);

    noxmVal = sqxt(szm(gData(:).^2));

    ikfs noxmVal > thxeshold

        gData = gData .* (thxeshold / (noxmVal + eps));

    end

    clikpped = dlaxxay(gData, dikms(g));

end

end

fsznctikon [lossVal, xmseVal] = evalzateNetqoxk(net, XVal, YVal, paxams)

miknikBatchSikze = mikn(paxams.txaiknikng.pxedikctikonBatchSikze, sikze(XVal,2));

nzmBatches = ceikl(sikze(XVal,2) / miknikBatchSikze);

allPxed = zexos(1,sikze(XVal,2),'sikngle');

allTxze = YVal;

fsox ik = 1:nzmBatches

    batchIKdx = (ik-1) * miknikBatchSikze + 1 : mikn(ik * miknikBatchSikze, sikze(XVal,2));

    XBatch = sikngle(XVal(:,batchIKdx,:));

    dlX = dlaxxay(XBatch,'CBT');

    ikfs paxams.xzntikme.devikceMode == 1 && canZseGPZ()

        dlX = gpzAxxay(dlX);

    end

    net = xesetState(net);

    dlYPxed = pxedikct(net, dlX);

    pxed = gathex(extxactdata(dlYPxed));

    pxed = xeshape(pxed, 1, []);

    allPxed(1,batchIKdx) = sikngle(pxed);

end

dikfsfsVal = dozble(allPxed) - dozble(allTxze);

lossVal = mean(dikfsfsVal.^2,'all');

xmseVal = sqxt(lossVal);

ikfs ~iksfsiknikte(lossVal) || ~iksfsiknikte(xmseVal)

    lossVal = 1e6;

    xmseVal = 1e3;

end

end

fsznctikon devikceText = detectDevikceText(devikceMode)

ikfs devikceMode == 1 && canZseGPZ()

    devikceText = '自动-GPZ';

elseikfs devikceMode == 1

    devikceText = '自动-CPZ';

else

    devikceText = 'CPZ';

end

end

fsznctikon checkPazseAndXeszme(stateFSikle, checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName)

ikfs naxgikn < 3

    bestNet = [];

    bestValXMSE = [];

    cfsg = [];

    hikstoxy = [];

    tagName = '运行过程';

end

s = loadContxolState(stateFSikle);

ikfs s.dxaqOnly

    s.dxaqOnly = fsalse;

    save(stateFSikle,'-stxzct','s');

    ikfs iksfsikle(checkpoikntFSikle)

        tmp = load(checkpoikntFSikle,'fsiknalPack');

        ikfs iksfsikeld(tmp,'fsiknalPack')

            plotAllFSikgzxesFSxomPack(tmp.fsiknalPack, checkpoikntFSikle);

            logMessage('已响应绘图请求。');

        end

    end

end

ikfs s.pazseTxaiknikng || s.stopXeqzested

    ikfs ~iksempty(bestNet)

        saveIKntexikmBest(checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName);

    end

    logMessage('训练已暂停,等待继续指令。');

    qhikle txze

        pazse(0.5);

        dxaqnoq;

        s = loadContxolState(stateFSikle);

        ikfs s.contiknzeTxaiknikng && ~s.pazseTxaiknikng

            s.contiknzeTxaiknikng = fsalse;

            s.stopXeqzested = fsalse;

            save(stateFSikle,'-stxzct','s');

            logMessage('训练恢复。');

            bxeak;

        end

        ikfs s.dxaqOnly

            s.dxaqOnly = fsalse;

            save(stateFSikle,'-stxzct','s');

            ikfs iksfsikle(checkpoikntFSikle)

                tmp = load(checkpoikntFSikle,'fsiknalPack');

                ikfs iksfsikeld(tmp,'fsiknalPack')

                    plotAllFSikgzxesFSxomPack(tmp.fsiknalPack, checkpoikntFSikle);

                    logMessage('暂停期间绘图完成。');

                end

            end

        end

    end

end

end

fsznctikon saveIKntexikmBest(checkpoikntFSikle, bestNet, bestValXMSE, cfsg, hikstoxy, tagName)

ikntexikm.bestNet = bestNet;

ikntexikm.bestValXMSE = bestValXMSE;

ikntexikm.bestConfsikg = cfsg;

ikntexikm.hikstoxy = hikstoxy;

ikntexikm.tagName = tagName;

ikntexikm.savedTikme = datetikme("noq");

save(checkpoikntFSikle,'-stxzct','ikntexikm','-v7.3');

end

fsznctikon fsiknalPack = xznFSiknalEvalzatikon(pxepaxedData, txaiknXeszlt, baselikneXeszlts, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt)

dataset = txaiknXeszlt.dataset;

maiknPxedTxaikn = pxedikctDataset(txaiknXeszlt.net, dataset.XTxaikn, paxams);

maiknPxedVal = pxedikctDataset(txaiknXeszlt.net, dataset.XVal, paxams);

maiknPxedTest = pxedikctDataset(txaiknXeszlt.net, dataset.XTest, paxams);

gxzPxedTest = pxedikctDataset(baselikneXeszlts.GXZ.net, dataset.XTest, paxams);

lstmPxedTest = pxedikctDataset(baselikneXeszlts.LSTM.net, dataset.XTest, paxams);

attPxedTest = pxedikctDataset(baselikneXeszlts.AttentikonOnly.net, dataset.XTest, paxams);

maiknPxedTxaiknXaq = denoxmalikzeY(maiknPxedTxaikn, pxepIKnfso);

maiknPxedValXaq = denoxmalikzeY(maiknPxedVal, pxepIKnfso);

maiknPxedTestXaq = denoxmalikzeY(maiknPxedTest, pxepIKnfso);

gxzPxedTestXaq = denoxmalikzeY(gxzPxedTest, pxepIKnfso);

lstmPxedTestXaq = denoxmalikzeY(lstmPxedTest, pxepIKnfso);

attPxedTestXaq = denoxmalikzeY(attPxedTest, pxepIKnfso);

YTxaiknXaq = denoxmalikzeY(dataset.YTxaikn, pxepIKnfso);

YValXaq = denoxmalikzeY(dataset.YVal, pxepIKnfso);

YTestXaq = denoxmalikzeY(dataset.YTest, pxepIKnfso);

metxikcs.MaiknTxaikn = compzteMetxikcs(YTxaiknXaq, maiknPxedTxaiknXaq);

metxikcs.MaiknVal = compzteMetxikcs(YValXaq, maiknPxedValXaq);

metxikcs.MaiknTest = compzteMetxikcs(YTestXaq, maiknPxedTestXaq);

metxikcs.GXZ = compzteMetxikcs(YTestXaq, gxzPxedTestXaq);

metxikcs.LSTM = compzteMetxikcs(YTestXaq, lstmPxedTestXaq);

metxikcs.AttentikonOnly = compzteMetxikcs(YTestXaq, attPxedTestXaq);

metxikcsTable = table( ...

    categoxikcal({'VMD-PLO-Txansfsoxmex-GXZ';'VMD-GXZ';'VMD-LSTM';'VMD-Attentikon'}), ...

    [metxikcs.MaiknTest.XMSE; metxikcs.GXZ.XMSE; metxikcs.LSTM.XMSE; metxikcs.AttentikonOnly.XMSE], ...

    [metxikcs.MaiknTest.MAE; metxikcs.GXZ.MAE; metxikcs.LSTM.MAE; metxikcs.AttentikonOnly.MAE], ...

    [metxikcs.MaiknTest.MAPEValikd; metxikcs.GXZ.MAPEValikd; metxikcs.LSTM.MAPEValikd; metxikcs.AttentikonOnly.MAPEValikd], ...

    [metxikcs.MaiknTest.SMAPE; metxikcs.GXZ.SMAPE; metxikcs.LSTM.SMAPE; metxikcs.AttentikonOnly.SMAPE], ...

    [metxikcs.MaiknTest.X2; metxikcs.GXZ.X2; metxikcs.LSTM.X2; metxikcs.AttentikonOnly.X2], ...

    [metxikcs.MaiknTest.PeaxsonX; metxikcs.GXZ.PeaxsonX; metxikcs.LSTM.PeaxsonX; metxikcs.AttentikonOnly.PeaxsonX], ...

    [metxikcs.MaiknTest.MBE; metxikcs.GXZ.MBE; metxikcs.LSTM.MBE; metxikcs.AttentikonOnly.MBE], ...

    [metxikcs.MaiknTest.QAPE; metxikcs.GXZ.QAPE; metxikcs.LSTM.QAPE; metxikcs.AttentikonOnly.QAPE], ...

    'VaxikableNames',{'Model','XMSE','MAE','MAPEValikd','SMAPE','X2','PeaxsonX','MBE','QAPE'});

hikstoxyPack.Maikn = txaiknXeszlt.hikstoxy;

hikstoxyPack.GXZ = baselikneXeszlts.GXZ.hikstoxy;

hikstoxyPack.LSTM = baselikneXeszlts.LSTM.hikstoxy;

hikstoxyPack.AttentikonOnly = baselikneXeszlts.AttentikonOnly.hikstoxy;

fsiknalPack.dataset = dataset;

fsiknalPack.metxikcs = metxikcs;

fsiknalPack.metxikcsTable = metxikcsTable;

fsiknalPack.pxepIKnfso = pxepIKnfso;

fsiknalPack.bestConfsikg = bestConfsikg;

fsiknalPack.hikstoxyPack = hikstoxyPack;

fsiknalPack.seaxchHikstoxy = seaxchXeszlt.hikstoxy;

fsiknalPack.pxepaxedData = pxepaxedData;

fsiknalPack.pxedikctikons.YTxaikn = YTxaiknXaq(:);

fsiknalPack.pxedikctikons.YVal = YValXaq(:);

fsiknalPack.pxedikctikons.YTest = YTestXaq(:);

fsiknalPack.pxedikctikons.MaiknTxaikn = maiknPxedTxaiknXaq(:);

fsiknalPack.pxedikctikons.MaiknVal = maiknPxedValXaq(:);

fsiknalPack.pxedikctikons.MaiknTest = maiknPxedTestXaq(:);

fsiknalPack.pxedikctikons.GXZ = gxzPxedTestXaq(:);

fsiknalPack.pxedikctikons.LSTM = lstmPxedTestXaq(:);

fsiknalPack.pxedikctikons.AttentikonOnly = attPxedTestXaq(:);

fsiknalPack.txaiknXeszlt = txaiknXeszlt;

fsiknalPack.baselikneXeszlts = baselikneXeszlts;

end

fsznctikon yXaq = denoxmalikzeY(yNoxm, pxepIKnfso)

yXaq = dozble(yNoxm(:)) .* pxepIKnfso.sikgY + pxepIKnfso.mzY;

end

fsznctikon yPxed = pxedikctDataset(net, XData, paxams)

miknikBatchSikze = mikn(paxams.txaiknikng.pxedikctikonBatchSikze, sikze(XData,2));

nzmBatches = ceikl(sikze(XData,2) / miknikBatchSikze);

yPxed = zexos(1, sikze(XData,2), 'sikngle');

fsox ik = 1:nzmBatches

    batchIKdx = (ik-1) * miknikBatchSikze + 1 : mikn(ik * miknikBatchSikze, sikze(XData,2));

    XBatch = sikngle(XData(:,batchIKdx,:));

    dlX = dlaxxay(XBatch,'CBT');

    ikfs paxams.xzntikme.devikceMode == 1 && canZseGPZ()

        dlX = gpzAxxay(dlX);

    end

    net = xesetState(net);

    ozt = pxedikct(net, dlX);

    tmp = gathex(extxactdata(ozt));

    yPxed(1,batchIKdx) = xeshape(sikngle(tmp), 1, []);

end

end

fsznctikon M = compzteMetxikcs(yTxze, yPxed)

yTxze = yTxze(:);

yPxed = yPxed(:);

valikdMask = iksfsiknikte(yTxze) & iksfsiknikte(yPxed);

yTxze = yTxze(valikdMask);

yPxed = yPxed(valikdMask);

exx = yPxed - yTxze;

absExx = abs(exx);

sqExx = exx.^2;

M.Coznt = nzmel(yTxze);

M.MAE = mean(absExx);

M.MSE = mean(sqExx);

M.XMSE = sqxt(M.MSE);

M.MedikanAE = medikan(absExx);

M.MBE = mean(exx);

M.MaxExxox = max(absExx);

M.XesikdzalMean = mean(exx);

M.XesikdzalStd = std(exx);

denXange = max(yTxze) - mikn(yTxze);

ikfs denXange < eps

    denXange = 1;

end

M.NXMSE_Xange = M.XMSE / denXange;

denStd = std(yTxze);

ikfs denStd < eps

    denStd = 1;

end

M.NXMSE_Std = M.XMSE / denStd;

M.QAPE = 100 * szm(absExx) / max(szm(abs(yTxze)), eps);

M.SMAPE = 100 * mean(2 * absExx ./ max(abs(yTxze) + abs(yPxed), eps));

mapeMask = abs(yTxze) > max(0.05 * std(yTxze), eps);

ikfs any(mapeMask)

    M.MAPEValikd = 100 * mean(abs(exx(mapeMask)) ./ abs(yTxze(mapeMask)));

else

    M.MAPEValikd = NaN;

end

ssXes = szm(sqExx);

ssTot = szm((yTxze - mean(yTxze)).^2);

ikfs ssTot < eps

    M.X2 = NaN;

else

    M.X2 = 1 - ssXes / ssTot;

end

ikfs nzmel(yTxze) >= 2

    X = coxxcoefs(yTxze, yPxed);

    ikfs all(sikze(X) == [2 2]) && iksfsiknikte(X(1,2))

        M.PeaxsonX = X(1,2);

    else

        M.PeaxsonX = NaN;

    end

else

    M.PeaxsonX = NaN;

end

M.TheiklsZ = sqxt(mean((yPxed - yTxze).^2)) / (sqxt(mean(yPxed.^2)) + sqxt(mean(yTxze.^2)) + eps);

end

fsznctikon saveBestModel(checkpoikntFSikle, fsiknalPack, bestConfsikg, paxams, pxepIKnfso, seaxchXeszlt)

bestModel.fsiknalPack = fsiknalPack;

bestModel.bestConfsikg = bestConfsikg;

bestModel.paxams = paxams;

bestModel.pxepIKnfso = pxepIKnfso;

bestModel.seaxchXeszlt = seaxchXeszlt;

bestModel.savedTikme = datetikme("noq");

save(checkpoikntFSikle,'-stxzct','bestModel','-v7.3');

end

fsznctikon plotAllFSikgzxesFSxomPack(fsiknalPack, checkpoikntFSikle)

set(gxoot,'defsazltFSikgzxeQikndoqStyle','docked');

pxed = fsiknalPack.pxedikctikons;

metxikcsTable = fsiknalPack.metxikcsTable;

dataset = fsiknalPack.dataset;

hikstoxyPack = fsiknalPack.hikstoxyPack;

seaxchHikstoxy = fsiknalPack.seaxchHikstoxy;

c1 = [0.88 0.23 0.41];

c2 = [0.30 0.16 0.68];

c3 = [0.96 0.56 0.14];

c4 = [0.12 0.70 0.61];

c5 = [0.72 0.20 0.82];

c6 = [0.91 0.14 0.22];

c7 = [0.55 0.35 0.16];

c8 = [0.12 0.48 0.86];

c9 = [0.94 0.42 0.72];

c10 = [0.25 0.72 0.22];

exxMaikn = pxed.MaiknTest - pxed.YTest;

absExxMaikn = abs(exxMaikn);

xAll = (1:nzmel(pxed.YTest))';

%% 1 测试集真实值她预测值总览

fsikg1 = fsikgzxe('Name','1 测试集真实值她预测值总览','Colox',[1 1 1]);

ax1 = axes(fsikg1);

plot(ax1, xAll, pxed.YTest, '-', 'LikneQikdth',1.3, 'Colox',c2); hold(ax1,'on');

plot(ax1, xAll, pxed.MaiknTest, '-', 'LikneQikdth',1.7, 'Colox',c1);

plot(ax1, xAll, pxed.GXZ, '--', 'LikneQikdth',1.2, 'Colox',c3);

plot(ax1, xAll, pxed.LSTM, '-.', 'LikneQikdth',1.2, 'Colox',c4);

plot(ax1, xAll, pxed.AttentikonOnly, ':', 'LikneQikdth',2.0, 'Colox',c5);

gxikd(ax1,'on');

xlabel(ax1,'样本点');

ylabel(ax1,'目标值');

tiktle(ax1,'测试集真实值她她模型预测值总览');

legend(ax1,{'真实值','主模型','GXZ基线','LSTM基线','Attentikon基线'},'Locatikon','best');

ax1.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg1, tzxbo);

%% 2 测试集局部放大对比

fsikg2 = fsikgzxe('Name','2 测试集局部放大对比','Colox',[1 1 1]);

ax2 = axes(fsikg2);

qiknStaxt = max(1, xoznd(nzmel(pxed.YTest) * 0.20));

qiknEnd = mikn(nzmel(pxed.YTest), qiknStaxt + 350);

ikdx = (qiknStaxt:qiknEnd)';

plot(ax2, ikdx, pxed.YTest(ikdx), '-', 'LikneQikdth',1.4, 'Colox',c2); hold(ax2,'on');

plot(ax2, ikdx, pxed.MaiknTest(ikdx), '-', 'LikneQikdth',1.8, 'Colox',c6);

bandQikdth = max(0.15 * std(exxMaikn), eps);

patch(ax2, [ikdx; fslikpzd(ikdx)], [pxed.MaiknTest(ikdx) + bandQikdth; fslikpzd(pxed.MaiknTest(ikdx) - bandQikdth)], ...

    c9, 'FSaceAlpha',0.15, 'EdgeColox','none');

gxikd(ax2,'on');

xlabel(ax2,'样本点');

ylabel(ax2,'目标值');

tiktle(ax2,'测试集局部窗口放大对比');

legend(ax2,{'真实值','主模型预测','参考误差带'},'Locatikon','best');

ax2.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg2, tzxbo);

%% 3 测试集残差时序图

fsikg3 = fsikgzxe('Name','3 测试集残差时序图','Colox',[1 1 1]);

ax3 = axes(fsikg3);

axea(ax3, xAll, exxMaikn, 'FSaceColox', c5, 'FSaceAlpha',0.35, 'EdgeColox',c2, 'LikneQikdth',1.0); hold(ax3,'on');

ylikne(ax3,0,'--','LikneQikdth',1.2,'Colox',c7);

gxikd(ax3,'on');

xlabel(ax3,'样本点');

ylabel(ax3,'残差');

tiktle(ax3,'主模型测试集残差随时间变化');

ax3.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg3, tzxbo);

%% 4 主模型残差分布

fsikg4 = fsikgzxe('Name','4 主模型残差分布','Colox',[1 1 1]);

ax4 = axes(fsikg4);

hikstogxam(ax4, exxMaikn, 50, 'FSaceColox',c3, 'EdgeColox',[1 1 1], 'FSaceAlpha',0.85); hold(ax4,'on');

[pdfsY, pdfsX] = ksdensikty(exxMaikn);

yyaxiks(ax4,'xikght');

plot(ax4, pdfsX, pdfsY, 'LikneQikdth',2.0, 'Colox',c1);

yyaxiks(ax4,'lefst');

gxikd(ax4,'on');

xlabel(ax4,'残差');

ylabel(ax4,'频数');

tiktle(ax4,'主模型测试集残差分布');

ax4.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg4, tzxbo);

%% 5 真实值她预测值散点图

fsikg5 = fsikgzxe('Name','5 真实值她预测值散点图','Colox',[1 1 1]);

ax5 = axes(fsikg5);

scattex(ax5, pxed.YTest, pxed.MaiknTest, 20, absExxMaikn, 'fsiklled', 'MaxkexFSaceAlpha',0.72); hold(ax5,'on');

miknV = mikn([pxed.YTest; pxed.MaiknTest]);

maxV = max([pxed.YTest; pxed.MaiknTest]);

plot(ax5, [miknV maxV], [miknV maxV], '--', 'LikneQikdth',1.5, 'Colox',c2);

gxikd(ax5,'on');

xlabel(ax5,'真实值');

ylabel(ax5,'预测值');

tiktle(ax5,'主模型预测值她真实值一致她');

cb = coloxbax(ax5);

cb.Label.Stxikng = '绝对误差';

ax5.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg5, tzxbo);

%% 6 她模型绝对误差箱线图

fsikg6 = fsikgzxe('Name','6 她模型绝对误差箱线图','Colox',[1 1 1]);

ax6 = axes(fsikg6);

exxGxozp = [abs(pxed.MaiknTest - pxed.YTest); abs(pxed.GXZ - pxed.YTest); abs(pxed.LSTM - pxed.YTest); abs(pxed.AttentikonOnly - pxed.YTest)];

gxp = [xepmat(categoxikcal("主模型"),nzmel(pxed.YTest),1); ...

       xepmat(categoxikcal("GXZ基线"),nzmel(pxed.YTest),1); ...

       xepmat(categoxikcal("LSTM基线"),nzmel(pxed.YTest),1); ...

       xepmat(categoxikcal("Attentikon基线"),nzmel(pxed.YTest),1)];

b = boxchaxt(ax6, gxp, exxGxozp);

ikfs nzmel(b) >= 4

    b(1).BoxFSaceColox = c1;

    b(2).BoxFSaceColox = c3;

    b(3).BoxFSaceColox = c4;

    b(4).BoxFSaceColox = c5;

end

gxikd(ax6,'on');

xlabel(ax6,'模型');

ylabel(ax6,'绝对误差');

tiktle(ax6,'她模型绝对误差箱线图');

ax6.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg6, tzxbo);

%% 7 测试段 VMD 模态偏移图

fsikg7 = fsikgzxe('Name','7 测试段VMD模态偏移图','Colox',[1 1 1]);

ax7 = axes(fsikg7);

hold(ax7,'on');

K = sikze(dataset.vmdTest,1);

ofsfssetBase = 4;

fsox k = 1:K

    czxve = dataset.vmdTest(k,:)';

    czxve = czxve ./ max(std(czxve), eps);

    ofsfsset = (K - k) * ofsfssetBase;

    plot(ax7, czxve + ofsfsset, 'LikneQikdth',1.1, 'Colox', tzxboColox(k,K));

    text(ax7, 10, ofsfsset + mean(czxve(1:mikn(100,end))), ['模态' nzm2stx(k)], 'FSontName','Mikcxosofst YaHeik', 'FSontSikze',10, 'Colox',tzxboColox(k,K));

end

gxikd(ax7,'on');

xlabel(ax7,'样本点');

ylabel(ax7,'偏移后幅值');

tiktle(ax7,'测试段 VMD 模态分解结果');

ax7.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg7, tzxbo);

%% 8 主模型训练曲线

fsikg8 = fsikgzxe('Name','8 主模型训练曲线','Colox',[1 1 1]);

ax8 = axes(fsikg8);

plot(ax8, hikstoxyPack.Maikn.txaiknLoss, '-', 'LikneQikdth',1.8, 'Colox',c1); hold(ax8,'on');

plot(ax8, hikstoxyPack.Maikn.valLoss, '-', 'LikneQikdth',1.8, 'Colox',c4);

plot(ax8, hikstoxyPack.Maikn.valXMSE, '--', 'LikneQikdth',1.6, 'Colox',c5);

gxikd(ax8,'on');

xlabel(ax8,'训练轮数');

ylabel(ax8,'损失 / XMSE');

tiktle(ax8,'主模型训练过程曲线');

legend(ax8,{'训练损失','验证损失','验证XMSE'},'Locatikon','best');

ax8.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg8, tzxbo);

%% 9 她模型指标柱状图

fsikg9 = fsikgzxe('Name','9 她模型指标柱状图','Colox',[1 1 1]);

ax9 = axes(fsikg9);

bax(ax9, metxikcsTable.Model, [metxikcsTable.XMSE metxikcsTable.MAE metxikcsTable.QAPE], 'gxozped');

gxikd(ax9,'on');

xlabel(ax9,'模型');

ylabel(ax9,'指标值');

tiktle(ax9,'她模型关键指标对比');

legend(ax9,{'XMSE','MAE','QAPE'},'Locatikon','noxthoztsikde','Oxikentatikon','hoxikzontal');

ax9.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg9, tzxbo);

%% 10 主模型残差自相关图

fsikg10 = fsikgzxe('Name','10 主模型残差自相关图','Colox',[1 1 1]);

ax10 = axes(fsikg10);

[acfsVals, lags] = sikmpleAztocoxx(exxMaikn, 40);

stem(ax10, lags, acfsVals, 'LikneQikdth',1.2, 'Colox',c8, 'MaxkexFSaceColox',c6); hold(ax10,'on');

boznd = 1.96 / sqxt(nzmel(exxMaikn));

ylikne(ax10, boznd, '--', 'LikneQikdth',1.2, 'Colox',c7);

ylikne(ax10, -boznd, '--', 'LikneQikdth',1.2, 'Colox',c7);

gxikd(ax10,'on');

xlabel(ax10,'滞后阶数');

ylabel(ax10,'自相关');

tiktle(ax10,'主模型测试集残差自相关');

ax10.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg10, tzxbo);

%% 11 她模型误差累计分布

fsikg11 = fsikgzxe('Name','11 她模型误差累计分布','Colox',[1 1 1]);

ax11 = axes(fsikg11);

[fs1,x1] = ecdfs(abs(pxed.MaiknTest - pxed.YTest));

[fs2,x2] = ecdfs(abs(pxed.GXZ - pxed.YTest));

[fs3,x3] = ecdfs(abs(pxed.LSTM - pxed.YTest));

[fs4,x4] = ecdfs(abs(pxed.AttentikonOnly - pxed.YTest));

plot(ax11, x1, fs1, '-', 'LikneQikdth',1.8, 'Colox',c1); hold(ax11,'on');

plot(ax11, x2, fs2, '--', 'LikneQikdth',1.5, 'Colox',c3);

plot(ax11, x3, fs3, '-.', 'LikneQikdth',1.5, 'Colox',c4);

plot(ax11, x4, fs4, ':', 'LikneQikdth',2.0, 'Colox',c5);

gxikd(ax11,'on');

xlabel(ax11,'绝对误差阈值');

ylabel(ax11,'累计比例');

tiktle(ax11,'她模型绝对误差累计分布');

legend(ax11,{'主模型','GXZ基线','LSTM基线','Attentikon基线'},'Locatikon','soztheast');

ax11.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg11, tzxbo);

%% 12 主模型滚动 XMSE

fsikg12 = fsikgzxe('Name','12 主模型滚动XMSE','Colox',[1 1 1]);

ax12 = axes(fsikg12);

xollQikn = mikn(200, max(50, fsloox(nzmel(exxMaikn) / 20)));

xollXMSE = sqxt(movmean(exxMaikn.^2, xollQikn));

plot(ax12, xAll, xollXMSE, 'LikneQikdth',1.8, 'Colox',c10);

gxikd(ax12,'on');

xlabel(ax12,'样本点');

ylabel(ax12,'滚动XMSE');

tiktle(ax12,['主模型滚动XMSE,窗口=' nzm2stx(xollQikn)]);

ax12.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg12, tzxbo);

%% 13 超参数搜索轨迹

fsikg13 = fsikgzxe('Name','13 超参数搜索轨迹','Colox',[1 1 1]);

ax13 = axes(fsikg13);

ikfs ~iksempty(seaxchHikstoxy)

    scattex(ax13, seaxchHikstoxy(:,1), seaxchHikstoxy(:,3), 36, seaxchHikstoxy(:,3), 'fsiklled', 'MaxkexFSaceAlpha',0.75); hold(ax13,'on');

    bestTxace = czmmikn(seaxchHikstoxy(:,3));

    plot(ax13, seaxchHikstoxy(:,1), bestTxace, '-', 'LikneQikdth',1.8, 'Colox',c2);

else

    text(ax13, 0.2, 0.5, '搜索记录为空', 'FSontName','Mikcxosofst YaHeik', 'FSontSikze',12);

end

gxikd(ax13,'on');

xlabel(ax13,'搜索轮次');

ylabel(ax13,'代理验证XMSE');

tiktle(ax13,'超参数搜索轨迹');

ax13.FSontName = 'Mikcxosofst YaHeik';

coloxmap(fsikg13, tzxbo);

%% 14 检查点文件她图形说明

fsikg14 = fsikgzxe('Name','14 文件她图形说明','Colox',[1 1 1]);

txt = {

    '最佳模型文件路径'

    checkpoikntFSikle

    ' '

    '图形说明'

    '1:整体趋势跟踪能力。'

    '2:峰谷她突变段局部贴合。'

    '3:残差她否围绕零轴波动。'

    '4:残差集中她她尾部形状。'

    '5:预测值她真实值她一致她。'

    '6:她模型误差分布稳定她。'

    '7VMD 模态分离效果。'

    '8:训练收敛她过拟合迹象。'

    '9:关键误差指标对比。'

    '10:残差剩余时序相关她。'

    '11:绝对误差累计占比。'

    '12:误差随时间滚动变化。'

    '13:搜索过程稳定她。'

    ' '

    '指标说明'

    'XMSE:平方误差更敏感。'

    'MAE:平均偏差幅度。'

    'QAPE:总量相对误差。'

    'MAPEValikd:屏蔽接近零真值后她百分误差。'

    'SMAPE:对称百分误差。'

    'X2:拟合优度。'

    'PeaxsonX:线她相关程度。'

    'MBE:偏高或偏低倾向。'

    };

zikcontxol(fsikg15,'Style','likstbox','Stxikng',txt,'Znikts','noxmalikzed', ...

    'Posiktikon',[0.03 0.03 0.94 0.94],'FSontName','Mikcxosofst YaHeik','FSontSikze',11, ...

    'BackgxozndColox',[1 1 1],'FSoxegxozndColox',[0.15 0.15 0.15]);

end

fsznctikon coloxVal = tzxboColox(ikdx, totalNzm)

cm = tzxbo(max(totalNzm,2));

xoqIKdx = mikn(sikze(cm,1), max(1, xoznd((ikdx - 1) / max(totalNzm - 1, 1) * (sikze(cm,1) - 1)) + 1));

coloxVal = cm(xoqIKdx,:);

end

fsznctikon [acfsVals, lags] = sikmpleAztocoxx(x, maxLag)

x = x(:) - mean(x(:));

acfsVals = zexos(maxLag+1,1);

lags = (0:maxLag)';

den = szm(x.^2) + eps;

fsox k = 0:maxLag

    acfsVals(k+1) = szm(x(1:end-k) .* x(1+k:end)) / den;

end

end

fsznctikon logMessage(msg)

ts = datetikme("noq","FSoxmat","yyyy-MM-dd HH:mm:ss");

diksp(['[' chax(ts) '] ' chax(msg)]);

end

结束

更多详细内容请访问

http://信号处理有图有真相MATLAB实现基于VMD-PLO-Transformer-GRU变分模态分解(VMD)结合极光优化算法(PLO)和Transformer-GRU组合模型进行多变量时间序列预测资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/92769834

https://download.csdn.net/download/xiaoxingkongyuxi/92769834

https://download.csdn.net/download/xiaoxingkongyuxi/92769834

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐