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

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

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

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

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

目录

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

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

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

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

项目实际效果图... 1

MATLAB实现基于SSA-GRU麻雀搜索算法(SSA)优化门控循环单元(GRU)进行多输入单输出回归预测     6

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

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

命令行窗口日志... 73

结束... 76

项目实际效果图

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种群数量', ... % 标签7SSA种群数量

    'SSA迭代次数', ... % 标签8SSA迭代次数

    '局部微调次数', ... % 标签9:局部微调次数

    '候选训练轮数', ... % 标签10:候选训练轮数

    '最优模型训练轮数', ... % 标签11:最优模型训练轮数

    '基线模型训练轮数', ... % 标签12:基线模型训练轮数

    '早停耐心值', ... % 标签13:早停耐心值

    '调参子集样本数', ... % 标签14:调参子集样本数

    '随机种子', ... % 标签15:随机种子

    '启用GPZ(10)'}; % 标签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(10)'};

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

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐