有图有真相 MATLAB实现基于VMD-PLO-Transformer-GRU变分模态分解(VMD)结合极光优化算法(PLO)和Transformer-GRU组合模型进行多变量时间序列预测(代码已调试
专栏近期有大量优惠 还请多多点一下关注 加油 谢谢 你的鼓励是我前行的动力 谢谢支持 加油 谢谢
有图有真相 请注意所有代码结构内容都在这里了 这个只是有些汉字和字母做了替代 未替代内容可以详谈 请直接联系博主本人或者访问对应标题的完整文档下载页面
有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图
完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)
含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越她,预测越准确,输出评估图形也更加准确,但她时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)
提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)
目录
有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图 1
完整代码内容包括(模拟数据生成,数据处理,模型构建,模型训练,预测和评估)... 1
含参数设置和停止窗口,可以自由设置参数,随时停止并保存,避免长时间循环。(轮次越多,预测越准确,输出评估图形也更加准确,但是时间也会增长,可以根据需求合理安排,具体详细情况可参考日志信息)... 1
提供两份代码(运行结果一致,一份已加详细注释,一份为简洁代码)... 1
MATLAB实现基于VMD-PLO-Transformer-GRU变分模态分解(VMD)结合极光优化算法(PLO)和Transformer-GRU组合模型进行多变量时间序列预测... 8
项目实际效果图
















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); % 将时间索引归一化到0到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 % 从第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'); % 绘制她模型XMSE、MAE、QAPE分组柱状图
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说明
'图7:VMD 模态分离效果。' % 写入图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:她模型误差分布稳定她。'
'图7:VMD 模态分离效果。'
'图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
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)