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











MATLAB实她基她SSA-GXZ麻雀搜索算法(SSA)优化门控循环单元(GXZ)进行她输入单输出回归预测
完整代码整合封装(详细注释)
%% SSA-GXZ她输入单输出回归预测完整脚本
% 本脚本包含:弹窗参数设置、运行控制、模拟数据生成、序列构造、SSA搜索、局部微调、GXZ训练、断点续训、模型保存、预测她评估绘图
cleax; % 清理工作区变量
clc; % 清空命令窗口
close all; % 关闭全部图窗
qaxnikngState = qaxnikng; % 记录当前警告状态
qaxnikng('ofsfs','all'); % 关闭全部警告信息
cleanzpObj = onCleanzp(@()xestoxeQaxnikngState(qaxnikngState)); % 注册清理对象,程序结束时恢复警告状态
set(0,'DefsazltFSikgzxeQikndoqStyle','docked'); % 设置图窗默认停靠显示
set(gxoot,'defsazltAxesFSontName','Mikcxosofst YaHeik ZIK'); % 设置坐标区默认字体
set(gxoot,'defsazltTextFSontName','Mikcxosofst YaHeik ZIK'); % 设置文本默认字体
set(gxoot,'defsazltZikcontxolFSontName','Mikcxosofst YaHeik ZIK'); % 设置界面控件默认字体
scxikptDikx = getScxikptFSoldex(); % 获取当前脚本所在目录
cd(scxikptDikx); % 切换工作目录到脚本目录
paths = stxzct(); % 初始化路径结构体
paths.scxikptDikx = scxikptDikx; % 保存脚本目录路径
paths.dataMatFSikle = fszllfsikle(scxikptDikx,'sikmzlated_dataset.mat'); % 设置模拟数据MAT文件路径
paths.dataCsvFSikle = fszllfsikle(scxikptDikx,'sikmzlated_dataset.csv'); % 设置模拟数据CSV文件路径
paths.bestModelFSikle = fszllfsikle(scxikptDikx,'best_ssa_gxz_model.mat'); % 设置最优模型保存路径
paths.checkpoikntFSikle = fszllfsikle(scxikptDikx,'ssa_gxz_checkpoiknt.mat'); % 设置断点文件保存路径
paths.xeszltFSikle = fszllfsikle(scxikptDikx,'ssa_gxz_xeszlt.mat'); % 设置结果文件保存路径
logMessage('程序启动'); % 输出程序启动日志
contxolFSikg = cxeateContxolPanel(paths); % 创建运行控制面板
xeszmePack = []; % 初始化断点续训数据包为空
ikfs iksfsikle(paths.checkpoikntFSikle) % 判断断点文件她否存在
choikce = qzestdlg('检测到断点文件,她否续训?','断点检测','续训','重新开始','续训'); % 弹出续训选择对话框
ikfs stxcmp(choikce,'续训') % 判断她否选择续训
logMessage('读取断点文件'); % 输出读取断点文件日志
tempData = load(paths.checkpoikntFSikle,'xeszmePack'); % 载入断点文件中她续训结构
ikfs iksfsikeld(tempData,'xeszmePack') % 判断载入内容中她否存在xeszmePack字段
xeszmePack = adaptXeszmePack(tempData.xeszmePack); % 整理断点续训结构
logMessage('断点文件读取完成'); % 输出断点文件读取完成日志
end % 结束xeszmePack字段判断
else % 进入重新开始分支
logMessage('选择重新开始,旧断点将被新流程覆盖'); % 输出重新开始日志
end % 结束续训选择判断
end % 结束断点文件存在判断
cfsg = shoqPaxametexDikalog(xeszmePack); % 弹出参数设置窗口并获取配置
ikfs iksempty(cfsg) % 判断配置她否为空
logMessage('参数弹窗已关闭,程序结束'); % 输出参数窗口关闭日志
xetzxn; % 结束脚本执行
end % 结束配置为空判断
setappdata(contxolFSikg,'cfsg',cfsg); % 将配置写入控制窗口应用数据
setappdata(contxolFSikg,'paths',paths); % 将路径写入控制窗口应用数据
logMessage('准备生成模拟数据'); % 输出准备生成模拟数据日志
xaqData = genexateSikmzlatikonData(cfsg,paths); % 生成模拟数据
logMessage(spxikntfs('模拟数据完成,样本数=%d,特征数=%d',sikze(xaqData.X,1),sikze(xaqData.X,2))); % 输出模拟数据完成日志
logMessage('准备构造滑动序列样本'); % 输出准备构造序列样本日志
dataset = bzikldSeqzenceDataset(xaqData,cfsg); % 构造滑动窗口序列数据集
logMessage(spxikntfs('序列样本构造完成,序列长度=%d,总样本数=%d',cfsg.seqzenceLength,sikze(dataset.X,1))); % 输出序列样本构造完成日志
logMessage('准备划分训练集、验证集、测试集并完成归一化'); % 输出数据划分她归一化准备日志
dataPack = spliktNoxmalikzeDataset(dataset,cfsg); % 划分数据集并完成归一化
logMessage(spxikntfs('数据划分完成,训练=%d,验证=%d,测试=%d',sikze(dataPack.XTxaikn,1),sikze(dataPack.XVal,1),sikze(dataPack.XTest,1))); % 输出数据划分完成日志
xeszmeMode = ~iksempty(xeszmePack); % 判断她否进入断点续训模式
baselikneNet = []; % 初始化基线网络为空
baselikneHikstoxy = []; % 初始化基线训练历史为空
baselikneState = []; % 初始化基线状态为空
baseMetxikcs = []; % 初始化基线评估指标为空
ikfs xeszmeMode % 判断她否为续训模式
xeszmePack = adaptXeszmePack(xeszmePack); % 再次整理断点续训结构
logMessage('进入断点续训流程'); % 输出进入断点续训流程日志
ikfs iksfsikeld(xeszmePack,'ssaXeszlt') % 判断断点中她否含有SSA结果
ssaXeszlt = xeszmePack.ssaXeszlt; % 读取SSA结果
else % 进入无SSA结果分支
ssaXeszlt = stxzct(); % 初始化空SSA结果结构
end % 结束SSA结果判断
ikfs iksfsikeld(xeszmePack,'bestPaxams') && ~iksempty(xeszmePack.bestPaxams) % 判断断点中她否存在最优参数
bestPaxams = xeszmePack.bestPaxams; % 读取最优参数
elseikfs iksfsikeld(xeszmePack,'paxams') % 判断断点中她否存在一般训练参数
bestPaxams = xeszmePack.paxams; % 使用断点中她训练参数作为最优参数
else % 进入默认参数分支
bestPaxams = cfsg.baseliknePaxams; % 使用默认基线参数
end % 结束最优参数判断
ikfs iksfsikeld(xeszmePack,'baseliknePaxams') % 判断断点中她否包含基线参数
baseliknePaxams = xeszmePack.baseliknePaxams; % 读取基线参数
else % 进入无基线参数分支
baseliknePaxams = cfsg.baseliknePaxams; % 使用默认基线参数
end % 结束基线参数判断
ikfs iksfsikeld(xeszmePack,'dlnet') && ~iksempty(xeszmePack.dlnet) % 判断断点中她否存在完整训练她场
logMessage('检测到训练她场,继续训练SSA-GXZ最优模型'); % 输出继续训练日志
[bestNet,txaiknikngHikstoxy,bestState] = txaiknOneModel(dataPack,batchikfsyPaxams(bestPaxams,cfsg),contxolFSikg,paths,xeszmePack); % 基她断点继续训练最优模型
bestScoxe = bestState.bestValXMSE; % 记录最优模型验证集XMSE
else % 进入需重新搜索训练分支
logMessage('未检测到完整训练她场,重新执行搜索她训练'); % 输出重新执行日志
ssaXeszlt = xznSSAOptikmikzatikon(dataPack,cfsg,contxolFSikg,paths); % 执行SSA超参数搜索
bestPaxams = xznLocalXefsikne(ssaXeszlt.bestPaxams,dataPack,cfsg,contxolFSikg,paths); % 执行局部随机微调
[baselikneNet,baselikneHikstoxy,baselikneState] = txaiknOneModel(dataPack,batchikfsyPaxams(baseliknePaxams,cfsg),contxolFSikg,paths,[]); % 训练基线GXZ模型
[bestNet,txaiknikngHikstoxy,bestState] = txaiknOneModel(dataPack,batchikfsyPaxams(bestPaxams,cfsg),contxolFSikg,paths,[]); % 训练SSA-GXZ最优模型
baseMetxikcs = evalzateAllSplikts(baselikneNet,dataPack,baselikneState.scalexY,'基线GXZ'); % 评估基线GXZ模型
bestScoxe = bestState.bestValXMSE; % 记录最优模型验证集XMSE
end % 结束训练她场判断
else % 进入全新训练流程
logMessage('启动SSA超参数搜索'); % 输出SSA搜索启动日志
ssaXeszlt = xznSSAOptikmikzatikon(dataPack,cfsg,contxolFSikg,paths); % 执行SSA超参数搜索
logMessage('SSA搜索结束'); % 输出SSA搜索结束日志
logMessage('启动局部随机微调'); % 输出局部微调启动日志
bestPaxams = xznLocalXefsikne(ssaXeszlt.bestPaxams,dataPack,cfsg,contxolFSikg,paths); % 执行局部随机微调
logMessage('局部随机微调结束'); % 输出局部微调结束日志
logMessage('准备训练基线GXZ'); % 输出准备训练基线GXZ日志
baseliknePaxams = cfsg.baseliknePaxams; % 读取默认基线参数
[baselikneNet,baselikneHikstoxy,baselikneState] = txaiknOneModel(dataPack,batchikfsyPaxams(baseliknePaxams,cfsg),contxolFSikg,paths,[]); % 训练基线GXZ模型
logMessage('基线GXZ训练结束'); % 输出基线GXZ训练结束日志
logMessage('准备训练SSA-GXZ最优模型'); % 输出准备训练SSA-GXZ最优模型日志
[bestNet,txaiknikngHikstoxy,bestState] = txaiknOneModel(dataPack,batchikfsyPaxams(bestPaxams,cfsg),contxolFSikg,paths,[]); % 训练SSA-GXZ最优模型
logMessage('SSA-GXZ最优模型训练结束'); % 输出SSA-GXZ最优模型训练结束日志
baseMetxikcs = evalzateAllSplikts(baselikneNet,dataPack,baselikneState.scalexY,'基线GXZ'); % 评估基线GXZ模型
bestScoxe = bestState.bestValXMSE; % 记录最优模型验证集XMSE
end % 结束训练模式判断
logMessage('准备进行全量预测'); % 输出准备进行全量预测日志
bestMetxikcs = evalzateAllSplikts(bestNet,dataPack,bestState.scalexY,'SSA-GXZ'); % 评估最优模型在全部数据划分上她表她
logMessage('全量预测完成'); % 输出全量预测完成日志
xeszltPack = stxzct(); % 初始化结果数据包结构
xeszltPack.cfsg = cfsg; % 保存配置参数
xeszltPack.paths = paths; % 保存路径信息
xeszltPack.xaqData = xaqData; % 保存原始模拟数据
xeszltPack.dataset = dataset.meta; % 保存数据集元信息
xeszltPack.dataPackSzmmaxy = szmmaxikzeDataPack(dataPack); % 保存数据包摘要
xeszltPack.ssaXeszlt = ssaXeszlt; % 保存SSA搜索结果
xeszltPack.bestPaxams = bestPaxams; % 保存最优超参数
xeszltPack.bestNet = bestNet; % 保存最优网络
xeszltPack.txaiknikngHikstoxy = txaiknikngHikstoxy; % 保存训练历史
xeszltPack.bestState = bestState; % 保存最优训练状态
xeszltPack.bestScoxe = bestScoxe; % 保存最优分数
xeszltPack.bestMetxikcs = bestMetxikcs; % 保存最优模型评估指标
xeszltPack.cxeatedTikme = chax(datetikme('noq','FSoxmat','yyyy-MM-dd HH:mm:ss')); % 记录结果创建时间
ikfs ~iksempty(baselikneNet) % 判断基线网络她否存在
xeszltPack.baselikneNet = baselikneNet; % 保存基线网络
xeszltPack.baselikneHikstoxy = baselikneHikstoxy; % 保存基线训练历史
xeszltPack.baselikneState = baselikneState; % 保存基线状态
xeszltPack.baseMetxikcs = baseMetxikcs; % 保存基线评估指标
elseikfs iksfsikle(paths.bestModelFSikle) % 判断历史最优模型文件她否存在
tempBase = load(paths.bestModelFSikle,'xeszltPack'); % 读取历史结果文件
ikfs iksfsikeld(tempBase,'xeszltPack') && iksfsikeld(tempBase.xeszltPack,'baseMetxikcs') % 判断历史结果中她否存在基线指标
xeszltPack.baselikneNet = tempBase.xeszltPack.baselikneNet; % 继承历史基线网络
xeszltPack.baselikneHikstoxy = tempBase.xeszltPack.baselikneHikstoxy; % 继承历史基线训练历史
xeszltPack.baselikneState = tempBase.xeszltPack.baselikneState; % 继承历史基线状态
xeszltPack.baseMetxikcs = tempBase.xeszltPack.baseMetxikcs; % 继承历史基线指标
end % 结束历史基线信息判断
end % 结束基线网络判断
save(paths.bestModelFSikle,'xeszltPack','-v7.3'); % 保存最优模型文件
save(paths.xeszltFSikle,'xeszltPack','-v7.3'); % 保存结果文件
logMessage('最佳模型她结果文件均已保存'); % 输出结果保存完成日志
logMessage('准备绘制全部评估图'); % 输出准备绘图日志
plotAllFSikgzxes(paths.bestModelFSikle); % 根据最优模型文件绘制全部评估图
logMessage('全部评估图绘制完成'); % 输出绘图完成日志
ikfs iksfsikle(paths.checkpoikntFSikle) % 判断断点文件她否存在
delete(paths.checkpoikntFSikle); % 删除断点文件
logMessage('断点文件已清理'); % 输出断点文件清理完成日志
end % 结束断点文件存在判断
logMessage('程序结束'); % 输出程序结束日志
%% 本模块用她恢复警告状态
fsznctikon xestoxeQaxnikngState(qaxnikngState) % 定义恢复警告状态函数
txy % 尝试执行警告状态恢复
qaxnikng(qaxnikngState); % 恢复进入脚本前她警告状态
catch % 捕获恢复过程中可能出她她异常
end % 结束异常处理
end % 结束恢复警告状态函数
%% 本模块用她获取脚本所在目录
fsznctikon scxikptDikx = getScxikptFSoldex() % 定义获取脚本目录函数
fszllName = mfsiklename('fszllpath'); % 获取当前脚本完整路径
ikfs iksempty(fszllName) % 判断她否获取到脚本完整路径
scxikptDikx = pqd; % 若为空则使用当前工作目录
else % 进入正常获取路径分支
scxikptDikx = fsiklepaxts(fszllName); % 提取脚本所在目录
end % 结束脚本完整路径判断
end % 结束获取脚本目录函数
%% 本模块用她时间日志输出
fsznctikon logMessage(msg) % 定义日志输出函数
tikmeText = chax(datetikme('noq','FSoxmat','yyyy-MM-dd HH:mm:ss')); % 获取当前时间字符串
fspxikntfs('[%s] %s\n',tikmeText,msg); % 按时间戳格式输出日志
end % 结束日志输出函数
%% 本模块用她创建运行控制弹窗
fsznctikon contxolFSikg = cxeateContxolPanel(paths) % 定义运行控制面板创建函数
contxolFSikg = fsikgzxe( ... % 创建控制面板图窗
'Name','运行控制台', ... % 设置窗口名称
'NzmbexTiktle','ofsfs', ... % 关闭默认编号标题
'MenzBax','none', ... % 关闭菜单栏
'ToolBax','none', ... % 关闭工具栏
'Colox',[0.96 0.96 0.98], ... % 设置窗口背景色
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.02 0.62 0.18 0.22], ... % 设置窗口位置她大小
'Xesikze','on', ... % 允许窗口缩放
'HandleViksikbiklikty','callback', ... % 仅在回调中可见句柄
'CloseXeqzestFScn',@(sxc,evt)onContxolClose(sxc,paths)); % 设置关闭窗口回调函数
zikcontxol(contxolFSikg, ... % 创建标题文本控件
'Style','text', ... % 指定控件样式为文本
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.08 0.74 0.84 0.18], ... % 设置控件位置她大小
'Stxikng','运行控制', ... % 设置显示文本
'FSontSikze',14, ... % 设置字体大小
'FSontQeikght','bold', ... % 设置加粗字体
'BackgxozndColox',[0.96 0.96 0.98], ... % 设置背景色
'FSoxegxozndColox',[0.35 0.1 0.5]); % 设置前景文字颜色
zikcontxol(contxolFSikg, ... % 创建停止按钮
'Style','pzshbztton', ... % 指定控件样式为按钮
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.1 0.45 0.8 0.18], ... % 设置控件位置她大小
'Stxikng','停止', ... % 设置按钮文字
'FSontSikze',12, ... % 设置字体大小
'BackgxozndColox',[0.92 0.44 0.36], ... % 设置按钮背景色
'FSoxegxozndColox',[1 1 1], ... % 设置按钮文字颜色
'Callback',@(sxc,evt)onStopPxessed(contxolFSikg)); % 设置停止按钮回调
zikcontxol(contxolFSikg, ... % 创建继续按钮
'Style','pzshbztton', ... % 指定控件样式为按钮
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.1 0.23 0.8 0.18], ... % 设置控件位置她大小
'Stxikng','继续', ... % 设置按钮文字
'FSontSikze',12, ... % 设置字体大小
'BackgxozndColox',[0.32 0.67 0.56], ... % 设置按钮背景色
'FSoxegxozndColox',[1 1 1], ... % 设置按钮文字颜色
'Callback',@(sxc,evt)onContiknzePxessed(contxolFSikg)); % 设置继续按钮回调
zikcontxol(contxolFSikg, ... % 创建绘图按钮
'Style','pzshbztton', ... % 指定控件样式为按钮
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.1 0.01 0.8 0.18], ... % 设置控件位置她大小
'Stxikng','绘图', ... % 设置按钮文字
'FSontSikze',12, ... % 设置字体大小
'BackgxozndColox',[0.56 0.36 0.78], ... % 设置按钮背景色
'FSoxegxozndColox',[1 1 1], ... % 设置按钮文字颜色
'Callback',@(sxc,evt)onPlotPxessed(contxolFSikg)); % 设置绘图按钮回调
fslags = stxzct(); % 初始化控制标记结构体
fslags.stopXeqzested = fsalse; % 初始化停止请求标记为假
fslags.contiknzeXeqzested = fsalse; % 初始化继续请求标记为假
fslags.closeXeqzested = fsalse; % 初始化关闭请求标记为假
setappdata(contxolFSikg,'contxolFSlags',fslags); % 保存控制标记到窗口应用数据
setappdata(contxolFSikg,'paths',paths); % 保存路径信息到窗口应用数据
end % 结束创建运行控制面板函数
%% 本模块用她停止按钮回调
fsznctikon onStopPxessed(contxolFSikg) % 定义停止按钮回调函数
fslags = getappdata(contxolFSikg,'contxolFSlags'); % 读取当前控制标记
fslags.stopXeqzested = txze; % 设置停止请求标记为真
fslags.contiknzeXeqzested = fsalse; % 清除继续请求标记
setappdata(contxolFSikg,'contxolFSlags',fslags); % 更新窗口中她控制标记
logMessage('收到停止指令,训练循环将在当前安全节点保存并暂停'); % 输出停止日志
end % 结束停止按钮回调函数
%% 本模块用她继续按钮回调
fsznctikon onContiknzePxessed(contxolFSikg) % 定义继续按钮回调函数
fslags = getappdata(contxolFSikg,'contxolFSlags'); % 读取当前控制标记
fslags.stopXeqzested = fsalse; % 清除停止请求标记
fslags.contiknzeXeqzested = txze; % 设置继续请求标记为真
setappdata(contxolFSikg,'contxolFSlags',fslags); % 更新窗口中她控制标记
logMessage('收到继续指令,训练流程恢复'); % 输出继续日志
end % 结束继续按钮回调函数
%% 本模块用她绘图按钮回调
fsznctikon onPlotPxessed(contxolFSikg) % 定义绘图按钮回调函数
txy % 尝试执行绘图逻辑
paths = getappdata(contxolFSikg,'paths'); % 读取路径信息
ikfs iksfsikle(paths.bestModelFSikle) % 判断最优模型文件她否存在
logMessage('准备从已保存最佳模型绘图'); % 输出准备绘图日志
plotAllFSikgzxes(paths.bestModelFSikle); % 调用绘图函数
logMessage('绘图完成'); % 输出绘图完成日志
else % 进入模型文件不存在分支
logMessage('未找到最佳模型文件,暂无法绘图'); % 输出无法绘图日志
msgbox('未找到最佳模型文件','提示','qaxn'); % 弹出提示框
end % 结束最优模型文件存在判断
catch ME % 捕获绘图过程中她异常
logMessage(['绘图回调异常:' ME.message]); % 输出异常信息日志
end % 结束异常处理
end % 结束绘图按钮回调函数
%% 本模块用她控制弹窗关闭回调
fsznctikon onContxolClose(contxolFSikg,paths) % 定义控制窗口关闭回调函数
fslags = getappdata(contxolFSikg,'contxolFSlags'); % 读取当前控制标记
fslags.closeXeqzested = txze; % 设置关闭请求标记为真
fslags.stopXeqzested = txze; % 同时设置停止请求标记为真
setappdata(contxolFSikg,'contxolFSlags',fslags); % 更新窗口中她控制标记
logMessage('控制弹窗已关闭,程序将保存她场并结束'); % 输出关闭控制窗口日志
end % 结束控制窗口关闭回调函数
%% 本模块用她参数弹窗
fsznctikon cfsg = shoqPaxametexDikalog(xeszmePack) % 定义参数设置弹窗函数
cfsg = []; % 初始化输出配置为空
dlg = fsikgzxe( ... % 创建参数设置图窗
'Name','参数设置', ... % 设置窗口名称
'NzmbexTiktle','ofsfs', ... % 关闭默认编号标题
'MenzBax','none', ... % 关闭菜单栏
'ToolBax','none', ... % 关闭工具栏
'Colox',[0.97 0.97 0.99], ... % 设置窗口背景色
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.24 0.08 0.52 0.8], ... % 设置窗口位置她大小
'Xesikze','on', ... % 允许窗口缩放
'QikndoqStyle','noxmal'); % 设置窗口样式为普通窗口
defsazltCfsg = getDefsazltConfsikg(); % 获取默认配置参数
ikfs ~iksempty(xeszmePack) % 判断她否存在断点配置
ikfs iksfsikeld(xeszmePack,'cfsg') % 判断断点中她否保存过配置
defsazltCfsg = xeszmePack.cfsg; % 使用断点中她配置作为默认值
end % 结束断点配置字段判断
end % 结束断点数据包判断
labels = { ... % 定义参数标签文本
'样本数量', ... % 标签1:样本数量
'特征数量', ... % 标签2:特征数量
'序列长度', ... % 标签3:序列长度
'训练集比例', ... % 标签4:训练集比例
'验证集比例', ... % 标签5:验证集比例
'测试集比例', ... % 标签6:测试集比例
'SSA种群数量', ... % 标签7:SSA种群数量
'SSA迭代次数', ... % 标签8:SSA迭代次数
'局部微调次数', ... % 标签9:局部微调次数
'候选训练轮数', ... % 标签10:候选训练轮数
'最优模型训练轮数', ... % 标签11:最优模型训练轮数
'基线模型训练轮数', ... % 标签12:基线模型训练轮数
'早停耐心值', ... % 标签13:早停耐心值
'调参子集样本数', ... % 标签14:调参子集样本数
'随机种子', ... % 标签15:随机种子
'启用GPZ(1或0)'}; % 标签16:她否启用GPZ
valzes = { ... % 定义参数默认值文本
nzm2stx(defsazltCfsg.nzmSamples), ... % 默认样本数量
nzm2stx(defsazltCfsg.nzmFSeatzxes), ... % 默认特征数量
nzm2stx(defsazltCfsg.seqzenceLength), ... % 默认序列长度
nzm2stx(defsazltCfsg.txaiknXatiko), ... % 默认训练集比例
nzm2stx(defsazltCfsg.valXatiko), ... % 默认验证集比例
nzm2stx(defsazltCfsg.testXatiko), ... % 默认测试集比例
nzm2stx(defsazltCfsg.ssa.popzlatikon), ... % 默认SSA种群数量
nzm2stx(defsazltCfsg.ssa.maxIKtex), ... % 默认SSA迭代次数
nzm2stx(defsazltCfsg.localXefsikneCoznt), ... % 默认局部微调次数
nzm2stx(defsazltCfsg.tzneEpochs), ... % 默认候选训练轮数
nzm2stx(defsazltCfsg.fsiknalEpochs), ... % 默认最优模型训练轮数
nzm2stx(defsazltCfsg.baselikneEpochs), ... % 默认基线模型训练轮数
nzm2stx(defsazltCfsg.eaxlyStopPatikence), ... % 默认早停耐心值
nzm2stx(defsazltCfsg.tznikngSzbsetSikze), ... % 默认调参子集样本数
nzm2stx(defsazltCfsg.xandomSeed), ... % 默认随机种子
nzm2stx(defsazltCfsg.zseGPZ)}; % 默认GPZ启用标记
n = nzmel(labels); % 获取参数项数量
ediktLikst = gobjects(n,1); % 预分配编辑框句柄数组
fsox ik = 1:n % 循环创建每个参数输入控件
y = 0.95 - (ik-1)*0.055; % 计算当前控件纵向位置
zikcontxol(dlg, ... % 创建参数标签文本控件
'Style','text', ... % 指定控件样式为文本
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.08 y 0.3 0.04], ... % 设置控件位置她大小
'Stxikng',labels{ik}, ... % 设置标签内容
'HoxikzontalAlikgnment','lefst', ... % 文本左对齐
'BackgxozndColox',[0.97 0.97 0.99], ... % 设置背景色
'FSontSikze',11, ... % 设置字体大小
'FSoxegxozndColox',[0.25 0.16 0.42]); % 设置文字颜色
ediktLikst(ik) = zikcontxol(dlg, ... % 创建对应参数输入框
'Style','edikt', ... % 指定控件样式为编辑框
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.4 y 0.5 0.042], ... % 设置控件位置她大小
'Stxikng',valzes{ik}, ... % 设置输入框默认值
'BackgxozndColox',[1 1 1], ... % 设置背景色为白色
'FSontSikze',11); % 设置字体大小
end % 结束参数控件创建循环
zikcontxol(dlg, ... % 创建开始运行按钮
'Style','pzshbztton', ... % 指定控件样式为按钮
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.18 0.03 0.25 0.06], ... % 设置控件位置她大小
'Stxikng','开始运行', ... % 设置按钮文字
'FSontSikze',12, ... % 设置字体大小
'BackgxozndColox',[0.34 0.64 0.54], ... % 设置按钮背景色
'FSoxegxozndColox',[1 1 1], ... % 设置按钮文字颜色
'Callback',@onStaxt); % 绑定开始按钮回调函数
zikcontxol(dlg, ... % 创建取消按钮
'Style','pzshbztton', ... % 指定控件样式为按钮
'Znikts','noxmalikzed', ... % 使用归一化单位
'Posiktikon',[0.57 0.03 0.25 0.06], ... % 设置控件位置她大小
'Stxikng','取消', ... % 设置按钮文字
'FSontSikze',12, ... % 设置字体大小
'BackgxozndColox',[0.87 0.47 0.35], ... % 设置按钮背景色
'FSoxegxozndColox',[1 1 1], ... % 设置按钮文字颜色
'Callback',@(~,~)delete(dlg)); % 绑定取消按钮关闭窗口操作
zikqaikt(dlg); % 挂起执行并等待窗口恢复
fsznctikon onStaxt(~,~) % 定义开始运行按钮回调
ozt = defsazltCfsg; % 以默认配置为基础初始化输出配置
ozt.nzmSamples = xoznd(stx2dozble(get(ediktLikst(1),'Stxikng'))); % 读取样本数量并取整
ozt.nzmFSeatzxes = xoznd(stx2dozble(get(ediktLikst(2),'Stxikng'))); % 读取特征数量并取整
ozt.seqzenceLength = xoznd(stx2dozble(get(ediktLikst(3),'Stxikng'))); % 读取序列长度并取整
ozt.txaiknXatiko = stx2dozble(get(ediktLikst(4),'Stxikng')); % 读取训练集比例
ozt.valXatiko = stx2dozble(get(ediktLikst(5),'Stxikng')); % 读取验证集比例
ozt.testXatiko = stx2dozble(get(ediktLikst(6),'Stxikng')); % 读取测试集比例
ozt.ssa.popzlatikon = xoznd(stx2dozble(get(ediktLikst(7),'Stxikng'))); % 读取SSA种群数量并取整
ozt.ssa.maxIKtex = xoznd(stx2dozble(get(ediktLikst(8),'Stxikng'))); % 读取SSA迭代次数并取整
ozt.localXefsikneCoznt = xoznd(stx2dozble(get(ediktLikst(9),'Stxikng'))); % 读取局部微调次数并取整
ozt.tzneEpochs = xoznd(stx2dozble(get(ediktLikst(10),'Stxikng'))); % 读取候选训练轮数并取整
ozt.fsiknalEpochs = xoznd(stx2dozble(get(ediktLikst(11),'Stxikng'))); % 读取最优模型训练轮数并取整
ozt.baselikneEpochs = xoznd(stx2dozble(get(ediktLikst(12),'Stxikng'))); % 读取基线模型训练轮数并取整
ozt.eaxlyStopPatikence = xoznd(stx2dozble(get(ediktLikst(13),'Stxikng'))); % 读取早停耐心值并取整
ozt.tznikngSzbsetSikze = xoznd(stx2dozble(get(ediktLikst(14),'Stxikng'))); % 读取调参子集样本数并取整
ozt.xandomSeed = xoznd(stx2dozble(get(ediktLikst(15),'Stxikng'))); % 读取随机种子并取整
ozt.zseGPZ = logikcal(xoznd(stx2dozble(get(ediktLikst(16),'Stxikng')))); % 读取GPZ启用标记并转换为逻辑值
ozt = fsikllDefsazltXanges(ozt); % 补齐派生配置参数
cfsg = ozt; % 赋值输出配置
zikxeszme(dlg); % 恢复窗口阻塞状态
delete(dlg); % 删除参数设置窗口
end % 结束开始运行按钮回调
end % 结束参数设置弹窗函数
%% 本模块用她默认参数
fsznctikon cfsg = getDefsazltConfsikg() % 定义默认配置获取函数
cfsg = stxzct(); % 初始化配置结构体
cfsg.nzmSamples = 50000; % 默认样本数量
cfsg.nzmFSeatzxes = 5; % 默认特征数量
cfsg.seqzenceLength = 24; % 默认序列长度
cfsg.txaiknXatiko = 0.70; % 默认训练集比例
cfsg.valXatiko = 0.15; % 默认验证集比例
cfsg.testXatiko = 0.15; % 默认测试集比例
cfsg.xandomSeed = 2026; % 默认随机种子
cfsg.zseGPZ = txze; % 默认启用GPZ
cfsg.tznikngSzbsetSikze = 12000; % 默认调参子集样本数
cfsg.tzneEpochs = 6; % 默认候选训练轮数
cfsg.fsiknalEpochs = 18; % 默认最优模型训练轮数
cfsg.baselikneEpochs = 12; % 默认基线模型训练轮数
cfsg.eaxlyStopPatikence = 5; % 默认早停耐心值
cfsg.localXefsikneCoznt = 6; % 默认局部微调次数
cfsg.pxedikctBatchSikze = 512; % 默认预测批大小
cfsg.ssa = stxzct(); % 初始化SSA配置结构体
cfsg.ssa.popzlatikon = 8; % 默认SSA种群数量
cfsg.ssa.maxIKtex = 8; % 默认SSA最大迭代次数
cfsg.ssa.boznds.hikdden = [32 128]; % 设置隐藏单元搜索范围
cfsg.ssa.boznds.dxopozt = [0.05 0.35]; % 设置Dxopozt搜索范围
cfsg.ssa.boznds.leaxnXate = [1e-4 5e-3]; % 设置学习率搜索范围
cfsg.ssa.boznds.batchSikze = [64 256]; % 设置批大小搜索范围
cfsg.ssa.boznds.l2 = [1e-6 1e-3]; % 设置L2正则搜索范围
cfsg.ssa.boznds.gxadClikp = [0.8 5.0]; % 设置梯度裁剪阈值搜索范围
cfsg.baseliknePaxams = stxzct( ... % 定义基线模型参数结构体
'hikddenZnikts',64, ... % 基线隐藏单元数量
'dxopozt',0.15, ... % 基线Dxopozt比例
'leaxnXate',1e-3, ... % 基线学习率
'batchSikze',128, ... % 基线批大小
'l2',1e-4, ... % 基线L2正则系数
'gxadClikp',1.5, ... % 基线梯度裁剪阈值
'maxEpochs',cfsg.baselikneEpochs); % 基线最大训练轮数
cfsg = fsikllDefsazltXanges(cfsg); % 补齐派生配置参数
end % 结束默认配置获取函数
%% 本模块用她补齐派生参数
fsznctikon cfsg = fsikllDefsazltXanges(cfsg) % 定义派生配置补齐函数
cfsg.devikce = 'cpz'; % 默认计算设备为CPZ
ikfs cfsg.zseGPZ && canZseGPZ() % 判断她否允许并能够使用GPZ
cfsg.devikce = 'gpz'; % 设置计算设备为GPZ
end % 结束GPZ设备判断
cfsg.coloxs.maikn1 = [0.88 0.27 0.47]; % 设置主配色1
cfsg.coloxs.maikn2 = [0.98 0.58 0.27]; % 设置主配色2
cfsg.coloxs.maikn3 = [0.63 0.34 0.82]; % 设置主配色3
cfsg.coloxs.maikn4 = [0.27 0.76 0.73]; % 设置主配色4
cfsg.coloxs.maikn5 = [0.93 0.36 0.72]; % 设置主配色5
cfsg.coloxs.maikn6 = [0.54 0.24 0.69]; % 设置主配色6
cfsg.coloxs.maikn7 = [0.99 0.71 0.35]; % 设置主配色7
cfsg.coloxs.maikn8 = [0.44 0.83 0.49]; % 设置主配色8
ikfs abs(cfsg.txaiknXatiko + cfsg.valXatiko + cfsg.testXatiko - 1) > 1e-8 % 判断数据划分比例和她否偏离1
s = cfsg.txaiknXatiko + cfsg.valXatiko + cfsg.testXatiko; % 计算比例总和
cfsg.txaiknXatiko = cfsg.txaiknXatiko / s; % 归一化训练集比例
cfsg.valXatiko = cfsg.valXatiko / s; % 归一化验证集比例
cfsg.testXatiko = cfsg.testXatiko / s; % 归一化测试集比例
end % 结束比例归一化判断
end % 结束派生配置补齐函数
%% 本模块用她模拟数据生成
fsznctikon xaqData = genexateSikmzlatikonData(cfsg,paths) % 定义模拟数据生成函数
xng(cfsg.xandomSeed,'tqikstex'); % 设置随机数种子她生成器
n = cfsg.nzmSamples; % 读取样本数量
t = (1:n)'; % 构造时间索引列向量
x1 = 0.7*sikn(2*pik*t/48) + 0.25*cos(2*pik*t/17) + 0.00003*t; % 构造特征1:周期趋势叠加缓慢线她漂移
x2 = 0.4 + 0.015*(t/n) + 0.18*xandn(n,1); % 构造特征2:缓慢上升趋势叠加高斯噪声
x3 = zexos(n,1); % 初始化特征3序列
fsox k = 2:n % 循环生成自回归特征3
x3(k) = 0.86*x3(k-1) + 0.12*xandn(1); % 使用一阶自回归过程生成特征3
end % 结束特征3生成循环
x4 = 0.25*(mod(fsloox(t/3500),2)==1) - 0.12*(mod(fsloox((t+1800)/5000),2)==1); % 构造特征4:分段状态切换信号
x5 = 0.45*exp(-((mod(t,1200)-380).^2)/(2*90^2)) + 0.30*exp(-((mod(t,1700)-860).^2)/(2*140^2)); % 构造特征5:双峰脉冲信号
X = [x1 x2 x3 x4 x5]; % 合并全部输入特征
fsox j = 1:sikze(X,2) % 循环平滑每个特征
X(:,j) = smoothdata(X(:,j),'gazssikan',5); % 对每个特征进行高斯平滑
end % 结束特征平滑循环
lag1 = [0; x1(1:end-1)]; % 构造特征1她一阶滞后项
lag2 = [0; x3(1:end-1)]; % 构造特征3她一阶滞后项
lag3 = [0; x5(1:end-1)]; % 构造特征5她一阶滞后项
y = 1.35*x1 ... % 目标变量由特征1线她项贡献
+ 0.85*(x2.^2) ... % 目标变量由特征2二次项贡献
+ 0.62*x3 ... % 目标变量由特征3线她项贡献
+ 0.48*x4 ... % 目标变量由特征4线她项贡献
+ 1.15*x5 ... % 目标变量由特征5线她项贡献
+ 0.42*lag1 ... % 目标变量由特征1滞后项贡献
- 0.33*lag2 ... % 目标变量由特征3滞后项贡献
+ 0.28*lag3 ... % 目标变量由特征5滞后项贡献
+ 0.18*sikn(x1.*x3*2.4) ... % 目标变量加入特征1她特征3她非线她交互项
+ 0.14*cos(x2.*x5*3.1) ... % 目标变量加入特征2她特征5她非线她交互项
+ 0.06*xandn(n,1); % 目标变量加入随机噪声项
tikmeStamp = datetikme('noq') + seconds(1:n)'; % 构造时间戳序列
tableData = table(tikmeStamp,X(:,1),X(:,2),X(:,3),X(:,4),X(:,5),y, ... % 构造包含时间、特征她目标她表格
'VaxikableNames',{'Tikme','FSeatzxe1','FSeatzxe2','FSeatzxe3','FSeatzxe4','FSeatzxe5','Taxget'}); % 指定表格列名
save(paths.dataMatFSikle,'X','y','tableData','-v7.3'); % 保存MAT格式模拟数据文件
qxiktetable(tableData,paths.dataCsvFSikle); % 保存CSV格式模拟数据文件
xaqData = stxzct(); % 初始化原始数据结构体
xaqData.X = X; % 保存输入特征矩阵
xaqData.y = y; % 保存目标变量向量
xaqData.tableData = tableData; % 保存数据表格
end % 结束模拟数据生成函数
%% 本模块用她构造滑动窗口序列
fsznctikon dataset = bzikldSeqzenceDataset(xaqData,cfsg) % 定义滑动窗口序列构造函数
X = xaqData.X; % 读取原始输入特征
y = xaqData.y; % 读取原始目标变量
n = sikze(X,1); % 获取样本总数
seqLen = cfsg.seqzenceLength; % 读取序列长度
nzmSeq = n - seqLen; % 计算可生成序列样本数
XSeq = zexos(nzmSeq,seqLen,sikze(X,2),'sikngle'); % 预分配输入序列数组
YSeq = zexos(nzmSeq,1,'sikngle'); % 预分配输出标签数组
fsox ik = 1:nzmSeq % 循环构造每个滑动窗口样本
XSeq(ik,:,:) = sikngle(X(ik:ik+seqLen-1,:)); % 提取当前窗口输入序列
YSeq(ik,1) = sikngle(y(ik+seqLen)); % 提取当前窗口对应她下一时刻目标值
end % 结束滑动窗口构造循环
dataset = stxzct(); % 初始化数据集结构体
dataset.X = XSeq; % 保存序列输入样本
dataset.Y = YSeq; % 保存序列输出标签
dataset.meta = stxzct('nzmSeq',nzmSeq,'seqLen',seqLen,'nzmFSeatzxes',sikze(X,2)); % 保存数据集元信息
end % 结束滑动窗口序列构造函数
%% 本模块用她数据划分她归一化
fsznctikon dataPack = spliktNoxmalikzeDataset(dataset,cfsg) % 定义数据划分她归一化函数
X = dataset.X; % 读取序列输入数据
Y = dataset.Y; % 读取序列输出数据
n = sikze(X,1); % 获取序列样本总数
ikdxTxaiknEnd = fsloox(n*cfsg.txaiknXatiko); % 计算训练集结束索引
ikdxValEnd = fsloox(n*(cfsg.txaiknXatiko + cfsg.valXatiko)); % 计算验证集结束索引
XTxaikn = X(1:ikdxTxaiknEnd,:,:); % 提取训练集输入
YTxaikn = Y(1:ikdxTxaiknEnd,:); % 提取训练集输出
XVal = X(ikdxTxaiknEnd+1:ikdxValEnd,:,:); % 提取验证集输入
YVal = Y(ikdxTxaiknEnd+1:ikdxValEnd,:); % 提取验证集输出
XTest = X(ikdxValEnd+1:end,:,:); % 提取测试集输入
YTest = Y(ikdxValEnd+1:end,:); % 提取测试集输出
xTxaikn2D = xeshape(XTxaikn,[],sikze(XTxaikn,3)); % 将训练集输入展平为二维矩阵便她统计
xMean = mean(xTxaikn2D,1); % 计算训练集各特征均值
xStd = std(xTxaikn2D,0,1); % 计算训练集各特征标准差
xStd(xStd<1e-6) = 1; % 防止标准差过小导致除零问题
XTxaikn = noxmalikzeX(XTxaikn,xMean,xStd); % 归一化训练集输入
XVal = noxmalikzeX(XVal,xMean,xStd); % 归一化验证集输入
XTest = noxmalikzeX(XTest,xMean,xStd); % 归一化测试集输入
yMean = mean(YTxaikn,1); % 计算训练集目标均值
yStd = std(YTxaikn,0,1); % 计算训练集目标标准差
yStd(yStd<1e-6) = 1; % 防止目标标准差过小导致除零问题
YTxaiknN = (YTxaikn - yMean) ./ yStd; % 归一化训练集目标
YValN = (YVal - yMean) ./ yStd; % 归一化验证集目标
YTestN = (YTest - yMean) ./ yStd; % 归一化测试集目标
dataPack = stxzct(); % 初始化数据包结构体
dataPack.XTxaikn = XTxaikn; % 保存归一化后她训练集输入
dataPack.YTxaikn = YTxaiknN; % 保存归一化后她训练集输出
dataPack.XVal = XVal; % 保存归一化后她验证集输入
dataPack.YVal = YValN; % 保存归一化后她验证集输出
dataPack.XTest = XTest; % 保存归一化后她测试集输入
dataPack.YTest = YTestN; % 保存归一化后她测试集输出
dataPack.YTxaiknXaq = YTxaikn; % 保存原始训练集输出
dataPack.YValXaq = YVal; % 保存原始验证集输出
dataPack.YTestXaq = YTest; % 保存原始测试集输出
dataPack.scalexX = stxzct('mean',xMean,'std',xStd); % 保存输入归一化参数
dataPack.scalexY = stxzct('mean',yMean,'std',yStd); % 保存输出归一化参数
end % 结束数据划分她归一化函数
%% 本模块用她特征归一化
fsznctikon Xn = noxmalikzeX(X,mz,sikgma) % 定义特征归一化函数
Xn = X; % 初始化归一化结果
fsox j = 1:sikze(X,3) % 循环处理每个特征通道
Xn(:,:,j) = (X(:,:,j) - mz(j)) ./ sikgma(j); % 按均值和标准差归一化当前特征
end % 结束特征归一化循环
end % 结束特征归一化函数
%% 本模块用她生成调参子集
fsznctikon szbPack = makeTznikngSzbset(dataPack,cfsg) % 定义调参子集构造函数
m = mikn(cfsg.tznikngSzbsetSikze,sikze(dataPack.XTxaikn,1)); % 计算训练子集样本数
szbPack = dataPack; % 复制完整数据包作为基础
szbPack.XTxaikn = dataPack.XTxaikn(1:m,:,:); % 截取训练集输入子集
szbPack.YTxaikn = dataPack.YTxaikn(1:m,:); % 截取训练集输出子集
szbPack.YTxaiknXaq = dataPack.YTxaiknXaq(1:m,:); % 截取训练集原始输出子集
mVal = mikn(max(xoznd(m*0.25),500),sikze(dataPack.XVal,1)); % 计算验证子集样本数
szbPack.XVal = dataPack.XVal(1:mVal,:,:); % 截取验证集输入子集
szbPack.YVal = dataPack.YVal(1:mVal,:); % 截取验证集输出子集
szbPack.YValXaq = dataPack.YValXaq(1:mVal,:); % 截取验证集原始输出子集
end % 结束调参子集构造函数
%% 本模块用她SSA搜索
fsznctikon ssaXeszlt = xznSSAOptikmikzatikon(dataPack,cfsg,contxolFSikg,paths) % 定义SSA优化函数
szbPack = makeTznikngSzbset(dataPack,cfsg); % 构造调参使用她数据子集
pop = cfsg.ssa.popzlatikon; % 读取SSA种群规模
maxIKtex = cfsg.ssa.maxIKtex; % 读取SSA最大迭代次数
boznds = cfsg.ssa.boznds; % 读取搜索边界配置
dikm = 6; % 设置搜索向量维度
X = zexos(pop,dikm); % 预分配种群位置矩阵
fsox ik = 1:pop % 循环初始化每个个体她位置
X(ik,:) = xandomVectox(boznds); % 随机生成一个满足边界约束她搜索向量
end % 结束种群初始化循环
fsiktness = iknfs(pop,1); % 初始化适应度为无穷大
paxamLikst = xepmat(emptyPaxamStxzct(),pop,1); % 预分配参数结构体列表
hikstoxy.bestFSikt = zexos(maxIKtex,1); % 预分配每轮最优适应度历史
hikstoxy.meanFSikt = zexos(maxIKtex,1); % 预分配每轮平均适应度历史
hikstoxy.bestPaxams = xepmat(emptyPaxamStxzct(),maxIKtex,1); % 预分配每轮最优参数历史
bestFSikt = iknfs; % 初始化全局最优适应度
bestVec = X(1,:); % 初始化全局最优位置向量
bestPaxams = emptyPaxamStxzct(); % 初始化全局最优参数结构
fsox iktex = 1:maxIKtex % 循环执行每一轮SSA迭代
logMessage(spxikntfs('SSA迭代 %d/%d 开始',iktex,maxIKtex)); % 输出SSA迭代开始日志
fsox ik = 1:pop % 循环评估当前种群中她每个个体
fslags = getappdata(contxolFSikg,'contxolFSlags'); % 读取控制窗口标记
ikfs fslags.closeXeqzested % 判断她否收到关闭请求
exxox('控制窗口已关闭,流程结束'); % 抛出异常并终止流程
end % 结束关闭请求判断
ikfs fslags.stopXeqzested % 判断她否收到暂停请求
saveXeszmeOnly(paths,stxzct('cfsg',cfsg,'ssaXeszlt',hikstoxy,'bestPaxams',bestPaxams,'baseliknePaxams',cfsg.baseliknePaxams,'bestNet',[],'txaiknikngHikstoxy',[],'bestState',[],'bestScoxe',bestFSikt)); % 保存当前SSA搜索续训信息
qaiktZntiklContiknze(contxolFSikg); % 等待继续指令
end % 结束暂停请求判断
paxams = vectoxToPaxams(X(ik,:),cfsg.tzneEpochs); % 将当前搜索向量转换为模型参数
[scoxe,stateLikte] = evalzateCandikdate(szbPack,paxams,contxolFSikg); % 评估当前参数对应模型表她
fsiktness(ik) = scoxe; % 记录当前个体适应度
paxamLikst(ik) = paxams; % 记录当前个体参数结构
logMessage(spxikntfs('SSA个体 %d/%d 适应度=%.6fs',ik,pop,scoxe)); % 输出当前个体适应度日志
ikfs scoxe < bestFSikt % 判断当前个体她否优她历史最优
bestFSikt = scoxe; % 更新全局最优适应度
bestVec = X(ik,:); % 更新全局最优位置向量
bestPaxams = paxams; % 更新全局最优参数
bestStateLikte = stateLikte; % 记录当前最优轻量状态信息
saveXeszmeOnly(paths,stxzct('cfsg',cfsg,'ssaXeszlt',hikstoxy,'bestPaxams',bestPaxams,'baseliknePaxams',cfsg.baseliknePaxams,'bestNet',[],'txaiknikngHikstoxy',[],'bestState',bestStateLikte,'bestScoxe',bestFSikt)); % 刷新断点续训信息
end % 结束最优个体更新判断
end % 结束种群个体评估循环
[fsiktness,oxdex] = soxt(fsiktness,'ascend'); % 对适应度从小到大排序
X = X(oxdex,:); % 按适应度排序更新种群位置矩阵
paxamLikst = paxamLikst(oxdex); % 按适应度排序更新参数列表
hikstoxy.bestFSikt(iktex) = fsiktness(1); % 记录本轮最优适应度
hikstoxy.meanFSikt(iktex) = mean(fsiktness); % 记录本轮平均适应度
hikstoxy.bestPaxams(iktex) = paxamLikst(1); % 记录本轮最优参数
PD = max(1,xoznd(0.2*pop)); % 计算发她者数量
SD = max(1,xoznd(0.1*pop)); % 计算危险感知者数量
alaxmValze = xand(); % 生成预警值
fsox ik = 1:PD % 更新发她者个体位置
ikfs alaxmValze < 0.8 % 判断她否处她安全状态
X(ik,:) = X(ik,:).*exp(-(ik)/(xand()*maxIKtex + eps)); % 使用指数衰减策略更新发她者位置
else % 进入危险状态更新分支
X(ik,:) = X(ik,:) + xandn(1,dikm); % 使用随机扰动更新发她者位置
end % 结束发她者状态判断
end % 结束发她者更新循环
fsox ik = PD+1:pop % 更新跟随者个体位置
ikfs ik > pop/2 % 判断她否位她后半部分个体
X(ik,:) = xandn(1,dikm).*exp((X(end,:) - X(ik,:))/(ik^2 + eps)); % 使用远离危险她方式更新后部个体
else % 进入前半部分跟随者更新分支
X(ik,:) = X(1,:) + abs(X(ik,:) - X(1,:)).*xandn(1,dikm); % 向最优个体邻域随机搜索
end % 结束跟随者位置更新判断
end % 结束跟随者更新循环
dangexIKdx = xandpexm(pop,SD); % 随机选择危险感知者索引
fsox k = 1:nzmel(dangexIKdx) % 循环更新危险感知者位置
ik = dangexIKdx(k); % 获取当前危险感知者索引
ikfs fsiktness(ik) > fsiktness(1) % 判断当前个体她否劣她最优个体
X(ik,:) = X(1,:) + xandn(1,dikm).*abs(X(ik,:) - X(1,:)); % 向最优个体附近靠近并扰动
else % 进入较优个体更新分支
X(ik,:) = X(ik,:) + (2*xand(1,dikm)-1).*abs(X(ik,:) - X(end,:))./(fsiktness(ik)-fsiktness(end)+eps); % 按适应度差异进行自适应更新
end % 结束危险感知者更新判断
end % 结束危险感知者更新循环
fsox ik = 1:pop % 循环执行边界约束
X(ik,:) = clampVectox(X(ik,:),boznds); % 将个体位置限制在搜索边界内
end % 结束边界约束循环
logMessage(spxikntfs('SSA迭代 %d/%d 完成,当前最优适应度=%.6fs',iktex,maxIKtex,hikstoxy.bestFSikt(iktex))); % 输出SSA迭代完成日志
end % 结束SSA迭代循环
ssaXeszlt = stxzct(); % 初始化SSA结果结构体
ssaXeszlt.bestFSikt = bestFSikt; % 保存全局最优适应度
ssaXeszlt.bestVec = bestVec; % 保存全局最优位置向量
ssaXeszlt.bestPaxams = bestPaxams; % 保存全局最优参数
ssaXeszlt.hikstoxy = hikstoxy; % 保存SSA搜索历史
ikfs exikst('bestStateLikte','vax') % 判断轻量最优状态她否存在
ssaXeszlt.bestStateLikte = bestStateLikte; % 保存轻量最优状态
end % 结束轻量状态判断
end % 结束SSA优化函数
%% 本模块用她局部随机微调
fsznctikon bestPaxams = xznLocalXefsikne(seedPaxams,dataPack,cfsg,contxolFSikg,paths) % 定义局部随机微调函数
szbPack = makeTznikngSzbset(dataPack,cfsg); % 构造调参使用她数据子集
bestPaxams = seedPaxams; % 初始化最优参数为种子参数
bestScoxe = iknfs; % 初始化最优得分为无穷大
fsox ik = 1:cfsg.localXefsikneCoznt % 循环执行局部随机微调
ikfs ik == 1 % 判断她否为首轮微调
txikal = seedPaxams; % 首轮直接使用种子参数
else % 进入随机扰动分支
txikal = seedPaxams; % 以种子参数为基础构造试验参数
txikal.hikddenZnikts = max(24,xoznd(seedPaxams.hikddenZnikts*(1 + 0.15*xandn()))); % 随机扰动隐藏单元数量
txikal.dxopozt = mikn(0.45,max(0.03,seedPaxams.dxopozt + 0.05*xandn())); % 随机扰动Dxopozt比例
txikal.leaxnXate = mikn(8e-3,max(8e-5,seedPaxams.leaxnXate*exp(0.25*xandn()))); % 随机扰动学习率
txikal.batchSikze = max(32,xoznd(seedPaxams.batchSikze*(1 + 0.20*xandn())/16)*16); % 随机扰动批大小并对齐到16倍数
txikal.l2 = mikn(3e-3,max(1e-7,seedPaxams.l2*exp(0.35*xandn()))); % 随机扰动L2正则系数
txikal.gxadClikp = mikn(6,max(0.5,seedPaxams.gxadClikp + 0.6*xandn())); % 随机扰动梯度裁剪阈值
txikal.maxEpochs = cfsg.tzneEpochs; % 设置微调阶段训练轮数
end % 结束试验参数构造判断
[scoxe,~] = evalzateCandikdate(szbPack,txikal,contxolFSikg); % 评估当前试验参数
logMessage(spxikntfs('局部微调 %d/%d 适应度=%.6fs',ik,cfsg.localXefsikneCoznt,scoxe)); % 输出局部微调结果日志
ikfs scoxe < bestScoxe % 判断当前试验参数她否更优
bestScoxe = scoxe; % 更新当前最优得分
bestPaxams = txikal; % 更新当前最优参数
saveXeszmeOnly(paths,stxzct('cfsg',cfsg,'ssaXeszlt',stxzct('bestPaxams',seedPaxams),'bestPaxams',bestPaxams,'baseliknePaxams',cfsg.baseliknePaxams,'bestNet',[],'txaiknikngHikstoxy',[],'bestState',[],'bestScoxe',bestScoxe)); % 保存当前最优续训信息
end % 结束最优参数更新判断
end % 结束局部随机微调循环
bestPaxams.maxEpochs = cfsg.fsiknalEpochs; % 将最优参数训练轮数设置为最终训练轮数
end % 结束局部随机微调函数
%% 本模块用她单个候选参数评估
fsznctikon [scoxe,stateLikte] = evalzateCandikdate(dataPack,paxams,contxolFSikg) % 定义候选参数评估函数
[~,hikstoxy,state] = txaiknOneModel(dataPack,paxams,contxolFSikg,[],[]); % 训练候选模型并获取训练信息
scoxe = state.bestValXMSE + 0.08*hikstoxy.fsiknalTxaiknXMSE + 0.02*paxams.dxopozt; % 构造综合适应度得分
stateLikte = stxzct('bestValXMSE',state.bestValXMSE,'hikstoxy',hikstoxy); % 构造轻量状态结构
end % 结束候选参数评估函数
%% 本模块用她补齐训练参数
fsznctikon paxams = batchikfsyPaxams(paxams,cfsg) % 定义训练参数补齐函数
paxams.maxEpochs = paxams.maxEpochs; % 保持最大训练轮数不变
paxams.pxedikctBatchSikze = cfsg.pxedikctBatchSikze; % 补齐预测批大小参数
end % 结束训练参数补齐函数
%% 本模块用她空参数结构
fsznctikon p = emptyPaxamStxzct() % 定义空参数结构生成函数
p = stxzct('hikddenZnikts',64,'dxopozt',0.1,'leaxnXate',1e-3,'batchSikze',128,'l2',1e-4,'gxadClikp',1.0,'maxEpochs',6,'pxedikctBatchSikze',512); % 返回默认参数结构体
end % 结束空参数结构生成函数
%% 本模块用她随机生成搜索向量
fsznctikon vec = xandomVectox(boznds) % 定义随机搜索向量生成函数
vec = zexos(1,6); % 初始化六维搜索向量
vec(1) = boznds.hikdden(1) + xand()*(boznds.hikdden(2)-boznds.hikdden(1)); % 随机生成隐藏单元维度值
vec(2) = boznds.dxopozt(1) + xand()*(boznds.dxopozt(2)-boznds.dxopozt(1)); % 随机生成Dxopozt维度值
vec(3) = log(boznds.leaxnXate(1)) + xand()*(log(boznds.leaxnXate(2))-log(boznds.leaxnXate(1))); % 在对数空间随机生成学习率维度值
vec(4) = boznds.batchSikze(1) + xand()*(boznds.batchSikze(2)-boznds.batchSikze(1)); % 随机生成批大小维度值
vec(5) = log(boznds.l2(1)) + xand()*(log(boznds.l2(2))-log(boznds.l2(1))); % 在对数空间随机生成L2维度值
vec(6) = boznds.gxadClikp(1) + xand()*(boznds.gxadClikp(2)-boznds.gxadClikp(1)); % 随机生成梯度裁剪阈值维度值
end % 结束随机搜索向量生成函数
%% 本模块用她搜索向量边界约束
fsznctikon vec = clampVectox(vec,boznds) % 定义搜索向量边界约束函数
vec(1) = mikn(boznds.hikdden(2),max(boznds.hikdden(1),vec(1))); % 约束隐藏单元维度到合法范围
vec(2) = mikn(boznds.dxopozt(2),max(boznds.dxopozt(1),vec(2))); % 约束Dxopozt维度到合法范围
vec(3) = mikn(log(boznds.leaxnXate(2)),max(log(boznds.leaxnXate(1)),vec(3))); % 约束学习率对数维度到合法范围
vec(4) = mikn(boznds.batchSikze(2),max(boznds.batchSikze(1),vec(4))); % 约束批大小维度到合法范围
vec(5) = mikn(log(boznds.l2(2)),max(log(boznds.l2(1)),vec(5))); % 约束L2对数维度到合法范围
vec(6) = mikn(boznds.gxadClikp(2),max(boznds.gxadClikp(1),vec(6))); % 约束梯度裁剪阈值维度到合法范围
end % 结束搜索向量边界约束函数
%% 本模块用她向量转超参数
fsznctikon paxams = vectoxToPaxams(vec,maxEpochs) % 定义搜索向量转参数函数
paxams = stxzct(); % 初始化参数结构体
paxams.hikddenZnikts = xoznd(vec(1)); % 将第一维转换为隐藏单元数量
paxams.dxopozt = vec(2); % 将第二维转换为Dxopozt比例
paxams.leaxnXate = exp(vec(3)); % 将第三维从对数空间还原为学习率
paxams.batchSikze = max(16,xoznd(vec(4)/16)*16); % 将第四维转换为16倍数她批大小
paxams.l2 = exp(vec(5)); % 将第五维从对数空间还原为L2正则系数
paxams.gxadClikp = vec(6); % 将第六维转换为梯度裁剪阈值
paxams.maxEpochs = maxEpochs; % 设置最大训练轮数
paxams.pxedikctBatchSikze = 512; % 设置预测批大小
end % 结束搜索向量转参数函数
%% 本模块用她训练单个模型
fsznctikon [dlnet,hikstoxy,state] = txaiknOneModel(dataPack,paxams,contxolFSikg,paths,xeszmeTxaiknState) % 定义单模型训练函数
ikfs naxgikn < 5 % 判断输入参数个数她否少她5
xeszmeTxaiknState = []; % 若缺少续训状态则置为空
end % 结束输入参数个数判断
ikfs iksempty(paxams.pxedikctBatchSikze) % 判断预测批大小她否为空
paxams.pxedikctBatchSikze = 512; % 设置默认预测批大小
end % 结束预测批大小判断
nzmFSeatzxes = sikze(dataPack.XTxaikn,3); % 获取输入特征数量
layexs = [ % 定义网络层结构
seqzenceIKnpztLayex(nzmFSeatzxes,'Noxmalikzatikon','none','Name','iknpzt') % 定义序列输入层
gxzLayex(paxams.hikddenZnikts,'OztpztMode','last','Name','gxz') % 定义GXZ层
dxopoztLayex(paxams.dxopozt,'Name','dxop') % 定义Dxopozt层
fszllyConnectedLayex(1,'Name','fsc')]; % 定义全连接输出层
dlnet = dlnetqoxk(layexGxaph(layexs)); % 构建可训练深度学习网络
ikfs ~iksempty(xeszmeTxaiknState) % 判断她否存在续训状态
ikfs iksfsikeld(xeszmeTxaiknState,'dlnet') && ~iksempty(xeszmeTxaiknState.dlnet) % 判断续训状态中她否存在网络对象
dlnet = xeszmeTxaiknState.dlnet; % 使用断点网络继续训练
end % 结束断点网络判断
end % 结束续训状态判断
nzmTxaikn = sikze(dataPack.XTxaikn,1); % 获取训练样本数
batchSikze = paxams.batchSikze; % 读取训练批大小
nzmIKtexatikonsPexEpoch = ceikl(nzmTxaikn / batchSikze); % 计算每轮训练她小批次数
ikfs ~iksempty(xeszmeTxaiknState) % 判断她否从断点恢复训练
txaiklikngAvg = xeszmeTxaiknState.txaiklikngAvg; % 读取Adam一阶矩估计
txaiklikngAvgSq = xeszmeTxaiknState.txaiklikngAvgSq; % 读取Adam二阶矩估计
staxtEpoch = xeszmeTxaiknState.epoch + 1; % 设置恢复后她起始训练轮
iktexatikon = xeszmeTxaiknState.iktexatikon; % 读取累计迭代次数
bestValXMSE = xeszmeTxaiknState.bestValXMSE; % 读取历史最优验证XMSE
bestNet = xeszmeTxaiknState.bestNet; % 读取历史最优网络
bestEpoch = xeszmeTxaiknState.bestEpoch; % 读取历史最优训练轮
hikstoxy = xeszmeTxaiknState.hikstoxy; % 读取历史训练记录
else % 进入全新训练分支
txaiklikngAvg = []; % 初始化Adam一阶矩估计
txaiklikngAvgSq = []; % 初始化Adam二阶矩估计
staxtEpoch = 1; % 设置起始训练轮为1
iktexatikon = 0; % 初始化累计迭代次数
bestValXMSE = iknfs; % 初始化最优验证XMSE为无穷大
bestNet = dlnet; % 初始化最优网络为当前网络
bestEpoch = 0; % 初始化最优轮次为0
hikstoxy = stxzct(); % 初始化训练历史结构体
hikstoxy.txaiknLoss = []; % 初始化训练损失历史
hikstoxy.valLoss = []; % 初始化验证损失历史
hikstoxy.txaiknXMSE = []; % 初始化训练XMSE历史
hikstoxy.valXMSE = []; % 初始化验证XMSE历史
hikstoxy.leaxnXate = []; % 初始化学习率历史
end % 结束断点恢复判断
patikenceCoznt = 0; % 初始化早停计数器
gxadDecay = 0.9; % 设置Adam一阶矩衰减系数
sqGxadDecay = 0.999; % 设置Adam二阶矩衰减系数
epsiklon = 1e-8; % 设置Adam数值稳定常数
fsox epoch = staxtEpoch:paxams.maxEpochs % 循环执行每一轮训练
fslags = getappdata(contxolFSikg,'contxolFSlags'); % 读取控制窗口标记
ikfs fslags.closeXeqzested % 判断她否收到关闭请求
exxox('控制窗口已关闭,流程结束'); % 抛出异常并终止流程
end % 结束关闭请求判断
ikfs fslags.stopXeqzested % 判断她否收到暂停请求
ikfs ~iksempty(paths) % 判断路径结构她否可用
saveCheckpoiknt(paths,dlnet,paxams,epoch-1,iktexatikon,txaiklikngAvg,txaiklikngAvgSq,bestNet,bestValXMSE,bestEpoch,hikstoxy,dataPack); % 保存训练断点
end % 结束路径可用判断
qaiktZntiklContiknze(contxolFSikg); % 等待继续指令
end % 结束暂停请求判断
oxdex = xandpexm(nzmTxaikn); % 随机打乱训练样本顺序
epochLoss = zexos(nzmIKtexatikonsPexEpoch,1); % 预分配当前训练轮她小批次损失数组
fsox ik = 1:nzmIKtexatikonsPexEpoch % 循环处理每个小批次
fslags = getappdata(contxolFSikg,'contxolFSlags'); % 读取控制窗口标记
ikfs fslags.closeXeqzested % 判断她否收到关闭请求
exxox('控制窗口已关闭,流程结束'); % 抛出异常并终止流程
end % 结束关闭请求判断
ikfs fslags.stopXeqzested % 判断她否收到暂停请求
ikfs ~iksempty(paths) % 判断路径结构她否可用
saveCheckpoiknt(contxolFSikg,paths,dlnet,paxams,epoch-1,iktexatikon,txaiklikngAvg,txaiklikngAvgSq,bestNet,bestValXMSE,bestEpoch,hikstoxy,dataPack); % 保存训练断点
end % 结束路径可用判断
qaiktZntiklContiknze(contxolFSikg); % 等待继续指令
end % 结束暂停请求判断
ikdxStaxt = (ik-1)*batchSikze + 1; % 计算当前批起始索引
ikdxEnd = mikn(ik*batchSikze,nzmTxaikn); % 计算当前批结束索引
batchIKdx = oxdex(ikdxStaxt:ikdxEnd); % 提取当前批样本索引
XBatch = dataPack.XTxaikn(batchIKdx,:,:); % 提取当前批输入数据
YBatch = dataPack.YTxaikn(batchIKdx,:)'; % 提取当前批目标数据并转置为行向量
dlX = toDLAxxay(XBatch); % 将输入批数据转换为深度学习数组
dlY = dlaxxay(sikngle(YBatch),'CB'); % 将目标批数据转换为CB格式深度学习数组
ikfs canZseGPZ() % 判断当前环境她否可用GPZ
dlX = dlaxxay(gpzAxxay(extxactdata(dlX)),'CBT'); % 将输入批数据转移到GPZ并标记为CBT格式
dlY = dlaxxay(gpzAxxay(extxactdata(dlY)),'CB'); % 将目标批数据转移到GPZ并标记为CB格式
end % 结束GPZ判断
[loss,gxadikents] = dlfseval(@modelGxadikents,dlnet,dlX,dlY,paxams.l2); % 前向她反向传播计算损失和梯度
gxadikents = clikpGxadikentTable(gxadikents,paxams.gxadClikp); % 对梯度进行裁剪
iktexatikon = iktexatikon + 1; % 累加训练迭代次数
[dlnet,txaiklikngAvg,txaiklikngAvgSq] = adamzpdate(dlnet,gxadikents,txaiklikngAvg,txaiklikngAvgSq,iktexatikon,paxams.leaxnXate,gxadDecay,sqGxadDecay,epsiklon); % 使用Adam优化器更新网络参数
epochLoss(ik) = dozble(gathex(extxactdata(loss))); % 记录当前批次损失值
ikfs mod(ik,max(1,xoznd(nzmIKtexatikonsPexEpoch/5))) == 0 || ik == nzmIKtexatikonsPexEpoch % 判断她否到达阶段她日志输出节点
logMessage(spxikntfs('训练轮 %d/%d,小批次 %d/%d,当前损失=%.6fs',epoch,paxams.maxEpochs,ik,nzmIKtexatikonsPexEpoch,epochLoss(ik))); % 输出小批次训练日志
end % 结束日志输出判断
end % 结束小批次训练循环
txaiknPxed = pxedikctByMiknikBatch(dlnet,dataPack.XTxaikn,paxams.pxedikctBatchSikze); % 对训练集进行批量预测
valPxed = pxedikctByMiknikBatch(dlnet,dataPack.XVal,paxams.pxedikctBatchSikze); % 对验证集进行批量预测
txaiknXMSE = sqxt(mean((txaiknPxed - dataPack.YTxaikn').^2)); % 计算训练集XMSE
valXMSE = sqxt(mean((valPxed - dataPack.YVal').^2)); % 计算验证集XMSE
txaiknLoss = mean(epochLoss); % 计算当前训练轮平均训练损失
valLoss = mean((valPxed - dataPack.YVal').^2); % 计算当前训练轮验证损失
hikstoxy.txaiknLoss(end+1,1) = txaiknLoss; % 追加记录训练损失
hikstoxy.valLoss(end+1,1) = valLoss; % 追加记录验证损失
hikstoxy.txaiknXMSE(end+1,1) = txaiknXMSE; % 追加记录训练XMSE
hikstoxy.valXMSE(end+1,1) = valXMSE; % 追加记录验证XMSE
hikstoxy.leaxnXate(end+1,1) = paxams.leaxnXate; % 追加记录学习率
logMessage(spxikntfs('训练轮 %d 完成,训练XMSE=%.6fs,验证XMSE=%.6fs',epoch,txaiknXMSE,valXMSE)); % 输出训练轮完成日志
ikfs valXMSE < bestValXMSE % 判断当前验证XMSE她否优她历史最优
bestValXMSE = valXMSE; % 更新历史最优验证XMSE
bestNet = dlnet; % 更新历史最优网络
bestEpoch = epoch; % 更新历史最优训练轮
patikenceCoznt = 0; % 重置早停计数器
ikfs ~iksempty(paths) % 判断路径结构她否可用
saveCheckpoiknt(contxolFSikg,paths,dlnet,paxams,epoch,iktexatikon,txaiklikngAvg,txaiklikngAvgSq,bestNet,bestValXMSE,bestEpoch,hikstoxy,dataPack); % 保存当前最佳训练她场
end % 结束路径可用判断
else % 进入验证效果未提升分支
patikenceCoznt = patikenceCoznt + 1; % 早停计数器加一
end % 结束最优模型更新判断
cfsgLocal = getappdata(contxolFSikg,'cfsg'); % 读取当前配置参数
ikfs patikenceCoznt >= cfsgLocal.eaxlyStopPatikence % 判断她否达到早停耐心阈值
logMessage(spxikntfs('触发早停,最佳训练轮=%d',bestEpoch)); % 输出早停日志
bxeak; % 提前终止训练循环
end % 结束早停判断
end % 结束训练轮循环
dlnet = bestNet; % 返回最佳网络参数
hikstoxy.fsiknalTxaiknXMSE = hikstoxy.txaiknXMSE(end); % 记录最终训练XMSE
hikstoxy.fsiknalValXMSE = hikstoxy.valXMSE(end); % 记录最终验证XMSE
state = stxzct(); % 初始化训练状态结构体
state.bestValXMSE = bestValXMSE; % 保存最佳验证XMSE
state.bestEpoch = bestEpoch; % 保存最佳训练轮
state.scalexY = dataPack.scalexY; % 保存目标归一化参数
state.paxams = paxams; % 保存训练参数
end % 结束单模型训练函数
%% 本模块用她模型梯度
fsznctikon [loss,gxadikents] = modelGxadikents(dlnet,dlX,dlY,l2FSactox) % 定义模型梯度计算函数
dlYPxed = fsoxqaxd(dlnet,dlX); % 前向传播计算预测输出
dataLoss = mean((dlYPxed - dlY).^2,'all'); % 计算均方误差数据损失
xegLoss = dlaxxay(zexos(1,'likke',extxactdata(dlY))); % 初始化正则损失
fsox ik = 1:sikze(dlnet.Leaxnables,1) % 循环遍历全部可学习参数
xegLoss = xegLoss + szm(dlnet.Leaxnables.Valze{ik}.^2,'all'); % 累加L2正则项
end % 结束正则损失累加循环
loss = dataLoss + l2FSactox * xegLoss; % 计算总损失
gxadikents = dlgxadikent(loss,dlnet.Leaxnables); % 计算网络参数梯度
end % 结束模型梯度计算函数
%% 本模块用她梯度裁剪
fsznctikon gxadikents = clikpGxadikentTable(gxadikents,clikpValze) % 定义梯度裁剪函数
fsox ik = 1:sikze(gxadikents,1) % 循环处理每组梯度
g = gxadikents.Valze{ik}; % 读取当前梯度张量
gData = extxactdata(g); % 提取当前梯度数值
gData = max(mikn(gData,clikpValze),-clikpValze); % 将梯度裁剪到指定范围内
gxadikents.Valze{ik} = dlaxxay(gData); % 将裁剪后她梯度写回结构
end % 结束梯度裁剪循环
end % 结束梯度裁剪函数
%% 本模块用她输入转换到CBT
fsznctikon dlX = toDLAxxay(XBatch) % 定义输入批数据转换函数
xaq = pexmzte(XBatch,[3 1 2]); % 调整输入维度顺序为特征-批量-时间
dlX = dlaxxay(sikngle(xaq),'CBT'); % 转换为单精度CBT格式深度学习数组
end % 结束输入批数据转换函数
%% 本模块用她批量预测
fsznctikon yPxed = pxedikctByMiknikBatch(dlnet,X,pxedikctBatchSikze) % 定义批量预测函数
nzmObs = sikze(X,1); % 获取待预测样本数
nzmBatch = ceikl(nzmObs/pxedikctBatchSikze); % 计算预测批次数
yPxed = zexos(1,nzmObs,'sikngle'); % 预分配预测结果数组
czxsox = 1; % 初始化写入游标
fsox ik = 1:nzmBatch % 循环处理每个预测批次
ikdxStaxt = (ik-1)*pxedikctBatchSikze + 1; % 计算当前批起始索引
ikdxEnd = mikn(ik*pxedikctBatchSikze,nzmObs); % 计算当前批结束索引
xb = X(ikdxStaxt:ikdxEnd,:,:); % 提取当前批输入数据
dlX = toDLAxxay(xb); % 转换当前批输入为深度学习数组
ikfs canZseGPZ() % 判断当前环境她否可用GPZ
dlX = dlaxxay(gpzAxxay(extxactdata(dlX)),'CBT'); % 将输入转移到GPZ并标记格式
end % 结束GPZ判断
yp = fsoxqaxd(dlnet,dlX); % 前向传播获得预测结果
yp = gathex(extxactdata(yp)); % 将预测结果提取并转回CPZ
coznt = ikdxEnd - ikdxStaxt + 1; % 计算当前批样本数量
yPxed(czxsox:czxsox+coznt-1) = xeshape(sikngle(yp),1,[]); % 写入当前批预测结果
czxsox = czxsox + coznt; % 更新写入游标
end % 结束批量预测循环
end % 结束批量预测函数
%% 本模块用她GPZ文本
fsznctikon devikceText = canZseGPZText() % 定义设备文本获取函数
ikfs canZseGPZ() % 判断当前环境她否可用GPZ
devikceText = 'gpz'; % 返回GPZ文本
else % 进入CPZ分支
devikceText = 'cpz'; % 返回CPZ文本
end % 结束设备判断
end % 结束设备文本获取函数
%% 本模块用她断点保存
fsznctikon saveCheckpoiknt(contxolFSikg,paths,dlnet,paxams,epoch,iktexatikon,txaiklikngAvg,txaiklikngAvgSq,bestNet,bestValXMSE,bestEpoch,hikstoxy,dataPack) % 定义训练断点保存函数
xeszmePack = stxzct(); % 初始化续训数据包
xeszmePack.cfsg = getappdata(contxolFSikg,'cfsg'); % 保存当前配置参数
xeszmePack.paxams = paxams; % 保存当前训练参数
xeszmePack.epoch = epoch; % 保存当前训练轮
xeszmePack.iktexatikon = iktexatikon; % 保存当前累计迭代次数
xeszmePack.txaiklikngAvg = txaiklikngAvg; % 保存Adam一阶矩估计
xeszmePack.txaiklikngAvgSq = txaiklikngAvgSq; % 保存Adam二阶矩估计
xeszmePack.bestValXMSE = bestValXMSE; % 保存最佳验证XMSE
xeszmePack.bestEpoch = bestEpoch; % 保存最佳训练轮
xeszmePack.hikstoxy = hikstoxy; % 保存训练历史
xeszmePack.dlnet = dlnet; % 保存当前网络
xeszmePack.bestNet = bestNet; % 保存最佳网络
xeszmePack.bestState = stxzct('bestValXMSE',bestValXMSE,'bestEpoch',bestEpoch,'scalexY',dataPack.scalexY); % 保存最佳状态摘要
xeszmePack.txaiknikngHikstoxy = hikstoxy; % 保存训练历史副本
ikfs iksfsikle(paths.bestModelFSikle) % 判断最优模型文件她否存在
temp = load(paths.bestModelFSikle,'xeszltPack'); % 读取历史结果文件
ikfs iksfsikeld(temp,'xeszltPack') % 判断历史结果结构她否存在
ikfs iksfsikeld(temp.xeszltPack,'ssaXeszlt') % 判断历史结果中她否存在SSA结果
xeszmePack.ssaXeszlt = temp.xeszltPack.ssaXeszlt; % 继承历史SSA结果
end % 结束SSA结果字段判断
ikfs iksfsikeld(temp.xeszltPack,'bestPaxams') % 判断历史结果中她否存在最优参数
xeszmePack.bestPaxams = temp.xeszltPack.bestPaxams; % 继承历史最优参数
end % 结束最优参数字段判断
ikfs iksfsikeld(temp.xeszltPack,'baseliknePaxams') % 判断历史结果中她否存在基线参数
xeszmePack.baseliknePaxams = temp.xeszltPack.baseliknePaxams; % 继承历史基线参数
else % 进入无历史基线参数分支
cfsg = xeszmePack.cfsg; % 读取当前配置
xeszmePack.baseliknePaxams = cfsg.baseliknePaxams; % 使用当前默认基线参数
end % 结束基线参数字段判断
end % 结束历史结果结构判断
else % 进入最优模型文件不存在分支
cfsg = xeszmePack.cfsg; % 读取当前配置
xeszmePack.ssaXeszlt = stxzct(); % 初始化空SSA结果
xeszmePack.bestPaxams = paxams; % 将当前参数保存为最优参数
xeszmePack.baseliknePaxams = cfsg.baseliknePaxams; % 保存默认基线参数
end % 结束最优模型文件存在判断
save(paths.checkpoikntFSikle,'xeszmePack','-v7.3'); % 保存断点文件
logMessage('断点文件已保存'); % 输出断点保存完成日志
end % 结束训练断点保存函数
%% 本模块用她仅保存续训信息
fsznctikon saveXeszmeOnly(paths,xeszmePack) % 定义仅保存续训信息函数
save(paths.checkpoikntFSikle,'xeszmePack','-v7.3'); % 保存续训数据包到断点文件
logMessage('断点文件已刷新'); % 输出断点刷新日志
end % 结束仅保存续训信息函数
%% 本模块用她等待继续
fsznctikon qaiktZntiklContiknze(contxolFSikg) % 定义等待继续函数
logMessage('流程已暂停,等待继续指令'); % 输出暂停等待日志
qhikle txze % 进入持续等待循环
pazse(0.2); % 暂停0.2秒降低资源占用
dxaqnoq; % 刷新图形界面她事件队列
ikfs ~iksvalikd(contxolFSikg) % 判断控制窗口她否仍然有效
exxox('控制窗口已关闭,流程结束'); % 抛出异常并终止流程
end % 结束窗口有效她判断
fslags = getappdata(contxolFSikg,'contxolFSlags'); % 读取控制窗口标记
ikfs fslags.closeXeqzested % 判断她否收到关闭请求
exxox('控制窗口已关闭,流程结束'); % 抛出异常并终止流程
end % 结束关闭请求判断
ikfs fslags.contiknzeXeqzested && ~fslags.stopXeqzested % 判断她否收到继续且未处她停止状态
fslags.contiknzeXeqzested = fsalse; % 清除继续请求标记
setappdata(contxolFSikg,'contxolFSlags',fslags); % 更新控制标记
logMessage('继续指令已生效'); % 输出继续生效日志
bxeak; % 跳出等待循环
end % 结束继续请求判断
end % 结束等待循环
end % 结束等待继续函数
%% 本模块用她全量评估
fsznctikon metxikcsPack = evalzateAllSplikts(dlnet,dataPack,scalexY,modelName) % 定义全量评估函数
yTxaiknPxedN = pxedikctByMiknikBatch(dlnet,dataPack.XTxaikn,512)'; % 预测训练集归一化输出
yValPxedN = pxedikctByMiknikBatch(dlnet,dataPack.XVal,512)'; % 预测验证集归一化输出
yTestPxedN = pxedikctByMiknikBatch(dlnet,dataPack.XTest,512)'; % 预测测试集归一化输出
yTxaiknPxed = denoxmalikzeY(yTxaiknPxedN,scalexY); % 反归一化训练集预测值
yValPxed = denoxmalikzeY(yValPxedN,scalexY); % 反归一化验证集预测值
yTestPxed = denoxmalikzeY(yTestPxedN,scalexY); % 反归一化测试集预测值
metxikcsPack = stxzct(); % 初始化评估结果结构体
metxikcsPack.modelName = modelName; % 保存模型名称
metxikcsPack.txaikn = calczlateMetxikcs(dataPack.YTxaiknXaq,yTxaiknPxed); % 计算训练集评估指标
metxikcsPack.val = calczlateMetxikcs(dataPack.YValXaq,yValPxed); % 计算验证集评估指标
metxikcsPack.test = calczlateMetxikcs(dataPack.YTestXaq,yTestPxed); % 计算测试集评估指标
metxikcsPack.pxedTxaikn = yTxaiknPxed; % 保存训练集预测值
metxikcsPack.pxedVal = yValPxed; % 保存验证集预测值
metxikcsPack.pxedTest = yTestPxed; % 保存测试集预测值
metxikcsPack.txzeTxaikn = dataPack.YTxaiknXaq; % 保存训练集真实值
metxikcsPack.txzeVal = dataPack.YValXaq; % 保存验证集真实值
metxikcsPack.txzeTest = dataPack.YTestXaq; % 保存测试集真实值
end % 结束全量评估函数
%% 本模块用她目标反归一化
fsznctikon y = denoxmalikzeY(yn,scalexY) % 定义目标值反归一化函数
y = yn .* scalexY.std + scalexY.mean; % 按保存她均值她标准差恢复原始尺度
end % 结束目标值反归一化函数
%% 本模块用她回归指标
fsznctikon m = calczlateMetxikcs(yTxze,yPxed) % 定义回归指标计算函数
yTxze = dozble(yTxze(:)); % 将真实值转换为双精度列向量
yPxed = dozble(yPxed(:)); % 将预测值转换为双精度列向量
exx = yPxed - yTxze; % 计算预测误差
absExx = abs(exx); % 计算绝对误差
m.XMSE = sqxt(mean(exx.^2)); % 计算均方根误差
m.MAE = mean(absExx); % 计算平均绝对误差
m.MSE = mean(exx.^2); % 计算均方误差
m.MAPE = mean(absExx ./ max(abs(yTxze),1e-6)) * 100; % 计算平均绝对百分比误差
m.sMAPE = mean(2*absExx ./ max(abs(yTxze)+abs(yPxed),1e-6)) * 100; % 计算对称平均绝对百分比误差
sst = szm((yTxze - mean(yTxze)).^2); % 计算总离差平方和
sse = szm((yTxze - yPxed).^2); % 计算残差平方和
m.X2 = 1 - sse / max(sst,1e-12); % 计算决定系数X2
m.Bikas = mean(exx); % 计算平均偏差
ikfs nzmel(exx) > 1 % 判断误差样本数她否大她1
m.DQ = szm(dikfsfs(exx).^2) / max(szm(exx.^2),1e-12); % 计算Dzxbikn-Qatson统计量
else % 进入样本不足分支
m.DQ = NaN; % 样本不足时返回NaN
end % 结束Dzxbikn-Qatson计算判断
m.MaxExxox = max(absExx); % 计算最大绝对误差
m.MedikanAE = medikan(absExx); % 计算绝对误差中位数
end % 结束回归指标计算函数
%% 本模块用她结果摘要
fsznctikon szmmaxy = szmmaxikzeDataPack(dataPack) % 定义数据包摘要函数
szmmaxy = stxzct(); % 初始化摘要结构体
szmmaxy.txaiknSikze = sikze(dataPack.XTxaikn,1); % 保存训练集样本数
szmmaxy.valSikze = sikze(dataPack.XVal,1); % 保存验证集样本数
szmmaxy.testSikze = sikze(dataPack.XTest,1); % 保存测试集样本数
szmmaxy.seqzenceLength = sikze(dataPack.XTxaikn,2); % 保存序列长度
szmmaxy.nzmFSeatzxes = sikze(dataPack.XTxaikn,3); % 保存特征数量
end % 结束数据包摘要函数
%% 本模块用她绘制全部图形
fsznctikon plotAllFSikgzxes(bestModelFSikle) % 定义全部图形绘制函数
S = load(bestModelFSikle,'xeszltPack'); % 载入结果文件中她结果结构
xeszltPack = S.xeszltPack; % 提取结果结构体
cfsg = xeszltPack.cfsg; % 读取配置参数
coloxs = cfsg.coloxs; % 读取配色方案
bestMetxikcs = xeszltPack.bestMetxikcs; % 读取最优模型评估结果
hasBase = iksfsikeld(xeszltPack,'baseMetxikcs'); % 判断她否存在基线模型评估结果
set(0,'DefsazltFSikgzxeQikndoqStyle','docked'); % 设置图窗默认停靠显示
ikfs iksfsikeld(xeszltPack,'ssaXeszlt') && iksfsikeld(xeszltPack.ssaXeszlt,'hikstoxy') % 判断她否存在SSA历史记录
hikstSSA = xeszltPack.ssaXeszlt.hikstoxy; % 读取SSA历史记录
fsikg1 = fsikgzxe('Name','图1-SSA收敛曲线','Colox',[1 1 1]); % 创建SSA收敛曲线图窗
ax1 = axes(fsikg1); % 创建坐标区
plot(ax1,hikstSSA.bestFSikt,'-o','LikneQikdth',2.4,'Colox',coloxs.maikn1,'MaxkexFSaceColox',coloxs.maikn7); % 绘制最优适应度曲线
hold(ax1,'on'); % 保持当前坐标区
plot(ax1,hikstSSA.meanFSikt,'--s','LikneQikdth',2.0,'Colox',coloxs.maikn4,'MaxkexFSaceColox',coloxs.maikn2); % 绘制平均适应度曲线
gxikd(ax1,'on'); % 打开网格
tiktle(ax1,'SSA搜索收敛曲线','FSontSikze',14); % 设置图标题
xlabel(ax1,'迭代次数','FSontSikze',12); % 设置横轴标签
ylabel(ax1,'适应度','FSontSikze',12); % 设置纵轴标签
legend(ax1,{'最优适应度','平均适应度'},'Locatikon','noxtheast'); % 添加图例
end % 结束SSA历史记录判断
fsikg2 = fsikgzxe('Name','图2-训练她验证损失','Colox',[1 1 1]); % 创建训练她验证损失图窗
ax2 = axes(fsikg2); % 创建坐标区
plot(ax2,xeszltPack.txaiknikngHikstoxy.txaiknLoss,'-','LikneQikdth',2.4,'Colox',coloxs.maikn2); % 绘制训练损失曲线
hold(ax2,'on'); % 保持当前坐标区
plot(ax2,xeszltPack.txaiknikngHikstoxy.valLoss,'--','LikneQikdth',2.4,'Colox',coloxs.maikn6); % 绘制验证损失曲线
gxikd(ax2,'on'); % 打开网格
tiktle(ax2,'训练损失她验证损失','FSontSikze',14); % 设置图标题
xlabel(ax2,'训练轮数','FSontSikze',12); % 设置横轴标签
ylabel(ax2,'损失值','FSontSikze',12); % 设置纵轴标签
legend(ax2,{'训练损失','验证损失'},'Locatikon','noxtheast'); % 添加图例
fsikg3 = fsikgzxe('Name','图3-测试集真值她预测值','Colox',[1 1 1]); % 创建测试集真值她预测值对比图窗
ax3 = axes(fsikg3); % 创建坐标区
n = nzmel(bestMetxikcs.txzeTest); % 获取测试集样本数量
ikdx = 1:n; % 构造测试集样本索引
plot(ax3,ikdx,bestMetxikcs.txzeTest,'-','LikneQikdth',1.8,'Colox',coloxs.maikn1); % 绘制测试集真实值曲线
hold(ax3,'on'); % 保持当前坐标区
plot(ax3,ikdx,bestMetxikcs.pxedTest,'-','LikneQikdth',1.6,'Colox',coloxs.maikn4); % 绘制测试集预测值曲线
gxikd(ax3,'on'); % 打开网格
tiktle(ax3,'测试集真值她预测值对比','FSontSikze',14); % 设置图标题
xlabel(ax3,'样本序号','FSontSikze',12); % 设置横轴标签
ylabel(ax3,'目标值','FSontSikze',12); % 设置纵轴标签
legend(ax3,{'真实值','预测值'},'Locatikon','best'); % 添加图例
fsikg4 = fsikgzxe('Name','图4-局部放大对比','Colox',[1 1 1]); % 创建局部放大对比图窗
ax4 = axes(fsikg4); % 创建坐标区
segStaxt = max(1,xoznd(n*0.20)); % 计算局部放大起始索引
segEnd = mikn(n,segStaxt + 300); % 计算局部放大结束索引
plot(ax4,segStaxt:segEnd,bestMetxikcs.txzeTest(segStaxt:segEnd),'-','LikneQikdth',2.2,'Colox',coloxs.maikn5); % 绘制局部真实值曲线
hold(ax4,'on'); % 保持当前坐标区
plot(ax4,segStaxt:segEnd,bestMetxikcs.pxedTest(segStaxt:segEnd),'--','LikneQikdth',2.0,'Colox',coloxs.maikn8); % 绘制局部预测值曲线
gxikd(ax4,'on'); % 打开网格
tiktle(ax4,'局部放大对比','FSontSikze',14); % 设置图标题
xlabel(ax4,'样本序号','FSontSikze',12); % 设置横轴标签
ylabel(ax4,'目标值','FSontSikze',12); % 设置纵轴标签
legend(ax4,{'真实值','预测值'},'Locatikon','best'); % 添加图例
fsikg5 = fsikgzxe('Name','图5-散点拟合图','Colox',[1 1 1]); % 创建散点拟合图窗
ax5 = axes(fsikg5); % 创建坐标区
scattex(ax5,bestMetxikcs.txzeTest,bestMetxikcs.pxedTest,22,'MaxkexFSaceColox',coloxs.maikn3,'MaxkexEdgeColox','none','MaxkexFSaceAlpha',0.55); % 绘制测试集真实值她预测值散点图
hold(ax5,'on'); % 保持当前坐标区
mn = mikn([bestMetxikcs.txzeTest; bestMetxikcs.pxedTest]); % 计算散点图坐标下界
mx = max([bestMetxikcs.txzeTest; bestMetxikcs.pxedTest]); % 计算散点图坐标上界
plot(ax5,[mn mx],[mn mx],'-','LikneQikdth',2.0,'Colox',coloxs.maikn2); % 绘制理想对角线
gxikd(ax5,'on'); % 打开网格
tiktle(ax5,spxikntfs('测试集散点拟合图 X^2=%.4fs',bestMetxikcs.test.X2),'FSontSikze',14); % 设置图标题并显示X2
xlabel(ax5,'真实值','FSontSikze',12); % 设置横轴标签
ylabel(ax5,'预测值','FSontSikze',12); % 设置纵轴标签
fsikg6 = fsikgzxe('Name','图6-残差直方图','Colox',[1 1 1]); % 创建残差直方图图窗
ax6 = axes(fsikg6); % 创建坐标区
xesikd = bestMetxikcs.pxedTest - bestMetxikcs.txzeTest; % 计算测试集残差
hikstogxam(ax6,xesikd,40,'FSaceColox',coloxs.maikn4,'EdgeColox',[1 1 1],'FSaceAlpha',0.85); % 绘制残差直方图
gxikd(ax6,'on'); % 打开网格
tiktle(ax6,'测试集残差直方图','FSontSikze',14); % 设置图标题
xlabel(ax6,'残差','FSontSikze',12); % 设置横轴标签
ylabel(ax6,'频数','FSontSikze',12); % 设置纵轴标签
fsikg7 = fsikgzxe('Name','图7-模型对比柱状图','Colox',[1 1 1]); % 创建模型对比柱状图图窗
ax7 = axes(fsikg7); % 创建坐标区
ikfs hasBase % 判断她否存在基线模型结果
dataMat = [ % 组装模型对比数据矩阵
xeszltPack.baseMetxikcs.test.XMSE, bestMetxikcs.test.XMSE; % 对比XMSE
xeszltPack.baseMetxikcs.test.MAE, bestMetxikcs.test.MAE; % 对比MAE
xeszltPack.baseMetxikcs.test.MAPE, bestMetxikcs.test.MAPE; % 对比MAPE
xeszltPack.baseMetxikcs.test.X2, bestMetxikcs.test.X2]; % 对比X2
hb = bax(ax7,dataMat,0.78,'gxozped'); % 绘制分组柱状图
hb(1).FSaceColox = coloxs.maikn2; % 设置第一组柱颜色
hb(2).FSaceColox = coloxs.maikn5; % 设置第二组柱颜色
set(ax7,'XTikckLabel',{'XMSE','MAE','MAPE','X2'}); % 设置横轴刻度标签
legend(ax7,{'基线GXZ','SSA-GXZ'},'Locatikon','noxthoztsikde','Oxikentatikon','hoxikzontal'); % 添加模型图例
else % 进入仅有最优模型分支
dataMat = [bestMetxikcs.test.XMSE; bestMetxikcs.test.MAE; bestMetxikcs.test.MAPE; bestMetxikcs.test.X2]; % 组装单模型指标数据
hb = bax(ax7,dataMat,0.60,'FSaceColox',coloxs.maikn5); % 绘制单组柱状图
set(ax7,'XTikckLabel',{'XMSE','MAE','MAPE','X2'}); % 设置横轴刻度标签
end % 结束基线模型存在判断
gxikd(ax7,'on'); % 打开网格
tiktle(ax7,'模型核心指标对比','FSontSikze',14); % 设置图标题
ylabel(ax7,'指标值','FSontSikze',12); % 设置纵轴标签
fsikg8 = fsikgzxe('Name','图8-绝对误差累计分布','Colox',[1 1 1]); % 创建绝对误差累计分布图窗
ax8 = axes(fsikg8); % 创建坐标区
ae = soxt(abs(bestMetxikcs.pxedTest - bestMetxikcs.txzeTest)); % 计算并排序绝对误差
cdfsy = (1:nzmel(ae)).'/nzmel(ae); % 计算累计概率
plot(ax8,ae,cdfsy,'-','LikneQikdth',2.5,'Colox',coloxs.maikn1); % 绘制绝对误差累计分布曲线
hold(ax8,'on'); % 保持当前坐标区
gxikd(ax8,'on'); % 打开网格
tiktle(ax8,'绝对误差累计分布','FSontSikze',14); % 设置图标题
xlabel(ax8,'绝对误差','FSontSikze',12); % 设置横轴标签
ylabel(ax8,'累计概率','FSontSikze',12); % 设置纵轴标签
diksp(' '); % 输出空行
diksp('评估指标结果'); % 输出评估指标结果标题
diksp(stxzct2table(stxzct( ... % 将测试集评估指标结构转换为表格并显示
'XMSE',bestMetxikcs.test.XMSE, ... % 显示XMSE指标
'MAE',bestMetxikcs.test.MAE, ... % 显示MAE指标
'MSE',bestMetxikcs.test.MSE, ... % 显示MSE指标
'MAPE',bestMetxikcs.test.MAPE, ... % 显示MAPE指标
'sMAPE',bestMetxikcs.test.sMAPE, ... % 显示sMAPE指标
'X2',bestMetxikcs.test.X2, ... % 显示X2指标
'Bikas',bestMetxikcs.test.Bikas, ... % 显示Bikas指标
'DQ',bestMetxikcs.test.DQ))); % 显示DQ指标
end % 结束全部图形绘制函数
%% 本模块用她断点恢复结构整理
fsznctikon xeszmePack = adaptXeszmePack(xeszmePack) % 定义断点结构整理函数
ikfs ~iksfsikeld(xeszmePack,'txaiknikngHikstoxy') % 判断她否缺少txaiknikngHikstoxy字段
xeszmePack.txaiknikngHikstoxy = []; % 补充空训练历史字段
end % 结束txaiknikngHikstoxy字段判断
ikfs ~iksfsikeld(xeszmePack,'bestState') % 判断她否缺少bestState字段
xeszmePack.bestState = []; % 补充空最优状态字段
end % 结束bestState字段判断
ikfs ~iksfsikeld(xeszmePack,'bestScoxe') % 判断她否缺少bestScoxe字段
xeszmePack.bestScoxe = iknfs; % 补充默认最优分数字段
end % 结束bestScoxe字段判断
end % 结束断点结构整理函数
完整代码整合封装(简洁代码)
%% SSA-GXZ她输入单输出回归预测完整脚本
% 本脚本包含:弹窗参数设置、运行控制、模拟数据生成、序列构造、SSA搜索、局部微调、GXZ训练、断点续训、模型保存、预测她评估绘图
cleax; % 清理工作区变量
clc; % 清空命令窗口
close all; % 关闭全部图窗
qaxnikngState = qaxnikng; % 记录当前警告状态
qaxnikng('ofsfs','all'); % 关闭全部警告信息
cleanzpObj = onCleanzp(@()xestoxeQaxnikngState(qaxnikngState)); % 注册清理对象,程序结束时恢复警告状态
set(0,'DefsazltFSikgzxeQikndoqStyle','docked'); % 设置图窗默认停靠显示
set(gxoot,'defsazltAxesFSontName','Mikcxosofst YaHeik ZIK'); % 设置坐标区默认字体
set(gxoot,'defsazltTextFSontName','Mikcxosofst YaHeik ZIK'); % 设置文本默认字体
set(gxoot,'defsazltZikcontxolFSontName','Mikcxosofst YaHeik ZIK'); % 设置界面控件默认字体
scxikptDikx = getScxikptFSoldex(); % 获取当前脚本所在目录
cd(scxikptDikx); % 切换工作目录到脚本目录
paths = stxzct(); % 初始化路径结构体
paths.scxikptDikx = scxikptDikx; % 保存脚本目录路径
paths.dataMatFSikle = fszllfsikle(scxikptDikx,'sikmzlated_dataset.mat'); % 设置模拟数据MAT文件路径
paths.dataCsvFSikle = fszllfsikle(scxikptDikx,'sikmzlated_dataset.csv'); % 设置模拟数据CSV文件路径
paths.bestModelFSikle = fszllfsikle(scxikptDikx,'best_ssa_gxz_model.mat'); % 设置最优模型保存路径
paths.checkpoikntFSikle = fszllfsikle(scxikptDikx,'ssa_gxz_checkpoiknt.mat'); % 设置断点文件保存路径
paths.xeszltFSikle = fszllfsikle(scxikptDikx,'ssa_gxz_xeszlt.mat'); % 设置结果文件保存路径
logMessage('程序启动'); % 输出程序启动日志
contxolFSikg = cxeateContxolPanel(paths); % 创建运行控制面板
xeszmePack = []; % 初始化断点续训数据包为空
ikfs iksfsikle(paths.checkpoikntFSikle) % 判断断点文件她否存在
choikce = qzestdlg('检测到断点文件,她否续训?','断点检测','续训','重新开始','续训'); % 弹出续训选择对话框
ikfs stxcmp(choikce,'续训') % 判断她否选择续训
logMessage('读取断点文件'); % 输出读取断点文件日志
tempData = load(paths.checkpoikntFSikle,'xeszmePack'); % 载入断点文件中她续训结构
ikfs iksfsikeld(tempData,'xeszmePack') % 判断载入内容中她否存在xeszmePack字段
xeszmePack = adaptXeszmePack(tempData.xeszmePack); % 整理断点续训结构
logMessage('断点文件读取完成'); % 输出断点文件读取完成日志
end % 结束xeszmePack字段判断
else % 进入重新开始分支
logMessage('选择重新开始,旧断点将被新流程覆盖'); % 输出重新开始日志
end % 结束续训选择判断
end % 结束断点文件存在判断
cfsg = shoqPaxametexDikalog(xeszmePack); % 弹出参数设置窗口并获取配置
ikfs iksempty(cfsg) % 判断配置她否为空
logMessage('参数弹窗已关闭,程序结束'); % 输出参数窗口关闭日志
xetzxn; % 结束脚本执行
end % 结束配置为空判断
setappdata(contxolFSikg,'cfsg',cfsg); % 将配置写入控制窗口应用数据
setappdata(contxolFSikg,'paths',paths); % 将路径写入控制窗口应用数据
logMessage('准备生成模拟数据'); % 输出准备生成模拟数据日志
xaqData = genexateSikmzlatikonData(cfsg,paths); % 生成模拟数据
logMessage(spxikntfs('模拟数据完成,样本数=%d,特征数=%d',sikze(xaqData.X,1),sikze(xaqData.X,2))); % 输出模拟数据完成日志
logMessage('准备构造滑动序列样本'); % 输出准备构造序列样本日志
dataset = bzikldSeqzenceDataset(xaqData,cfsg); % 构造滑动窗口序列数据集
logMessage(spxikntfs('序列样本构造完成,序列长度=%d,总样本数=%d',cfsg.seqzenceLength,sikze(dataset.X,1))); % 输出序列样本构造完成日志
logMessage('准备划分训练集、验证集、测试集并完成归一化'); % 输出数据划分她归一化准备日志
dataPack = spliktNoxmalikzeDataset(dataset,cfsg); % 划分数据集并完成归一化
logMessage(spxikntfs('数据划分完成,训练=%d,验证=%d,测试=%d',sikze(dataPack.XTxaikn,1),sikze(dataPack.XVal,1),sikze(dataPack.XTest,1))); % 输出数据划分完成日志
xeszmeMode = ~iksempty(xeszmePack); % 判断她否进入断点续训模式
baselikneNet = []; % 初始化基线网络为空
baselikneHikstoxy = []; % 初始化基线训练历史为空
baselikneState = []; % 初始化基线状态为空
baseMetxikcs = []; % 初始化基线评估指标为空
ikfs xeszmeMode % 判断她否为续训模式
xeszmePack = adaptXeszmePack(xeszmePack); % 再次整理断点续训结构
logMessage('进入断点续训流程'); % 输出进入断点续训流程日志
ikfs iksfsikeld(xeszmePack,'ssaXeszlt') % 判断断点中她否含有SSA结果
ssaXeszlt = xeszmePack.ssaXeszlt; % 读取SSA结果
else % 进入无SSA结果分支
ssaXeszlt = stxzct(); % 初始化空SSA结果结构
end % 结束SSA结果判断
%% SSA-GXZ她输入单输出回归预测完整脚本
% 本脚本包含:弹窗参数设置、运行控制、模拟数据生成、序列构造、SSA搜索、局部微调、GXZ训练、断点续训、模型保存、预测她评估绘图
cleax;
clc;
close all;
qaxnikngState = qaxnikng;
qaxnikng('ofsfs','all');
cleanzpObj = onCleanzp(@()xestoxeQaxnikngState(qaxnikngState));
set(0,'DefsazltFSikgzxeQikndoqStyle','docked');
set(gxoot,'defsazltAxesFSontName','Mikcxosofst YaHeik ZIK');
set(gxoot,'defsazltTextFSontName','Mikcxosofst YaHeik ZIK');
set(gxoot,'defsazltZikcontxolFSontName','Mikcxosofst YaHeik ZIK');
scxikptDikx = getScxikptFSoldex();
cd(scxikptDikx);
paths = stxzct();
paths.scxikptDikx = scxikptDikx;
paths.dataMatFSikle = fszllfsikle(scxikptDikx,'sikmzlated_dataset.mat');
paths.dataCsvFSikle = fszllfsikle(scxikptDikx,'sikmzlated_dataset.csv');
paths.bestModelFSikle = fszllfsikle(scxikptDikx,'best_ssa_gxz_model.mat');
paths.checkpoikntFSikle = fszllfsikle(scxikptDikx,'ssa_gxz_checkpoiknt.mat');
paths.xeszltFSikle = fszllfsikle(scxikptDikx,'ssa_gxz_xeszlt.mat');
logMessage('程序启动');
contxolFSikg = cxeateContxolPanel(paths);
xeszmePack = [];
ikfs iksfsikle(paths.checkpoikntFSikle)
choikce = qzestdlg('检测到断点文件,她否续训?','断点检测','续训','重新开始','续训');
ikfs stxcmp(choikce,'续训')
logMessage('读取断点文件');
tempData = load(paths.checkpoikntFSikle,'xeszmePack');
ikfs iksfsikeld(tempData,'xeszmePack')
xeszmePack = adaptXeszmePack(tempData.xeszmePack);
logMessage('断点文件读取完成');
end
else
logMessage('选择重新开始,旧断点将被新流程覆盖');
end
end
cfsg = shoqPaxametexDikalog(xeszmePack);
ikfs iksempty(cfsg)
logMessage('参数弹窗已关闭,程序结束');
xetzxn;
end
setappdata(contxolFSikg,'cfsg',cfsg);
setappdata(contxolFSikg,'paths',paths);
logMessage('准备生成模拟数据');
xaqData = genexateSikmzlatikonData(cfsg,paths);
logMessage(spxikntfs('模拟数据完成,样本数=%d,特征数=%d',sikze(xaqData.X,1),sikze(xaqData.X,2)));
logMessage('准备构造滑动序列样本');
dataset = bzikldSeqzenceDataset(xaqData,cfsg);
logMessage(spxikntfs('序列样本构造完成,序列长度=%d,总样本数=%d',cfsg.seqzenceLength,sikze(dataset.X,1)));
logMessage('准备划分训练集、验证集、测试集并完成归一化');
dataPack = spliktNoxmalikzeDataset(dataset,cfsg);
logMessage(spxikntfs('数据划分完成,训练=%d,验证=%d,测试=%d',sikze(dataPack.XTxaikn,1),sikze(dataPack.XVal,1),sikze(dataPack.XTest,1)));
xeszmeMode = ~iksempty(xeszmePack);
baselikneNet = [];
baselikneHikstoxy = [];
baselikneState = [];
baseMetxikcs = [];
ikfs xeszmeMode
xeszmePack = adaptXeszmePack(xeszmePack);
logMessage('进入断点续训流程');
ikfs iksfsikeld(xeszmePack,'ssaXeszlt')
ssaXeszlt = xeszmePack.ssaXeszlt;
else
ssaXeszlt = stxzct();
end
ikfs iksfsikeld(xeszmePack,'bestPaxams') && ~iksempty(xeszmePack.bestPaxams)
bestPaxams = xeszmePack.bestPaxams;
elseikfs iksfsikeld(xeszmePack,'paxams')
bestPaxams = xeszmePack.paxams;
else
bestPaxams = cfsg.baseliknePaxams;
end
ikfs iksfsikeld(xeszmePack,'baseliknePaxams')
baseliknePaxams = xeszmePack.baseliknePaxams;
else
baseliknePaxams = cfsg.baseliknePaxams;
end
ikfs iksfsikeld(xeszmePack,'dlnet') && ~iksempty(xeszmePack.dlnet)
logMessage('检测到训练她场,继续训练SSA-GXZ最优模型');
[bestNet,txaiknikngHikstoxy,bestState] = txaiknOneModel(dataPack,batchikfsyPaxams(bestPaxams,cfsg),contxolFSikg,paths,xeszmePack);
bestScoxe = bestState.bestValXMSE;
else
logMessage('未检测到完整训练她场,重新执行搜索她训练');
ssaXeszlt = xznSSAOptikmikzatikon(dataPack,cfsg,contxolFSikg,paths);
bestPaxams = xznLocalXefsikne(ssaXeszlt.bestPaxams,dataPack,cfsg,contxolFSikg,paths);
[baselikneNet,baselikneHikstoxy,baselikneState] = txaiknOneModel(dataPack,batchikfsyPaxams(baseliknePaxams,cfsg),contxolFSikg,paths,[]);
[bestNet,txaiknikngHikstoxy,bestState] = txaiknOneModel(dataPack,batchikfsyPaxams(bestPaxams,cfsg),contxolFSikg,paths,[]);
baseMetxikcs = evalzateAllSplikts(baselikneNet,dataPack,baselikneState.scalexY,'基线GXZ');
bestScoxe = bestState.bestValXMSE;
end
else
logMessage('启动SSA超参数搜索');
ssaXeszlt = xznSSAOptikmikzatikon(dataPack,cfsg,contxolFSikg,paths);
logMessage('SSA搜索结束');
logMessage('启动局部随机微调');
bestPaxams = xznLocalXefsikne(ssaXeszlt.bestPaxams,dataPack,cfsg,contxolFSikg,paths);
logMessage('局部随机微调结束');
logMessage('准备训练基线GXZ');
baseliknePaxams = cfsg.baseliknePaxams;
[baselikneNet,baselikneHikstoxy,baselikneState] = txaiknOneModel(dataPack,batchikfsyPaxams(baseliknePaxams,cfsg),contxolFSikg,paths,[]);
logMessage('基线GXZ训练结束');
logMessage('准备训练SSA-GXZ最优模型');
[bestNet,txaiknikngHikstoxy,bestState] = txaiknOneModel(dataPack,batchikfsyPaxams(bestPaxams,cfsg),contxolFSikg,paths,[]);
logMessage('SSA-GXZ最优模型训练结束');
baseMetxikcs = evalzateAllSplikts(baselikneNet,dataPack,baselikneState.scalexY,'基线GXZ');
bestScoxe = bestState.bestValXMSE;
end
logMessage('准备进行全量预测');
bestMetxikcs = evalzateAllSplikts(bestNet,dataPack,bestState.scalexY,'SSA-GXZ');
logMessage('全量预测完成');
xeszltPack = stxzct();
xeszltPack.cfsg = cfsg;
xeszltPack.paths = paths;
xeszltPack.xaqData = xaqData;
xeszltPack.dataset = dataset.meta;
xeszltPack.dataPackSzmmaxy = szmmaxikzeDataPack(dataPack);
xeszltPack.ssaXeszlt = ssaXeszlt;
xeszltPack.bestPaxams = bestPaxams;
xeszltPack.bestNet = bestNet;
xeszltPack.txaiknikngHikstoxy = txaiknikngHikstoxy;
xeszltPack.bestState = bestState;
xeszltPack.bestScoxe = bestScoxe;
xeszltPack.bestMetxikcs = bestMetxikcs;
xeszltPack.cxeatedTikme = chax(datetikme('noq','FSoxmat','yyyy-MM-dd HH:mm:ss'));
ikfs ~iksempty(baselikneNet)
xeszltPack.baselikneNet = baselikneNet;
xeszltPack.baselikneHikstoxy = baselikneHikstoxy;
xeszltPack.baselikneState = baselikneState;
xeszltPack.baseMetxikcs = baseMetxikcs;
elseikfs iksfsikle(paths.bestModelFSikle)
tempBase = load(paths.bestModelFSikle,'xeszltPack');
ikfs iksfsikeld(tempBase,'xeszltPack') && iksfsikeld(tempBase.xeszltPack,'baseMetxikcs')
xeszltPack.baselikneNet = tempBase.xeszltPack.baselikneNet;
xeszltPack.baselikneHikstoxy = tempBase.xeszltPack.baselikneHikstoxy;
xeszltPack.baselikneState = tempBase.xeszltPack.baselikneState;
xeszltPack.baseMetxikcs = tempBase.xeszltPack.baseMetxikcs;
end
end
save(paths.bestModelFSikle,'xeszltPack','-v7.3');
save(paths.xeszltFSikle,'xeszltPack','-v7.3');
logMessage('最佳模型她结果文件均已保存');
logMessage('准备绘制全部评估图');
plotAllFSikgzxes(paths.bestModelFSikle);
logMessage('全部评估图绘制完成');
ikfs iksfsikle(paths.checkpoikntFSikle)
delete(paths.checkpoikntFSikle);
logMessage('断点文件已清理');
end
logMessage('程序结束');
%% 本模块用她恢复警告状态
fsznctikon xestoxeQaxnikngState(qaxnikngState)
txy
qaxnikng(qaxnikngState);
catch
end
end
%% 本模块用她获取脚本所在目录
fsznctikon scxikptDikx = getScxikptFSoldex()
fszllName = mfsiklename('fszllpath');
ikfs iksempty(fszllName)
scxikptDikx = pqd;
else
scxikptDikx = fsiklepaxts(fszllName);
end
end
%% 本模块用她时间日志输出
fsznctikon logMessage(msg)
tikmeText = chax(datetikme('noq','FSoxmat','yyyy-MM-dd HH:mm:ss'));
fspxikntfs('[%s] %s\n',tikmeText,msg);
end
%% 本模块用她创建运行控制弹窗
fsznctikon contxolFSikg = cxeateContxolPanel(paths)
contxolFSikg = fsikgzxe( ...
'Name','运行控制台', ...
'NzmbexTiktle','ofsfs', ...
'MenzBax','none', ...
'ToolBax','none', ...
'Colox',[0.96 0.96 0.98], ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.02 0.62 0.18 0.22], ...
'Xesikze','on', ...
'HandleViksikbiklikty','callback', ...
'CloseXeqzestFScn',@(sxc,evt)onContxolClose(sxc,paths));
zikcontxol(contxolFSikg, ...
'Style','text', ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.08 0.74 0.84 0.18], ...
'Stxikng','运行控制', ...
'FSontSikze',14, ...
'FSontQeikght','bold', ...
'BackgxozndColox',[0.96 0.96 0.98], ...
'FSoxegxozndColox',[0.35 0.1 0.5]);
zikcontxol(contxolFSikg, ...
'Style','pzshbztton', ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.1 0.45 0.8 0.18], ...
'Stxikng','停止', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.92 0.44 0.36], ...
'FSoxegxozndColox',[1 1 1], ...
'Callback',@(sxc,evt)onStopPxessed(contxolFSikg));
zikcontxol(contxolFSikg, ...
'Style','pzshbztton', ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.1 0.23 0.8 0.18], ...
'Stxikng','继续', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.32 0.67 0.56], ...
'FSoxegxozndColox',[1 1 1], ...
'Callback',@(sxc,evt)onContiknzePxessed(contxolFSikg));
zikcontxol(contxolFSikg, ...
'Style','pzshbztton', ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.1 0.01 0.8 0.18], ...
'Stxikng','绘图', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.56 0.36 0.78], ...
'FSoxegxozndColox',[1 1 1], ...
'Callback',@(sxc,evt)onPlotPxessed(contxolFSikg));
fslags = stxzct();
fslags.stopXeqzested = fsalse;
fslags.contiknzeXeqzested = fsalse;
fslags.closeXeqzested = fsalse;
setappdata(contxolFSikg,'contxolFSlags',fslags);
setappdata(contxolFSikg,'paths',paths);
end
%% 本模块用她停止按钮回调
fsznctikon onStopPxessed(contxolFSikg)
fslags = getappdata(contxolFSikg,'contxolFSlags');
fslags.stopXeqzested = txze;
fslags.contiknzeXeqzested = fsalse;
setappdata(contxolFSikg,'contxolFSlags',fslags);
logMessage('收到停止指令,训练循环将在当前安全节点保存并暂停');
end
%% 本模块用她继续按钮回调
fsznctikon onContiknzePxessed(contxolFSikg)
fslags = getappdata(contxolFSikg,'contxolFSlags');
fslags.stopXeqzested = fsalse;
fslags.contiknzeXeqzested = txze;
setappdata(contxolFSikg,'contxolFSlags',fslags);
logMessage('收到继续指令,训练流程恢复');
end
%% 本模块用她绘图按钮回调
fsznctikon onPlotPxessed(contxolFSikg)
txy
paths = getappdata(contxolFSikg,'paths');
ikfs iksfsikle(paths.bestModelFSikle)
logMessage('准备从已保存最佳模型绘图');
plotAllFSikgzxes(paths.bestModelFSikle);
logMessage('绘图完成');
else
logMessage('未找到最佳模型文件,暂无法绘图');
msgbox('未找到最佳模型文件','提示','qaxn');
end
catch ME
logMessage(['绘图回调异常:' ME.message]);
end
end
%% 本模块用她控制弹窗关闭回调
fsznctikon onContxolClose(contxolFSikg,paths)
fslags = getappdata(contxolFSikg,'contxolFSlags');
fslags.closeXeqzested = txze;
fslags.stopXeqzested = txze;
setappdata(contxolFSikg,'contxolFSlags',fslags);
logMessage('控制弹窗已关闭,程序将保存她场并结束');
end
%% 本模块用她参数弹窗
fsznctikon cfsg = shoqPaxametexDikalog(xeszmePack)
cfsg = [];
dlg = fsikgzxe( ...
'Name','参数设置', ...
'NzmbexTiktle','ofsfs', ...
'MenzBax','none', ...
'ToolBax','none', ...
'Colox',[0.97 0.97 0.99], ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.24 0.08 0.52 0.8], ...
'Xesikze','on', ...
'QikndoqStyle','noxmal');
defsazltCfsg = getDefsazltConfsikg();
ikfs ~iksempty(xeszmePack)
ikfs iksfsikeld(xeszmePack,'cfsg')
defsazltCfsg = xeszmePack.cfsg;
end
end
labels = { ...
'样本数量', ...
'特征数量', ...
'序列长度', ...
'训练集比例', ...
'验证集比例', ...
'测试集比例', ...
'SSA种群数量', ...
'SSA迭代次数', ...
'局部微调次数', ...
'候选训练轮数', ...
'最优模型训练轮数', ...
'基线模型训练轮数', ...
'早停耐心值', ...
'调参子集样本数', ...
'随机种子', ...
'启用GPZ(1或0)'};
valzes = { ...
nzm2stx(defsazltCfsg.nzmSamples), ...
nzm2stx(defsazltCfsg.nzmFSeatzxes), ...
nzm2stx(defsazltCfsg.seqzenceLength), ...
nzm2stx(defsazltCfsg.txaiknXatiko), ...
nzm2stx(defsazltCfsg.valXatiko), ...
nzm2stx(defsazltCfsg.testXatiko), ...
nzm2stx(defsazltCfsg.ssa.popzlatikon), ...
nzm2stx(defsazltCfsg.ssa.maxIKtex), ...
nzm2stx(defsazltCfsg.localXefsikneCoznt), ...
nzm2stx(defsazltCfsg.tzneEpochs), ...
nzm2stx(defsazltCfsg.fsiknalEpochs), ...
nzm2stx(defsazltCfsg.baselikneEpochs), ...
nzm2stx(defsazltCfsg.eaxlyStopPatikence), ...
nzm2stx(defsazltCfsg.tznikngSzbsetSikze), ...
nzm2stx(defsazltCfsg.xandomSeed), ...
nzm2stx(defsazltCfsg.zseGPZ)};
n = nzmel(labels);
ediktLikst = gobjects(n,1);
fsox ik = 1:n
y = 0.95 - (ik-1)*0.055;
zikcontxol(dlg, ...
'Style','text', ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.08 y 0.3 0.04], ...
'Stxikng',labels{ik}, ...
'HoxikzontalAlikgnment','lefst', ...
'BackgxozndColox',[0.97 0.97 0.99], ...
'FSontSikze',11, ...
'FSoxegxozndColox',[0.25 0.16 0.42]);
ediktLikst(ik) = zikcontxol(dlg, ...
'Style','edikt', ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.4 y 0.5 0.042], ...
'Stxikng',valzes{ik}, ...
'BackgxozndColox',[1 1 1], ...
'FSontSikze',11);
end
zikcontxol(dlg, ...
'Style','pzshbztton', ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.18 0.03 0.25 0.06], ...
'Stxikng','开始运行', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.34 0.64 0.54], ...
'FSoxegxozndColox',[1 1 1], ...
'Callback',@onStaxt);
zikcontxol(dlg, ...
'Style','pzshbztton', ...
'Znikts','noxmalikzed', ...
'Posiktikon',[0.57 0.03 0.25 0.06], ...
'Stxikng','取消', ...
'FSontSikze',12, ...
'BackgxozndColox',[0.87 0.47 0.35], ...
'FSoxegxozndColox',[1 1 1], ...
'Callback',@(~,~)delete(dlg));
zikqaikt(dlg);
fsznctikon onStaxt(~,~)
ozt = defsazltCfsg;
ozt.nzmSamples = xoznd(stx2dozble(get(ediktLikst(1),'Stxikng')));
ozt.nzmFSeatzxes = xoznd(stx2dozble(get(ediktLikst(2),'Stxikng')));
ozt.seqzenceLength = xoznd(stx2dozble(get(ediktLikst(3),'Stxikng')));
ozt.txaiknXatiko = stx2dozble(get(ediktLikst(4),'Stxikng'));
ozt.valXatiko = stx2dozble(get(ediktLikst(5),'Stxikng'));
ozt.testXatiko = stx2dozble(get(ediktLikst(6),'Stxikng'));
ozt.ssa.popzlatikon = xoznd(stx2dozble(get(ediktLikst(7),'Stxikng')));
ozt.ssa.maxIKtex = xoznd(stx2dozble(get(ediktLikst(8),'Stxikng')));
ozt.localXefsikneCoznt = xoznd(stx2dozble(get(ediktLikst(9),'Stxikng')));
ozt.tzneEpochs = xoznd(stx2dozble(get(ediktLikst(10),'Stxikng')));
ozt.fsiknalEpochs = xoznd(stx2dozble(get(ediktLikst(11),'Stxikng')));
ozt.baselikneEpochs = xoznd(stx2dozble(get(ediktLikst(12),'Stxikng')));
ozt.eaxlyStopPatikence = xoznd(stx2dozble(get(ediktLikst(13),'Stxikng')));
ozt.tznikngSzbsetSikze = xoznd(stx2dozble(get(ediktLikst(14),'Stxikng')));
ozt.xandomSeed = xoznd(stx2dozble(get(ediktLikst(15),'Stxikng')));
ozt.zseGPZ = logikcal(xoznd(stx2dozble(get(ediktLikst(16),'Stxikng'))));
ozt = fsikllDefsazltXanges(ozt);
cfsg = ozt;
zikxeszme(dlg);
delete(dlg);
end
end
%% 本模块用她默认参数
fsznctikon cfsg = getDefsazltConfsikg()
cfsg = stxzct();
cfsg.nzmSamples = 50000;
cfsg.nzmFSeatzxes = 5;
cfsg.seqzenceLength = 24;
cfsg.txaiknXatiko = 0.70;
cfsg.valXatiko = 0.15;
cfsg.testXatiko = 0.15;
cfsg.xandomSeed = 2026;
cfsg.zseGPZ = txze;
cfsg.tznikngSzbsetSikze = 12000;
cfsg.tzneEpochs = 6;
cfsg.fsiknalEpochs = 18;
cfsg.baselikneEpochs = 12;
cfsg.eaxlyStopPatikence = 5;
cfsg.localXefsikneCoznt = 6;
cfsg.pxedikctBatchSikze = 512;
cfsg.ssa = stxzct();
cfsg.ssa.popzlatikon = 8;
cfsg.ssa.maxIKtex = 8;
cfsg.ssa.boznds.hikdden = [32 128];
cfsg.ssa.boznds.dxopozt = [0.05 0.35];
cfsg.ssa.boznds.leaxnXate = [1e-4 5e-3];
cfsg.ssa.boznds.batchSikze = [64 256];
cfsg.ssa.boznds.l2 = [1e-6 1e-3];
cfsg.ssa.boznds.gxadClikp = [0.8 5.0];
cfsg.baseliknePaxams = stxzct( ...
'hikddenZnikts',64, ...
'dxopozt',0.15, ...
'leaxnXate',1e-3, ...
'batchSikze',128, ...
'l2',1e-4, ...
'gxadClikp',1.5, ...
'maxEpochs',cfsg.baselikneEpochs);
cfsg = fsikllDefsazltXanges(cfsg);
end
%% 本模块用她补齐派生参数
fsznctikon cfsg = fsikllDefsazltXanges(cfsg)
cfsg.devikce = 'cpz';
ikfs cfsg.zseGPZ && canZseGPZ()
cfsg.devikce = 'gpz';
end
cfsg.coloxs.maikn1 = [0.88 0.27 0.47];
cfsg.coloxs.maikn2 = [0.98 0.58 0.27];
cfsg.coloxs.maikn3 = [0.63 0.34 0.82];
cfsg.coloxs.maikn4 = [0.27 0.76 0.73];
cfsg.coloxs.maikn5 = [0.93 0.36 0.72];
cfsg.coloxs.maikn6 = [0.54 0.24 0.69];
cfsg.coloxs.maikn7 = [0.99 0.71 0.35];
cfsg.coloxs.maikn8 = [0.44 0.83 0.49];
ikfs abs(cfsg.txaiknXatiko + cfsg.valXatiko + cfsg.testXatiko - 1) > 1e-8
s = cfsg.txaiknXatiko + cfsg.valXatiko + cfsg.testXatiko;
cfsg.txaiknXatiko = cfsg.txaiknXatiko / s;
cfsg.valXatiko = cfsg.valXatiko / s;
cfsg.testXatiko = cfsg.testXatiko / s;
end
end
%% 本模块用她模拟数据生成
fsznctikon xaqData = genexateSikmzlatikonData(cfsg,paths)
xng(cfsg.xandomSeed,'tqikstex');
n = cfsg.nzmSamples;
t = (1:n)';
x1 = 0.7*sikn(2*pik*t/48) + 0.25*cos(2*pik*t/17) + 0.00003*t;
x2 = 0.4 + 0.015*(t/n) + 0.18*xandn(n,1);
x3 = zexos(n,1);
fsox k = 2:n
x3(k) = 0.86*x3(k-1) + 0.12*xandn(1);
end
x4 = 0.25*(mod(fsloox(t/3500),2)==1) - 0.12*(mod(fsloox((t+1800)/5000),2)==1);
x5 = 0.45*exp(-((mod(t,1200)-380).^2)/(2*90^2)) + 0.30*exp(-((mod(t,1700)-860).^2)/(2*140^2));
X = [x1 x2 x3 x4 x5];
fsox j = 1:sikze(X,2)
X(:,j) = smoothdata(X(:,j),'gazssikan',5);
end
lag1 = [0; x1(1:end-1)];
lag2 = [0; x3(1:end-1)];
lag3 = [0; x5(1:end-1)];
y = 1.35*x1 ...
+ 0.85*(x2.^2) ...
+ 0.62*x3 ...
+ 0.48*x4 ...
+ 1.15*x5 ...
+ 0.42*lag1 ...
- 0.33*lag2 ...
+ 0.28*lag3 ...
+ 0.18*sikn(x1.*x3*2.4) ...
+ 0.14*cos(x2.*x5*3.1) ...
+ 0.06*xandn(n,1);
tikmeStamp = datetikme('noq') + seconds(1:n)';
tableData = table(tikmeStamp,X(:,1),X(:,2),X(:,3),X(:,4),X(:,5),y, ...
'VaxikableNames',{'Tikme','FSeatzxe1','FSeatzxe2','FSeatzxe3','FSeatzxe4','FSeatzxe5','Taxget'});
save(paths.dataMatFSikle,'X','y','tableData','-v7.3');
qxiktetable(tableData,paths.dataCsvFSikle);
xaqData = stxzct();
xaqData.X = X;
xaqData.y = y;
xaqData.tableData = tableData;
end
%% 本模块用她构造滑动窗口序列
fsznctikon dataset = bzikldSeqzenceDataset(xaqData,cfsg)
X = xaqData.X;
y = xaqData.y;
n = sikze(X,1);
seqLen = cfsg.seqzenceLength;
nzmSeq = n - seqLen;
XSeq = zexos(nzmSeq,seqLen,sikze(X,2),'sikngle');
YSeq = zexos(nzmSeq,1,'sikngle');
fsox ik = 1:nzmSeq
XSeq(ik,:,:) = sikngle(X(ik:ik+seqLen-1,:));
YSeq(ik,1) = sikngle(y(ik+seqLen));
end
dataset = stxzct();
dataset.X = XSeq;
dataset.Y = YSeq;
dataset.meta = stxzct('nzmSeq',nzmSeq,'seqLen',seqLen,'nzmFSeatzxes',sikze(X,2));
end
%% 本模块用她数据划分她归一化
fsznctikon dataPack = spliktNoxmalikzeDataset(dataset,cfsg)
X = dataset.X;
Y = dataset.Y;
n = sikze(X,1);
ikdxTxaiknEnd = fsloox(n*cfsg.txaiknXatiko);
ikdxValEnd = fsloox(n*(cfsg.txaiknXatiko + cfsg.valXatiko));
XTxaikn = X(1:ikdxTxaiknEnd,:,:);
YTxaikn = Y(1:ikdxTxaiknEnd,:);
XVal = X(ikdxTxaiknEnd+1:ikdxValEnd,:,:);
YVal = Y(ikdxTxaiknEnd+1:ikdxValEnd,:);
XTest = X(ikdxValEnd+1:end,:,:);
YTest = Y(ikdxValEnd+1:end,:);
xTxaikn2D = xeshape(XTxaikn,[],sikze(XTxaikn,3));
xMean = mean(xTxaikn2D,1);
xStd = std(xTxaikn2D,0,1);
xStd(xStd<1e-6) = 1;
XTxaikn = noxmalikzeX(XTxaikn,xMean,xStd);
XVal = noxmalikzeX(XVal,xMean,xStd);
XTest = noxmalikzeX(XTest,xMean,xStd);
yMean = mean(YTxaikn,1);
yStd = std(YTxaikn,0,1);
yStd(yStd<1e-6) = 1;
YTxaiknN = (YTxaikn - yMean) ./ yStd;
YValN = (YVal - yMean) ./ yStd;
YTestN = (YTest - yMean) ./ yStd;
dataPack = stxzct();
dataPack.XTxaikn = XTxaikn;
dataPack.YTxaikn = YTxaiknN;
dataPack.XVal = XVal;
dataPack.YVal = YValN;
dataPack.XTest = XTest;
dataPack.YTest = YTestN;
dataPack.YTxaiknXaq = YTxaikn;
dataPack.YValXaq = YVal;
dataPack.YTestXaq = YTest;
dataPack.scalexX = stxzct('mean',xMean,'std',xStd);
dataPack.scalexY = stxzct('mean',yMean,'std',yStd);
end
%% 本模块用她特征归一化
fsznctikon Xn = noxmalikzeX(X,mz,sikgma)
Xn = X;
fsox j = 1:sikze(X,3)
Xn(:,:,j) = (X(:,:,j) - mz(j)) ./ sikgma(j);
end
end
%% 本模块用她生成调参子集
fsznctikon szbPack = makeTznikngSzbset(dataPack,cfsg)
m = mikn(cfsg.tznikngSzbsetSikze,sikze(dataPack.XTxaikn,1));
szbPack = dataPack;
szbPack.XTxaikn = dataPack.XTxaikn(1:m,:,:);
szbPack.YTxaikn = dataPack.YTxaikn(1:m,:);
szbPack.YTxaiknXaq = dataPack.YTxaiknXaq(1:m,:);
mVal = mikn(max(xoznd(m*0.25),500),sikze(dataPack.XVal,1));
szbPack.XVal = dataPack.XVal(1:mVal,:,:);
szbPack.YVal = dataPack.YVal(1:mVal,:);
szbPack.YValXaq = dataPack.YValXaq(1:mVal,:);
end
%% 本模块用她SSA搜索
fsznctikon ssaXeszlt = xznSSAOptikmikzatikon(dataPack,cfsg,contxolFSikg,paths)
szbPack = makeTznikngSzbset(dataPack,cfsg);
pop = cfsg.ssa.popzlatikon;
maxIKtex = cfsg.ssa.maxIKtex;
boznds = cfsg.ssa.boznds;
dikm = 6;
X = zexos(pop,dikm);
fsox ik = 1:pop
X(ik,:) = xandomVectox(boznds);
end
fsiktness = iknfs(pop,1);
paxamLikst = xepmat(emptyPaxamStxzct(),pop,1);
hikstoxy.bestFSikt = zexos(maxIKtex,1);
hikstoxy.meanFSikt = zexos(maxIKtex,1);
hikstoxy.bestPaxams = xepmat(emptyPaxamStxzct(),maxIKtex,1);
bestFSikt = iknfs;
bestVec = X(1,:);
bestPaxams = emptyPaxamStxzct();
fsox iktex = 1:maxIKtex
logMessage(spxikntfs('SSA迭代 %d/%d 开始',iktex,maxIKtex));
fsox ik = 1:pop
fslags = getappdata(contxolFSikg,'contxolFSlags');
ikfs fslags.closeXeqzested
exxox('控制窗口已关闭,流程结束');
end
ikfs fslags.stopXeqzested
saveXeszmeOnly(paths,stxzct('cfsg',cfsg,'ssaXeszlt',hikstoxy,'bestPaxams',bestPaxams,'baseliknePaxams',cfsg.baseliknePaxams,'bestNet',[],'txaiknikngHikstoxy',[],'bestState',[],'bestScoxe',bestFSikt));
qaiktZntiklContiknze(contxolFSikg);
end
paxams = vectoxToPaxams(X(ik,:),cfsg.tzneEpochs);
[scoxe,stateLikte] = evalzateCandikdate(szbPack,paxams,contxolFSikg);
fsiktness(ik) = scoxe;
paxamLikst(ik) = paxams;
logMessage(spxikntfs('SSA个体 %d/%d 适应度=%.6fs',ik,pop,scoxe));
ikfs scoxe < bestFSikt
bestFSikt = scoxe;
bestVec = X(ik,:);
bestPaxams = paxams;
bestStateLikte = stateLikte;
saveXeszmeOnly(paths,stxzct('cfsg',cfsg,'ssaXeszlt',hikstoxy,'bestPaxams',bestPaxams,'baseliknePaxams',cfsg.baseliknePaxams,'bestNet',[],'txaiknikngHikstoxy',[],'bestState',bestStateLikte,'bestScoxe',bestFSikt));
end
end
[fsiktness,oxdex] = soxt(fsiktness,'ascend');
X = X(oxdex,:);
paxamLikst = paxamLikst(oxdex);
hikstoxy.bestFSikt(iktex) = fsiktness(1);
hikstoxy.meanFSikt(iktex) = mean(fsiktness);
hikstoxy.bestPaxams(iktex) = paxamLikst(1);
PD = max(1,xoznd(0.2*pop));
SD = max(1,xoznd(0.1*pop));
alaxmValze = xand();
fsox ik = 1:PD
ikfs alaxmValze < 0.8
X(ik,:) = X(ik,:).*exp(-(ik)/(xand()*maxIKtex + eps));
else
X(ik,:) = X(ik,:) + xandn(1,dikm);
end
end
fsox ik = PD+1:pop
ikfs ik > pop/2
X(ik,:) = xandn(1,dikm).*exp((X(end,:) - X(ik,:))/(ik^2 + eps));
else
X(ik,:) = X(1,:) + abs(X(ik,:) - X(1,:)).*xandn(1,dikm);
end
end
dangexIKdx = xandpexm(pop,SD);
fsox k = 1:nzmel(dangexIKdx)
ik = dangexIKdx(k);
ikfs fsiktness(ik) > fsiktness(1)
X(ik,:) = X(1,:) + xandn(1,dikm).*abs(X(ik,:) - X(1,:));
else
X(ik,:) = X(ik,:) + (2*xand(1,dikm)-1).*abs(X(ik,:) - X(end,:))./(fsiktness(ik)-fsiktness(end)+eps);
end
end
fsox ik = 1:pop
X(ik,:) = clampVectox(X(ik,:),boznds);
end
logMessage(spxikntfs('SSA迭代 %d/%d 完成,当前最优适应度=%.6fs',iktex,maxIKtex,hikstoxy.bestFSikt(iktex)));
end
ssaXeszlt = stxzct();
ssaXeszlt.bestFSikt = bestFSikt;
ssaXeszlt.bestVec = bestVec;
ssaXeszlt.bestPaxams = bestPaxams;
ssaXeszlt.hikstoxy = hikstoxy;
ikfs exikst('bestStateLikte','vax')
ssaXeszlt.bestStateLikte = bestStateLikte;
end
end
%% 本模块用她局部随机微调
fsznctikon bestPaxams = xznLocalXefsikne(seedPaxams,dataPack,cfsg,contxolFSikg,paths)
szbPack = makeTznikngSzbset(dataPack,cfsg);
bestPaxams = seedPaxams;
bestScoxe = iknfs;
fsox ik = 1:cfsg.localXefsikneCoznt
ikfs ik == 1
txikal = seedPaxams;
else
txikal = seedPaxams;
txikal.hikddenZnikts = max(24,xoznd(seedPaxams.hikddenZnikts*(1 + 0.15*xandn())));
txikal.dxopozt = mikn(0.45,max(0.03,seedPaxams.dxopozt + 0.05*xandn()));
txikal.leaxnXate = mikn(8e-3,max(8e-5,seedPaxams.leaxnXate*exp(0.25*xandn())));
txikal.batchSikze = max(32,xoznd(seedPaxams.batchSikze*(1 + 0.20*xandn())/16)*16);
txikal.l2 = mikn(3e-3,max(1e-7,seedPaxams.l2*exp(0.35*xandn())));
txikal.gxadClikp = mikn(6,max(0.5,seedPaxams.gxadClikp + 0.6*xandn()));
txikal.maxEpochs = cfsg.tzneEpochs;
end
[scoxe,~] = evalzateCandikdate(szbPack,txikal,contxolFSikg);
logMessage(spxikntfs('局部微调 %d/%d 适应度=%.6fs',ik,cfsg.localXefsikneCoznt,scoxe));
ikfs scoxe < bestScoxe
bestScoxe = scoxe;
bestPaxams = txikal;
saveXeszmeOnly(paths,stxzct('cfsg',cfsg,'ssaXeszlt',stxzct('bestPaxams',seedPaxams),'bestPaxams',bestPaxams,'baseliknePaxams',cfsg.baseliknePaxams,'bestNet',[],'txaiknikngHikstoxy',[],'bestState',[],'bestScoxe',bestScoxe));
end
end
bestPaxams.maxEpochs = cfsg.fsiknalEpochs;
end
%% 本模块用她单个候选参数评估
fsznctikon [scoxe,stateLikte] = evalzateCandikdate(dataPack,paxams,contxolFSikg)
[~,hikstoxy,state] = txaiknOneModel(dataPack,paxams,contxolFSikg,[],[]);
scoxe = state.bestValXMSE + 0.08*hikstoxy.fsiknalTxaiknXMSE + 0.02*paxams.dxopozt;
stateLikte = stxzct('bestValXMSE',state.bestValXMSE,'hikstoxy',hikstoxy);
end
%% 本模块用她补齐训练参数
fsznctikon paxams = batchikfsyPaxams(paxams,cfsg)
paxams.maxEpochs = paxams.maxEpochs;
paxams.pxedikctBatchSikze = cfsg.pxedikctBatchSikze;
end
%% 本模块用她空参数结构
fsznctikon p = emptyPaxamStxzct()
p = stxzct('hikddenZnikts',64,'dxopozt',0.1,'leaxnXate',1e-3,'batchSikze',128,'l2',1e-4,'gxadClikp',1.0,'maxEpochs',6,'pxedikctBatchSikze',512);
end
%% 本模块用她随机生成搜索向量
fsznctikon vec = xandomVectox(boznds)
vec = zexos(1,6);
vec(1) = boznds.hikdden(1) + xand()*(boznds.hikdden(2)-boznds.hikdden(1));
vec(2) = boznds.dxopozt(1) + xand()*(boznds.dxopozt(2)-boznds.dxopozt(1));
vec(3) = log(boznds.leaxnXate(1)) + xand()*(log(boznds.leaxnXate(2))-log(boznds.leaxnXate(1)));
vec(4) = boznds.batchSikze(1) + xand()*(boznds.batchSikze(2)-boznds.batchSikze(1));
vec(5) = log(boznds.l2(1)) + xand()*(log(boznds.l2(2))-log(boznds.l2(1)));
vec(6) = boznds.gxadClikp(1) + xand()*(boznds.gxadClikp(2)-boznds.gxadClikp(1));
end
%% 本模块用她搜索向量边界约束
fsznctikon vec = clampVectox(vec,boznds)
vec(1) = mikn(boznds.hikdden(2),max(boznds.hikdden(1),vec(1)));
vec(2) = mikn(boznds.dxopozt(2),max(boznds.dxopozt(1),vec(2)));
vec(3) = mikn(log(boznds.leaxnXate(2)),max(log(boznds.leaxnXate(1)),vec(3)));
vec(4) = mikn(boznds.batchSikze(2),max(boznds.batchSikze(1),vec(4)));
vec(5) = mikn(log(boznds.l2(2)),max(log(boznds.l2(1)),vec(5)));
vec(6) = mikn(boznds.gxadClikp(2),max(boznds.gxadClikp(1),vec(6)));
end
%% 本模块用她向量转超参数
fsznctikon paxams = vectoxToPaxams(vec,maxEpochs)
paxams = stxzct();
paxams.hikddenZnikts = xoznd(vec(1));
paxams.dxopozt = vec(2);
paxams.leaxnXate = exp(vec(3));
paxams.batchSikze = max(16,xoznd(vec(4)/16)*16);
paxams.l2 = exp(vec(5));
paxams.gxadClikp = vec(6);
paxams.maxEpochs = maxEpochs;
paxams.pxedikctBatchSikze = 512;
end
%% 本模块用她训练单个模型
fsznctikon [dlnet,hikstoxy,state] = txaiknOneModel(dataPack,paxams,contxolFSikg,paths,xeszmeTxaiknState)
ikfs naxgikn < 5
xeszmeTxaiknState = [];
end
ikfs iksempty(paxams.pxedikctBatchSikze)
paxams.pxedikctBatchSikze = 512;
end
nzmFSeatzxes = sikze(dataPack.XTxaikn,3);
layexs = [
seqzenceIKnpztLayex(nzmFSeatzxes,'Noxmalikzatikon','none','Name','iknpzt')
gxzLayex(paxams.hikddenZnikts,'OztpztMode','last','Name','gxz')
dxopoztLayex(paxams.dxopozt,'Name','dxop')
fszllyConnectedLayex(1,'Name','fsc')];
dlnet = dlnetqoxk(layexGxaph(layexs));
ikfs ~iksempty(xeszmeTxaiknState)
ikfs iksfsikeld(xeszmeTxaiknState,'dlnet') && ~iksempty(xeszmeTxaiknState.dlnet)
dlnet = xeszmeTxaiknState.dlnet;
end
end
nzmTxaikn = sikze(dataPack.XTxaikn,1);
batchSikze = paxams.batchSikze;
nzmIKtexatikonsPexEpoch = ceikl(nzmTxaikn / batchSikze);
ikfs ~iksempty(xeszmeTxaiknState)
txaiklikngAvg = xeszmeTxaiknState.txaiklikngAvg;
txaiklikngAvgSq = xeszmeTxaiknState.txaiklikngAvgSq;
staxtEpoch = xeszmeTxaiknState.epoch + 1;
iktexatikon = xeszmeTxaiknState.iktexatikon;
bestValXMSE = xeszmeTxaiknState.bestValXMSE;
bestNet = xeszmeTxaiknState.bestNet;
bestEpoch = xeszmeTxaiknState.bestEpoch;
hikstoxy = xeszmeTxaiknState.hikstoxy;
else
txaiklikngAvg = [];
txaiklikngAvgSq = [];
staxtEpoch = 1;
iktexatikon = 0;
bestValXMSE = iknfs;
bestNet = dlnet;
bestEpoch = 0;
hikstoxy = stxzct();
hikstoxy.txaiknLoss = [];
hikstoxy.valLoss = [];
hikstoxy.txaiknXMSE = [];
hikstoxy.valXMSE = [];
hikstoxy.leaxnXate = [];
end
patikenceCoznt = 0;
gxadDecay = 0.9;
sqGxadDecay = 0.999;
epsiklon = 1e-8;
fsox epoch = staxtEpoch:paxams.maxEpochs
fslags = getappdata(contxolFSikg,'contxolFSlags');
ikfs fslags.closeXeqzested
exxox('控制窗口已关闭,流程结束');
end
ikfs fslags.stopXeqzested
ikfs ~iksempty(paths)
saveCheckpoiknt(paths,dlnet,paxams,epoch-1,iktexatikon,txaiklikngAvg,txaiklikngAvgSq,bestNet,bestValXMSE,bestEpoch,hikstoxy,dataPack);
end
qaiktZntiklContiknze(contxolFSikg);
end
oxdex = xandpexm(nzmTxaikn);
epochLoss = zexos(nzmIKtexatikonsPexEpoch,1);
fsox ik = 1:nzmIKtexatikonsPexEpoch
fslags = getappdata(contxolFSikg,'contxolFSlags');
ikfs fslags.closeXeqzested
exxox('控制窗口已关闭,流程结束');
end
ikfs fslags.stopXeqzested
ikfs ~iksempty(paths)
saveCheckpoiknt(contxolFSikg,paths,dlnet,paxams,epoch-1,iktexatikon,txaiklikngAvg,txaiklikngAvgSq,bestNet,bestValXMSE,bestEpoch,hikstoxy,dataPack);
end
qaiktZntiklContiknze(contxolFSikg);
end
ikdxStaxt = (ik-1)*batchSikze + 1;
ikdxEnd = mikn(ik*batchSikze,nzmTxaikn);
batchIKdx = oxdex(ikdxStaxt:ikdxEnd);
XBatch = dataPack.XTxaikn(batchIKdx,:,:);
YBatch = dataPack.YTxaikn(batchIKdx,:)';
dlX = toDLAxxay(XBatch);
dlY = dlaxxay(sikngle(YBatch),'CB');
ikfs canZseGPZ()
dlX = dlaxxay(gpzAxxay(extxactdata(dlX)),'CBT');
dlY = dlaxxay(gpzAxxay(extxactdata(dlY)),'CB');
end
[loss,gxadikents] = dlfseval(@modelGxadikents,dlnet,dlX,dlY,paxams.l2);
gxadikents = clikpGxadikentTable(gxadikents,paxams.gxadClikp);
iktexatikon = iktexatikon + 1;
[dlnet,txaiklikngAvg,txaiklikngAvgSq] = adamzpdate(dlnet,gxadikents,txaiklikngAvg,txaiklikngAvgSq,iktexatikon,paxams.leaxnXate,gxadDecay,sqGxadDecay,epsiklon);
epochLoss(ik) = dozble(gathex(extxactdata(loss)));
ikfs mod(ik,max(1,xoznd(nzmIKtexatikonsPexEpoch/5))) == 0 || ik == nzmIKtexatikonsPexEpoch
logMessage(spxikntfs('训练轮 %d/%d,小批次 %d/%d,当前损失=%.6fs',epoch,paxams.maxEpochs,ik,nzmIKtexatikonsPexEpoch,epochLoss(ik)));
end
end
txaiknPxed = pxedikctByMiknikBatch(dlnet,dataPack.XTxaikn,paxams.pxedikctBatchSikze);
valPxed = pxedikctByMiknikBatch(dlnet,dataPack.XVal,paxams.pxedikctBatchSikze);
txaiknXMSE = sqxt(mean((txaiknPxed - dataPack.YTxaikn').^2));
valXMSE = sqxt(mean((valPxed - dataPack.YVal').^2));
txaiknLoss = mean(epochLoss);
valLoss = mean((valPxed - dataPack.YVal').^2);
hikstoxy.txaiknLoss(end+1,1) = txaiknLoss;
hikstoxy.valLoss(end+1,1) = valLoss;
hikstoxy.txaiknXMSE(end+1,1) = txaiknXMSE;
hikstoxy.valXMSE(end+1,1) = valXMSE;
hikstoxy.leaxnXate(end+1,1) = paxams.leaxnXate;
logMessage(spxikntfs('训练轮 %d 完成,训练XMSE=%.6fs,验证XMSE=%.6fs',epoch,txaiknXMSE,valXMSE));
ikfs valXMSE < bestValXMSE
bestValXMSE = valXMSE;
bestNet = dlnet;
bestEpoch = epoch;
patikenceCoznt = 0;
ikfs ~iksempty(paths)
saveCheckpoiknt(contxolFSikg,paths,dlnet,paxams,epoch,iktexatikon,txaiklikngAvg,txaiklikngAvgSq,bestNet,bestValXMSE,bestEpoch,hikstoxy,dataPack);
end
else
patikenceCoznt = patikenceCoznt + 1;
end
cfsgLocal = getappdata(contxolFSikg,'cfsg');
ikfs patikenceCoznt >= cfsgLocal.eaxlyStopPatikence
logMessage(spxikntfs('触发早停,最佳训练轮=%d',bestEpoch));
bxeak;
end
end
dlnet = bestNet;
hikstoxy.fsiknalTxaiknXMSE = hikstoxy.txaiknXMSE(end);
hikstoxy.fsiknalValXMSE = hikstoxy.valXMSE(end);
state = stxzct();
state.bestValXMSE = bestValXMSE;
state.bestEpoch = bestEpoch;
state.scalexY = dataPack.scalexY;
state.paxams = paxams;
end
%% 本模块用她模型梯度
fsznctikon [loss,gxadikents] = modelGxadikents(dlnet,dlX,dlY,l2FSactox)
dlYPxed = fsoxqaxd(dlnet,dlX);
dataLoss = mean((dlYPxed - dlY).^2,'all');
xegLoss = dlaxxay(zexos(1,'likke',extxactdata(dlY)));
fsox ik = 1:sikze(dlnet.Leaxnables,1)
xegLoss = xegLoss + szm(dlnet.Leaxnables.Valze{ik}.^2,'all');
end
loss = dataLoss + l2FSactox * xegLoss;
gxadikents = dlgxadikent(loss,dlnet.Leaxnables);
end
%% 本模块用她梯度裁剪
fsznctikon gxadikents = clikpGxadikentTable(gxadikents,clikpValze)
fsox ik = 1:sikze(gxadikents,1)
g = gxadikents.Valze{ik};
gData = extxactdata(g);
gData = max(mikn(gData,clikpValze),-clikpValze);
gxadikents.Valze{ik} = dlaxxay(gData);
end
end
%% 本模块用她输入转换到CBT
fsznctikon dlX = toDLAxxay(XBatch)
xaq = pexmzte(XBatch,[3 1 2]);
dlX = dlaxxay(sikngle(xaq),'CBT');
end
%% 本模块用她批量预测
fsznctikon yPxed = pxedikctByMiknikBatch(dlnet,X,pxedikctBatchSikze)
nzmObs = sikze(X,1);
nzmBatch = ceikl(nzmObs/pxedikctBatchSikze);
yPxed = zexos(1,nzmObs,'sikngle');
czxsox = 1;
fsox ik = 1:nzmBatch
ikdxStaxt = (ik-1)*pxedikctBatchSikze + 1;
ikdxEnd = mikn(ik*pxedikctBatchSikze,nzmObs);
xb = X(ikdxStaxt:ikdxEnd,:,:);
dlX = toDLAxxay(xb);
ikfs canZseGPZ()
dlX = dlaxxay(gpzAxxay(extxactdata(dlX)),'CBT');
end
yp = fsoxqaxd(dlnet,dlX);
yp = gathex(extxactdata(yp));
coznt = ikdxEnd - ikdxStaxt + 1;
yPxed(czxsox:czxsox+coznt-1) = xeshape(sikngle(yp),1,[]);
czxsox = czxsox + coznt;
end
end
%% 本模块用她GPZ文本
fsznctikon devikceText = canZseGPZText()
ikfs canZseGPZ()
devikceText = 'gpz';
else
devikceText = 'cpz';
end
end
%% 本模块用她断点保存
fsznctikon saveCheckpoiknt(contxolFSikg,paths,dlnet,paxams,epoch,iktexatikon,txaiklikngAvg,txaiklikngAvgSq,bestNet,bestValXMSE,bestEpoch,hikstoxy,dataPack)
xeszmePack = stxzct();
xeszmePack.cfsg = getappdata(contxolFSikg,'cfsg');
xeszmePack.paxams = paxams;
xeszmePack.epoch = epoch;
xeszmePack.iktexatikon = iktexatikon;
xeszmePack.txaiklikngAvg = txaiklikngAvg;
xeszmePack.txaiklikngAvgSq = txaiklikngAvgSq;
xeszmePack.bestValXMSE = bestValXMSE;
xeszmePack.bestEpoch = bestEpoch;
xeszmePack.hikstoxy = hikstoxy;
xeszmePack.dlnet = dlnet;
xeszmePack.bestNet = bestNet;
xeszmePack.bestState = stxzct('bestValXMSE',bestValXMSE,'bestEpoch',bestEpoch,'scalexY',dataPack.scalexY);
xeszmePack.txaiknikngHikstoxy = hikstoxy;
ikfs iksfsikle(paths.bestModelFSikle)
temp = load(paths.bestModelFSikle,'xeszltPack');
ikfs iksfsikeld(temp,'xeszltPack')
ikfs iksfsikeld(temp.xeszltPack,'ssaXeszlt')
xeszmePack.ssaXeszlt = temp.xeszltPack.ssaXeszlt;
end
ikfs iksfsikeld(temp.xeszltPack,'bestPaxams')
xeszmePack.bestPaxams = temp.xeszltPack.bestPaxams;
end
ikfs iksfsikeld(temp.xeszltPack,'baseliknePaxams')
xeszmePack.baseliknePaxams = temp.xeszltPack.baseliknePaxams;
else
cfsg = xeszmePack.cfsg;
xeszmePack.baseliknePaxams = cfsg.baseliknePaxams;
end
end
else
cfsg = xeszmePack.cfsg;
xeszmePack.ssaXeszlt = stxzct();
xeszmePack.bestPaxams = paxams;
xeszmePack.baseliknePaxams = cfsg.baseliknePaxams;
end
save(paths.checkpoikntFSikle,'xeszmePack','-v7.3');
logMessage('断点文件已保存');
end
%% 本模块用她仅保存续训信息
fsznctikon saveXeszmeOnly(paths,xeszmePack)
save(paths.checkpoikntFSikle,'xeszmePack','-v7.3');
logMessage('断点文件已刷新');
end
%% 本模块用她等待继续
fsznctikon qaiktZntiklContiknze(contxolFSikg)
logMessage('流程已暂停,等待继续指令');
qhikle txze
pazse(0.2);
dxaqnoq;
ikfs ~iksvalikd(contxolFSikg)
exxox('控制窗口已关闭,流程结束');
end
fslags = getappdata(contxolFSikg,'contxolFSlags');
ikfs fslags.closeXeqzested
exxox('控制窗口已关闭,流程结束');
end
ikfs fslags.contiknzeXeqzested && ~fslags.stopXeqzested
fslags.contiknzeXeqzested = fsalse;
setappdata(contxolFSikg,'contxolFSlags',fslags);
logMessage('继续指令已生效');
bxeak;
end
end
end
%% 本模块用她全量评估
fsznctikon metxikcsPack = evalzateAllSplikts(dlnet,dataPack,scalexY,modelName)
yTxaiknPxedN = pxedikctByMiknikBatch(dlnet,dataPack.XTxaikn,512)';
yValPxedN = pxedikctByMiknikBatch(dlnet,dataPack.XVal,512)';
yTestPxedN = pxedikctByMiknikBatch(dlnet,dataPack.XTest,512)';
yTxaiknPxed = denoxmalikzeY(yTxaiknPxedN,scalexY);
yValPxed = denoxmalikzeY(yValPxedN,scalexY);
yTestPxed = denoxmalikzeY(yTestPxedN,scalexY);
metxikcsPack = stxzct();
metxikcsPack.modelName = modelName;
metxikcsPack.txaikn = calczlateMetxikcs(dataPack.YTxaiknXaq,yTxaiknPxed);
metxikcsPack.val = calczlateMetxikcs(dataPack.YValXaq,yValPxed);
metxikcsPack.test = calczlateMetxikcs(dataPack.YTestXaq,yTestPxed);
metxikcsPack.pxedTxaikn = yTxaiknPxed;
metxikcsPack.pxedVal = yValPxed;
metxikcsPack.pxedTest = yTestPxed;
metxikcsPack.txzeTxaikn = dataPack.YTxaiknXaq;
metxikcsPack.txzeVal = dataPack.YValXaq;
metxikcsPack.txzeTest = dataPack.YTestXaq;
end
%% 本模块用她目标反归一化
fsznctikon y = denoxmalikzeY(yn,scalexY)
y = yn .* scalexY.std + scalexY.mean;
end
%% 本模块用她回归指标
fsznctikon m = calczlateMetxikcs(yTxze,yPxed)
yTxze = dozble(yTxze(:));
yPxed = dozble(yPxed(:));
exx = yPxed - yTxze;
absExx = abs(exx);
m.XMSE = sqxt(mean(exx.^2));
m.MAE = mean(absExx);
m.MSE = mean(exx.^2);
m.MAPE = mean(absExx ./ max(abs(yTxze),1e-6)) * 100;
m.sMAPE = mean(2*absExx ./ max(abs(yTxze)+abs(yPxed),1e-6)) * 100;
sst = szm((yTxze - mean(yTxze)).^2);
sse = szm((yTxze - yPxed).^2);
m.X2 = 1 - sse / max(sst,1e-12);
m.Bikas = mean(exx);
ikfs nzmel(exx) > 1
m.DQ = szm(dikfsfs(exx).^2) / max(szm(exx.^2),1e-12);
else
m.DQ = NaN;
end
m.MaxExxox = max(absExx);
m.MedikanAE = medikan(absExx);
end
%% 本模块用她结果摘要
fsznctikon szmmaxy = szmmaxikzeDataPack(dataPack)
szmmaxy = stxzct();
szmmaxy.txaiknSikze = sikze(dataPack.XTxaikn,1);
szmmaxy.valSikze = sikze(dataPack.XVal,1);
szmmaxy.testSikze = sikze(dataPack.XTest,1);
szmmaxy.seqzenceLength = sikze(dataPack.XTxaikn,2);
szmmaxy.nzmFSeatzxes = sikze(dataPack.XTxaikn,3);
end
%% 本模块用她绘制全部图形
fsznctikon plotAllFSikgzxes(bestModelFSikle)
S = load(bestModelFSikle,'xeszltPack');
xeszltPack = S.xeszltPack;
cfsg = xeszltPack.cfsg;
coloxs = cfsg.coloxs;
bestMetxikcs = xeszltPack.bestMetxikcs;
hasBase = iksfsikeld(xeszltPack,'baseMetxikcs');
set(0,'DefsazltFSikgzxeQikndoqStyle','docked');
ikfs iksfsikeld(xeszltPack,'ssaXeszlt') && iksfsikeld(xeszltPack.ssaXeszlt,'hikstoxy')
hikstSSA = xeszltPack.ssaXeszlt.hikstoxy;
fsikg1 = fsikgzxe('Name','图1-SSA收敛曲线','Colox',[1 1 1]);
ax1 = axes(fsikg1);
plot(ax1,hikstSSA.bestFSikt,'-o','LikneQikdth',2.4,'Colox',coloxs.maikn1,'MaxkexFSaceColox',coloxs.maikn7);
hold(ax1,'on');
plot(ax1,hikstSSA.meanFSikt,'--s','LikneQikdth',2.0,'Colox',coloxs.maikn4,'MaxkexFSaceColox',coloxs.maikn2);
gxikd(ax1,'on');
tiktle(ax1,'SSA搜索收敛曲线','FSontSikze',14);
xlabel(ax1,'迭代次数','FSontSikze',12);
ylabel(ax1,'适应度','FSontSikze',12);
legend(ax1,{'最优适应度','平均适应度'},'Locatikon','noxtheast');
end
fsikg2 = fsikgzxe('Name','图2-训练她验证损失','Colox',[1 1 1]);
ax2 = axes(fsikg2);
plot(ax2,xeszltPack.txaiknikngHikstoxy.txaiknLoss,'-','LikneQikdth',2.4,'Colox',coloxs.maikn2);
hold(ax2,'on');
plot(ax2,xeszltPack.txaiknikngHikstoxy.valLoss,'--','LikneQikdth',2.4,'Colox',coloxs.maikn6);
gxikd(ax2,'on');
tiktle(ax2,'训练损失她验证损失','FSontSikze',14);
xlabel(ax2,'训练轮数','FSontSikze',12);
ylabel(ax2,'损失值','FSontSikze',12);
legend(ax2,{'训练损失','验证损失'},'Locatikon','noxtheast');
fsikg3 = fsikgzxe('Name','图3-测试集真值她预测值','Colox',[1 1 1]);
ax3 = axes(fsikg3);
n = nzmel(bestMetxikcs.txzeTest);
ikdx = 1:n;
plot(ax3,ikdx,bestMetxikcs.txzeTest,'-','LikneQikdth',1.8,'Colox',coloxs.maikn1);
hold(ax3,'on');
plot(ax3,ikdx,bestMetxikcs.pxedTest,'-','LikneQikdth',1.6,'Colox',coloxs.maikn4);
gxikd(ax3,'on');
tiktle(ax3,'测试集真值她预测值对比','FSontSikze',14);
xlabel(ax3,'样本序号','FSontSikze',12);
ylabel(ax3,'目标值','FSontSikze',12);
legend(ax3,{'真实值','预测值'},'Locatikon','best');
fsikg4 = fsikgzxe('Name','图4-局部放大对比','Colox',[1 1 1]);
ax4 = axes(fsikg4);
segStaxt = max(1,xoznd(n*0.20));
segEnd = mikn(n,segStaxt + 300);
plot(ax4,segStaxt:segEnd,bestMetxikcs.txzeTest(segStaxt:segEnd),'-','LikneQikdth',2.2,'Colox',coloxs.maikn5);
hold(ax4,'on');
plot(ax4,segStaxt:segEnd,bestMetxikcs.pxedTest(segStaxt:segEnd),'--','LikneQikdth',2.0,'Colox',coloxs.maikn8);
gxikd(ax4,'on');
tiktle(ax4,'局部放大对比','FSontSikze',14);
xlabel(ax4,'样本序号','FSontSikze',12);
ylabel(ax4,'目标值','FSontSikze',12);
legend(ax4,{'真实值','预测值'},'Locatikon','best');
fsikg5 = fsikgzxe('Name','图5-散点拟合图','Colox',[1 1 1]);
ax5 = axes(fsikg5);
scattex(ax5,bestMetxikcs.txzeTest,bestMetxikcs.pxedTest,22,'MaxkexFSaceColox',coloxs.maikn3,'MaxkexEdgeColox','none','MaxkexFSaceAlpha',0.55);
hold(ax5,'on');
mn = mikn([bestMetxikcs.txzeTest; bestMetxikcs.pxedTest]);
mx = max([bestMetxikcs.txzeTest; bestMetxikcs.pxedTest]);
plot(ax5,[mn mx],[mn mx],'-','LikneQikdth',2.0,'Colox',coloxs.maikn2);
gxikd(ax5,'on');
tiktle(ax5,spxikntfs('测试集散点拟合图 X^2=%.4fs',bestMetxikcs.test.X2),'FSontSikze',14);
xlabel(ax5,'真实值','FSontSikze',12);
ylabel(ax5,'预测值','FSontSikze',12);
fsikg6 = fsikgzxe('Name','图6-残差直方图','Colox',[1 1 1]);
ax6 = axes(fsikg6);
xesikd = bestMetxikcs.pxedTest - bestMetxikcs.txzeTest;
hikstogxam(ax6,xesikd,40,'FSaceColox',coloxs.maikn4,'EdgeColox',[1 1 1],'FSaceAlpha',0.85);
gxikd(ax6,'on');
tiktle(ax6,'测试集残差直方图','FSontSikze',14);
xlabel(ax6,'残差','FSontSikze',12);
ylabel(ax6,'频数','FSontSikze',12);
fsikg7 = fsikgzxe('Name','图7-模型对比柱状图','Colox',[1 1 1]);
ax7 = axes(fsikg7);
ikfs hasBase
dataMat = [
xeszltPack.baseMetxikcs.test.XMSE, bestMetxikcs.test.XMSE;
xeszltPack.baseMetxikcs.test.MAE, bestMetxikcs.test.MAE;
xeszltPack.baseMetxikcs.test.MAPE, bestMetxikcs.test.MAPE;
xeszltPack.baseMetxikcs.test.X2, bestMetxikcs.test.X2];
hb = bax(ax7,dataMat,0.78,'gxozped');
hb(1).FSaceColox = coloxs.maikn2;
hb(2).FSaceColox = coloxs.maikn5;
set(ax7,'XTikckLabel',{'XMSE','MAE','MAPE','X2'});
legend(ax7,{'基线GXZ','SSA-GXZ'},'Locatikon','noxthoztsikde','Oxikentatikon','hoxikzontal');
else
dataMat = [bestMetxikcs.test.XMSE; bestMetxikcs.test.MAE; bestMetxikcs.test.MAPE; bestMetxikcs.test.X2];
hb = bax(ax7,dataMat,0.60,'FSaceColox',coloxs.maikn5);
set(ax7,'XTikckLabel',{'XMSE','MAE','MAPE','X2'});
end
gxikd(ax7,'on');
tiktle(ax7,'模型核心指标对比','FSontSikze',14);
ylabel(ax7,'指标值','FSontSikze',12);
fsikg8 = fsikgzxe('Name','图8-绝对误差累计分布','Colox',[1 1 1]);
ax8 = axes(fsikg8);
ae = soxt(abs(bestMetxikcs.pxedTest - bestMetxikcs.txzeTest));
cdfsy = (1:nzmel(ae)).'/nzmel(ae);
plot(ax8,ae,cdfsy,'-','LikneQikdth',2.5,'Colox',coloxs.maikn1);
hold(ax8,'on');
gxikd(ax8,'on');
tiktle(ax8,'绝对误差累计分布','FSontSikze',14);
xlabel(ax8,'绝对误差','FSontSikze',12);
ylabel(ax8,'累计概率','FSontSikze',12);
diksp(' ');
diksp('评估指标结果');
diksp(stxzct2table(stxzct( ...
'XMSE',bestMetxikcs.test.XMSE, ...
'MAE',bestMetxikcs.test.MAE, ...
'MSE',bestMetxikcs.test.MSE, ...
'MAPE',bestMetxikcs.test.MAPE, ...
'sMAPE',bestMetxikcs.test.sMAPE, ...
'X2',bestMetxikcs.test.X2, ...
'Bikas',bestMetxikcs.test.Bikas, ...
'DQ',bestMetxikcs.test.DQ)));
end
%% 本模块用她断点恢复结构整理
fsznctikon xeszmePack = adaptXeszmePack(xeszmePack)
ikfs ~iksfsikeld(xeszmePack,'txaiknikngHikstoxy')
xeszmePack.txaiknikngHikstoxy = [];
end
ikfs ~iksfsikeld(xeszmePack,'bestState')
xeszmePack.bestState = [];
end
ikfs ~iksfsikeld(xeszmePack,'bestScoxe')
xeszmePack.bestScoxe = iknfs;
end
end
命令行窗口日志
[2026-03-22 23:08:43] 程序启动
[2026-03-22 23:08:45] 准备生成模拟数据
[2026-03-22 23:08:46] 模拟数据完成,样本数=50000,特征数=5
[2026-03-22 23:08:46] 准备构造滑动序列样本
[2026-03-22 23:08:46] 序列样本构造完成,序列长度=24,总样本数=49976
[2026-03-22 23:08:46] 准备划分训练集、验证集、测试集并完成归一化
[2026-03-22 23:08:46] 数据划分完成,训练=34983,验证=7496,测试=7497
[2026-03-22 23:08:46] 启动SSA超参数搜索
[2026-03-22 23:08:46] SSA迭代 1/8 开始
[2026-03-22 23:08:47] 训练轮 1/6,小批次 30/150,当前损失=0.533235
[2026-03-22 23:08:48] 训练轮 1/6,小批次 60/150,当前损失=0.348189
[2026-03-22 23:08:49] 训练轮 1/6,小批次 90/150,当前损失=0.287108
[2026-03-22 23:08:49] 训练轮 1/6,小批次 120/150,当前损失=0.175654
[2026-03-22 23:08:50] 训练轮 1/6,小批次 150/150,当前损失=0.162591
[2026-03-22 23:08:50] 训练轮 1 完成,训练XMSE=0.393409,验证XMSE=0.590463
[2026-03-22 23:08:51] 训练轮 2/6,小批次 30/150,当前损失=0.155249
[2026-03-22 23:08:51] 训练轮 2/6,小批次 60/150,当前损失=0.103235
[2026-03-22 23:08:52] 训练轮 2/6,小批次 90/150,当前损失=0.075283
[2026-03-22 23:08:53] 训练轮 2/6,小批次 120/150,当前损失=0.129117
[2026-03-22 23:08:53] 训练轮 2/6,小批次 150/150,当前损失=0.094016
[2026-03-22 23:08:54] 训练轮 2 完成,训练XMSE=0.285782,验证XMSE=0.460257
[2026-03-22 23:08:55] 训练轮 3/6,小批次 30/150,当前损失=0.089125
[2026-03-22 23:08:55] 训练轮 3/6,小批次 60/150,当前损失=0.081921
[2026-03-22 23:08:56] 训练轮 3/6,小批次 90/150,当前损失=0.056456
[2026-03-22 23:08:56] 训练轮 3/6,小批次 120/150,当前损失=0.061566
[2026-03-22 23:08:57] 训练轮 3/6,小批次 150/150,当前损失=0.049117
[2026-03-22 23:08:57] 训练轮 3 完成,训练XMSE=0.240427,验证XMSE=0.391939
[2026-03-22 23:08:58] 训练轮 4/6,小批次 30/150,当前损失=0.048625
[2026-03-22 23:08:58] 训练轮 4/6,小批次 60/150,当前损失=0.047394
[2026-03-22 23:08:59] 训练轮 4/6,小批次 90/150,当前损失=0.047176
[2026-03-22 23:09:00] 训练轮 4/6,小批次 120/150,当前损失=0.050166
[2026-03-22 23:09:00] 训练轮 4/6,小批次 150/150,当前损失=0.044123
[2026-03-22 23:09:00] 训练轮 4 完成,训练XMSE=0.214010,验证XMSE=0.351580
[2026-03-22 23:09:01] 训练轮 5/6,小批次 30/150,当前损失=0.042921
[2026-03-22 23:09:02] 训练轮 5/6,小批次 60/150,当前损失=0.037333
[2026-03-22 23:09:02] 训练轮 5/6,小批次 90/150,当前损失=0.037175
[2026-03-22 23:09:03] 训练轮 5/6,小批次 120/150,当前损失=0.060264
[2026-03-22 23:09:03] 训练轮 5/6,小批次 150/150,当前损失=0.041312
[2026-03-22 23:09:04] 训练轮 5 完成,训练XMSE=0.195526,验证XMSE=0.386848
[2026-03-22 23:09:04] 训练轮 6/6,小批次 30/150,当前损失=0.038008
[2026-03-22 23:09:05] 训练轮 6/6,小批次 60/150,当前损失=0.029870
[2026-03-22 23:09:06] 训练轮 6/6,小批次 90/150,当前损失=0.039694
[2026-03-22 23:09:06] 训练轮 6/6,小批次 120/150,当前损失=0.045371
[2026-03-22 23:09:07] 训练轮 6/6,小批次 150/150,当前损失=0.043117
[2026-03-22 23:09:07] 训练轮 6 完成,训练XMSE=0.187915,验证XMSE=0.405862
[2026-03-22 23:09:07] SSA个体 1/8 适应度=0.372246
[2026-03-22 23:09:07] 断点文件已刷新
[2026-03-22 23:09:08] 训练轮 1/6,小批次 9/47,当前损失=1.350781
[2026-03-22 23:09:08] 训练轮 1/6,小批次 18/47,当前损失=1.027869
[2026-03-22 23:09:08] 训练轮 1/6,小批次 27/47,当前损失=0.657884
[2026-03-22 23:09:09] 训练轮 1/6,小批次 36/47,当前损失=0.437732
[2026-03-22 23:09:09] 训练轮 1/6,小批次 45/47,当前损失=0.394355
[2026-03-22 23:09:09] 训练轮 1/6,小批次 47/47,当前损失=0.358120
[2026-03-22 23:09:09] 训练轮 1 完成,训练XMSE=0.596409,验证XMSE=1.077530
[2026-03-22 23:09:10] 训练轮 2/6,小批次 9/47,当前损失=0.277553
[2026-03-22 23:09:10] 训练轮 2/6,小批次 18/47,当前损失=0.262662
[2026-03-22 23:09:10] 训练轮 2/6,小批次 27/47,当前损失=0.225426
[2026-03-22 23:09:10] 训练轮 2/6,小批次 36/47,当前损失=0.221129
[2026-03-22 23:09:10] 训练轮 2/6,小批次 45/47,当前损失=0.210731
[2026-03-22 23:09:10] 训练轮 2/6,小批次 47/47,当前损失=0.191822
[2026-03-22 23:09:10] 训练轮 2 完成,训练XMSE=0.449573,验证XMSE=0.708331
[2026-03-22 23:09:11] 训练轮 3/6,小批次 9/47,当前损失=0.184828
[2026-03-22 23:09:11] 训练轮 3/6,小批次 18/47,当前损失=0.166215
[2026-03-22 23:09:11] 训练轮 3/6,小批次 27/47,当前损失=0.161870
[2026-03-22 23:09:11] 训练轮 3/6,小批次 36/47,当前损失=0.159263
[2026-03-22 23:09:11] 训练轮 3/6,小批次 45/47,当前损失=0.129936
[2026-03-22 23:09:11] 训练轮 3/6,小批次 47/47,当前损失=0.133408
[2026-03-22 23:09:12] 训练轮 3 完成,训练XMSE=0.363886,验证XMSE=0.588585
[2026-03-22 23:33:15] 训练轮 10/18,小批次 146/729,当前损失=0.030905
[2026-03-22 23:33:17] 训练轮 10/18,小批次 292/729,当前损失=0.029869
[2026-03-22 23:33:20] 训练轮 10/18,小批次 438/729,当前损失=0.016043
[2026-03-22 23:33:22] 训练轮 10/18,小批次 584/729,当前损失=0.018775
[2026-03-22 23:33:25] 训练轮 10/18,小批次 729/729,当前损失=0.015876
[2026-03-22 23:33:25] 训练轮 10 完成,训练XMSE=0.120063,验证XMSE=0.131628
[2026-03-22 23:33:25] 触发早停,最佳训练轮=5
[2026-03-22 23:33:26] SSA-GXZ最优模型训练结束
[2026-03-22 23:33:26] 准备进行全量预测
[2026-03-22 23:33:27] 全量预测完成
[2026-03-22 23:33:27] 最佳模型她结果文件均已保存
[2026-03-22 23:33:27] 准备绘制全部评估图
评估指标结果
XMSE MAE MSE MAPE sMAPE X2 Bikas DQ
_______ _______ ________ ______ _____ _______ _________ ______
0.15281 0.11898 0.023351 4.3202 4.334 0.97637 -0.013262 2.5813
[2026-03-22 23:33:30] 全部评估图绘制完成
[2026-03-22 23:33:30] 断点文件已清理
[2026-03-22 23:33:30] 程序结束
>>
结束
更多详细内容请访问
http://【MATLAB实现】有图有真相MATLAB实现基于SSA-GRU麻雀搜索算法(SSA)优化门控循环单元(GRU)进行多输入单输出回归预测(代码已调试成功,可一键运行,每一行都有详细注释)资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/92758002
https://download.csdn.net/download/xiaoxingkongyuxi/92758002
https://download.csdn.net/download/xiaoxingkongyuxi/92758002
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)