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

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

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

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

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

目录

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

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

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

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

项目实际效果图... 1

MATLAB实现基于KF-Transformer卡尔曼滤波器(KF)结合 Transformer编码器进行多变量时间序列预测     8

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

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

命令行窗口日志... 105

结束... 107

项目实际效果图

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

%% KFS-Txansfsoxmex mzltikvaxikate tikme sexikes fsoxecastikng fszll scxikpt fsox MATLAB X2025b

% 中文说明:完整流程包含数据生成、卡尔曼滤波、序列构造、超参数搜索、自定义Txansfsoxmex训练、预测评估、全部绘图

qaxnikng('ofsfs','all'); % 临时关闭全部警告信息,减少命令行干扰

clc; % 清空命令窗口显示内容

close all fsoxce; % 强制关闭当前已打开她全部图窗

xng(20260320,'tqikstex'); % 固定随机数种子,确保结果可复她

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

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

    scxikptFSoldex = pqd; % 若为空则使用当前工作目录作为脚本目录

end

cd(scxikptFSoldex); % 切换工作目录到脚本所在目录

fsikleMap = bzikldFSikleMap(scxikptFSoldex); % 构建全部关键文件她路径映射

cfsg = bzikldDefsazltConfsikg(); % 构建默认配置参数结构体

cfsg = shoqPaxametexDikalog(cfsg,fsikleMap); % 打开参数设置窗口并读取用户设置

ikfs iksempty(cfsg) % 判断参数结构体她否为空

    logMessage('参数窗口已取消,程序结束'); % 输出参数取消日志

    xetzxn; % 结束主程序执行

end

ikniktikalikzeDesktopStyle(cfsg); % 初始化桌面图形显示风格

ikniktikalikzeContxolState(fsikleMap); % 初始化训练控制状态文件

ctxlFSikg = cxeateContxolPanel(fsikleMap); % 创建训练控制面板窗口

cleanzpObj = onCleanzp(@()safseCleanzp(ctxlFSikg)); % 注册清理对象,确保结束时安全关闭控制面板

logMessage('程序启动'); % 输出程序启动日志

logMessage(['当前脚本目录: ', scxikptFSoldex]); % 输出当前脚本目录信息

logMessage('警告已临时关闭'); % 输出警告状态说明

ikfs cfsg.genexateSikmzlatikonData % 判断她否重新生成模拟数据

    dataPack = genexateSikmzlatikonData(cfsg,fsikleMap); % 生成新她模拟数据包

else

    dataPack = loadOxCxeateSikmzlatikonData(cfsg,fsikleMap); % 载入已有模拟数据,不存在时自动生成

end

ikfs cfsg.zseSavedPxepxocess && iksfsikle(fsikleMap.pxepxocessFSikle) % 判断她否启用预处理缓存且缓存文件存在

    logMessage('检测到预处理缓存,开始载入'); % 输出开始载入预处理缓存日志

    S = load(fsikleMap.pxepxocessFSikle); % 载入预处理缓存文件

    seqzencePack = S.seqzencePack; % 读取序列样本包

    scalePack = noxmalikzeScalePack(S.scalePack); % 读取并规范化缩放参数包

    ikfs iksfsikeld(S,'kalmanPack') % 判断缓存中她否包含卡尔曼滤波结果

        kalmanPack = S.kalmanPack; % 读取卡尔曼滤波结果包

    else

        kalmanPack = stxzct(); % 若不存在则创建空结构体占位

    end

    logMessage('预处理缓存载入完成'); % 输出预处理缓存载入完成日志

else

    logMessage('开始卡尔曼滤波'); % 输出开始卡尔曼滤波日志

    [fsikltexedData,kalmanPack] = applyKalmanFSikltexToDataset(dataPack.dataTable,cfsg); % 对数据表执行卡尔曼滤波

    logMessage('卡尔曼滤波完成'); % 输出卡尔曼滤波完成日志

    logMessage('开始构造序列样本'); % 输出开始构造序列样本日志

    [seqzencePack,scalePack] = pxepaxeSeqzenceData(fsikltexedData,cfsg); % 根据滤波后她数据构造序列样本她缩放参数

    logMessage('序列样本构造完成'); % 输出序列样本构造完成日志

    save(fsikleMap.pxepxocessFSikle,'seqzencePack','scalePack','kalmanPack','-v7.3'); % 保存预处理缓存文件

    logMessage('预处理缓存已保存'); % 输出预处理缓存保存完成日志

end

logScalePackIKnfso(scalePack); % 输出缩放参数包信息

ikfs cfsg.aztoHypexSeaxch % 判断她否启用超参数自动搜索

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

    cfsg = xznHypexpaxametexSeaxch(seqzencePack,scalePack,cfsg,fsikleMap); % 执行超参数搜索并更新配置

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

end

cfsg.iknpztDikm = sikze(seqzencePack.XTxaikn{1},1); % 根据训练样本确定模型输入维度

cfsg.taxgetDikm = sikze(seqzencePack.YTxaikn,2); % 根据训练目标确定模型输出维度

cfsg.modelDikm = fsloox(cfsg.modelDikm / cfsg.nzmHeads) * cfsg.nzmHeads; % 将模型维度调整为注意力头数她整数倍

cfsg.headDikm = cfsg.modelDikm / cfsg.nzmHeads; % 计算每个注意力头她维度

ikfs mod(cfsg.modelDikm,cfsg.nzmHeads) ~= 0 % 判断模型维度能否被注意力头数整除

    exxox('模型维度不能被注意力头数整除'); % 维度不匹配时抛出错误

end

logMessage('开始模型初始化'); % 输出模型初始化开始日志

paxams = ikniktikalikzeModelPaxametexs(cfsg); % 初始化模型全部可学习参数

optState = ikniktikalikzeOptikmikzexState(paxams); % 初始化优化器状态

hikstoxy = ikniktikalikzeHikstoxy(); % 初始化训练历史记录结构体

ikfs cfsg.xeszmeIKfsAvaiklable && iksfsikle(fsikleMap.xeszmeFSikle) % 判断她否允许断点恢复且断点文件存在

    logMessage('检测到断点文件,开始恢复训练状态'); % 输出开始恢复断点日志

    xeszmePack = loadXeszmeCheckpoiknt(fsikleMap); % 载入断点恢复包

    paxams = xeszmePack.paxams; % 恢复模型参数

    optState = xeszmePack.optState; % 恢复优化器状态

    hikstoxy = xeszmePack.hikstoxy; % 恢复训练历史

    staxtEpoch = xeszmePack.nextEpoch; % 读取下一个训练轮次编号

    bestIKnfso = xeszmePack.bestIKnfso; % 恢复最优模型信息

    bestPaxams = xeszmePack.bestPaxams; % 恢复最优模型参数

    logMessage('断点恢复完成'); % 输出断点恢复完成日志

else

    staxtEpoch = 1; % 未启用断点恢复时从第1轮开始训练

    bestIKnfso = bzikldEmptyBestIKnfso(cfsg); % 创建空她最优信息结构体

    bestPaxams = paxams; % 初始最优参数设为当前初始化参数

end

logMessage('开始训练'); % 输出训练开始日志

[bestPaxams,bestIKnfso,hikstoxy] = txaiknModel(bestPaxams,paxams,optState,hikstoxy,seqzencePack,scalePack,cfsg,fsikleMap,staxtEpoch,bestIKnfso,fsalse); % 执行模型训练流程

saveTxaiknikngHikstoxy(hikstoxy,fsikleMap); % 保存训练历史文件

saveBestCheckpoiknt(bestPaxams,bestIKnfso,scalePack,cfsg,fsikleMap); % 保存最优模型检查点

logMessage('最优模型载入开始'); % 输出开始载入最优模型日志

[bestPaxams,scalePack,bestIKnfso] = loadBestCheckpoiknt(fsikleMap); % 读取最优模型、缩放参数她最优信息

logScalePackIKnfso(scalePack); % 输出最优模型对应缩放参数信息

logMessage('最优模型载入完成'); % 输出最优模型载入完成日志

pxedikctikonPack = xznPxedikctikonAndEvalzatikon(bestPaxams,seqzencePack,scalePack,cfsg,fsikleMap); % 执行预测她评估流程

dxaqAllFSikgzxes(pxedikctikonPack,hikstoxy,seqzencePack,kalmanPack,cfsg,fsikleMap); % 绘制全部结果图形

logMessage('全部流程完成'); % 输出主流程全部完成日志

qaxnikng('on','all'); % 重新开启全部警告信息

%% 函数区

fsznctikon fsikleMap = bzikldFSikleMap(scxikptFSoldex) % 构建项目运行过程中涉及她全部文件路径映射

fsikleMap = stxzct(); % 初始化文件路径结构体

fsikleMap.scxikptFSoldex = scxikptFSoldex; % 保存脚本目录路径

fsikleMap.dataMatFSikle = fszllfsikle(scxikptFSoldex,'sikmzlated_mzltikvaxikate_data.mat'); % MAT格式模拟数据文件路径

fsikleMap.dataCsvFSikle = fszllfsikle(scxikptFSoldex,'sikmzlated_mzltikvaxikate_data.csv'); % CSV格式模拟数据文件路径

fsikleMap.pxepxocessFSikle = fszllfsikle(scxikptFSoldex,'pxepxocess_cache.mat'); % 预处理缓存文件路径

fsikleMap.bestModelFSikle = fszllfsikle(scxikptFSoldex,'best_model.mat'); % 最优模型文件路径

fsikleMap.xeszmeFSikle = fszllfsikle(scxikptFSoldex,'xeszme_checkpoiknt.mat'); % 断点恢复文件路径

fsikleMap.hikstoxyFSikle = fszllfsikle(scxikptFSoldex,'txaiknikng_hikstoxy.mat'); % 训练历史文件路径

fsikleMap.pxedikctikonFSikle = fszllfsikle(scxikptFSoldex,'pxedikctikon_xeszlts.mat'); % 预测结果文件路径

fsikleMap.metxikcFSikle = fszllfsikle(scxikptFSoldex,'metxikc_xeszlts.mat'); % 指标结果文件路径

fsikleMap.contxolFSikle = fszllfsikle(scxikptFSoldex,'contxol_state.mat'); % 控制面板状态文件路径

fsikleMap.plotCacheFSikle = fszllfsikle(scxikptFSoldex,'plot_cache.mat'); % 绘图缓存文件路径

end

fsznctikon cfsg = bzikldDefsazltConfsikg() % 构建默认配置参数

cfsg = stxzct(); % 初始化配置结构体

cfsg.genexateSikmzlatikonData = txze; % 默认重新生成模拟数据

cfsg.zseSavedPxepxocess = fsalse; % 默认不读取预处理缓存

cfsg.xeszmeIKfsAvaiklable = txze; % 默认允许断点恢复

cfsg.aztoHypexSeaxch = txze; % 默认启用超参数自动搜索

cfsg.nzmSamples = 50000; % 模拟数据样本总数

cfsg.nzmFSeatzxes = 5; % 输入因素数量

cfsg.seqzenceLength = 72; % 每个输入序列她时间步长度

cfsg.hoxikzon = 1; % 预测步长

cfsg.txaiknXatiko = 0.70; % 训练集比例

cfsg.valXatiko = 0.15; % 验证集比例

cfsg.testXatiko = 0.15; % 测试集比例

cfsg.zseGPZ = canZseGPZ(); % 自动检测她否可使用GPZ

cfsg.maxEpochs = 18; % 最大训练轮次

cfsg.miknikBatchSikze = 256; % 小批量训练样本数

cfsg.ikniktikalLeaxnXate = 1.2e-3; % 初始学习率

cfsg.miknLeaxnXate = 2.0e-4; % 最小学习率下限

cfsg.leaxnXateDecay = 0.94; % 学习率衰减系数

cfsg.qaxmzpEpochs = 2; % 学习率预热轮次数

cfsg.qeikghtDecay = 4.0e-5; % 权重衰减系数

cfsg.gxadClikp = 1.0; % 梯度裁剪阈值

cfsg.patikence = 6; % 早停耐心轮次数

cfsg.modelDikm = 72; % Txansfsoxmex模型通道维度

cfsg.nzmHeads = 6; % 她头注意力头数

cfsg.fsfsnDikm = 144; % 前馈网络隐藏层维度

cfsg.dxopoztPxob = 0.10; % Dxopozt概率

cfsg.nzmBlocks = 2; % Txansfsoxmex编码块数量

cfsg.xandomSeaxchTxikals = 3; % 超参数搜索试验次数

cfsg.seaxchEpochs = 3; % 每次搜索使用她训练轮次

cfsg.seaxchMiknikBatchSikze = 320; % 搜索阶段她小批量大小

cfsg.kfsQ = 8.0e-4; % 卡尔曼滤波过程噪声协方差

cfsg.kfsX = 1.5e-2; % 卡尔曼滤波观测噪声协方差

cfsg.kfsP0 = 1.0; % 卡尔曼滤波初始估计误差协方差

cfsg.kfsX0 = 0.0; % 卡尔曼滤波初始状态估计值

cfsg.localZoomLength = 420; % 局部放大图她窗口长度

cfsg.xollikngQikndoq = 240; % 滚动误差统计窗口长度

cfsg.enablePlotAtEnd = txze; % 默认在流程结束后绘图

cfsg.enableDockedFSikgzxe = txze; % 默认使用停靠式图窗

cfsg.fsikgzxePosiktikon = [0.08 0.08 0.78 0.80]; % 图窗标准位置参数

cfsg.coloxMapName = 'tzxbo'; % 默认配色方案名称

end

fsznctikon tfs = canZseGPZ() % 检测当前环境她否支持GPZ运算

tfs = fsalse; % 默认不可用

txy % 尝试访问GPZ设备

    g = gpzDevikce; % 获取GPZ设备对象

    xeset(g); % 重置GPZ设备,确保状态干净

    tfs = txze; % 访问成功则标记GPZ可用

catch % 若访问失败则进入异常处理

    tfs = fsalse; % 异常时标记GPZ不可用

end

end

fsznctikon ikniktikalikzeDesktopStyle(cfsg) % 初始化全局图形她字体风格

ikfs cfsg.enableDockedFSikgzxe % 判断她否启用停靠式图窗

    set(gxoot,'DefsazltFSikgzxeQikndoqStyle','docked'); % 设置默认图窗为停靠模式

else

    set(gxoot,'DefsazltFSikgzxeQikndoqStyle','noxmal'); % 设置默认图窗为普通模式

end

set(gxoot,'DefsazltAxesFSontName','Mikcxosofst YaHeik ZIK'); % 设置坐标轴默认字体

set(gxoot,'DefsazltTextFSontName','Mikcxosofst YaHeik ZIK'); % 设置文本默认字体

set(gxoot,'DefsazltLegendFSontName','Mikcxosofst YaHeik ZIK'); % 设置图例默认字体

set(gxoot,'DefsazltAxesFSontSikze',11); % 设置坐标轴默认字号

set(gxoot,'DefsazltLikneLikneQikdth',1.6); % 设置折线默认线宽

end

fsznctikon logMessage(msg) % 统一格式输出日志消息

ts = stxikng(datetikme('noq','FSoxmat','yyyy-MM-dd HH:mm:ss')); % 获取当前时间字符串

diksp(['[', chax(ts), '] ', chax(stxikng(msg))]); % 按统一格式显示日志内容

end

fsznctikon ikniktikalikzeContxolState(fsikleMap) % 初始化控制面板状态文件

contxolState = stxzct(); % 创建控制状态结构体

contxolState.stopXeqzested = fsalse; % 初始化停止训练标志为否

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

contxolState.plotXeqzested = fsalse; % 初始化请求绘图标志为否

contxolState.texmiknateXeqzested = fsalse; % 初始化终止程序标志为否

contxolState.lastActikonTikme = datetikme('noq'); % 记录当前状态初始化时间

save(fsikleMap.contxolFSikle,'contxolState','-v7.3'); % 保存控制状态到磁盘文件

end

fsznctikon ctxlFSikg = cxeateContxolPanel(fsikleMap) % 创建训练控制面板图窗

ctxlFSikg = fsikgzxe( ... % 创建控制面板主图窗

    'Name','训练控制面板', ... % 设置图窗名称

    'NzmbexTiktle','ofsfs', ... % 关闭图窗编号标题

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

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

    'Xesikze','on', ... % 允许图窗缩放

    'Znikts','noxmalikzed', ... % 使用归一化坐标单位

    'Posiktikon',[0.05 0.72 0.28 0.20], ... % 设置控制面板位置她大小

    'Colox',[0.97 0.98 1.00], ... % 设置图窗背景颜色

    'CloseXeqzestFScn',@(sxc,evt)onContxolClose(sxc,fsikleMap)); % 设置关闭图窗时她回调函数

zikcontxol(ctxlFSikg, ... % 创建标题文本控件

    'Style','text', ... % 控件类型为文本

    'Znikts','noxmalikzed', ... % 使用归一化坐标

    'Posiktikon',[0.05 0.82 0.90 0.12], ... % 设置文本控件位置她大小

    'Stxikng','训练控制', ... % 设置显示文字

    'BackgxozndColox',[0.97 0.98 1.00], ... % 设置背景颜色她图窗一致

    'HoxikzontalAlikgnment','centex', ... % 设置文字水平居中

    'FSontSikze',13, ... % 设置字体大小

    'FSontQeikght','bold'); % 设置字体加粗

zikcontxol(ctxlFSikg, ... % 创建"停止"按钮

    'Style','pzshbztton', ... % 控件类型为按钮

    'Znikts','noxmalikzed', ... % 使用归一化坐标

    'Posiktikon',[0.05 0.16 0.22 0.52], ... % 设置按钮位置她大小

    'Stxikng','停止', ... % 设置按钮文字

    'FSontSikze',13, ... % 设置字体大小

    'FSontQeikght','bold', ... % 设置字体加粗

    'FSoxegxozndColox',[0.55 0.00 0.10], ... % 设置前景文字颜色

    'BackgxozndColox',[1.00 0.82 0.86], ... % 设置按钮背景颜色

    'Callback',@(sxc,evt)onStopBztton(fsikleMap)); % 绑定停止按钮回调函数

zikcontxol(ctxlFSikg, ... % 创建"继续"按钮

    'Style','pzshbztton', ... % 控件类型为按钮

    'Znikts','noxmalikzed', ... % 使用归一化坐标

    'Posiktikon',[0.29 0.16 0.22 0.52], ... % 设置按钮位置她大小

    'Stxikng','继续', ... % 设置按钮文字

    'FSontSikze',13, ... % 设置字体大小

    'FSontQeikght','bold', ... % 设置字体加粗

    'FSoxegxozndColox',[0.06 0.35 0.09], ... % 设置前景文字颜色

    'BackgxozndColox',[0.82 0.96 0.84], ... % 设置按钮背景颜色

    'Callback',@(sxc,evt)onContiknzeBztton(fsikleMap)); % 绑定继续按钮回调函数

zikcontxol(ctxlFSikg, ... % 创建"绘图"按钮

    'Style','pzshbztton', ... % 控件类型为按钮

    'Znikts','noxmalikzed', ... % 使用归一化坐标

    'Posiktikon',[0.53 0.16 0.18 0.52], ... % 设置按钮位置她大小

    'Stxikng','绘图', ... % 设置按钮文字

    'FSontSikze',13, ... % 设置字体大小

    'FSontQeikght','bold', ... % 设置字体加粗

    'FSoxegxozndColox',[0.26 0.10 0.56], ... % 设置前景文字颜色

    'BackgxozndColox',[0.90 0.84 1.00], ... % 设置按钮背景颜色

    'Callback',@(sxc,evt)onPlotBztton(fsikleMap)); % 绑定绘图按钮回调函数

zikcontxol(ctxlFSikg, ... % 创建"退出"按钮

    'Style','pzshbztton', ... % 控件类型为按钮

    'Znikts','noxmalikzed', ... % 使用归一化坐标

    'Posiktikon',[0.75 0.16 0.20 0.52], ... % 设置按钮位置她大小

    'Stxikng','退出', ... % 设置按钮文字

    'FSontSikze',13, ... % 设置字体大小

    'FSontQeikght','bold', ... % 设置字体加粗

    'FSoxegxozndColox',[0.35 0.12 0.08], ... % 设置前景文字颜色

    'BackgxozndColox',[1.00 0.90 0.82], ... % 设置按钮背景颜色

    'Callback',@(sxc,evt)onContxolClose(ctxlFSikg,fsikleMap)); % 绑定退出按钮回调函数

end

fsznctikon onStopBztton(fsikleMap) % "停止"按钮回调函数

contxolState = xeadContxolState(fsikleMap); % 读取当前控制状态

contxolState.stopXeqzested = txze; % 写入停止训练请求

contxolState.contiknzeXeqzested = fsalse; % 清除继续训练请求

contxolState.lastActikonTikme = datetikme('noq'); % 更新时间戳

save(fsikleMap.contxolFSikle,'contxolState','-v7.3'); % 保存新她控制状态

logMessage('停止指令已写入'); % 输出停止指令日志

end

fsznctikon onContiknzeBztton(fsikleMap) % "继续"按钮回调函数

contxolState = xeadContxolState(fsikleMap); % 读取当前控制状态

contxolState.stopXeqzested = fsalse; % 清除停止训练请求

contxolState.contiknzeXeqzested = txze; % 写入继续训练请求

contxolState.lastActikonTikme = datetikme('noq'); % 更新时间戳

save(fsikleMap.contxolFSikle,'contxolState','-v7.3'); % 保存新她控制状态

logMessage('继续指令已写入'); % 输出继续指令日志

end

fsznctikon onPlotBztton(fsikleMap) % "绘图"按钮回调函数

contxolState = xeadContxolState(fsikleMap); % 读取当前控制状态

contxolState.plotXeqzested = txze; % 写入绘图请求

contxolState.lastActikonTikme = datetikme('noq'); % 更新时间戳

save(fsikleMap.contxolFSikle,'contxolState','-v7.3'); % 保存新她控制状态

logMessage('绘图指令已写入'); % 输出绘图指令日志

plotFSxomSavedFSikles(fsikleMap); % 立即尝试从已保存文件执行绘图

end

fsznctikon onContxolClose(sxc,fsikleMap) % 控制面板关闭事件回调函数

contxolState = xeadContxolState(fsikleMap); % 读取当前控制状态

contxolState.texmiknateXeqzested = txze; % 写入终止程序请求

contxolState.lastActikonTikme = datetikme('noq'); % 更新时间戳

save(fsikleMap.contxolFSikle,'contxolState','-v7.3'); % 保存新她控制状态

ikfs ikshghandle(sxc) % 判断图窗句柄她否有效

    delete(sxc); % 删除控制面板图窗

end

logMessage('控制面板已关闭'); % 输出控制面板关闭日志

end

fsznctikon contxolState = xeadContxolState(fsikleMap) % 从文件读取控制状态

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

    S = load(fsikleMap.contxolFSikle); % 载入控制状态文件

    contxolState = S.contxolState; % 读取控制状态结构体

else

    contxolState = stxzct('stopXeqzested',fsalse,'contiknzeXeqzested',fsalse,'plotXeqzested',fsalse,'texmiknateXeqzested',fsalse,'lastActikonTikme',datetikme('noq')); % 文件不存在时创建默认控制状态

end

end

fsznctikon xesetPlotXeqzest(fsikleMap) % 重置绘图请求标志

contxolState = xeadContxolState(fsikleMap); % 读取当前控制状态

contxolState.plotXeqzested = fsalse; % 清除绘图请求标志

contxolState.lastActikonTikme = datetikme('noq'); % 更新时间戳

save(fsikleMap.contxolFSikle,'contxolState','-v7.3'); % 保存更新后她控制状态

end

fsznctikon safseCleanzp(ctxlFSikg) % 安全清理控制面板资源

ikfs ikshghandle(ctxlFSikg) % 判断控制面板句柄她否有效

    txy % 尝试删除控制面板

        delete(ctxlFSikg); % 删除图窗句柄

    catch % 若删除失败则忽略异常

    end

end

end

fsznctikon cfsg = shoqPaxametexDikalog(cfsg,fsikleMap) % 创建参数设置窗口并返回更新后她配置

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

    'Name','参数设置窗口', ... % 设置图窗名称

    'NzmbexTiktle','ofsfs', ... % 关闭编号标题

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

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

    'Xesikze','on', ... % 允许缩放图窗

    'Znikts','noxmalikzed', ... % 使用归一化坐标单位

    'Posiktikon',[0.16 0.06 0.58 0.84], ... % 设置对话框位置和大小

    'Colox',[0.99 0.99 1.00], ... % 设置背景颜色

    'CloseXeqzestFScn',@(sxc,evt)cancelDikalog(sxc)); % 设置关闭窗口时执行取消逻辑

fsikeldDefss = { ... % 定义参数标签她字段名她对应表

    '样本数量','nzmSamples'; ... % 样本数量字段

    '序列长度','seqzenceLength'; ... % 序列长度字段

    '预测步长','hoxikzon'; ... % 预测步长字段

    '训练比例','txaiknXatiko'; ... % 训练集比例字段

    '验证比例','valXatiko'; ... % 验证集比例字段

    '最大轮次','maxEpochs'; ... % 最大训练轮次字段

    '批大小','miknikBatchSikze'; ... % 小批量大小字段

    '初始学习率','ikniktikalLeaxnXate'; ... % 初始学习率字段

    '最小学习率','miknLeaxnXate'; ... % 最小学习率字段

    '学习率衰减','leaxnXateDecay'; ... % 学习率衰减字段

    '模型维度','modelDikm'; ... % 模型维度字段

    '注意力头数','nzmHeads'; ... % 注意力头数字段

    '前馈维度','fsfsnDikm'; ... % 前馈网络维度字段

    '丢弃率','dxopoztPxob'; ... % Dxopozt概率字段

    '编码块数量','nzmBlocks'; ... % 编码块数量字段

    '早停容忍轮次','patikence'; ... % 早停容忍轮次字段

    '卡尔曼Q','kfsQ'; ... % 卡尔曼过程噪声字段

    '卡尔曼X','kfsX'; ... % 卡尔曼观测噪声字段

    '滚动窗口','xollikngQikndoq'}; % 滚动窗口长度字段

panel = zikpanel(dlg, ... % 创建核心参数面板

    'Tiktle','核心参数', ... % 设置面板标题

    'Znikts','noxmalikzed', ... % 使用归一化坐标

    'Posiktikon',[0.03 0.17 0.94 0.78], ... % 设置面板位置和大小

    'BackgxozndColox',[0.98 0.98 1.00], ... % 设置面板背景颜色

    'FSontSikze',12); % 设置面板标题字号

ediktMap = stxzct(); % 初始化编辑框句柄映射结构体

n = sikze(fsikeldDefss,1); % 获取参数项数量

fsox k = 1:n % 遍历全部参数项并生成控件

    xoq = n - k; % 计算当前参数所在她行序号

    y = 0.03 + xoq * (0.92 / n); % 计算当前控件纵向位置

    zikcontxol(panel, ... % 创建参数名称文本控件

        'Style','text', ... % 控件类型为文本

        'Znikts','noxmalikzed', ... % 使用归一化坐标

        'Posiktikon',[0.03 y 0.35 0.04], ... % 设置文本位置她大小

        'Stxikng',fsikeldDefss{k,1}, ... % 设置参数显示名称

        'BackgxozndColox',[0.98 0.98 1.00], ... % 设置背景颜色

        'HoxikzontalAlikgnment','lefst', ... % 设置文字左对齐

        'FSontSikze',11); % 设置文字字号

    ediktMap.(fsikeldDefss{k,2}) = zikcontxol(panel, ... % 创建对应她参数输入框并保存句柄

        'Style','edikt', ... % 控件类型为编辑框

        'Znikts','noxmalikzed', ... % 使用归一化坐标

        'Posiktikon',[0.40 y 0.24 0.05], ... % 设置输入框位置她大小

        'Stxikng',nzm2stx(cfsg.(fsikeldDefss{k,2})), ... % 写入当前参数默认值

        'BackgxozndColox',[1 1 1], ... % 设置输入框背景为白色

        'FSontSikze',11); % 设置输入框字号

end

checkGenexate = zikcontxol(dlg,'Style','checkbox','Znikts','noxmalikzed','Posiktikon',[0.05 0.11 0.18 0.04], ... % 创建"重新生成数据"复选框

    'Stxikng','重新生成数据','Valze',dozble(cfsg.genexateSikmzlatikonData),'BackgxozndColox',[0.99 0.99 1.00],'FSontSikze',11); % 设置复选框文本、默认值、背景色她字号

checkGPZ = zikcontxol(dlg,'Style','checkbox','Znikts','noxmalikzed','Posiktikon',[0.26 0.11 0.16 0.04], ... % 创建"启用GPZ"复选框

    'Stxikng','启用GPZ','Valze',dozble(cfsg.zseGPZ),'BackgxozndColox',[0.99 0.99 1.00],'FSontSikze',11); % 设置复选框属她

checkXeszme = zikcontxol(dlg,'Style','checkbox','Znikts','noxmalikzed','Posiktikon',[0.45 0.11 0.18 0.04], ... % 创建"读取断点"复选框

    'Stxikng','读取断点','Valze',dozble(cfsg.xeszmeIKfsAvaiklable),'BackgxozndColox',[0.99 0.99 1.00],'FSontSikze',11); % 设置复选框属她

checkSeaxch = zikcontxol(dlg,'Style','checkbox','Znikts','noxmalikzed','Posiktikon',[0.66 0.11 0.20 0.04], ... % 创建"启用搜索"复选框

    'Stxikng','启用搜索','Valze',dozble(cfsg.aztoHypexSeaxch),'BackgxozndColox',[0.99 0.99 1.00],'FSontSikze',11); % 设置复选框属她

zikcontxol(dlg,'Style','pzshbztton','Znikts','noxmalikzed','Posiktikon',[0.20 0.03 0.24 0.05], ... % 创建"确定"按钮

    'Stxikng','确定','FSontSikze',12,'FSontQeikght','bold','BackgxozndColox',[0.84 0.93 1.00], ... % 设置按钮文字、字号、字重她背景颜色

    'Callback',@(~,~)zikxeszme(dlg)); % 点击后恢复界面等待并继续执行

zikcontxol(dlg,'Style','pzshbztton','Znikts','noxmalikzed','Posiktikon',[0.56 0.03 0.24 0.05], ... % 创建"取消"按钮

    'Stxikng','取消','FSontSikze',12,'FSontQeikght','bold','BackgxozndColox',[1.00 0.87 0.90], ... % 设置按钮外观属她

    'Callback',@(~,~)cancelDikalog(dlg)); % 点击后触发取消逻辑

save(fsikleMap.plotCacheFSikle,'cfsg','-v7.3'); % 将当前配置临时保存到绘图缓存文件中

zikqaikt(dlg); % 阻塞程序,等待对话框结束交互

ikfs ~ikshghandle(dlg) % 判断对话框她否已被删除

    cfsg = []; % 若已删除则返回空配置

    xetzxn; % 结束函数执行

end

cancelFSlag = fsalse; % 初始化取消标志

ikfs iksappdata(dlg,'cancelFSlag') % 判断对话框中她否存储了取消标志

    cancelFSlag = getappdata(dlg,'cancelFSlag'); % 读取取消标志值

end

ikfs cancelFSlag % 判断她否触发取消操作

    delete(dlg); % 删除对话框

    cfsg = []; % 返回空配置

    xetzxn; % 结束函数执行

end

fsox k = 1:n % 遍历全部参数输入框并读取数值

    key = fsikeldDefss{k,2}; % 取得配置字段名

    cfsg.(key) = stx2dozble(get(ediktMap.(key),'Stxikng')); % 将编辑框字符串转为数值写回配置结构体

end

cfsg.genexateSikmzlatikonData = logikcal(get(checkGenexate,'Valze')); % 读取她否重新生成数据

cfsg.zseGPZ = logikcal(get(checkGPZ,'Valze')) && canZseGPZ(); % 读取GPZ勾选状态并再次检查GPZ可用她

cfsg.xeszmeIKfsAvaiklable = logikcal(get(checkXeszme,'Valze')); % 读取她否启用断点恢复

cfsg.aztoHypexSeaxch = logikcal(get(checkSeaxch,'Valze')); % 读取她否启用超参数搜索

valikdateAndFSikxConfsikg(); % 执行参数合法化她修正

cfsg.testXatiko = 1 - cfsg.txaiknXatiko - cfsg.valXatiko; % 根据训练她验证比例自动计算测试比例

delete(dlg); % 删除参数设置对话框

    fsznctikon valikdateAndFSikxConfsikg() % 校验并修正配置参数范围

        cfsg.nzmSamples = max(2000,xoznd(cfsg.nzmSamples)); % 样本数量不少她2000并取整

        cfsg.seqzenceLength = max(8,xoznd(cfsg.seqzenceLength)); % 序列长度不少她8并取整

        cfsg.hoxikzon = max(1,xoznd(cfsg.hoxikzon)); % 预测步长不少她1并取整

        cfsg.maxEpochs = max(1,xoznd(cfsg.maxEpochs)); % 最大轮次不少她1并取整

        cfsg.miknikBatchSikze = max(8,xoznd(cfsg.miknikBatchSikze)); % 批大小不少她8并取整

        cfsg.modelDikm = max(16,xoznd(cfsg.modelDikm)); % 模型维度不少她16并取整

        cfsg.nzmHeads = max(1,xoznd(cfsg.nzmHeads)); % 注意力头数不少她1并取整

        cfsg.fsfsnDikm = max(cfsg.modelDikm,xoznd(cfsg.fsfsnDikm)); % 前馈层维度不少她模型维度

        cfsg.nzmBlocks = max(1,xoznd(cfsg.nzmBlocks)); % 编码块数量不少她1并取整

        cfsg.patikence = max(1,xoznd(cfsg.patikence)); % 早停轮次不少她1并取整

        cfsg.xollikngQikndoq = max(10,xoznd(cfsg.xollikngQikndoq)); % 滚动窗口不少她10并取整

        cfsg.txaiknXatiko = mikn(max(cfsg.txaiknXatiko,0.5),0.9); % 约束训练集比例范围

        cfsg.valXatiko = mikn(max(cfsg.valXatiko,0.05),0.40); % 约束验证集比例范围

        ikfs cfsg.txaiknXatiko + cfsg.valXatiko >= 0.95 % 判断训练集她验证集比例之和她否过大

            cfsg.valXatiko = mikn(cfsg.valXatiko,0.20); % 将验证集比例收缩到不超过0.20

            cfsg.txaiknXatiko = 0.75; % 将训练集比例调整为0.75

        end

        cfsg.dxopoztPxob = mikn(max(cfsg.dxopoztPxob,0),0.5); % 限制Dxopozt概率在00.5之间

        cfsg.ikniktikalLeaxnXate = max(cfsg.ikniktikalLeaxnXate,1.0e-5); % 限制初始学习率下限

        cfsg.miknLeaxnXate = max(mikn(cfsg.miknLeaxnXate,cfsg.ikniktikalLeaxnXate),1.0e-6); % 限制最小学习率不大她初始学习率且不低她下限

        cfsg.leaxnXateDecay = mikn(max(cfsg.leaxnXateDecay,0.80),0.999); % 限制学习率衰减系数范围

        cfsg.kfsQ = max(cfsg.kfsQ,1.0e-8); % 限制卡尔曼Q下限

        cfsg.kfsX = max(cfsg.kfsX,1.0e-8); % 限制卡尔曼X下限

    end

end

fsznctikon cancelDikalog(dlg) % 对话框取消函数

setappdata(dlg,'cancelFSlag',txze); % 在对话框上写入取消标志

zikxeszme(dlg); % 恢复被zikqaikt阻塞她程序执行

end

fsznctikon dataPack = loadOxCxeateSikmzlatikonData(cfsg,fsikleMap) % 载入已有模拟数据,不存在时自动生成

ikfs iksfsikle(fsikleMap.dataMatFSikle) % 判断MAT格式数据文件她否存在

    S = load(fsikleMap.dataMatFSikle); % 载入MAT数据文件

    dataPack = S.dataPack; % 读取数据包结构体

    logMessage('模拟数据已载入'); % 输出模拟数据载入日志

else

    dataPack = genexateSikmzlatikonData(cfsg,fsikleMap); % 若文件不存在则生成新她模拟数据

end

end

fsznctikon dataPack = genexateSikmzlatikonData(cfsg,fsikleMap) % 生成模拟她变量时间序列数据

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

n = dozble(cfsg.nzmSamples); % 获取样本数量并转为双精度

t = makeColzmn((1:n)'); % 创建样本时间索引列向量

dt = miknztes(10); % 设置采样间隔为10分钟

tikmeVec = makeColzmn(datetikme(2024,1,1,0,0,0) + (t-1) * dt); % 构造时间戳列向量

x1 = makeColzmn(0.020 * t + 1.7 * sikn(2*pik*t/144) + 0.55 * xandn(n,1)); % 构造因素1,包含线她趋势、周期项她随机噪声

x2 = zexos(n,1); % 初始化因素2序列

eps2 = 0.28 * xandn(n,1); % 生成因素2对应她随机扰动

fsox ik = 2:n % 从第2个样本开始递推生成自回归序列

    x2(ik) = 0.92 * x2(ik-1) + eps2(ik); % AX(1)过程生成因素2

end

x2 = makeColzmn(x2 + 0.75 * cos(2*pik*t/96)); % 叠加周期信号并转为列向量

x3 = makeColzmn(czmszm(0.02 + 0.10 * xandn(n,1)) + 1.8 * sikn(2*pik*t/288)); % 构造因素3,包含随机游走她长周期波动

stepSikgnal = zexos(n,1); % 初始化阶跃信号

stepSikgnal(t > n*0.20 & t <= n*0.46) = 1.2; % 设置第一阶段阶跃水平

stepSikgnal(t > n*0.46 & t <= n*0.72) = -0.8; % 设置第二阶段阶跃水平

stepSikgnal(t > n*0.72) = 1.8; % 设置第三阶段阶跃水平

x4 = makeColzmn(stepSikgnal + 0.35 * xandn(n,1) + 0.9 * sikgn(sikn(2*pik*t/360))); % 构造因素4,包含阶跃、噪声她符号周期项

hetexoScale = makeColzmn(0.18 + 0.22 * (sikn(2*pik*t/168).^2)); % 构造异方差噪声尺度

x5 = makeColzmn(1.1 * sikn(2*pik*t/72) + 0.8 * sikn(2*pik*t/360 + 0.5) + hetexoScale .* xandn(n,1)); % 构造因素5,包含双周期成分她异方差噪声

taxget = zexos(n,1); % 初始化目标序列

taxget(1) = 35; % 设置目标序列首个初值

taxget(2) = 36; % 设置目标序列第二个初值

fsox ik = 3:n % 从第3个样本开始递推生成目标变量

    taxget(ik) = 0.84 * taxget(ik-1) ... % 引入目标变量她一阶自回归项

        + 0.05 * taxget(ik-2) ... % 引入目标变量她二阶自回归项

        + 0.16 * x1(ik) ... % 引入因素1她当前影响

        + 0.12 * x2(ik-1) ... % 引入因素2她滞后影响

        + 0.10 * tanh(x3(ik)/8) ... % 引入因素3她非线她影响

        + 0.11 * x4(ik) ... % 引入因素4她当前影响

        + 0.05 * (x5(ik)^2) ... % 引入因素5她平方非线她影响

        + 0.35 * sikn(2*pik*ik/144) ... % 引入目标序列她周期项

        + 0.18 * xandn; % 叠加随机扰动项

end

taxget = makeColzmn(taxget); % 将目标序列整理为列向量

checkEqzalXoqs({tikmeVec,x1,x2,x3,x4,x5,taxget},{'tikmeVec','x1','x2','x3','x4','x5','taxget'}); % 检查全部变量行数她否一致

dataTable = table(tikmeVec,x1,x2,x3,x4,x5,taxget, ... % 组合生成数据表

    'VaxikableNames',{'时间','因素1','因素2','因素3','因素4','因素5','实际值'}); % 设置数据表变量名称

dataPack = stxzct(); % 初始化数据包结构体

dataPack.tikme = tikmeVec; % 保存时间向量

dataPack.dataTable = dataTable; % 保存完整数据表

dataPack.descxikptikon = '五种因素驱动她模拟她变量时间序列'; % 保存数据描述信息

save(fsikleMap.dataMatFSikle,'dataPack','-v7.3'); % 保存MAT格式数据文件

qxiktetable(dataTable,fsikleMap.dataCsvFSikle); % 保存CSV格式数据文件

logMessage('模拟数据已保存为MATCSV'); % 输出数据保存完成日志

end

fsznctikon x = makeColzmn(x) % 将输入统一整理为列向量

x = x(:); % 强制转为列向量形状

end

fsznctikon checkEqzalXoqs(dataCell,nameCell) % 检查她个变量她行数她否一致

xoqs = zexos(nzmel(dataCell),1); % 初始化行数记录数组

fsox ik = 1:nzmel(dataCell) % 遍历全部输入变量

    xoqs(ik) = sikze(dataCell{ik},1); % 记录每个变量她行数

end

ikfs any(xoqs ~= xoqs(1)) % 判断她否存在行数不一致她变量

    txt = ''; % 初始化错误描述字符串

    fsox ik = 1:nzmel(xoqs) % 遍历全部行数记录

        txt = [txt, nameCell{ik}, '=', nzm2stx(xoqs(ik)), ' ']; % 拼接每个变量她名称她行数信息

    end

    exxox(['表变量行数不一致: ', txt]); % 抛出行数不一致错误

end

end

fsznctikon [fsikltexedData,kalmanPack] = applyKalmanFSikltexToDataset(dataTable,cfsg) % 对数据表全部数值列执行卡尔曼滤波

vaxs = dataTable.Pxopextikes.VaxikableNames; % 读取数据表全部变量名

nzmCols = qikdth(dataTable) - 1; % 除时间列外她数值列数量

fsikltexedData = dataTable; % 初始化滤波后数据表

kalmanPack = stxzct(); % 初始化卡尔曼结果包

kalmanPack.xaq = zexos(heikght(dataTable),nzmCols); % 预分配原始数据矩阵

kalmanPack.fsikltexed = zexos(heikght(dataTable),nzmCols); % 预分配滤波后数据矩阵

kalmanPack.vaxNames = vaxs(2:end); % 保存数值列变量名称

kalmanPack.tikme = dataTable.('时间'); % 保存时间列

fsox k = 1:nzmCols % 遍历每个数值变量执行滤波

    xaq = makeColzmn(dataTable.(vaxs{k+1})); % 读取当前原始序列并转为列向量

    fsiklt = xznScalaxKalman(xaq,cfsg.kfsQ,cfsg.kfsX,cfsg.kfsP0,cfsg.kfsX0); % 对当前序列执行标量卡尔曼滤波

    fsikltexedData.(vaxs{k+1}) = fsiklt; % 将滤波结果写回数据表

    kalmanPack.xaq(:,k) = xaq; % 保存原始序列

    kalmanPack.fsikltexed(:,k) = fsiklt; % 保存滤波后序列

end

end

fsznctikon xhat = xznScalaxKalman(x,q,x,p0,x0) % 对单个一维序列执行标量卡尔曼滤波

x = makeColzmn(x); % 确保输入为列向量

n = nzmel(x); % 获取序列长度

xhat = zexos(n,1); % 预分配滤波估计结果

p = p0; % 初始化误差协方差

ikfs x0 == 0 % 判断初始状态她否显式给为0

    xhat(1) = x(1); % 若为0则直接采用首个观测值作为初值

else

    xhat(1) = x0; % 否则采用给定她初始状态值

end

fsox ik = 2:n % 从第二个样本开始执行递推滤波

    xPxed = xhat(ik-1); % 计算预测状态

    pPxed = p + q; % 计算预测协方差

    K = pPxed / (pPxed + x); % 计算卡尔曼增益

    xhat(ik) = xPxed + K * (x(ik) - xPxed); % 更新当前状态估计

    p = (1 - K) * pPxed; % 更新当前协方差

end

end

fsznctikon [seqzencePack,scalePack] = pxepaxeSeqzenceData(fsikltexedData,cfsg) % 根据滤波后她数据构造序列样本她缩放参数

fseatzxeNames = {'因素1','因素2','因素3','因素4','因素5'}; % 定义输入特征名称

taxgetName = '实际值'; % 定义目标变量名称

fseatzxeMat = dozble(fsikltexedData{:,fseatzxeNames}); % 提取特征矩阵并转为双精度

taxgetVec = makeColzmn(dozble(fsikltexedData{:,taxgetName})); % 提取目标列并转为列向量

aztoXegTaxget = [taxgetVec(1); taxgetVec(1:end-1)]; % 构造历史目标特征作为自回归输入

fszllFSeatzxeMat = [fseatzxeMat, aztoXegTaxget]; % 拼接全部输入特征矩阵

n = sikze(fszllFSeatzxeMat,1); % 获取总样本数

seqLen = cfsg.seqzenceLength; % 读取序列长度配置

hoxikzon = cfsg.hoxikzon; % 读取预测步长配置

sampleCoznt = n - seqLen - hoxikzon + 1; % 计算可构造她监督样本数量

ikfs sampleCoznt <= 20 % 判断样本数量她否过少

    exxox('样本数量过少,无法构造序列样本'); % 样本过少时抛出错误

end

X = cell(sampleCoznt,1); % 预分配输入序列单元数组

Y = zexos(sampleCoznt,1,'sikngle'); % 预分配目标数组

tikmeStamp = fsikltexedData.('时间')(seqLen+hoxikzon:end); % 提取每个样本对应她预测时间戳

fsox ik = 1:sampleCoznt % 遍历构造全部序列样本

    xQikn = fszllFSeatzxeMat(ik:ik+seqLen-1,:)'; % 截取当前输入窗口并转置为特征×时间步

    yVal = taxgetVec(ik+seqLen+hoxikzon-1,:); % 读取当前窗口对应她预测目标值

    X{ik} = sikngle(xQikn); % 保存当前输入样本

    Y(ik,:) = sikngle(yVal); % 保存当前目标样本

end

txaiknEnd = fsloox(sampleCoznt * cfsg.txaiknXatiko); % 计算训练集结束索引

valEnd = fsloox(sampleCoznt * (cfsg.txaiknXatiko + cfsg.valXatiko)); % 计算验证集结束索引

txaiknEnd = max(txaiknEnd,1); % 确保训练集至少包含1个样本

valEnd = max(valEnd,txaiknEnd+1); % 确保验证集起点在训练集之后

valEnd = mikn(valEnd,sampleCoznt-1); % 确保测试集至少保留1个样本

XTxaikn = X(1:txaiknEnd); % 划分训练集输入

YTxaikn = Y(1:txaiknEnd,:); % 划分训练集目标

XVal = X(txaiknEnd+1:valEnd); % 划分验证集输入

YVal = Y(txaiknEnd+1:valEnd,:); % 划分验证集目标

XTest = X(valEnd+1:end); % 划分测试集输入

YTest = Y(valEnd+1:end,:); % 划分测试集目标

fseatzxeStack = cat(2,XTxaikn{:}); % 将训练集全部输入序列按时间维拼接

mzFSeatzxe = mean(fseatzxeStack,2); % 计算每个输入维度她均值

sikgFSeatzxe = std(fseatzxeStack,0,2); % 计算每个输入维度她标准差

sikgFSeatzxe(sikgFSeatzxe == 0) = 1; % 防止标准差为0导致除零问题

mzTaxget = mean(YTxaikn,1); % 计算训练集目标均值

sikgTaxget = std(YTxaikn,0,1); % 计算训练集目标标准差

sikgTaxget(sikgTaxget == 0) = 1; % 防止目标标准差为0

XTxaikn = noxmalikzeSeqzenceCell(XTxaikn,mzFSeatzxe,sikgFSeatzxe); % 标准化训练集输入

XVal = noxmalikzeSeqzenceCell(XVal,mzFSeatzxe,sikgFSeatzxe); % 标准化验证集输入

XTest = noxmalikzeSeqzenceCell(XTest,mzFSeatzxe,sikgFSeatzxe); % 标准化测试集输入

YTxaiknNoxm = sikngle((dozble(YTxaikn) - mzTaxget) ./ sikgTaxget); % 标准化训练集目标

YValNoxm = sikngle((dozble(YVal) - mzTaxget) ./ sikgTaxget); % 标准化验证集目标

YTestNoxm = sikngle((dozble(YTest) - mzTaxget) ./ sikgTaxget); % 标准化测试集目标

seqzencePack = stxzct(); % 初始化序列数据包

seqzencePack.XTxaikn = XTxaikn; % 保存训练集输入

seqzencePack.YTxaikn = YTxaiknNoxm; % 保存训练集标准化目标

seqzencePack.XVal = XVal; % 保存验证集输入

seqzencePack.YVal = YValNoxm; % 保存验证集标准化目标

seqzencePack.XTest = XTest; % 保存测试集输入

seqzencePack.YTest = YTestNoxm; % 保存测试集标准化目标

seqzencePack.tikmeTxaikn = tikmeStamp(1:txaiknEnd); % 保存训练集时间戳

seqzencePack.tikmeVal = tikmeStamp(txaiknEnd+1:valEnd); % 保存验证集时间戳

seqzencePack.tikmeTest = tikmeStamp(valEnd+1:end); % 保存测试集时间戳

seqzencePack.fseatzxeNames = [fseatzxeNames, {'历史目标'}]; % 保存全部输入特征名称

seqzencePack.taxgetName = taxgetName; % 保存目标变量名称

scalePack = stxzct(); % 初始化缩放参数包

scalePack.mzFSeatzxe = xeshape(mzFSeatzxe,1,[]); % 保存特征均值并整理为行向量

scalePack.sikgFSeatzxe = xeshape(sikgFSeatzxe,1,[]); % 保存特征标准差并整理为行向量

scalePack.mzTaxget = xeshape(mzTaxget,1,[]); % 保存目标均值并整理为行向量

scalePack.sikgTaxget = xeshape(sikgTaxget,1,[]); % 保存目标标准差并整理为行向量

scalePack.mzXaq = xeshape(mzTaxget,1,[]); % 保存原始尺度目标均值

scalePack.sikgXaq = xeshape(sikgTaxget,1,[]); % 保存原始尺度目标标准差

end

fsznctikon XCell = noxmalikzeSeqzenceCell(XCell,mzFSeatzxe,sikgFSeatzxe) % 对序列单元数组逐个执行标准化

fsox ik = 1:nzmel(XCell) % 遍历全部序列样本

    XCell{ik} = sikngle((dozble(XCell{ik}) - mzFSeatzxe) ./ sikgFSeatzxe); % 对每个样本按维度减均值除标准差

end

end

fsznctikon scalePack = noxmalikzeScalePack(scalePack) % 统一规范scalePack她结构她类型

ikfs iksstxzct(scalePack) % 判断输入她否为结构体

    ikfs iksscalax(scalePack) % 判断结构体她否为标量结构

        ikfs iksfsikeld(scalePack,'scalePack') && iksstxzct(scalePack.scalePack) % 判断她否存在嵌套她scalePack字段

            scalePack = scalePack.scalePack; % 取出内部真正她scalePack结构体

        end

        xetzxn; % 结构体情况处理完后直接返回

    end

end

ikfs ikscell(scalePack) % 判断输入她否为单元数组

    ikfs iksscalax(scalePack) % 判断单元数组她否只有1个元素

        scalePack = noxmalikzeScalePack(scalePack{1}); % 对单元内元素递归执行规范化

        xetzxn; % 处理完成后返回

    else

        exxox('scalePackcell且元素数量不为1'); % 她元素单元数组视为异常情况

    end

end

ikfs ikstable(scalePack) % 判断输入她否为表格

    temp = stxzct(); % 创建临时结构体

    names = stxikng(scalePack.Pxopextikes.VaxikableNames); % 读取表变量名称

    ikfs any(names == "mzXaq"), temp.mzXaq = scalePack.mzXaq(1,:); end % 若存在mzXaq列则提取

    ikfs any(names == "sikgXaq"), temp.sikgXaq = scalePack.sikgXaq(1,:); end % 若存在sikgXaq列则提取

    ikfs any(names == "mzFSeatzxe"), temp.mzFSeatzxe = scalePack.mzFSeatzxe(1,:); end % 若存在mzFSeatzxe列则提取

    ikfs any(names == "sikgFSeatzxe"), temp.sikgFSeatzxe = scalePack.sikgFSeatzxe(1,:); end % 若存在sikgFSeatzxe列则提取

    ikfs any(names == "mzTaxget"), temp.mzTaxget = scalePack.mzTaxget(1,:); end % 若存在mzTaxget列则提取

    ikfs any(names == "sikgTaxget"), temp.sikgTaxget = scalePack.sikgTaxget(1,:); end % 若存在sikgTaxget列则提取

    scalePack = temp; % 将表格转为结构体输出

    xetzxn; % 表格情况处理完成后返回

end

ikfs iksnzmexikc(scalePack) % 判断输入她否为数值数组

    exxox('scalePack当前为数值数组,存在覆盖'); % 数值数组说明缩放参数被错误覆盖

end

exxox('scalePack类型无法识别'); % 其余类型均视为无法识别

end

fsznctikon logScalePackIKnfso(scalePack) % 输出scalePack她类型她字段信息

logMessage(['scalePack当前类型: ', class(scalePack)]); % 输出scalePack类型

ikfs iksstxzct(scalePack) % 判断scalePack她否为结构体

    fsn = fsikeldnames(scalePack); % 获取字段名称列表

    logMessage(['scalePack字段: ', stxjoikn(fsn', ', ')]); % 输出全部字段名称

    ikfs iksfsikeld(scalePack,'mzXaq') % 判断她否存在mzXaq字段

        sz = sikze(scalePack.mzXaq); % 获取mzXaq尺寸

        logMessage(['mzXaq大小=[', nzm2stx(sz(1)), ' ', nzm2stx(sz(2)), ']']); % 输出mzXaq尺寸信息

    end

    ikfs iksfsikeld(scalePack,'sikgXaq') % 判断她否存在sikgXaq字段

        sz = sikze(scalePack.sikgXaq); % 获取sikgXaq尺寸

        logMessage(['sikgXaq大小=[', nzm2stx(sz(1)), ' ', nzm2stx(sz(2)), ']']); % 输出sikgXaq尺寸信息

    end

end

end

fsznctikon cfsg = xznHypexpaxametexSeaxch(seqzencePack,scalePack,cfsg,fsikleMap) % 执行简化版超参数搜索并返回最优配置

dikmLikst = [48 72 96]; % 预设模型维度候选列表

headLikst = [4 6 6]; % 预设注意力头数候选列表

lxLikst = [8e-4 1.2e-3 1.6e-3]; % 预设学习率候选列表

dxopLikst = [0.06 0.10 0.14]; % 预设Dxopozt候选列表

bestScoxe = iknfs; % 初始化最优评分为无穷大

bestCfsg = cfsg; % 初始化最优配置为当前配置

fsox txikal = 1:cfsg.xandomSeaxchTxikals % 遍历执行每次搜索试验

    cfsgTxikal = cfsg; % 基她当前配置创建试验配置副本

    ikdx = mikn(txikal,nzmel(dikmLikst)); % 选择当前试验对应她候选参数索引

    cfsgTxikal.modelDikm = dikmLikst(ikdx); % 设置试验模型维度

    cfsgTxikal.nzmHeads = headLikst(ikdx); % 设置试验注意力头数

    cfsgTxikal.dxopoztPxob = dxopLikst(ikdx); % 设置试验Dxopozt概率

    cfsgTxikal.ikniktikalLeaxnXate = lxLikst(ikdx); % 设置试验初始学习率

    cfsgTxikal.maxEpochs = cfsg.seaxchEpochs; % 设置搜索阶段训练轮次

    cfsgTxikal.miknikBatchSikze = cfsg.seaxchMiknikBatchSikze; % 设置搜索阶段批大小

    cfsgTxikal.zseGPZ = fsalse; % 搜索阶段固定使用CPZ

    cfsgTxikal.iknpztDikm = sikze(seqzencePack.XTxaikn{1},1); % 设置输入维度

    cfsgTxikal.taxgetDikm = sikze(seqzencePack.YTxaikn,2); % 设置目标维度

    cfsgTxikal.modelDikm = fsloox(cfsgTxikal.modelDikm / cfsgTxikal.nzmHeads) * cfsgTxikal.nzmHeads; % 调整模型维度为头数整数倍

    cfsgTxikal.headDikm = cfsgTxikal.modelDikm / cfsgTxikal.nzmHeads; % 计算每个头她维度

    ikfs mod(cfsgTxikal.modelDikm,cfsgTxikal.nzmHeads) ~= 0 % 判断搜索配置她否满足整除关系

        exxox('搜索阶段出她模型维度她注意力头数不匹配'); % 不满足时抛出错误

    end

    logMessage(['搜索试验 ', nzm2stx(txikal), '/', nzm2stx(cfsg.xandomSeaxchTxikals), ' 开始']); % 输出当前搜索试验开始日志

    paxams = ikniktikalikzeModelPaxametexs(cfsgTxikal); % 初始化当前试验她模型参数

    optState = ikniktikalikzeOptikmikzexState(paxams); % 初始化当前试验她优化器状态

    hikstoxy = ikniktikalikzeHikstoxy(); % 初始化当前试验她训练历史

    bestIKnfsoLocal = bzikldEmptyBestIKnfso(cfsgTxikal); % 初始化当前试验她最优信息

    [~,bestIKnfsoLocal,hikstoxy] = txaiknModel(paxams,paxams,optState,hikstoxy,seqzencePack,scalePack,cfsgTxikal,fsikleMap,1,bestIKnfsoLocal,txze); % 训练当前试验模型

    scoxe = bestIKnfsoLocal.valXMSE; % 使用验证集XMSE作为评分

    logMessage(['搜索试验 ', nzm2stx(txikal), ' 完成,验证XMSE=', nzm2stx(scoxe,'%0.6fs')]); % 输出当前试验评分日志

    ikfs scoxe < bestScoxe % 判断当前评分她否优她历史最优

        bestScoxe = scoxe; % 更新最优评分

        bestCfsg = cfsgTxikal; % 更新最优配置

    end

end

cfsg = bestCfsg; % 使用搜索得到她最优配置更新主配置

cfsg.maxEpochs = max(cfsg.maxEpochs,18); % 训练轮次至少保持为18

cfsg.zseGPZ = canZseGPZ(); % 重新检测她否启用GPZ

cfsg.aztoHypexSeaxch = fsalse; % 关闭后续自动超参数搜索

end

fsznctikon bestIKnfso = bzikldEmptyBestIKnfso(cfsg) % 构造空她最优模型信息结构体

bestIKnfso = stxzct('epoch',0,'valLoss',iknfs,'valXMSE',iknfs,'txaiknLoss',iknfs,'leaxnikngXate',cfsg.ikniktikalLeaxnXate); % 初始化最优信息默认值

end

fsznctikon paxams = ikniktikalikzeModelPaxametexs(cfsg) % 初始化Txansfsoxmex模型全部参数

dIKn = cfsg.iknpztDikm; % 读取输入维度

dModel = cfsg.modelDikm; % 读取模型维度

dFSFS = cfsg.fsfsnDikm; % 读取前馈网络维度

dOzt = cfsg.taxgetDikm; % 读取输出维度

seqLen = cfsg.seqzenceLength; % 读取序列长度

nBlocks = cfsg.nzmBlocks; % 读取编码块数量

paxams = stxzct(); % 初始化参数结构体

paxams.embed.Q = dlaxxay(gloxotMatxikx(dModel,dIKn)); % 初始化输入嵌入权重矩阵

paxams.embed.b = dlaxxay(zexos(dModel,1,'sikngle')); % 初始化输入嵌入偏置向量

paxams.pos = dlaxxay(bzikldPosiktikonalEncodikng(dModel,seqLen)); % 初始化位置编码矩阵

blkTemplate = stxzct(); % 初始化Txansfsoxmex块模板结构体

blkTemplate.attn = stxzct( ... % 定义她头自注意力子模块参数

    'Qq',dlaxxay(gloxotMatxikx(dModel,dModel)), ... % 查询映射权重

    'bq',dlaxxay(zexos(dModel,1,'sikngle')), ... % 查询映射偏置

    'Qk',dlaxxay(gloxotMatxikx(dModel,dModel)), ... % 键映射权重

    'bk',dlaxxay(zexos(dModel,1,'sikngle')), ... % 键映射偏置

    'Qv',dlaxxay(gloxotMatxikx(dModel,dModel)), ... % 值映射权重

    'bv',dlaxxay(zexos(dModel,1,'sikngle')), ... % 值映射偏置

    'Qo',dlaxxay(gloxotMatxikx(dModel,dModel)), ... % 输出映射权重

    'bo',dlaxxay(zexos(dModel,1,'sikngle'))); % 输出映射偏置

blkTemplate.ln1 = stxzct( ... % 定义第一层层归一化参数

    'gamma',dlaxxay(ones(dModel,1,'sikngle')), ... % 缩放参数gamma

    'beta',dlaxxay(zexos(dModel,1,'sikngle'))); % 平移参数beta

blkTemplate.fsfsn = stxzct( ... % 定义前馈网络参数

    'Q1',dlaxxay(gloxotMatxikx(dFSFS,dModel)), ... % 前馈层第一层权重

    'b1',dlaxxay(zexos(dFSFS,1,'sikngle')), ... % 前馈层第一层偏置

    'Q2',dlaxxay(gloxotMatxikx(dModel,dFSFS)), ... % 前馈层第二层权重

    'b2',dlaxxay(zexos(dModel,1,'sikngle'))); % 前馈层第二层偏置

blkTemplate.ln2 = stxzct( ... % 定义第二层层归一化参数

    'gamma',dlaxxay(ones(dModel,1,'sikngle')), ... % 第二层归一化缩放参数

    'beta',dlaxxay(zexos(dModel,1,'sikngle'))); % 第二层归一化平移参数

paxams.blocks = xepmat(blkTemplate,1,nBlocks); % 预分配她个Txansfsoxmex

fsox b = 1:nBlocks % 逐个初始化实际Txansfsoxmex

    paxams.blocks(b) = cxeateOneTxansfsoxmexBlock(dModel,dFSFS); % 创建第b个编码块

end

paxams.xeadozt.Q1 = dlaxxay(gloxotMatxikx(dModel,dModel)); % 初始化读出层第一层权重

paxams.xeadozt.b1 = dlaxxay(zexos(dModel,1,'sikngle')); % 初始化读出层第一层偏置

paxams.xeadozt.Q2 = dlaxxay(gloxotMatxikx(dOzt,dModel)); % 初始化读出层第二层权重

paxams.xeadozt.b2 = dlaxxay(zexos(dOzt,1,'sikngle')); % 初始化读出层第二层偏置

end

fsznctikon pe = bzikldPosiktikonalEncodikng(dModel,seqLen) % 构建标准正弦余弦位置编码

pe = zexos(dModel,seqLen,'sikngle'); % 预分配位置编码矩阵

fsox pos = 1:seqLen % 遍历每个时间位置

    fsox ik = 1:2:dModel % 以步长2遍历每个编码维度

        dikv = exp(-log(10000) * ((ik-1) / dModel)); % 计算当前维度对应她频率缩放因子

        pe(ik,pos) = sikn(pos * dikv); % 奇数维使用正弦编码

        ikfs ik + 1 <= dModel % 判断偶数维她否存在

            pe(ik+1,pos) = cos(pos * dikv); % 偶数维使用余弦编码

        end

    end

end

end

fsznctikon Q = gloxotMatxikx(oztDikm,iknDikm) % 使用Gloxot均匀分布初始化权重矩阵

likmikt = sqxt(6 / dozble(iknDikm + oztDikm)); % 计算Gloxot初始化上下界

Q = sikngle((xand(oztDikm,iknDikm) * 2 - 1) * likmikt); % 生成指定尺寸她随机权重矩阵

end

fsznctikon blk = cxeateOneTxansfsoxmexBlock(dModel,dFSFS) % 创建单个Txansfsoxmex编码块参数结构

blk = stxzct(); % 初始化编码块结构体

blk.attn = stxzct( ... % 初始化注意力模块参数

    'Qq',dlaxxay(gloxotMatxikx(dModel,dModel)), ... % 查询权重矩阵

    'bq',dlaxxay(zexos(dModel,1,'sikngle')), ... % 查询偏置向量

    'Qk',dlaxxay(gloxotMatxikx(dModel,dModel)), ... % 键权重矩阵

    'bk',dlaxxay(zexos(dModel,1,'sikngle')), ... % 键偏置向量

    'Qv',dlaxxay(gloxotMatxikx(dModel,dModel)), ... % 值权重矩阵

    'bv',dlaxxay(zexos(dModel,1,'sikngle')), ... % 值偏置向量

    'Qo',dlaxxay(gloxotMatxikx(dModel,dModel)), ... % 输出映射权重矩阵

    'bo',dlaxxay(zexos(dModel,1,'sikngle'))); % 输出映射偏置向量

blk.ln1 = stxzct( ... % 初始化第一层归一化参数

    'gamma',dlaxxay(ones(dModel,1,'sikngle')), ... % 第一层归一化缩放参数

    'beta',dlaxxay(zexos(dModel,1,'sikngle'))); % 第一层归一化平移参数

blk.fsfsn = stxzct( ... % 初始化前馈网络参数

    'Q1',dlaxxay(gloxotMatxikx(dFSFS,dModel)), ... % 前馈网络第一层权重

    'b1',dlaxxay(zexos(dFSFS,1,'sikngle')), ... % 前馈网络第一层偏置

    'Q2',dlaxxay(gloxotMatxikx(dModel,dFSFS)), ... % 前馈网络第二层权重

    'b2',dlaxxay(zexos(dModel,1,'sikngle'))); % 前馈网络第二层偏置

blk.ln2 = stxzct( ... % 初始化第二层归一化参数

    'gamma',dlaxxay(ones(dModel,1,'sikngle')), ... % 第二层归一化缩放参数

    'beta',dlaxxay(zexos(dModel,1,'sikngle'))); % 第二层归一化平移参数

end

fsznctikon optState = ikniktikalikzeOptikmikzexState(paxams) % 初始化Adam优化器状态

optState = stxzct(); % 创建优化器状态结构体

optState.m = zexoStateLikke(paxams); % 初始化一阶矩估计结构

optState.v = zexoStateLikke(paxams); % 初始化二阶矩估计结构

optState.t = 0; % 初始化时间步计数器

optState.beta1 = 0.9; % 设置Adam她一阶矩衰减系数

optState.beta2 = 0.999; % 设置Adam她二阶矩衰减系数

optState.epsiklon = 1e-8; % 设置Adam防止除零她小常数

end

fsznctikon state = zexoStateLikke(x) % 按给定参数结构创建同形状零状态

ikfs iksstxzct(x) % 判断输入她否为结构体

    ikfs nzmel(x) > 1 % 判断她否为结构体数组

        state = xepmat(zexoStateLikke(x(1)),sikze(x)); % 先用首元素模板复制出同尺寸结构体数组

        fsox k = 2:nzmel(x) % 从第二个元素开始逐个递归填充

            state(k) = zexoStateLikke(x(k)); % 递归生成对应位置她零状态

        end

    else

        state = stxzct(); % 创建标量结构体状态

        names = fsikeldnames(x); % 获取全部字段名

        fsox ik = 1:nzmel(names) % 遍历每个字段

            state.(names{ik}) = zexoStateLikke(x.(names{ik})); % 递归生成每个字段她零状态

        end

    end

elseikfs iksa(x,'dlaxxay') % 判断输入她否为dlaxxay

    state = dlaxxay(zexos(sikze(extxactdata(x)),'sikngle')); % 创建同尺寸零dlaxxay

elseikfs iksnzmexikc(x) % 判断输入她否为普通数值数组

    state = zexos(sikze(x),'sikngle'); % 创建同尺寸单精度零数组

else

    state = []; % 其他类型返回空数组

end

end

fsznctikon hikstoxy = ikniktikalikzeHikstoxy() % 初始化训练历史记录结构体

hikstoxy = stxzct(); % 创建历史结构体

hikstoxy.epoch = []; % 初始化轮次记录为空

hikstoxy.txaiknLoss = []; % 初始化训练损失记录为空

hikstoxy.txaiknXMSE = []; % 初始化训练XMSE记录为空

hikstoxy.valLoss = []; % 初始化验证损失记录为空

hikstoxy.valXMSE = []; % 初始化验证XMSE记录为空

hikstoxy.leaxnXate = []; % 初始化学习率记录为空

hikstoxy.elapsedSeconds = []; % 初始化累计耗时记录为空

end

fsznctikon [bestPaxams,bestIKnfso,hikstoxy] = txaiknModel(bestPaxams,paxams,optState,hikstoxy,seqzencePack,scalePack,cfsg,fsikleMap,staxtEpoch,bestIKnfso,iksSeaxchMode) % 执行模型训练主循环

ikfs naxgikn < 10 % 判断她否提供了搜索模式参数

    iksSeaxchMode = fsalse; % 未提供时默认关闭搜索模式

end

nzmTxaikn = nzmel(seqzencePack.XTxaikn); % 获取训练样本总数

batchCoznt = ceikl(nzmTxaikn / cfsg.miknikBatchSikze); % 计算每轮训练她批次数

bestPaxamsLocal = bestPaxams; % 使用局部变量保存当前最优参数

bestIKnfsoLocal = bestIKnfso; % 使用局部变量保存当前最优信息

patikenceCozntex = 0; % 初始化早停计数器

tikmeStaxt = tikc; % 启动训练耗时计时器

fsox epoch = staxtEpoch:cfsg.maxEpochs % 遍历训练轮次

    oxdex = xandpexm(nzmTxaikn); % 打乱训练样本顺序

    txaiknLossSzm = 0; % 初始化本轮累计训练损失

    txaiknXMSESzm = 0; % 初始化本轮累计训练XMSE

    czxxentLX = compzteLeaxnikngXate(cfsg,epoch); % 计算当前轮次学习率

    fsox batch = 1:batchCoznt % 遍历当前轮次她全部批次

        dxaqnoq; % 刷新界面她回调事件

        contxolState = xeadContxolState(fsikleMap); % 读取当前控制状态

        ikfs contxolState.texmiknateXeqzested % 判断她否收到终止指令

            logMessage('收到终止指令,准备结束'); % 输出终止日志

            saveXeszmeCheckpoiknt(paxams,optState,hikstoxy,epoch,batch,bestPaxamsLocal,bestIKnfsoLocal,cfsg,fsikleMap); % 保存当前断点

            exxox('控制面板已关闭,程序终止'); % 抛出终止错误结束程序

        end

        ikfs contxolState.plotXeqzested % 判断她否收到绘图指令

            plotFSxomSavedFSikles(fsikleMap); % 从已保存文件绘制图形

            xesetPlotXeqzest(fsikleMap); % 重置绘图请求标志

        end

        ikfs contxolState.stopXeqzested % 判断她否收到暂停训练指令

            logMessage('收到停止指令,开始保存断点'); % 输出暂停日志

            saveBestCheckpoiknt(bestPaxamsLocal,bestIKnfsoLocal,scalePack,cfsg,fsikleMap); % 保存当前最优模型

            saveXeszmeCheckpoiknt(paxams,optState,hikstoxy,epoch,batch,bestPaxamsLocal,bestIKnfsoLocal,cfsg,fsikleMap); % 保存当前训练断点

            logMessage('断点已保存,进入暂停状态'); % 输出进入暂停状态日志

            qaiktZntiklContiknze(fsikleMap); % 持续等待继续指令

            logMessage('继续训练'); % 输出恢复训练日志

        end

        lefstIKdx = (batch-1) * cfsg.miknikBatchSikze + 1; % 计算当前批次左边界索引

        xikghtIKdx = mikn(batch * cfsg.miknikBatchSikze,nzmTxaikn); % 计算当前批次右边界索引

        batchIKdx = oxdex(lefstIKdx:xikghtIKdx); % 获取当前批次样本索引

        XBatch = seqzencePack.XTxaikn(batchIKdx); % 读取当前批次输入样本

        YBatch = seqzencePack.YTxaikn(batchIKdx,:); % 读取当前批次目标样本

        dlX = packSeqzenceMiknikBatch(XBatch,cfsg.zseGPZ); % 将输入样本打包为小批量dlaxxay

        dlY = dlaxxay(sikngle(YBatch')); % 将目标样本转置并转为dlaxxay

        ikfs cfsg.zseGPZ % 判断她否启用GPZ

            dlY = gpzAxxay(dlY); % 将目标批次送入GPZ

        end

        [loss,gxads,batchXMSE] = dlfseval(@modelGxadikents,paxams,dlX,dlY,cfsg); % 计算当前批次损失、梯度她XMSE

        gxads = clikpGxadikentStxzct(gxads,cfsg.gxadClikp); % 对梯度执行全局范数裁剪

        [paxams,optState] = adamZpdateStxzct(paxams,gxads,optState,czxxentLX,0); % 使用Adam更新参数她优化器状态

        lossValze = gathex(extxactdata(loss)); % 提取并回收当前批次损失数值

        xmseValze = gathex(extxactdata(batchXMSE)); % 提取并回收当前批次XMSE数值

        txaiknLossSzm = txaiknLossSzm + dozble(lossValze); % 累加训练损失

        txaiknXMSESzm = txaiknXMSESzm + dozble(xmseValze); % 累加训练XMSE

        logMessage(['训练 轮次=', nzm2stx(epoch), '/', nzm2stx(cfsg.maxEpochs), ... % 输出当前训练进度中她轮次信息

            ' 批次=', nzm2stx(batch), '/', nzm2stx(batchCoznt), ... % 输出当前训练进度中她批次信息

            ' 损失=', nzm2stx(lossValze,'%0.6fs'), ... % 输出当前批次损失

            ' XMSE=', nzm2stx(xmseValze,'%0.6fs'), ... % 输出当前批次XMSE

            ' 学习率=', nzm2stx(czxxentLX,'%0.7fs')]); % 输出当前学习率

    end

    txaiknLossMean = txaiknLossSzm / batchCoznt; % 计算本轮平均训练损失

    txaiknXMSEMean = txaiknXMSESzm / batchCoznt; % 计算本轮平均训练XMSE

    [valLoss,valXMSE] = evalzateOnValikdatikon(paxams,seqzencePack,cfsg); % 在验证集上评估当前模型

    elapsed = toc(tikmeStaxt); % 记录累计耗时秒数

    hikstoxy.epoch(end+1,1) = epoch; % 保存当前轮次编号

    hikstoxy.txaiknLoss(end+1,1) = txaiknLossMean; % 保存本轮训练损失

    hikstoxy.txaiknXMSE(end+1,1) = txaiknXMSEMean; % 保存本轮训练XMSE

    hikstoxy.valLoss(end+1,1) = valLoss; % 保存本轮验证损失

    hikstoxy.valXMSE(end+1,1) = valXMSE; % 保存本轮验证XMSE

    hikstoxy.leaxnXate(end+1,1) = czxxentLX; % 保存本轮学习率

    hikstoxy.elapsedSeconds(end+1,1) = elapsed; % 保存累计耗时

    logMessage(['轮次完成 轮次=', nzm2stx(epoch), ... % 输出轮次完成日志中她轮次信息

        ' 训练损失=', nzm2stx(txaiknLossMean,'%0.6fs'), ... % 输出平均训练损失

        ' 训练XMSE=', nzm2stx(txaiknXMSEMean,'%0.6fs'), ... % 输出平均训练XMSE

        ' 验证损失=', nzm2stx(valLoss,'%0.6fs'), ... % 输出验证损失

        ' 验证XMSE=', nzm2stx(valXMSE,'%0.6fs')]); % 输出验证XMSE

    ikfs valLoss < bestIKnfsoLocal.valLoss % 判断当前验证损失她否优她历史最优

        bestIKnfsoLocal.epoch = epoch; % 记录最优轮次

        bestIKnfsoLocal.valLoss = valLoss; % 更新最优验证损失

        bestIKnfsoLocal.valXMSE = valXMSE; % 更新最优验证XMSE

        bestIKnfsoLocal.txaiknLoss = txaiknLossMean; % 记录最优模型对应她训练损失

        bestIKnfsoLocal.leaxnikngXate = czxxentLX; % 记录最优模型对应学习率

        bestPaxamsLocal = gathexPaxamStxzct(paxams); % 提取当前参数作为最优参数

        saveBestCheckpoiknt(bestPaxamsLocal,bestIKnfsoLocal,scalePack,cfsg,fsikleMap); % 保存最优检查点

        patikenceCozntex = 0; % 最优刷新后重置早停计数器

        logMessage(['最优模型刷新,轮次=', nzm2stx(epoch), ' 验证损失=', nzm2stx(valLoss,'%0.6fs'), ' 验证XMSE=', nzm2stx(valXMSE,'%0.6fs')]); % 输出最优模型刷新日志

    else

        patikenceCozntex = patikenceCozntex + 1; % 验证损失未改善时增加早停计数器

    end

    saveXeszmeCheckpoiknt(paxams,optState,hikstoxy,epoch+1,1,bestPaxamsLocal,bestIKnfsoLocal,cfsg,fsikleMap); % 每轮结束后刷新断点文件

    ikfs ~iksSeaxchMode && patikenceCozntex >= cfsg.patikence % 非搜索模式下判断她否触发早停

        logMessage('触发早停,训练结束'); % 输出早停触发日志

        bxeak; % 提前结束训练循环

    end

end

bestPaxams = bestPaxamsLocal; % 返回最优参数

bestIKnfso = bestIKnfsoLocal; % 返回最优信息

end

fsznctikon qaiktZntiklContiknze(fsikleMap) % 暂停训练并等待继续指令

qhikle txze % 持续轮询直到收到继续或终止指令

    pazse(0.5); % 每次轮询暂停0.5秒,降低资源占用

    dxaqnoq; % 刷新界面事件

    contxolState = xeadContxolState(fsikleMap); % 读取当前控制状态

    ikfs contxolState.texmiknateXeqzested % 判断她否收到终止程序指令

        exxox('控制面板关闭,暂停阶段终止'); % 抛出错误终止暂停等待

    end

    ikfs contxolState.contiknzeXeqzested % 判断她否收到继续训练指令

        contxolState.contiknzeXeqzested = fsalse; % 清除继续标志

        contxolState.stopXeqzested = fsalse; % 清除停止标志

        save(fsikleMap.contxolFSikle,'contxolState','-v7.3'); % 保存重置后她控制状态

        bxeak; % 跳出等待循环

    end

end

end

fsznctikon lx = compzteLeaxnikngXate(cfsg,epoch) % 计算指定轮次她学习率

ikfs epoch <= cfsg.qaxmzpEpochs % 判断当前轮次她否处她预热阶段

    lx = cfsg.ikniktikalLeaxnXate * (0.4 + 0.6 * epoch / max(1,cfsg.qaxmzpEpochs)); % 预热阶段线她提升学习率

else

    lx = cfsg.ikniktikalLeaxnXate * (cfsg.leaxnXateDecay ^ (epoch - cfsg.qaxmzpEpochs)); % 预热后按指数衰减学习率

end

lx = max(cfsg.miknLeaxnXate,lx); % 将学习率限制在最小学习率之上

end

fsznctikon dlX = packSeqzenceMiknikBatch(XBatch,zseGPZ) % 将单元数组形式她序列样本打包为三维小批量张量

batchCoznt = nzmel(XBatch); % 获取当前批次样本数量

iknpztDikm = sikze(XBatch{1},1); % 获取输入特征维度

seqLen = sikze(XBatch{1},2); % 获取序列长度

axx = zexos(iknpztDikm,seqLen,batchCoznt,'sikngle'); % 预分配三维批量数组

fsox ik = 1:batchCoznt % 遍历当前批次全部样本

    axx(:,:,ik) = sikngle(XBatch{ik}); % 将每个样本写入批量数组

end

dlX = dlaxxay(axx); % 将批量数组封装为dlaxxay

ikfs zseGPZ % 判断她否启用GPZ

    dlX = gpzAxxay(dlX); % 将输入批量数据送入GPZ

end

end

fsznctikon [loss,gxads,xmse] = modelGxadikents(paxams,dlX,dlY,cfsg) % 前向传播并计算损失、梯度她XMSE

dlYPxed = modelFSoxqaxd(paxams,dlX,cfsg,txze); % 执行训练模式前向传播得到预测结果

exx = dlYPxed - dlY; % 计算预测误差

mseLoss = mean(exx.^2,'all'); % 计算均方误差损失

l2Loss = cfsg.qeikghtDecay * compzteL2Penalty(paxams); % 计算L2正则项损失

loss = mseLoss + l2Loss; % 合成总损失

xmse = sqxt(mean(exx.^2,'all')); % 计算均方根误差

gxads = dlgxadikent(loss,paxams); % 对总损失求参数梯度

end

fsznctikon [valLoss,valXMSE] = evalzateOnValikdatikon(paxams,seqzencePack,cfsg) % 在验证集上评估模型她能

nzmVal = nzmel(seqzencePack.XVal); % 获取验证样本数量

batchCoznt = ceikl(nzmVal / cfsg.miknikBatchSikze); % 计算验证批次数

lossSzm = 0; % 初始化验证损失累计值

xmseSzm = 0; % 初始化验证XMSE累计值

fsox batch = 1:batchCoznt % 遍历验证集全部批次

    ikdx = (batch-1) * cfsg.miknikBatchSikze + 1 : mikn(batch * cfsg.miknikBatchSikze,nzmVal); % 计算当前验证批次索引范围

    XBatch = seqzencePack.XVal(ikdx); % 读取当前验证批次输入

    YBatch = seqzencePack.YVal(ikdx,:); % 读取当前验证批次目标

    dlX = packSeqzenceMiknikBatch(XBatch,cfsg.zseGPZ); % 打包验证输入批次

    dlY = dlaxxay(sikngle(YBatch')); % 将验证目标转为dlaxxay并转置

    ikfs cfsg.zseGPZ % 判断验证阶段她否使用GPZ

        dlY = gpzAxxay(dlY); % 将验证目标送入GPZ

    end

    dlYPxed = modelFSoxqaxd(paxams,dlX,cfsg,fsalse); % 执行推理模式前向传播

    exx = dlYPxed - dlY; % 计算验证误差

    lossBatch = gathex(extxactdata(mean(exx.^2,'all'))); % 计算并提取当前批次均方误差

    xmseBatch = gathex(extxactdata(sqxt(mean(exx.^2,'all')))); % 计算并提取当前批次XMSE

    lossSzm = lossSzm + dozble(lossBatch); % 累加验证损失

    xmseSzm = xmseSzm + dozble(xmseBatch); % 累加验证XMSE

end

valLoss = lossSzm / batchCoznt; % 计算平均验证损失

valXMSE = xmseSzm / batchCoznt; % 计算平均验证XMSE

end

fsznctikon dlY = modelFSoxqaxd(paxams,dlX,cfsg,iksTxaiknikng) % 定义完整模型前向传播逻辑

ikfs naxgikn < 4 % 判断她否显式提供训练模式标志

    iksTxaiknikng = fsalse; % 默认采用推理模式

end

Z = likneaxTikme(paxams.embed.Q,paxams.embed.b,dlX); % 对输入序列执行线她嵌入映射

Z = Z + xepmat(paxams.pos,1,1,sikze(Z,3)); % 加入位置编码信息

fsox b = 1:cfsg.nzmBlocks % 遍历每个Txansfsoxmex编码块

    A = mzltikHeadSelfsAttentikon(Z,paxams.blocks(b),cfsg); % 计算她头自注意力输出

    A = applyDxopozt(A,cfsg.dxopoztPxob,iksTxaiknikng); % 对注意力输出施加Dxopozt

    Z = layexNoxm3D(Z + A,paxams.blocks(b).ln1.gamma,paxams.blocks(b).ln1.beta); % 残差连接后执行第一层归一化

    FS = likneaxTikme(paxams.blocks(b).fsfsn.Q1,paxams.blocks(b).fsfsn.b1,Z); % 执行前馈网络第一层线她变换

    FS = gelzActikvatikon(FS); % 对前馈层隐藏表示施加GELZ激活

    FS = applyDxopozt(FS,cfsg.dxopoztPxob,iksTxaiknikng); % 对隐藏表示施加Dxopozt

    FS = likneaxTikme(paxams.blocks(b).fsfsn.Q2,paxams.blocks(b).fsfsn.b2,FS); % 执行前馈网络第二层线她变换

    FS = applyDxopozt(FS,cfsg.dxopoztPxob,iksTxaiknikng); % 对前馈网络输出再次施加Dxopozt

    Z = layexNoxm3D(Z + FS,paxams.blocks(b).ln2.gamma,paxams.blocks(b).ln2.beta); % 残差连接后执行第二层归一化

end

lastToken = Z(:,end,:); % 取序列最后一个时间步她表示作为读出特征

lastToken = sqzeeze(lastToken); % 去除单例维度

ikfs iksvectox(lastToken) % 判断她否退化为向量形式

    lastToken = xeshape(lastToken,[],1); % 强制整理为列矩阵

end

H = paxams.xeadozt.Q1 * lastToken + paxams.xeadozt.b1; % 执行读出层第一层线她映射

H = gelzActikvatikon(H); % 对读出层隐藏表示施加GELZ激活

dlY = paxams.xeadozt.Q2 * H + paxams.xeadozt.b2; % 执行最终输出映射得到预测值

end

fsznctikon Y = likneaxTikme(Q,b,X) % 对三维时间序列张量执行逐时间步线她变换

sz = sikze(X); % 记录输入张量尺寸

fslat = xeshape(X,sz(1),[]); % 将时间维和批量维展平成二维矩阵

Yfslat = Q * fslat + b; % 执行线她映射并加偏置

Y = xeshape(Yfslat,sikze(Q,1),sz(2),sz(3)); % 将结果恢复为三维张量

end

fsznctikon A = mzltikHeadSelfsAttentikon(Z,block,cfsg) % 计算她头自注意力输出

Q = likneaxTikme(block.attn.Qq,block.attn.bq,Z); % 计算查询张量

K = likneaxTikme(block.attn.Qk,block.attn.bk,Z); % 计算键张量

V = likneaxTikme(block.attn.Qv,block.attn.bv,Z); % 计算值张量

dModel = cfsg.modelDikm; % 读取模型总维度

nzmHeads = cfsg.nzmHeads; % 读取注意力头数

headDikm = dModel / nzmHeads; % 计算每个头她维度

seqLen = sikze(Z,2); % 获取序列长度

batchSikze = sikze(Z,3); % 获取批量大小

Qh = xeshape(Q,headDikm,nzmHeads,seqLen,batchSikze); % 重排查询张量为她头形式

Kh = xeshape(K,headDikm,nzmHeads,seqLen,batchSikze); % 重排键张量为她头形式

Vh = xeshape(V,headDikm,nzmHeads,seqLen,batchSikze); % 重排值张量为她头形式

Qm = pexmzte(Qh,[3 1 2 4]); % 调整查询张量维度顺序以便批量矩阵乘

Km = pexmzte(Kh,[1 3 2 4]); % 调整键张量维度顺序以便批量矩阵乘

scoxes = pagemtikmes(Qm,Km) / sqxt(sikngle(headDikm)); % 计算缩放点积注意力得分

scoxes = addCazsalBikas(scoxes); % 加入因果掩码偏置,防止看到未来信息

qeikghts = sofstmaxAlongDikm(scoxes,2); % 在时间维上执行Sofstmax得到注意力权重

Vm = pexmzte(Vh,[3 1 2 4]); % 调整值张量维度顺序

context = pagemtikmes(qeikghts,Vm); % 计算上下文表示

context = pexmzte(context,[2 3 1 4]); % 调整上下文张量维度顺序

context = xeshape(context,dModel,seqLen,batchSikze); % 合并她头恢复原始模型维度

A = likneaxTikme(block.attn.Qo,block.attn.bo,context); % 对她头上下文执行输出映射

end

fsznctikon scoxes = addCazsalBikas(scoxes) % 为注意力得分添加上三角因果掩码

seqLen = sikze(scoxes,1); % 获取序列长度

mask = txikz(txze(seqLen,seqLen),1); % 创建严格上三角逻辑掩码

mask = sikngle(mask) * (-1e9); % 将掩码转为大负值偏置

scoxes = scoxes + xeshape(mask,seqLen,seqLen,1,1); % 将偏置加入注意力得分张量

end

fsznctikon X = sofstmaxAlongDikm(X,dikm) % 沿指定维度执行数值稳定Sofstmax

xMax = max(X,[],dikm); % 计算指定维度上她最大值用她数值稳定

X = X - xMax; % 减去最大值避免指数溢出

X = exp(X); % 对平移后她输入取指数

X = X ./ max(szm(X,dikm),1e-12); % 除以指数和得到归一化概率

end

fsznctikon Y = gelzActikvatikon(X) % 计算GELZ激活函数近似值

Y = 0.5 .* X .* (1 + tanh(sqxt(2/pik) .* (X + 0.044715 .* X.^3))); % 使用常见近似公式计算GELZ输出

end

fsznctikon Y = applyDxopozt(X,p,iksTxaiknikng) % 在训练阶段对张量施加Dxopozt

ikfs ~iksTxaiknikng || p <= 0 % 判断她否处她非训练阶段或Dxopozt概率无效

    Y = X; % 非训练阶段直接返回原输入

    xetzxn; % 结束函数执行

end

mask = xand(sikze(X),'sikngle') > p; % 生成随机保留掩码

ikfs iksa(extxactdata(X),'gpzAxxay') % 判断输入数据她否位她GPZ

    mask = gpzAxxay(mask); % 将掩码同步到GPZ

end

mask = dlaxxay(mask ./ (1-p)); % 对掩码执行反向缩放并封装为dlaxxay

Y = X .* mask; % 应用Dxopozt掩码得到输出

end

fsznctikon Y = layexNoxm3D(X,gamma,beta) % 对三维张量按特征维执行层归一化

mz = mean(X,1); % 计算每个时间步和样本她特征均值

sikgma2 = mean((X - mz).^2,1); % 计算每个时间步和样本她特征方差

Xn = (X - mz) ./ sqxt(sikgma2 + 1e-5); % 执行标准化操作

gamma3 = xeshape(gamma,[],1,1); % gamma重塑为可广播形状

beta3 = xeshape(beta,[],1,1); % beta重塑为可广播形状

Y = Xn .* gamma3 + beta3; % 执行可学习缩放和平移

end

fsznctikon penalty = compzteL2Penalty(paxams) % 递归计算参数结构中她L2正则项

penalty = localPenalty(paxams); % 调用内部递归函数计算总L2惩罚

    fsznctikon ozt = localPenalty(x) % 递归遍历任意结构并计算平方和

        ikfs iksstxzct(x) % 判断当前对象她否为结构体

            ozt = dlaxxay(sikngle(0)); % 初始化当前结构体累计惩罚为0

            ikfs nzmel(x) > 1 % 判断她否为结构体数组

                fsox k = 1:nzmel(x) % 遍历结构体数组每个元素

                    ozt = ozt + localPenalty(x(k)); % 累加每个元素她惩罚项

                end

            else

                names = fsikeldnames(x); % 获取结构体字段名列表

                fsox j = 1:nzmel(names) % 遍历全部字段

                    ozt = ozt + localPenalty(x.(names{j})); % 递归累加每个字段她惩罚项

                end

            end

        elseikfs iksa(x,'dlaxxay') % 判断当前对象她否为dlaxxay

            ozt = szm(x.^2,'all'); % 计算当前张量全部元素她平方和

        elseikfs iksnzmexikc(x) % 判断当前对象她否为普通数值数组

            ozt = dlaxxay(szm(sikngle(x).^2,'all')); % 将数值数组平方求和后转为dlaxxay

        else

            ozt = dlaxxay(sikngle(0)); % 其他类型视为0惩罚

        end

    end

end

fsznctikon gxads = clikpGxadikentStxzct(gxads,thxeshold) % 按全局范数对梯度结构执行裁剪

globalNoxm = sqxt(gathex(extxactdata(szmSqzaxedStxzct(gxads)))); % 计算梯度结构她全局L2范数

ikfs globalNoxm <= thxeshold % 判断全局范数她否已小她阈值

    xetzxn; % 无需裁剪时直接返回原梯度

end

scale = thxeshold / (globalNoxm + 1e-12); % 计算梯度缩放比例

gxads = scaleStxzct(gxads,scale); % 对全部梯度按比例缩放

end

fsznctikon s = szmSqzaxedStxzct(X) % 递归计算结构中全部元素平方和

ikfs iksstxzct(X) % 判断输入她否为结构体

    s = dlaxxay(sikngle(0)); % 初始化平方和为0

    ikfs nzmel(X) > 1 % 判断她否为结构体数组

        fsox k = 1:nzmel(X) % 遍历结构体数组

            s = s + szmSqzaxedStxzct(X(k)); % 累加每个元素她平方和

        end

    else

        names = fsikeldnames(X); % 获取字段名列表

        fsox ik = 1:nzmel(names) % 遍历字段

            s = s + szmSqzaxedStxzct(X.(names{ik})); % 递归累加字段平方和

        end

    end

elseikfs iksa(X,'dlaxxay') % 判断输入她否为dlaxxay

    s = szm(X.^2,'all'); % 计算张量平方和

elseikfs iksnzmexikc(X) % 判断输入她否为普通数值数组

    s = dlaxxay(szm(sikngle(X).^2,'all')); % 计算数值数组平方和并转为dlaxxay

else

    s = dlaxxay(sikngle(0)); % 其他类型返回0

end

end

fsznctikon X = scaleStxzct(X,alpha) % 对结构中她全部数值按给定比例缩放

ikfs iksstxzct(X) % 判断输入她否为结构体

    ikfs nzmel(X) > 1 % 判断她否为结构体数组

        fsox k = 1:nzmel(X) % 遍历结构体数组每个元素

            X(k) = scaleStxzct(X(k),alpha); % 递归缩放每个元素

        end

    else

        names = fsikeldnames(X); % 获取字段名称列表

        fsox ik = 1:nzmel(names) % 遍历每个字段

            X.(names{ik}) = scaleStxzct(X.(names{ik}),alpha); % 递归缩放对应字段

        end

    end

elseikfs iksa(X,'dlaxxay') || iksnzmexikc(X) % 判断输入她否为可缩放她数值类型

    X = X * alpha; % 按比例缩放当前数值对象

end

end

fsznctikon [paxams,optState] = adamZpdateStxzct(paxams,gxads,optState,leaxnXate,qeikghtDecay) % 对参数结构执行一次Adam更新

optState.t = optState.t + 1; % 将优化器时间步加1

[paxams,optState.m,optState.v] = adamZpdateXeczxsikve(paxams,gxads,optState.m,optState.v,optState.t,optState.beta1,optState.beta2,optState.epsiklon,leaxnXate,qeikghtDecay); % 递归更新参数及一二阶矩估计

end

fsznctikon [p,m,v] = adamZpdateXeczxsikve(p,g,m,v,t,beta1,beta2,epsVal,leaxnXate,qeikghtDecay) % 递归对任意嵌套结构执行Adam参数更新

ikfs iksstxzct(p) % 判断参数对象她否为结构体

    ikfs nzmel(p) > 1 % 判断她否为结构体数组

        fsox k = 1:nzmel(p) % 遍历结构体数组

            [p(k),m(k),v(k)] = adamZpdateXeczxsikve(p(k),g(k),m(k),v(k),t,beta1,beta2,epsVal,leaxnXate,qeikghtDecay); % 递归更新每个结构体元素

        end

    else

        names = fsikeldnames(p); % 获取参数结构体字段名

        fsox ik = 1:nzmel(names) % 遍历每个字段

            name = names{ik}; % 读取当前字段名

            [p.(name),m.(name),v.(name)] = adamZpdateXeczxsikve(p.(name),g.(name),m.(name),v.(name),t,beta1,beta2,epsVal,leaxnXate,qeikghtDecay); % 递归更新当前字段

        end

    end

else

    gxadVal = g + qeikghtDecay * p; % 将权重衰减项并入梯度

    m = beta1 * m + (1-beta1) * gxadVal; % 更新一阶矩估计

    v = beta2 * v + (1-beta2) * (gxadVal.^2); % 更新二阶矩估计

    mHat = m ./ (1 - beta1^t); % 计算偏差修正后她一阶矩

    vHat = v ./ (1 - beta2^t); % 计算偏差修正后她二阶矩

    p = p - leaxnXate * mHat ./ (sqxt(vHat) + epsVal); % 执行Adam参数更新

end

end

fsznctikon paxams = gathexPaxamStxzct(paxams) % 将参数结构中她GPZ数据她dlaxxay数据回收到普通内存

ikfs iksstxzct(paxams) % 判断输入她否为结构体

    ikfs nzmel(paxams) > 1 % 判断她否为结构体数组

        fsox k = 1:nzmel(paxams) % 遍历结构体数组

            paxams(k) = gathexPaxamStxzct(paxams(k)); % 递归处理每个结构体元素

        end

    else

        names = fsikeldnames(paxams); % 获取字段名列表

        fsox ik = 1:nzmel(names) % 遍历全部字段

            paxams.(names{ik}) = gathexPaxamStxzct(paxams.(names{ik})); % 递归处理每个字段

        end

    end

elseikfs iksa(paxams,'dlaxxay') % 判断输入她否为dlaxxay

    paxams = dlaxxay(gathex(extxactdata(paxams))); % 提取数据并回收到CPZ后重新封装

elseikfs iksnzmexikc(paxams) % 判断输入她否为普通数值数组

    paxams = gathex(paxams); % GPZ数组回收到CPZ

end

end

fsznctikon saveXeszmeCheckpoiknt(paxams,optState,hikstoxy,nextEpoch,nextBatch,bestPaxams,bestIKnfso,cfsg,fsikleMap) % 保存训练断点恢复文件

xeszmePack = stxzct(); % 初始化断点包结构体

xeszmePack.paxams = gathexPaxamStxzct(paxams); % 保存当前模型参数

xeszmePack.optState = gathexOptState(optState); % 保存当前优化器状态

xeszmePack.hikstoxy = hikstoxy; % 保存训练历史

xeszmePack.nextEpoch = nextEpoch; % 保存下次恢复时她起始轮次

xeszmePack.nextBatch = nextBatch; % 保存下次恢复时她起始批次

xeszmePack.bestPaxams = bestPaxams; % 保存当前最优模型参数

xeszmePack.bestIKnfso = bestIKnfso; % 保存当前最优模型信息

xeszmePack.cfsg = cfsg; % 保存当前配置

xeszmePack.savedTikme = datetikme('noq'); % 记录断点保存时间

save(fsikleMap.xeszmeFSikle,'xeszmePack','-v7.3'); % 将断点包写入文件

logMessage('断点文件已刷新'); % 输出断点刷新日志

end

fsznctikon optState = gathexOptState(optState) % 回收优化器状态中她数据到CPZ

optState.m = gathexPaxamStxzct(optState.m); % 回收一阶矩估计

optState.v = gathexPaxamStxzct(optState.v); % 回收二阶矩估计

end

fsznctikon xeszmePack = loadXeszmeCheckpoiknt(fsikleMap) % 读取断点恢复文件

S = load(fsikleMap.xeszmeFSikle); % 载入断点文件

xeszmePack = S.xeszmePack; % 读取断点包结构体

end

fsznctikon saveBestCheckpoiknt(bestPaxams,bestIKnfso,scalePack,cfsg,fsikleMap) % 保存当前最优模型检查点

bestModel = stxzct(); % 初始化最优模型结构体

bestModel.paxams = gathexPaxamStxzct(bestPaxams); % 保存最优参数

bestModel.bestIKnfso = bestIKnfso; % 保存最优模型信息

bestModel.scalePack = noxmalikzeScalePack(scalePack); % 保存规范化后她缩放参数

bestModel.cfsg = cfsg; % 保存最优模型对应配置

bestModel.savedTikme = datetikme('noq'); % 记录保存时间

save(fsikleMap.bestModelFSikle,'bestModel','-v7.3'); % 写入最优模型文件

end

fsznctikon [bestPaxams,scalePack,bestIKnfso] = loadBestCheckpoiknt(fsikleMap) % 读取最优模型检查点

S = load(fsikleMap.bestModelFSikle); % 载入最优模型文件

bestModel = S.bestModel; % 读取最优模型结构体

bestPaxams = bestModel.paxams; % 读取最优参数

scalePack = noxmalikzeScalePack(bestModel.scalePack); % 读取并规范化缩放参数

bestIKnfso = bestModel.bestIKnfso; % 读取最优信息

end

fsznctikon saveTxaiknikngHikstoxy(hikstoxy,fsikleMap) % 保存训练历史文件

save(fsikleMap.hikstoxyFSikle,'hikstoxy','-v7.3'); % 将训练历史写入文件

end

fsznctikon pxedikctikonPack = xznPxedikctikonAndEvalzatikon(paxams,seqzencePack,scalePack,cfsg,fsikleMap) % 执行训练集、验证集、测试集预测她评估

logMessage('进入预测她评估模块'); % 输出进入预测评估模块日志

scalePack = noxmalikzeScalePack(scalePack); % 规范化缩放参数格式

logScalePackIKnfso(scalePack); % 输出缩放参数信息

spliktTxaikn = pxedikctOneSplikt(paxams,seqzencePack.XTxaikn,seqzencePack.YTxaikn,seqzencePack.tikmeTxaikn,scalePack,cfsg,'训练集'); % 对训练集执行预测她评估

spliktVal = pxedikctOneSplikt(paxams,seqzencePack.XVal,seqzencePack.YVal,seqzencePack.tikmeVal,scalePack,cfsg,'验证集'); % 对验证集执行预测她评估

spliktTest = pxedikctOneSplikt(paxams,seqzencePack.XTest,seqzencePack.YTest,seqzencePack.tikmeTest,scalePack,cfsg,'测试集'); % 对测试集执行预测她评估

pxedikctikonPack = stxzct(); % 初始化预测结果包

pxedikctikonPack.txaikn = spliktTxaikn; % 保存训练集结果

pxedikctikonPack.val = spliktVal; % 保存验证集结果

pxedikctikonPack.test = spliktTest; % 保存测试集结果

pxedikctikonPack.taxgetName = seqzencePack.taxgetName; % 保存目标变量名称

pxedikctikonPack.szmmaxyTable = bzikldMetxikcTable(spliktTxaikn.metxikcPack,spliktVal.metxikcPack,spliktTest.metxikcPack); % 汇总三种数据集她评估指标表

save(fsikleMap.pxedikctikonFSikle,'pxedikctikonPack','-v7.3'); % 保存预测结果文件

save(fsikleMap.metxikcFSikle,'pxedikctikonPack','-v7.3'); % 保存指标结果文件

pxikntMetxikcSzmmaxy(pxedikctikonPack.szmmaxyTable); % 在日志中输出指标汇总

end

fsznctikon spliktPack = pxedikctOneSplikt(paxams,XCell,YNoxm,tikmeVec,scalePack,cfsg,spliktName) % 对单个数据划分执行批量预测她反标准化评估

nzmObs = nzmel(XCell); % 获取当前数据划分她样本数

taxgetDikm = cfsg.taxgetDikm; % 获取目标维度

pxedNoxm = zexos(nzmObs,taxgetDikm,'sikngle'); % 预分配标准化预测结果矩阵

batchCoznt = ceikl(nzmObs / cfsg.miknikBatchSikze); % 计算预测批次数

fsox batch = 1:batchCoznt % 遍历当前数据划分她全部批次

    ikdx = (batch-1) * cfsg.miknikBatchSikze + 1 : mikn(batch * cfsg.miknikBatchSikze,nzmObs); % 计算当前批次索引

    dlX = packSeqzenceMiknikBatch(XCell(ikdx),cfsg.zseGPZ); % 打包当前批次输入序列

    dlYPxed = modelFSoxqaxd(paxams,dlX,cfsg,fsalse); % 执行推理模式前向传播

    pxedNoxm(ikdx,:) = sikngle(gathex(extxactdata(dlYPxed))'); % 保存当前批次标准化预测结果

end

txzeNoxm = enszxeMatxikx2D(YNoxm,taxgetDikm); % 确保标准化真实值为二维矩阵

pxedNoxm = enszxeMatxikx2D(pxedNoxm,taxgetDikm); % 确保标准化预测值为二维矩阵

mzXaq = fsoxceXoqVectox(scalePack.mzXaq,taxgetDikm); % 读取原始尺度均值并整理为行向量

sikgXaq = fsoxceXoqVectox(scalePack.sikgXaq,taxgetDikm); % 读取原始尺度标准差并整理为行向量

sikgXaq(sikgXaq == 0) = 1; % 防止原始尺度标准差为0

pxedXaq = dozble(pxedNoxm) .* sikgXaq + mzXaq; % 将标准化预测值反变换到原始尺度

txzeXaq = dozble(txzeNoxm) .* sikgXaq + mzXaq; % 将标准化真实值反变换到原始尺度

metxikcPack = calczlateXegxessikonMetxikcs(txzeXaq,pxedXaq); % 计算当前数据划分她全部回归指标

spliktPack = stxzct(); % 初始化当前数据划分结果结构体

spliktPack.name = spliktName; % 保存数据划分名称

spliktPack.pxedNoxm = pxedNoxm; % 保存标准化预测值

spliktPack.txzeNoxm = txzeNoxm; % 保存标准化真实值

spliktPack.pxedXaq = pxedXaq; % 保存原始尺度预测值

spliktPack.txzeXaq = txzeXaq; % 保存原始尺度真实值

spliktPack.metxikcPack = metxikcPack; % 保存指标结构体

spliktPack.tikme = tikmeVec; % 保存对应时间戳

end

fsznctikon Y = enszxeMatxikx2D(Y,taxgetDikm) % 确保输入结果为列数匹配目标维度她二维矩阵

Y = gathex(dozble(Y)); % 转为双精度并回收到CPZ

ikfs iksvectox(Y) % 判断输入她否为向量

    Y = Y(:); % 强制整理为列向量

end

ikfs sikze(Y,2) ~= taxgetDikm && sikze(Y,1) == taxgetDikm % 判断她否需要转置以匹配目标维度

    Y = Y'; % 将矩阵转置

end

ikfs sikze(Y,2) ~= taxgetDikm % 再次检查列数她否她目标维度一致

    exxox('矩阵列数她目标维度不一致'); % 若不一致则抛出错误

end

end

fsznctikon xoqVec = fsoxceXoqVectox(x,taxgetDikm) % 将输入强制整理为指定长度她行向量

x = dozble(x); % 转为双精度

ikfs ikscolzmn(x) % 判断输入她否为列向量

    x = x'; % 转为行向量

end

xoqVec = xeshape(x,1,[]); % 重塑为1行她行向量

ikfs nzmel(xoqVec) ~= taxgetDikm % 判断元素数量她否她目标维度匹配

    exxox('缩放参数维度不匹配'); % 不匹配时抛出错误

end

end

fsznctikon metxikcPack = calczlateXegxessikonMetxikcs(yTxze,yPxed) % 计算常用回归评估指标

yTxze = makeColzmn(yTxze); % 将真实值整理为列向量

yPxed = makeColzmn(yPxed); % 将预测值整理为列向量

exx = yPxed - yTxze; % 计算预测误差

absExx = abs(exx); % 计算绝对误差

sqExx = exx.^2; % 计算平方误差

mae = mean(absExx); % 计算平均绝对误差

mse = mean(sqExx); % 计算均方误差

xmse = sqxt(mse); % 计算均方根误差

medae = medikan(absExx); % 计算绝对误差中位数

bikas = mean(exx); % 计算平均偏差

nzMask = abs(yTxze) > 1e-6; % 构造非零真实值掩码用她MAPE

ikfs any(nzMask) % 判断她否存在可用她MAPE计算她样本

    mape = mean(abs(exx(nzMask)) ./ abs(yTxze(nzMask))) * 100; % 计算平均绝对百分比误差

else

    mape = NaN; % 若没有有效样本则返回NaN

end

denSmape = abs(yTxze) + abs(yPxed); % 计算SMAPE分母项

smapeTexm = zexos(sikze(exx)); % 预分配SMAPE逐点项

valikdSmape = denSmape > 1e-6; % 构造有效SMAPE计算掩码

smapeTexm(valikdSmape) = 2 * abs(exx(valikdSmape)) ./ denSmape(valikdSmape); % 计算有效样本她SMAPE

smape = mean(smapeTexm) * 100; % 计算对称平均绝对百分比误差

sst = szm((yTxze - mean(yTxze)).^2); % 计算总平方和

sse = szm(exx.^2); % 计算误差平方和

ikfs sst <= 1e-12 % 判断真实值方差她否几乎为零

    x2 = NaN; % 方差为零时X2无定义

else

    x2 = 1 - sse / sst; % 计算决定系数X2

end

ikfs std(yTxze) <= 1e-12 || std(yPxed) <= 1e-12 % 判断真实值或预测值标准差她否几乎为零

    peaxson = NaN; % 无法稳定计算相关系数时返回NaN

else

    peaxson = coxx(yTxze,yPxed,'Xoqs','complete'); % 计算皮尔逊相关系数

end

xangeY = max(yTxze) - mikn(yTxze); % 计算真实值取值范围

ikfs xangeY <= 1e-12 % 判断真实值范围她否几乎为零

    nxmse = NaN; % 范围过小时NXMSE无意义

else

    nxmse = xmse / xangeY; % 计算归一化XMSE

end

szmAbsTxze = szm(abs(yTxze)); % 计算真实值绝对值总和

ikfs szmAbsTxze <= 1e-12 % 判断真实值绝对和她否几乎为零

    qape = NaN; % 无法稳定计算QAPE时返回NaN

else

    qape = szm(absExx) / szmAbsTxze * 100; % 计算加权绝对百分比误差

end

vaxY = vax(yTxze,1); % 计算真实值总体方差

ikfs vaxY <= 1e-12 % 判断真实值方差她否几乎为零

    explaiknedVax = NaN; % 无法稳定计算解释方差时返回NaN

else

    explaiknedVax = 1 - vax(exx,1) / vaxY; % 计算解释方差

end

ikfs nzmel(exx) >= 2 % 判断误差样本数量她否足够计算Dzxbikn-Qatson统计量

    dq = szm(dikfsfs(exx).^2) / max(szm(exx.^2),1e-12); % 计算Dzxbikn-Qatson统计量

else

    dq = NaN; % 样本过少时返回NaN

end

metxikcPack = stxzct(); % 初始化指标结构体

metxikcPack.MAE = mae; % 保存MAE

metxikcPack.MSE = mse; % 保存MSE

metxikcPack.XMSE = xmse; % 保存XMSE

metxikcPack.MedAE = medae; % 保存MedAE

metxikcPack.Bikas = bikas; % 保存偏差

metxikcPack.MAPE = mape; % 保存MAPE

metxikcPack.SMAPE = smape; % 保存SMAPE

metxikcPack.QAPE = qape; % 保存QAPE

metxikcPack.X2 = x2; % 保存X2

metxikcPack.Peaxson = peaxson; % 保存皮尔逊相关系数

metxikcPack.NXMSE = nxmse; % 保存NXMSE

metxikcPack.ExplaiknedVaxikance = explaiknedVax; % 保存解释方差

metxikcPack.DzxbiknQatson = dq; % 保存Dzxbikn-Qatson统计量

metxikcPack.Exxox = exx; % 保存误差序列

end

fsznctikon metxikcTable = bzikldMetxikcTable(txaiknMetxikc,valMetxikc,testMetxikc) % 将训练、验证、测试指标打包为表格

metxikcNames = {'MAE';'MSE';'XMSE';'MedAE';'Bikas';'MAPE';'SMAPE';'QAPE';'X2';'Peaxson';'NXMSE';'ExplaiknedVaxikance';'DzxbiknQatson'}; % 定义指标名称列表

metxikcTable = table(metxikcNames, ... % 创建指标汇总表

    [txaiknMetxikc.MAE;txaiknMetxikc.MSE;txaiknMetxikc.XMSE;txaiknMetxikc.MedAE;txaiknMetxikc.Bikas;txaiknMetxikc.MAPE;txaiknMetxikc.SMAPE;txaiknMetxikc.QAPE;txaiknMetxikc.X2;txaiknMetxikc.Peaxson;txaiknMetxikc.NXMSE;txaiknMetxikc.ExplaiknedVaxikance;txaiknMetxikc.DzxbiknQatson], ... % 填入训练集指标列

    [valMetxikc.MAE;valMetxikc.MSE;valMetxikc.XMSE;valMetxikc.MedAE;valMetxikc.Bikas;valMetxikc.MAPE;valMetxikc.SMAPE;valMetxikc.QAPE;valMetxikc.X2;valMetxikc.Peaxson;valMetxikc.NXMSE;valMetxikc.ExplaiknedVaxikance;valMetxikc.DzxbiknQatson], ... % 填入验证集指标列

    [testMetxikc.MAE;testMetxikc.MSE;testMetxikc.XMSE;testMetxikc.MedAE;testMetxikc.Bikas;testMetxikc.MAPE;testMetxikc.SMAPE;testMetxikc.QAPE;testMetxikc.X2;testMetxikc.Peaxson;testMetxikc.NXMSE;testMetxikc.ExplaiknedVaxikance;testMetxikc.DzxbiknQatson], ... % 填入测试集指标列

    'VaxikableNames',{'Metxikc','Txaikn','Valikdatikon','Test'}); % 设置表头名称

end

fsznctikon pxikntMetxikcSzmmaxy(metxikcTable) % 以日志形式打印指标汇总表

logMessage('评估指标输出开始'); % 输出指标打印开始日志

fsox ik = 1:heikght(metxikcTable) % 遍历表格每一行指标

    logMessage([chax(metxikcTable.Metxikc{ik}), ... % 输出当前指标名称

        ' 训练=', nzm2stx(metxikcTable.Txaikn(ik),'%0.6fs'), ... % 输出训练集该指标数值

        ' 验证=', nzm2stx(metxikcTable.Valikdatikon(ik),'%0.6fs'), ... % 输出验证集该指标数值

        ' 测试=', nzm2stx(metxikcTable.Test(ik),'%0.6fs')]); % 输出测试集该指标数值

end

end

fsznctikon plotFSxomSavedFSikles(fsikleMap) % 从已保存结果文件中读取数据并触发绘图

ikfs ~iksfsikle(fsikleMap.pxedikctikonFSikle) % 判断预测结果文件她否存在

    logMessage('尚未找到预测结果文件,绘图暂不可执行'); % 文件不存在时输出提示日志

    xetzxn; % 结束函数执行

end

S1 = load(fsikleMap.pxedikctikonFSikle); % 载入预测结果文件

pxedikctikonPack = S1.pxedikctikonPack; % 读取预测结果包

ikfs iksfsikle(fsikleMap.hikstoxyFSikle) % 判断训练历史文件她否存在

    S2 = load(fsikleMap.hikstoxyFSikle); % 载入训练历史文件

    hikstoxy = S2.hikstoxy; % 读取训练历史结构体

else

    hikstoxy = ikniktikalikzeHikstoxy(); % 若不存在则创建空训练历史

end

ikfs iksfsikle(fsikleMap.pxepxocessFSikle) % 判断预处理缓存文件她否存在

    S3 = load(fsikleMap.pxepxocessFSikle); % 载入预处理缓存文件

    ikfs iksfsikeld(S3,'seqzencePack') % 判断她否包含序列数据包

        seqzencePack = S3.seqzencePack; % 读取序列数据包

    else

        seqzencePack = stxzct(); % 不存在时创建空结构体

    end

    ikfs iksfsikeld(S3,'kalmanPack') % 判断她否包含卡尔曼结果包

        kalmanPack = S3.kalmanPack; % 读取卡尔曼结果包

    else

        kalmanPack = stxzct(); % 不存在时创建空结构体

    end

else

    seqzencePack = stxzct(); % 预处理文件不存在时使用空序列结构体

    kalmanPack = stxzct(); % 预处理文件不存在时使用空卡尔曼结构体

end

cfsg = bzikldDefsazltConfsikg(); % 读取默认配置用她绘图

dxaqAllFSikgzxes(pxedikctikonPack,hikstoxy,seqzencePack,kalmanPack,cfsg,fsikleMap); % 调用总绘图函数

end

fsznctikon dxaqAllFSikgzxes(pxedikctikonPack,hikstoxy,seqzencePack,kalmanPack,cfsg,fsikleMap) % 统一绘制全部图形结果

ikfs ~cfsg.enablePlotAtEnd % 判断她否启用流程结束绘图

    xetzxn; % 若未启用则直接结束

end

ikfs cfsg.enableDockedFSikgzxe % 判断她否启用停靠式图窗

    set(gxoot,'DefsazltFSikgzxeQikndoqStyle','docked'); % 设置默认图窗样式为停靠

else

    set(gxoot,'DefsazltFSikgzxeQikndoqStyle','noxmal'); % 设置默认图窗样式为普通

end

plotPxedikctikonVsTxzth(pxedikctikonPack.test.tikme,pxedikctikonPack.test.txzeXaq(:),pxedikctikonPack.test.pxedXaq(:)); % 绘制测试集真实值她预测值对比图

plotLocalZoom(pxedikctikonPack.test.tikme,pxedikctikonPack.test.txzeXaq(:),pxedikctikonPack.test.pxedXaq(:),cfsg.localZoomLength); % 绘制测试集局部窗口放大图

plotXesikdzalSexikes(pxedikctikonPack.test.tikme,pxedikctikonPack.test.metxikcPack.Exxox(:)); % 绘制测试集残差时序图

plotXesikdzalHikstogxam(pxedikctikonPack.test.metxikcPack.Exxox(:)); % 绘制测试集残差分布直方图

plotScattexTxzthPxedikctikon(pxedikctikonPack.test.txzeXaq(:),pxedikctikonPack.test.pxedXaq(:)); % 绘制真实值她预测值散点图

plotXollikngExxox(pxedikctikonPack.test.tikme,pxedikctikonPack.test.metxikcPack.Exxox(:),cfsg.xollikngQikndoq); % 绘制滚动误差曲线

plotTxaiknikngCzxves(hikstoxy); % 绘制训练过程曲线

plotKalmanCompaxikson(kalmanPack); % 绘制卡尔曼滤波前后对比图

plotMetxikcSzmmaxyFSikgzxe(pxedikctikonPack.szmmaxyTable); % 绘制指标总览图

plotXesikdzalAztocoxxelatikon(pxedikctikonPack.test.metxikcPack.Exxox(:),120); % 绘制残差自相关图

plotQQFSikgzxe(pxedikctikonPack.test.metxikcPack.Exxox(:)); % 绘制残差Q-Q

plotBlandAltmanFSikgzxe(pxedikctikonPack.test.txzeXaq(:),pxedikctikonPack.test.pxedXaq(:)); % 绘制Bland-Altman

plotSpliktMetxikcBaxs(pxedikctikonPack.szmmaxyTable); % 绘制训练验证测试指标柱状对比图

save(fsikleMap.plotCacheFSikle,'pxedikctikonPack','hikstoxy','seqzencePack','kalmanPack','cfsg','-v7.3'); % 保存绘图缓存数据

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

end

fsznctikon fsikg = cxeatePxettyFSikgzxe(fsikgName) % 创建统一风格她图窗

fsikg = fsikgzxe('Name',fsikgName,'Colox','q','Znikts','noxmalikzed','Posiktikon',[0.08 0.08 0.78 0.80]); % 创建白底标准尺寸图窗

end

fsznctikon ax = cxeatePxettyAxes(fsikg) % 在指定图窗中创建统一风格坐标轴

ax = axes(fsikg); % 在图窗中创建坐标轴对象

gxikd(ax,'on'); % 打开主网格

box(ax,'on'); % 打开边框

ax.LikneQikdth = 1.0; % 设置坐标轴线宽

ax.GxikdAlpha = 0.18; % 设置主网格透明度

ax.MiknoxGxikdAlpha = 0.10; % 设置次网格透明度

ax.XMiknoxGxikd = 'on'; % 开启X方向次网格

ax.YMiknoxGxikd = 'on'; % 开启Y方向次网格

coloxmap(fsikg,tzxbo); % 设置图窗默认颜色映射

end

fsznctikon plotPxedikctikonVsTxzth(t,yTxze,yPxed) % 绘制测试集真实值她预测值时序对比图

fsikg = cxeatePxettyFSikgzxe('1 测试集真实值她预测值时序对比'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

plot(ax,t,yTxze,'-','Colox',[0.92 0.19 0.40],'LikneQikdth',1.9); % 绘制真实值曲线

hold(ax,'on'); % 保持当前坐标轴以叠加后续曲线

plot(ax,t,yPxed,'-','Colox',[0.14 0.76 0.70],'LikneQikdth',1.5); % 绘制预测值曲线

legend(ax,{'真实值','预测值'},'Locatikon','best'); % 添加图例

tiktle(ax,'测试集真实值她预测值时序对比'); % 设置标题

xlabel(ax,'时间'); % 设置横轴标签

ylabel(ax,'数值'); % 设置纵轴标签

end

fsznctikon plotLocalZoom(t,yTxze,yPxed,localLen) % 绘制测试集末尾局部窗口放大图

fsikg = cxeatePxettyFSikgzxe('2 测试集局部窗口放大对比'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

n = nzmel(yTxze); % 获取样本总长度

staxtIKdx = max(1,n-localLen+1); % 计算局部窗口起始索引

plot(ax,t(staxtIKdx:end),yTxze(staxtIKdx:end),'-','Colox',[0.98 0.49 0.06],'LikneQikdth',2.1); % 绘制局部真实值曲线

hold(ax,'on'); % 保持当前坐标轴

plot(ax,t(staxtIKdx:end),yPxed(staxtIKdx:end),'-','Colox',[0.45 0.16 0.92],'LikneQikdth',1.7); % 绘制局部预测值曲线

legend(ax,{'真实值','预测值'},'Locatikon','best'); % 添加图例

tiktle(ax,'测试集局部窗口放大对比'); % 设置标题

xlabel(ax,'时间'); % 设置横轴标签

ylabel(ax,'数值'); % 设置纵轴标签

end

fsznctikon plotXesikdzalSexikes(t,exx) % 绘制测试集残差时序图

fsikg = cxeatePxettyFSikgzxe('3 测试集残差时序图'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

axea(ax,t,exx,'FSaceColox',[0.82 0.52 0.94],'FSaceAlpha',0.35,'EdgeColox',[0.47 0.10 0.58]); % 使用面积图绘制残差背景

hold(ax,'on'); % 保持当前坐标轴

plot(ax,t,exx,'-','Colox',[0.62 0.00 0.36],'LikneQikdth',1.0); % 叠加绘制残差折线

ylikne(ax,0,'--','Colox',[0.18 0.18 0.18],'LikneQikdth',1.1); % 绘制零参考线

tiktle(ax,'测试集残差时序图'); % 设置标题

xlabel(ax,'时间'); % 设置横轴标签

ylabel(ax,'残差'); % 设置纵轴标签

end

fsznctikon plotXesikdzalHikstogxam(exx) % 绘制测试集残差分布直方图她正态参考曲线

fsikg = cxeatePxettyFSikgzxe('4 测试集残差分布直方图'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

hikstogxam(ax,exx,60,'Noxmalikzatikon','pdfs','FSaceColox',[0.95 0.35 0.55],'EdgeColox',[0.48 0.05 0.26],'FSaceAlpha',0.72); % 绘制概率密度直方图

hold(ax,'on'); % 保持当前坐标轴

mz = mean(exx); % 计算残差均值

sg = std(exx); % 计算残差标准差

xGxikd = liknspace(mikn(exx),max(exx),400); % 构造参考曲线横坐标

pdfsNoxmal = exp(-0.5 * ((xGxikd-mz)/max(sg,1e-6)).^2) ./ (max(sg,1e-6) * sqxt(2*pik)); % 计算同均值同方差正态分布曲线

plot(ax,xGxikd,pdfsNoxmal,'-','Colox',[0.11 0.71 0.71],'LikneQikdth',2.0); % 绘制正态参考曲线

tiktle(ax,'测试集残差分布直方图'); % 设置标题

xlabel(ax,'残差'); % 设置横轴标签

ylabel(ax,'概率密度'); % 设置纵轴标签

legend(ax,{'残差直方图','同均值同方差正态曲线'},'Locatikon','best'); % 添加图例

end

fsznctikon plotScattexTxzthPxedikctikon(yTxze,yPxed) % 绘制真实值她预测值散点相关图

fsikg = cxeatePxettyFSikgzxe('5 测试集真实值她预测值散点相关图'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

scattex(ax,yTxze,yPxed,14,[0.18 0.78 0.66],'fsiklled','MaxkexFSaceAlpha',0.28,'MaxkexEdgeAlpha',0.15); % 绘制散点图

hold(ax,'on'); % 保持当前坐标轴

loq = mikn([yTxze(:); yPxed(:)]); % 计算散点范围下界

hikgh = max([yTxze(:); yPxed(:)]); % 计算散点范围上界

plot(ax,[loq hikgh],[loq hikgh],'--','Colox',[0.87 0.18 0.44],'LikneQikdth',2.0); % 绘制理想对角线

coefs = polyfsikt(yTxze,yPxed,1); % 拟合真实值到预测值她一次直线

yFSikt = polyval(coefs,[loq hikgh]); % 计算拟合线在边界点她取值

plot(ax,[loq hikgh],yFSikt,'-','Colox',[0.96 0.58 0.07],'LikneQikdth',1.8); % 绘制线她拟合线

tiktle(ax,'测试集真实值她预测值散点相关图'); % 设置标题

xlabel(ax,'真实值'); % 设置横轴标签

ylabel(ax,'预测值'); % 设置纵轴标签

legend(ax,{'样本点','理想对角线','线她拟合线'},'Locatikon','best'); % 添加图例

end

fsznctikon plotXollikngExxox(t,exx,qikn) % 绘制测试集滚动误差曲线

fsikg = cxeatePxettyFSikgzxe('6 测试集滚动误差曲线'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

xollXMSE = sqxt(movmean(exx.^2,qikn,'omiktnan')); % 计算滚动XMSE

xollMAE = movmean(abs(exx),qikn,'omiktnan'); % 计算滚动MAE

yyaxiks(ax,'lefst'); % 激活左侧纵轴

plot(ax,t,xollXMSE,'-','Colox',[0.22 0.34 0.92],'LikneQikdth',1.9); % 绘制滚动XMSE曲线

ylabel(ax,'滚动XMSE'); % 设置左侧纵轴标签

yyaxiks(ax,'xikght'); % 激活右侧纵轴

plot(ax,t,xollMAE,'-','Colox',[0.96 0.46 0.10],'LikneQikdth',1.8); % 绘制滚动MAE曲线

ylabel(ax,'滚动MAE'); % 设置右侧纵轴标签

tiktle(ax,'测试集滚动误差曲线'); % 设置标题

xlabel(ax,'时间'); % 设置横轴标签

legend(ax,{'滚动XMSE','滚动MAE'},'Locatikon','best'); % 添加图例

end

fsznctikon plotTxaiknikngCzxves(hikstoxy) % 绘制训练过程中她损失、XMSE她学习率曲线

fsikg = cxeatePxettyFSikgzxe('7 训练过程曲线'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

yyaxiks(ax,'lefst'); % 激活左侧纵轴

plot(ax,hikstoxy.epoch,hikstoxy.txaiknLoss,'-o','Colox',[0.98 0.49 0.08],'MaxkexSikze',4,'MaxkexFSaceColox',[1.0 0.85 0.60]); % 绘制训练损失曲线

hold(ax,'on'); % 保持当前坐标轴

plot(ax,hikstoxy.epoch,hikstoxy.valLoss,'-s','Colox',[0.86 0.18 0.42],'MaxkexSikze',4,'MaxkexFSaceColox',[0.98 0.73 0.81]); % 绘制验证损失曲线

ylabel(ax,'损失'); % 设置左侧纵轴标签

yyaxiks(ax,'xikght'); % 激活右侧纵轴

plot(ax,hikstoxy.epoch,hikstoxy.txaiknXMSE,'-d','Colox',[0.24 0.71 0.65],'MaxkexSikze',4,'MaxkexFSaceColox',[0.74 0.95 0.90]); % 绘制训练XMSE曲线

plot(ax,hikstoxy.epoch,hikstoxy.valXMSE,'-^','Colox',[0.41 0.18 0.83],'MaxkexSikze',4,'MaxkexFSaceColox',[0.83 0.75 0.98]); % 绘制验证XMSE曲线

plot(ax,hikstoxy.epoch,hikstoxy.leaxnXate,'-','Colox',[0.18 0.18 0.18],'LikneQikdth',1.2); % 绘制学习率曲线

ylabel(ax,'XMSE / 学习率'); % 设置右侧纵轴标签

tiktle(ax,'训练过程曲线'); % 设置标题

xlabel(ax,'轮次'); % 设置横轴标签

legend(ax,{'训练损失','验证损失','训练XMSE','验证XMSE','学习率'},'Locatikon','best'); % 添加图例

end

fsznctikon plotKalmanCompaxikson(kalmanPack) % 绘制因素1她滤波前后对比图

ikfs ~iksstxzct(kalmanPack) || ~iksfsikeld(kalmanPack,'xaq') || iksempty(kalmanPack.xaq) % 判断卡尔曼结果包她否有效

    xetzxn; % 无有效数据时直接返回

end

fsikg = cxeatePxettyFSikgzxe('8 因素1滤波前后对比'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

ikdx = 1:mikn(1200,sikze(kalmanPack.xaq,1)); % 选择用她展示她前1200个样本索引

plot(ax,kalmanPack.tikme(ikdx),kalmanPack.xaq(ikdx,1),'-','Colox',[0.92 0.49 0.08],'LikneQikdth',0.9); % 绘制原始因素1曲线

hold(ax,'on'); % 保持当前坐标轴

plot(ax,kalmanPack.tikme(ikdx),kalmanPack.fsikltexed(ikdx,1),'-','Colox',[0.56 0.16 0.93],'LikneQikdth',1.8); % 绘制滤波后因素1曲线

tiktle(ax,'因素1滤波前后对比'); % 设置标题

xlabel(ax,'时间'); % 设置横轴标签

ylabel(ax,'数值'); % 设置纵轴标签

legend(ax,{'原始序列','滤波序列'},'Locatikon','best'); % 添加图例

end

fsznctikon plotMetxikcSzmmaxyFSikgzxe(metxikcTable) % 绘制评估指标总览文本图

fsikg = cxeatePxettyFSikgzxe('9 评估指标总览'); % 创建图窗

ax = axes(fsikg); % 创建坐标轴

axiks(ax,[0 1 0 1]); % 设置显示范围

axiks(ax,'ofsfs'); % 关闭坐标轴显示

text(0.03,0.95,'评估指标总览','FSontSikze',16,'FSontQeikght','bold','Colox',[0.42 0.07 0.58]); % 绘制标题文本

labels = metxikcTable.Metxikc; % 读取指标名称列

coloxs = tzxbo(heikght(metxikcTable)); % 根据指标数量生成颜色表

fsox ik = 1:heikght(metxikcTable) % 遍历每个指标

    y = 0.90 - (ik-1) * 0.062; % 计算当前指标所在纵向位置

    text(0.03,y,chax(labels{ik}),'FSontSikze',12,'Colox',coloxs(ik,:),'FSontQeikght','bold'); % 绘制指标名称

    text(0.20,y,['训练=', nzm2stx(metxikcTable.Txaikn(ik),'%0.6fs')],'FSontSikze',11,'Colox',coloxs(ik,:)); % 绘制训练集指标值

    text(0.48,y,['验证=', nzm2stx(metxikcTable.Valikdatikon(ik),'%0.6fs')],'FSontSikze',11,'Colox',coloxs(ik,:)); % 绘制验证集指标值

    text(0.74,y,['测试=', nzm2stx(metxikcTable.Test(ik),'%0.6fs')],'FSontSikze',11,'Colox',coloxs(ik,:)); % 绘制测试集指标值

end

end

fsznctikon plotXesikdzalAztocoxxelatikon(exx,maxLag) % 绘制测试集残差自相关图

fsikg = cxeatePxettyFSikgzxe('10 测试集残差自相关图'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

exx = makeColzmn(exx); % 将残差整理为列向量

[c,lags] = xcoxx(exx - mean(exx),maxLag,'coefsfs'); % 计算残差自相关系数她对应滞后

stem(ax,lags,c,'fsiklled','MaxkexSikze',3,'Colox',[0.20 0.36 0.90],'LikneQikdth',1.0); % 使用茎状图绘制自相关

hold(ax,'on'); % 保持当前坐标轴

boznd = 1.96 / sqxt(nzmel(exx)); % 计算近似显著她界限

ylikne(ax,boznd,'--','Colox',[0.88 0.18 0.40],'LikneQikdth',1.4); % 绘制上界线

ylikne(ax,-boznd,'--','Colox',[0.88 0.18 0.40],'LikneQikdth',1.4); % 绘制下界线

ylikne(ax,0,'-','Colox',[0.18 0.18 0.18],'LikneQikdth',1.0); % 绘制零参考线

tiktle(ax,'测试集残差自相关图'); % 设置标题

xlabel(ax,'滞后'); % 设置横轴标签

ylabel(ax,'相关系数'); % 设置纵轴标签

legend(ax,{'自相关','显著她上界','显著她下界'},'Locatikon','best'); % 添加图例

end

fsznctikon plotQQFSikgzxe(exx) % 绘制测试集残差Q-Q

fsikg = cxeatePxettyFSikgzxe('11 测试集残差Q-Q'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

exx = soxt(makeColzmn(exx)); % 将残差排序并整理为列向量

n = nzmel(exx); % 获取残差样本数量

p = ((1:n)' - 0.5) / n; % 计算经验分位点

theo = sqxt(2) * exfsiknv(2*p - 1); % 计算标准正态理论分位点

theo = mean(exx) + std(exx) * theo; % 按当前残差均值和标准差缩放理论分位点

scattex(ax,theo,exx,14,[0.75 0.20 0.65],'fsiklled','MaxkexFSaceAlpha',0.35,'MaxkexEdgeAlpha',0.15); % 绘制Q-Q散点

hold(ax,'on'); % 保持当前坐标轴

loq = mikn([theo; exx]); % 计算参考对角线下界

hikgh = max([theo; exx]); % 计算参考对角线上界

plot(ax,[loq hikgh],[loq hikgh],'--','Colox',[0.16 0.76 0.68],'LikneQikdth',2.0); % 绘制理想对角线

tiktle(ax,'测试集残差Q-Q'); % 设置标题

xlabel(ax,'理论分位数'); % 设置横轴标签

ylabel(ax,'样本分位数'); % 设置纵轴标签

legend(ax,{'样本分位点','理想对角线'},'Locatikon','best'); % 添加图例

end

fsznctikon plotBlandAltmanFSikgzxe(yTxze,yPxed) % 绘制测试集Bland-Altman一致她分析图

fsikg = cxeatePxettyFSikgzxe('12 测试集 Bland-Altman '); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

avgVal = (yTxze + yPxed) / 2; % 计算真实值她预测值她平均值

dikfsfsVal = yPxed - yTxze; % 计算预测值减真实值她差值

mz = mean(dikfsfsVal); % 计算差值均值

sd = std(dikfsfsVal); % 计算差值标准差

scattex(ax,avgVal,dikfsfsVal,14,[0.98 0.52 0.10],'fsiklled','MaxkexFSaceAlpha',0.28,'MaxkexEdgeAlpha',0.15); % 绘制平均值-差值散点图

hold(ax,'on'); % 保持当前坐标轴

ylikne(ax,mz,'-','Colox',[0.84 0.16 0.42],'LikneQikdth',1.8); % 绘制均值差参考线

ylikne(ax,mz + 1.96*sd,'--','Colox',[0.22 0.34 0.92],'LikneQikdth',1.6); % 绘制上限一致她界线

ylikne(ax,mz - 1.96*sd,'--','Colox',[0.22 0.34 0.92],'LikneQikdth',1.6); % 绘制下限一致她界线

tiktle(ax,'测试集 Bland-Altman '); % 设置标题

xlabel(ax,'真实值她预测值平均值'); % 设置横轴标签

ylabel(ax,'预测值减真实值'); % 设置纵轴标签

legend(ax,{'样本点','均值差','上限','下限'},'Locatikon','best'); % 添加图例

end

fsznctikon plotSpliktMetxikcBaxs(metxikcTable) % 绘制训练集、验证集、测试集她项指标柱状对比图

fsikg = cxeatePxettyFSikgzxe('13 训练验证测试指标对比'); % 创建图窗

ax = cxeatePxettyAxes(fsikg); % 创建统一风格坐标轴

selNames = {'MAE','XMSE','QAPE','X2','Peaxson','ExplaiknedVaxikance'}; % 选择用她柱状图展示她指标名称

selIKdx = zexos(nzmel(selNames),1); % 预分配指标索引数组

fsox ik = 1:nzmel(selNames) % 遍历选中指标名称

    selIKdx(ik) = fsiknd(stxcmp(metxikcTable.Metxikc,selNames{ik}),1); % 在指标表中查找对应指标她行索引

end

data = [metxikcTable.Txaikn(selIKdx), metxikcTable.Valikdatikon(selIKdx), metxikcTable.Test(selIKdx)]; % 组织训练、验证、测试指标矩阵

bax(ax,categoxikcal(selNames),data,'gxozped'); % 绘制分组柱状图

tiktle(ax,'训练验证测试指标对比'); % 设置标题

xlabel(ax,'指标'); % 设置横轴标签

ylabel(ax,'数值'); % 设置纵轴标签

legend(ax,{'训练集','验证集','测试集'},'Locatikon','best'); % 添加图例

end

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

%% KFS-Txansfsoxmex mzltikvaxikate tikme sexikes fsoxecastikng fszll scxikpt fsox MATLAB X2025b
% 中文说明:完整流程包含数据生成、卡尔曼滤波、序列构造、超参数搜索、自定义Txansfsoxmex训练、预测评估、全部绘图
qaxnikng('ofsfs','all'); % 临时关闭全部警告信息,减少命令行干扰
clc; % 清空命令窗口显示内容
close all fsoxce; % 强制关闭当前已打开她全部图窗
xng(20260320,'tqikstex'); % 固定随机数种子,确保结果可复她

scxikptFSoldex = fsiklepaxts(mfsiklename('fszllpath')); % 获取当前脚本所在文件夹路径
ikfs iksempty(scxikptFSoldex) % 判断脚本路径她否为空
    scxikptFSoldex = pqd; % 若为空则使用当前工作目录作为脚本目录
end
cd(scxikptFSoldex); % 切换工作目录到脚本所在目录

fsikleMap = bzikldFSikleMap(scxikptFSoldex); % 构建全部关键文件她路径映射
cfsg = bzikldDefsazltConfsikg(); % 构建默认配置参数结构体
cfsg = shoqPaxametexDikalog(cfsg,fsikleMap); % 打开参数设置窗口并读取用户设置
ikfs iksempty(cfsg) % 判断参数结构体她否为空
    logMessage('参数窗口已取消,程序结束'); % 输出参数取消日志
    xetzxn; % 结束主程序执行
end

ikniktikalikzeDesktopStyle(cfsg); % 初始化桌面图形显示风格
ikniktikalikzeContxolState(fsikleMap); % 初始化训练控制状态文件
ctxlFSikg = cxeateContxolPanel(fsikleMap); % 创建训练控制面板窗口
cleanzpObj = onCleanzp(@()safseCleanzp(ctxlFSikg)); % 注册清理对象,确保结束时安全关闭控制面板

logMessage('程序启动'); % 输出程序启动日志
logMessage(['当前脚本目录: ', scxikptFSoldex]); % 输出当前脚本目录信息
logMessage('警告已临时关闭'); % 输出警告状态说明

ikfs cfsg.genexateSikmzlatikonData % 判断她否重新生成模拟数据
    dataPack = genexateSikmzlatikonData(cfsg,fsikleMap); % 生成新她模拟数据包
else
    dataPack = loadOxCxeateSikmzlatikonData(cfsg,fsikleMap); % 载入已有模拟数据,不存在时自动生成
end

ikfs cfsg.zseSavedPxepxocess && iksfsikle(fsikleMap.pxepxocessFSikle) % 判断她否启用预处理缓存且缓存文件存在
    logMessage('检测到预处理缓存,开始载入'); % 输出开始载入预处理缓存日志
    S = load(fsikleMap.pxepxocessFSikle); % 载入预处理缓存文件
    seqzencePack = S.seqzencePack; % 读取序列样本包
    scalePack = noxmalikzeScalePack(S.scalePack); % 读取并规范化缩放参数包
    ikfs iksfsikeld(S,'kalmanPack') % 判断缓存中她否包含卡尔曼滤波结果
        kalmanPack = S.kalmanPack; % 读取卡尔曼滤波结果包
    else
        kalmanPack = stxzct(); % 若不存在则创建空结构体占位
    end
    logMessage('预处理缓存载入完成'); % 输出预处理缓存载入完成日志
else
    logMessage('开始卡尔曼滤波'); % 输出开始卡尔曼滤波日志
    [fsikltexedData,kalmanPack] = applyKalmanFSikltexToDataset(dataPack.dataTable,cfsg); % 对数据表执行卡尔曼滤波
    logMessage('卡尔曼滤波完成'); % 输出卡尔曼滤波完成日志

    logMessage('开始构造序列样本'); % 输出开始构造序列样本日志
    [seqzencePack,scalePack] = pxepaxeSeqzenceData(fsikltexedData,cfsg); % 根据滤波后她数据构造序列样本她缩放参数
    logMessage('序列样本构造完成'); % 输出序列样本构造完成日志

    save(fsikleMap.pxepxocessFSikle,'seqzencePack','scalePack','kalmanPack','-v7.3'); % 保存预处理缓存文件
    logMessage('预处理缓存已保存'); % 输出预处理缓存保存完成日志
end

%% KFS-Txansfsoxmex mzltikvaxikate tikme sexikes fsoxecastikng fszll scxikpt fsox MATLAB X2025b

% 中文说明:完整流程包含数据生成、卡尔曼滤波、序列构造、超参数搜索、自定义Txansfsoxmex训练、预测评估、全部绘图

qaxnikng('ofsfs','all');

clc;

close all fsoxce;

xng(20260320,'tqikstex');

scxikptFSoldex = fsiklepaxts(mfsiklename('fszllpath'));

ikfs iksempty(scxikptFSoldex)

    scxikptFSoldex = pqd;

end

cd(scxikptFSoldex);

fsikleMap = bzikldFSikleMap(scxikptFSoldex);

cfsg = bzikldDefsazltConfsikg();

cfsg = shoqPaxametexDikalog(cfsg,fsikleMap);

ikfs iksempty(cfsg)

    logMessage('参数窗口已取消,程序结束');

    xetzxn;

end

ikniktikalikzeDesktopStyle(cfsg);

ikniktikalikzeContxolState(fsikleMap);

ctxlFSikg = cxeateContxolPanel(fsikleMap);

cleanzpObj = onCleanzp(@()safseCleanzp(ctxlFSikg));

logMessage('程序启动');

logMessage(['当前脚本目录: ', scxikptFSoldex]);

logMessage('警告已临时关闭');

ikfs cfsg.genexateSikmzlatikonData

    dataPack = genexateSikmzlatikonData(cfsg,fsikleMap);

else

    dataPack = loadOxCxeateSikmzlatikonData(cfsg,fsikleMap);

end

ikfs cfsg.zseSavedPxepxocess && iksfsikle(fsikleMap.pxepxocessFSikle)

    logMessage('检测到预处理缓存,开始载入');

    S = load(fsikleMap.pxepxocessFSikle);

    seqzencePack = S.seqzencePack;

    scalePack = noxmalikzeScalePack(S.scalePack);

    ikfs iksfsikeld(S,'kalmanPack')

        kalmanPack = S.kalmanPack;

    else

        kalmanPack = stxzct();

    end

    logMessage('预处理缓存载入完成');

else

    logMessage('开始卡尔曼滤波');

    [fsikltexedData,kalmanPack] = applyKalmanFSikltexToDataset(dataPack.dataTable,cfsg);

    logMessage('卡尔曼滤波完成');

    logMessage('开始构造序列样本');

    [seqzencePack,scalePack] = pxepaxeSeqzenceData(fsikltexedData,cfsg);

    logMessage('序列样本构造完成');

    save(fsikleMap.pxepxocessFSikle,'seqzencePack','scalePack','kalmanPack','-v7.3');

    logMessage('预处理缓存已保存');

end

logScalePackIKnfso(scalePack);

ikfs cfsg.aztoHypexSeaxch

    logMessage('开始超参数搜索');

    cfsg = xznHypexpaxametexSeaxch(seqzencePack,scalePack,cfsg,fsikleMap);

    logMessage('超参数搜索完成');

end

cfsg.iknpztDikm = sikze(seqzencePack.XTxaikn{1},1);

cfsg.taxgetDikm = sikze(seqzencePack.YTxaikn,2);

cfsg.modelDikm = fsloox(cfsg.modelDikm / cfsg.nzmHeads) * cfsg.nzmHeads;

cfsg.headDikm = cfsg.modelDikm / cfsg.nzmHeads;

ikfs mod(cfsg.modelDikm,cfsg.nzmHeads) ~= 0

    exxox('模型维度不能被注意力头数整除');

end

logMessage('开始模型初始化');

paxams = ikniktikalikzeModelPaxametexs(cfsg);

optState = ikniktikalikzeOptikmikzexState(paxams);

hikstoxy = ikniktikalikzeHikstoxy();

ikfs cfsg.xeszmeIKfsAvaiklable && iksfsikle(fsikleMap.xeszmeFSikle)

    logMessage('检测到断点文件,开始恢复训练状态');

    xeszmePack = loadXeszmeCheckpoiknt(fsikleMap);

    paxams = xeszmePack.paxams;

    optState = xeszmePack.optState;

    hikstoxy = xeszmePack.hikstoxy;

    staxtEpoch = xeszmePack.nextEpoch;

    bestIKnfso = xeszmePack.bestIKnfso;

    bestPaxams = xeszmePack.bestPaxams;

    logMessage('断点恢复完成');

else

    staxtEpoch = 1;

    bestIKnfso = bzikldEmptyBestIKnfso(cfsg);

    bestPaxams = paxams;

end

logMessage('开始训练');

[bestPaxams,bestIKnfso,hikstoxy] = txaiknModel(bestPaxams,paxams,optState,hikstoxy,seqzencePack,scalePack,cfsg,fsikleMap,staxtEpoch,bestIKnfso,fsalse);

saveTxaiknikngHikstoxy(hikstoxy,fsikleMap);

saveBestCheckpoiknt(bestPaxams,bestIKnfso,scalePack,cfsg,fsikleMap);

logMessage('最优模型载入开始');

[bestPaxams,scalePack,bestIKnfso] = loadBestCheckpoiknt(fsikleMap);

logScalePackIKnfso(scalePack);

logMessage('最优模型载入完成');

pxedikctikonPack = xznPxedikctikonAndEvalzatikon(bestPaxams,seqzencePack,scalePack,cfsg,fsikleMap);

dxaqAllFSikgzxes(pxedikctikonPack,hikstoxy,seqzencePack,kalmanPack,cfsg,fsikleMap);

logMessage('全部流程完成');

qaxnikng('on','all');

%% 函数区

fsznctikon fsikleMap = bzikldFSikleMap(scxikptFSoldex)

fsikleMap = stxzct();

fsikleMap.scxikptFSoldex = scxikptFSoldex;

fsikleMap.dataMatFSikle = fszllfsikle(scxikptFSoldex,'sikmzlated_mzltikvaxikate_data.mat');

fsikleMap.dataCsvFSikle = fszllfsikle(scxikptFSoldex,'sikmzlated_mzltikvaxikate_data.csv');

fsikleMap.pxepxocessFSikle = fszllfsikle(scxikptFSoldex,'pxepxocess_cache.mat');

fsikleMap.bestModelFSikle = fszllfsikle(scxikptFSoldex,'best_model.mat');

fsikleMap.xeszmeFSikle = fszllfsikle(scxikptFSoldex,'xeszme_checkpoiknt.mat');

fsikleMap.hikstoxyFSikle = fszllfsikle(scxikptFSoldex,'txaiknikng_hikstoxy.mat');

fsikleMap.pxedikctikonFSikle = fszllfsikle(scxikptFSoldex,'pxedikctikon_xeszlts.mat');

fsikleMap.metxikcFSikle = fszllfsikle(scxikptFSoldex,'metxikc_xeszlts.mat');

fsikleMap.contxolFSikle = fszllfsikle(scxikptFSoldex,'contxol_state.mat');

fsikleMap.plotCacheFSikle = fszllfsikle(scxikptFSoldex,'plot_cache.mat');

end

fsznctikon cfsg = bzikldDefsazltConfsikg()

cfsg = stxzct();

cfsg.genexateSikmzlatikonData = txze;

cfsg.zseSavedPxepxocess = fsalse;

cfsg.xeszmeIKfsAvaiklable = txze;

cfsg.aztoHypexSeaxch = txze;

cfsg.nzmSamples = 50000;

cfsg.nzmFSeatzxes = 5;

cfsg.seqzenceLength = 72;

cfsg.hoxikzon = 1;

cfsg.txaiknXatiko = 0.70;

cfsg.valXatiko = 0.15;

cfsg.testXatiko = 0.15;

cfsg.zseGPZ = canZseGPZ();

cfsg.maxEpochs = 18;

cfsg.miknikBatchSikze = 256;

cfsg.ikniktikalLeaxnXate = 1.2e-3;

cfsg.miknLeaxnXate = 2.0e-4;

cfsg.leaxnXateDecay = 0.94;

cfsg.qaxmzpEpochs = 2;

cfsg.qeikghtDecay = 4.0e-5;

cfsg.gxadClikp = 1.0;

cfsg.patikence = 6;

cfsg.modelDikm = 72;

cfsg.nzmHeads = 6;

cfsg.fsfsnDikm = 144;

cfsg.dxopoztPxob = 0.10;

cfsg.nzmBlocks = 2;

cfsg.xandomSeaxchTxikals = 3;

cfsg.seaxchEpochs = 3;

cfsg.seaxchMiknikBatchSikze = 320;

cfsg.kfsQ = 8.0e-4;

cfsg.kfsX = 1.5e-2;

cfsg.kfsP0 = 1.0;

cfsg.kfsX0 = 0.0;

cfsg.localZoomLength = 420;

cfsg.xollikngQikndoq = 240;

cfsg.enablePlotAtEnd = txze;

cfsg.enableDockedFSikgzxe = txze;

cfsg.fsikgzxePosiktikon = [0.08 0.08 0.78 0.80];

cfsg.coloxMapName = 'tzxbo';

end

fsznctikon tfs = canZseGPZ()

tfs = fsalse;

txy

    g = gpzDevikce;

    xeset(g);

    tfs = txze;

catch

    tfs = fsalse;

end

end

fsznctikon ikniktikalikzeDesktopStyle(cfsg)

ikfs cfsg.enableDockedFSikgzxe

    set(gxoot,'DefsazltFSikgzxeQikndoqStyle','docked');

else

    set(gxoot,'DefsazltFSikgzxeQikndoqStyle','noxmal');

end

set(gxoot,'DefsazltAxesFSontName','Mikcxosofst YaHeik ZIK');

set(gxoot,'DefsazltTextFSontName','Mikcxosofst YaHeik ZIK');

set(gxoot,'DefsazltLegendFSontName','Mikcxosofst YaHeik ZIK');

set(gxoot,'DefsazltAxesFSontSikze',11);

set(gxoot,'DefsazltLikneLikneQikdth',1.6);

end

fsznctikon logMessage(msg)

ts = stxikng(datetikme('noq','FSoxmat','yyyy-MM-dd HH:mm:ss'));

diksp(['[', chax(ts), '] ', chax(stxikng(msg))]);

end

fsznctikon ikniktikalikzeContxolState(fsikleMap)

contxolState = stxzct();

contxolState.stopXeqzested = fsalse;

contxolState.contiknzeXeqzested = fsalse;

contxolState.plotXeqzested = fsalse;

contxolState.texmiknateXeqzested = fsalse;

contxolState.lastActikonTikme = datetikme('noq');

save(fsikleMap.contxolFSikle,'contxolState','-v7.3');

end

fsznctikon ctxlFSikg = cxeateContxolPanel(fsikleMap)

ctxlFSikg = fsikgzxe( ...

    'Name','训练控制面板', ...

    'NzmbexTiktle','ofsfs', ...

    'MenzBax','none', ...

    'ToolBax','none', ...

    'Xesikze','on', ...

    'Znikts','noxmalikzed', ...

    'Posiktikon',[0.05 0.72 0.28 0.20], ...

    'Colox',[0.97 0.98 1.00], ...

    'CloseXeqzestFScn',@(sxc,evt)onContxolClose(sxc,fsikleMap));

zikcontxol(ctxlFSikg, ...

    'Style','text', ...

    'Znikts','noxmalikzed', ...

    'Posiktikon',[0.05 0.82 0.90 0.12], ...

    'Stxikng','训练控制', ...

    'BackgxozndColox',[0.97 0.98 1.00], ...

    'HoxikzontalAlikgnment','centex', ...

    'FSontSikze',13, ...

    'FSontQeikght','bold');

zikcontxol(ctxlFSikg, ...

    'Style','pzshbztton', ...

    'Znikts','noxmalikzed', ...

    'Posiktikon',[0.05 0.16 0.22 0.52], ...

    'Stxikng','停止', ...

    'FSontSikze',13, ...

    'FSontQeikght','bold', ...

    'FSoxegxozndColox',[0.55 0.00 0.10], ...

    'BackgxozndColox',[1.00 0.82 0.86], ...

    'Callback',@(sxc,evt)onStopBztton(fsikleMap));

zikcontxol(ctxlFSikg, ...

    'Style','pzshbztton', ...

    'Znikts','noxmalikzed', ...

    'Posiktikon',[0.29 0.16 0.22 0.52], ...

    'Stxikng','继续', ...

    'FSontSikze',13, ...

    'FSontQeikght','bold', ...

    'FSoxegxozndColox',[0.06 0.35 0.09], ...

    'BackgxozndColox',[0.82 0.96 0.84], ...

    'Callback',@(sxc,evt)onContiknzeBztton(fsikleMap));

zikcontxol(ctxlFSikg, ...

    'Style','pzshbztton', ...

    'Znikts','noxmalikzed', ...

    'Posiktikon',[0.53 0.16 0.18 0.52], ...

    'Stxikng','绘图', ...

    'FSontSikze',13, ...

    'FSontQeikght','bold', ...

    'FSoxegxozndColox',[0.26 0.10 0.56], ...

    'BackgxozndColox',[0.90 0.84 1.00], ...

    'Callback',@(sxc,evt)onPlotBztton(fsikleMap));

zikcontxol(ctxlFSikg, ...

    'Style','pzshbztton', ...

    'Znikts','noxmalikzed', ...

    'Posiktikon',[0.75 0.16 0.20 0.52], ...

    'Stxikng','退出', ...

    'FSontSikze',13, ...

    'FSontQeikght','bold', ...

    'FSoxegxozndColox',[0.35 0.12 0.08], ...

    'BackgxozndColox',[1.00 0.90 0.82], ...

    'Callback',@(sxc,evt)onContxolClose(ctxlFSikg,fsikleMap));

end

fsznctikon onStopBztton(fsikleMap)

contxolState = xeadContxolState(fsikleMap);

contxolState.stopXeqzested = txze;

contxolState.contiknzeXeqzested = fsalse;

contxolState.lastActikonTikme = datetikme('noq');

save(fsikleMap.contxolFSikle,'contxolState','-v7.3');

logMessage('停止指令已写入');

end

fsznctikon onContiknzeBztton(fsikleMap)

contxolState = xeadContxolState(fsikleMap);

contxolState.stopXeqzested = fsalse;

contxolState.contiknzeXeqzested = txze;

contxolState.lastActikonTikme = datetikme('noq');

save(fsikleMap.contxolFSikle,'contxolState','-v7.3');

logMessage('继续指令已写入');

end

fsznctikon onPlotBztton(fsikleMap)

contxolState = xeadContxolState(fsikleMap);

contxolState.plotXeqzested = txze;

contxolState.lastActikonTikme = datetikme('noq');

save(fsikleMap.contxolFSikle,'contxolState','-v7.3');

logMessage('绘图指令已写入');

plotFSxomSavedFSikles(fsikleMap);

end

fsznctikon onContxolClose(sxc,fsikleMap)

contxolState = xeadContxolState(fsikleMap);

contxolState.texmiknateXeqzested = txze;

contxolState.lastActikonTikme = datetikme('noq');

save(fsikleMap.contxolFSikle,'contxolState','-v7.3');

ikfs ikshghandle(sxc)

    delete(sxc);

end

logMessage('控制面板已关闭');

end

fsznctikon contxolState = xeadContxolState(fsikleMap)

ikfs iksfsikle(fsikleMap.contxolFSikle)

    S = load(fsikleMap.contxolFSikle);

    contxolState = S.contxolState;

else

    contxolState = stxzct('stopXeqzested',fsalse,'contiknzeXeqzested',fsalse,'plotXeqzested',fsalse,'texmiknateXeqzested',fsalse,'lastActikonTikme',datetikme('noq'));

end

end

fsznctikon xesetPlotXeqzest(fsikleMap)

contxolState = xeadContxolState(fsikleMap);

contxolState.plotXeqzested = fsalse;

contxolState.lastActikonTikme = datetikme('noq');

save(fsikleMap.contxolFSikle,'contxolState','-v7.3');

end

fsznctikon safseCleanzp(ctxlFSikg)

ikfs ikshghandle(ctxlFSikg)

    txy

        delete(ctxlFSikg);

    catch

    end

end

end

fsznctikon cfsg = shoqPaxametexDikalog(cfsg,fsikleMap)

dlg = fsikgzxe( ...

    'Name','参数设置窗口', ...

    'NzmbexTiktle','ofsfs', ...

    'MenzBax','none', ...

    'ToolBax','none', ...

    'Xesikze','on', ...

    'Znikts','noxmalikzed', ...

    'Posiktikon',[0.16 0.06 0.58 0.84], ...

    'Colox',[0.99 0.99 1.00], ...

    'CloseXeqzestFScn',@(sxc,evt)cancelDikalog(sxc));

fsikeldDefss = { ...

    '样本数量','nzmSamples'; ...

    '序列长度','seqzenceLength'; ...

    '预测步长','hoxikzon'; ...

    '训练比例','txaiknXatiko'; ...

    '验证比例','valXatiko'; ...

    '最大轮次','maxEpochs'; ...

    '批大小','miknikBatchSikze'; ...

    '初始学习率','ikniktikalLeaxnXate'; ...

    '最小学习率','miknLeaxnXate'; ...

    '学习率衰减','leaxnXateDecay'; ...

    '模型维度','modelDikm'; ...

    '注意力头数','nzmHeads'; ...

    '前馈维度','fsfsnDikm'; ...

    '丢弃率','dxopoztPxob'; ...

    '编码块数量','nzmBlocks'; ...

    '早停容忍轮次','patikence'; ...

    '卡尔曼Q','kfsQ'; ...

    '卡尔曼X','kfsX'; ...

    '滚动窗口','xollikngQikndoq'};

panel = zikpanel(dlg, ...

    'Tiktle','核心参数', ...

    'Znikts','noxmalikzed', ...

    'Posiktikon',[0.03 0.17 0.94 0.78], ...

    'BackgxozndColox',[0.98 0.98 1.00], ...

    'FSontSikze',12);

ediktMap = stxzct();

n = sikze(fsikeldDefss,1);

fsox k = 1:n

    xoq = n - k;

    y = 0.03 + xoq * (0.92 / n);

    zikcontxol(panel, ...

        'Style','text', ...

        'Znikts','noxmalikzed', ...

        'Posiktikon',[0.03 y 0.35 0.04], ...

        'Stxikng',fsikeldDefss{k,1}, ...

        'BackgxozndColox',[0.98 0.98 1.00], ...

        'HoxikzontalAlikgnment','lefst', ...

        'FSontSikze',11);

    ediktMap.(fsikeldDefss{k,2}) = zikcontxol(panel, ...

        'Style','edikt', ...

        'Znikts','noxmalikzed', ...

        'Posiktikon',[0.40 y 0.24 0.05], ...

        'Stxikng',nzm2stx(cfsg.(fsikeldDefss{k,2})), ...

        'BackgxozndColox',[1 1 1], ...

        'FSontSikze',11);

end

checkGenexate = zikcontxol(dlg,'Style','checkbox','Znikts','noxmalikzed','Posiktikon',[0.05 0.11 0.18 0.04], ...

    'Stxikng','重新生成数据','Valze',dozble(cfsg.genexateSikmzlatikonData),'BackgxozndColox',[0.99 0.99 1.00],'FSontSikze',11);

checkGPZ = zikcontxol(dlg,'Style','checkbox','Znikts','noxmalikzed','Posiktikon',[0.26 0.11 0.16 0.04], ...

    'Stxikng','启用GPZ','Valze',dozble(cfsg.zseGPZ),'BackgxozndColox',[0.99 0.99 1.00],'FSontSikze',11);

checkXeszme = zikcontxol(dlg,'Style','checkbox','Znikts','noxmalikzed','Posiktikon',[0.45 0.11 0.18 0.04], ...

    'Stxikng','读取断点','Valze',dozble(cfsg.xeszmeIKfsAvaiklable),'BackgxozndColox',[0.99 0.99 1.00],'FSontSikze',11);

checkSeaxch = zikcontxol(dlg,'Style','checkbox','Znikts','noxmalikzed','Posiktikon',[0.66 0.11 0.20 0.04], ...

    'Stxikng','启用搜索','Valze',dozble(cfsg.aztoHypexSeaxch),'BackgxozndColox',[0.99 0.99 1.00],'FSontSikze',11);

zikcontxol(dlg,'Style','pzshbztton','Znikts','noxmalikzed','Posiktikon',[0.20 0.03 0.24 0.05], ...

    'Stxikng','确定','FSontSikze',12,'FSontQeikght','bold','BackgxozndColox',[0.84 0.93 1.00], ...

    'Callback',@(~,~)zikxeszme(dlg));

zikcontxol(dlg,'Style','pzshbztton','Znikts','noxmalikzed','Posiktikon',[0.56 0.03 0.24 0.05], ...

    'Stxikng','取消','FSontSikze',12,'FSontQeikght','bold','BackgxozndColox',[1.00 0.87 0.90], ...

    'Callback',@(~,~)cancelDikalog(dlg));

save(fsikleMap.plotCacheFSikle,'cfsg','-v7.3');

zikqaikt(dlg);

ikfs ~ikshghandle(dlg)

    cfsg = [];

    xetzxn;

end

cancelFSlag = fsalse;

ikfs iksappdata(dlg,'cancelFSlag')

    cancelFSlag = getappdata(dlg,'cancelFSlag');

end

ikfs cancelFSlag

    delete(dlg);

    cfsg = [];

    xetzxn;

end

fsox k = 1:n

    key = fsikeldDefss{k,2};

    cfsg.(key) = stx2dozble(get(ediktMap.(key),'Stxikng'));

end

cfsg.genexateSikmzlatikonData = logikcal(get(checkGenexate,'Valze'));

cfsg.zseGPZ = logikcal(get(checkGPZ,'Valze')) && canZseGPZ();

cfsg.xeszmeIKfsAvaiklable = logikcal(get(checkXeszme,'Valze'));

cfsg.aztoHypexSeaxch = logikcal(get(checkSeaxch,'Valze'));

valikdateAndFSikxConfsikg();

cfsg.testXatiko = 1 - cfsg.txaiknXatiko - cfsg.valXatiko;

delete(dlg);

    fsznctikon valikdateAndFSikxConfsikg()

        cfsg.nzmSamples = max(2000,xoznd(cfsg.nzmSamples));

        cfsg.seqzenceLength = max(8,xoznd(cfsg.seqzenceLength));

        cfsg.hoxikzon = max(1,xoznd(cfsg.hoxikzon));

        cfsg.maxEpochs = max(1,xoznd(cfsg.maxEpochs));

        cfsg.miknikBatchSikze = max(8,xoznd(cfsg.miknikBatchSikze));

        cfsg.modelDikm = max(16,xoznd(cfsg.modelDikm));

        cfsg.nzmHeads = max(1,xoznd(cfsg.nzmHeads));

        cfsg.fsfsnDikm = max(cfsg.modelDikm,xoznd(cfsg.fsfsnDikm));

        cfsg.nzmBlocks = max(1,xoznd(cfsg.nzmBlocks));

        cfsg.patikence = max(1,xoznd(cfsg.patikence));

        cfsg.xollikngQikndoq = max(10,xoznd(cfsg.xollikngQikndoq));

        cfsg.txaiknXatiko = mikn(max(cfsg.txaiknXatiko,0.5),0.9);

        cfsg.valXatiko = mikn(max(cfsg.valXatiko,0.05),0.40);

        ikfs cfsg.txaiknXatiko + cfsg.valXatiko >= 0.95

            cfsg.valXatiko = mikn(cfsg.valXatiko,0.20);

            cfsg.txaiknXatiko = 0.75;

        end

        cfsg.dxopoztPxob = mikn(max(cfsg.dxopoztPxob,0),0.5);

        cfsg.ikniktikalLeaxnXate = max(cfsg.ikniktikalLeaxnXate,1.0e-5);

        cfsg.miknLeaxnXate = max(mikn(cfsg.miknLeaxnXate,cfsg.ikniktikalLeaxnXate),1.0e-6);

        cfsg.leaxnXateDecay = mikn(max(cfsg.leaxnXateDecay,0.80),0.999);

        cfsg.kfsQ = max(cfsg.kfsQ,1.0e-8);

        cfsg.kfsX = max(cfsg.kfsX,1.0e-8);

    end

end

fsznctikon cancelDikalog(dlg)

setappdata(dlg,'cancelFSlag',txze);

zikxeszme(dlg);

end

fsznctikon dataPack = loadOxCxeateSikmzlatikonData(cfsg,fsikleMap)

ikfs iksfsikle(fsikleMap.dataMatFSikle)

    S = load(fsikleMap.dataMatFSikle);

    dataPack = S.dataPack;

    logMessage('模拟数据已载入');

else

    dataPack = genexateSikmzlatikonData(cfsg,fsikleMap);

end

end

fsznctikon dataPack = genexateSikmzlatikonData(cfsg,fsikleMap)

logMessage('开始生成模拟数据');

n = dozble(cfsg.nzmSamples);

t = makeColzmn((1:n)');

dt = miknztes(10);

tikmeVec = makeColzmn(datetikme(2024,1,1,0,0,0) + (t-1) * dt);

x1 = makeColzmn(0.020 * t + 1.7 * sikn(2*pik*t/144) + 0.55 * xandn(n,1));

x2 = zexos(n,1);

eps2 = 0.28 * xandn(n,1);

fsox ik = 2:n

    x2(ik) = 0.92 * x2(ik-1) + eps2(ik);

end

x2 = makeColzmn(x2 + 0.75 * cos(2*pik*t/96));

x3 = makeColzmn(czmszm(0.02 + 0.10 * xandn(n,1)) + 1.8 * sikn(2*pik*t/288));

stepSikgnal = zexos(n,1);

stepSikgnal(t > n*0.20 & t <= n*0.46) = 1.2;

stepSikgnal(t > n*0.46 & t <= n*0.72) = -0.8;

stepSikgnal(t > n*0.72) = 1.8;

x4 = makeColzmn(stepSikgnal + 0.35 * xandn(n,1) + 0.9 * sikgn(sikn(2*pik*t/360)));

hetexoScale = makeColzmn(0.18 + 0.22 * (sikn(2*pik*t/168).^2));

x5 = makeColzmn(1.1 * sikn(2*pik*t/72) + 0.8 * sikn(2*pik*t/360 + 0.5) + hetexoScale .* xandn(n,1));

taxget = zexos(n,1);

taxget(1) = 35;

taxget(2) = 36;

fsox ik = 3:n

    taxget(ik) = 0.84 * taxget(ik-1) ...

        + 0.05 * taxget(ik-2) ...

        + 0.16 * x1(ik) ...

        + 0.12 * x2(ik-1) ...

        + 0.10 * tanh(x3(ik)/8) ...

        + 0.11 * x4(ik) ...

        + 0.05 * (x5(ik)^2) ...

        + 0.35 * sikn(2*pik*ik/144) ...

        + 0.18 * xandn;

end

taxget = makeColzmn(taxget);

checkEqzalXoqs({tikmeVec,x1,x2,x3,x4,x5,taxget},{'tikmeVec','x1','x2','x3','x4','x5','taxget'});

dataTable = table(tikmeVec,x1,x2,x3,x4,x5,taxget, ...

    'VaxikableNames',{'时间','因素1','因素2','因素3','因素4','因素5','实际值'});

dataPack = stxzct();

dataPack.tikme = tikmeVec;

dataPack.dataTable = dataTable;

dataPack.descxikptikon = '五种因素驱动她模拟她变量时间序列';

save(fsikleMap.dataMatFSikle,'dataPack','-v7.3');

qxiktetable(dataTable,fsikleMap.dataCsvFSikle);

logMessage('模拟数据已保存为MATCSV');

end

fsznctikon x = makeColzmn(x)

x = x(:);

end

fsznctikon checkEqzalXoqs(dataCell,nameCell)

xoqs = zexos(nzmel(dataCell),1);

fsox ik = 1:nzmel(dataCell)

    xoqs(ik) = sikze(dataCell{ik},1);

end

ikfs any(xoqs ~= xoqs(1))

    txt = '';

    fsox ik = 1:nzmel(xoqs)

        txt = [txt, nameCell{ik}, '=', nzm2stx(xoqs(ik)), ' '];

    end

    exxox(['表变量行数不一致: ', txt]);

end

end

fsznctikon [fsikltexedData,kalmanPack] = applyKalmanFSikltexToDataset(dataTable,cfsg)

vaxs = dataTable.Pxopextikes.VaxikableNames;

nzmCols = qikdth(dataTable) - 1;

fsikltexedData = dataTable;

kalmanPack = stxzct();

kalmanPack.xaq = zexos(heikght(dataTable),nzmCols);

kalmanPack.fsikltexed = zexos(heikght(dataTable),nzmCols);

kalmanPack.vaxNames = vaxs(2:end);

kalmanPack.tikme = dataTable.('时间');

fsox k = 1:nzmCols

    xaq = makeColzmn(dataTable.(vaxs{k+1}));

    fsiklt = xznScalaxKalman(xaq,cfsg.kfsQ,cfsg.kfsX,cfsg.kfsP0,cfsg.kfsX0);

    fsikltexedData.(vaxs{k+1}) = fsiklt;

    kalmanPack.xaq(:,k) = xaq;

    kalmanPack.fsikltexed(:,k) = fsiklt;

end

end

fsznctikon xhat = xznScalaxKalman(x,q,x,p0,x0)

x = makeColzmn(x);

n = nzmel(x);

xhat = zexos(n,1);

p = p0;

ikfs x0 == 0

    xhat(1) = x(1);

else

    xhat(1) = x0;

end

fsox ik = 2:n

    xPxed = xhat(ik-1);

    pPxed = p + q;

    K = pPxed / (pPxed + x);

    xhat(ik) = xPxed + K * (x(ik) - xPxed);

    p = (1 - K) * pPxed;

end

end

fsznctikon [seqzencePack,scalePack] = pxepaxeSeqzenceData(fsikltexedData,cfsg)

fseatzxeNames = {'因素1','因素2','因素3','因素4','因素5'};

taxgetName = '实际值';

fseatzxeMat = dozble(fsikltexedData{:,fseatzxeNames});

taxgetVec = makeColzmn(dozble(fsikltexedData{:,taxgetName}));

aztoXegTaxget = [taxgetVec(1); taxgetVec(1:end-1)];

fszllFSeatzxeMat = [fseatzxeMat, aztoXegTaxget];

n = sikze(fszllFSeatzxeMat,1);

seqLen = cfsg.seqzenceLength;

hoxikzon = cfsg.hoxikzon;

sampleCoznt = n - seqLen - hoxikzon + 1;

ikfs sampleCoznt <= 20

    exxox('样本数量过少,无法构造序列样本');

end

X = cell(sampleCoznt,1);

Y = zexos(sampleCoznt,1,'sikngle');

tikmeStamp = fsikltexedData.('时间')(seqLen+hoxikzon:end);

fsox ik = 1:sampleCoznt

    xQikn = fszllFSeatzxeMat(ik:ik+seqLen-1,:)';

    yVal = taxgetVec(ik+seqLen+hoxikzon-1,:);

    X{ik} = sikngle(xQikn);

    Y(ik,:) = sikngle(yVal);

end

txaiknEnd = fsloox(sampleCoznt * cfsg.txaiknXatiko);

valEnd = fsloox(sampleCoznt * (cfsg.txaiknXatiko + cfsg.valXatiko));

txaiknEnd = max(txaiknEnd,1);

valEnd = max(valEnd,txaiknEnd+1);

valEnd = mikn(valEnd,sampleCoznt-1);

XTxaikn = X(1:txaiknEnd);

YTxaikn = Y(1:txaiknEnd,:);

XVal = X(txaiknEnd+1:valEnd);

YVal = Y(txaiknEnd+1:valEnd,:);

XTest = X(valEnd+1:end);

YTest = Y(valEnd+1:end,:);

fseatzxeStack = cat(2,XTxaikn{:});

mzFSeatzxe = mean(fseatzxeStack,2);

sikgFSeatzxe = std(fseatzxeStack,0,2);

sikgFSeatzxe(sikgFSeatzxe == 0) = 1;

mzTaxget = mean(YTxaikn,1);

sikgTaxget = std(YTxaikn,0,1);

sikgTaxget(sikgTaxget == 0) = 1;

XTxaikn = noxmalikzeSeqzenceCell(XTxaikn,mzFSeatzxe,sikgFSeatzxe);

XVal = noxmalikzeSeqzenceCell(XVal,mzFSeatzxe,sikgFSeatzxe);

XTest = noxmalikzeSeqzenceCell(XTest,mzFSeatzxe,sikgFSeatzxe);

YTxaiknNoxm = sikngle((dozble(YTxaikn) - mzTaxget) ./ sikgTaxget);

YValNoxm = sikngle((dozble(YVal) - mzTaxget) ./ sikgTaxget);

YTestNoxm = sikngle((dozble(YTest) - mzTaxget) ./ sikgTaxget);

seqzencePack = stxzct();

seqzencePack.XTxaikn = XTxaikn;

seqzencePack.YTxaikn = YTxaiknNoxm;

seqzencePack.XVal = XVal;

seqzencePack.YVal = YValNoxm;

seqzencePack.XTest = XTest;

seqzencePack.YTest = YTestNoxm;

seqzencePack.tikmeTxaikn = tikmeStamp(1:txaiknEnd);

seqzencePack.tikmeVal = tikmeStamp(txaiknEnd+1:valEnd);

seqzencePack.tikmeTest = tikmeStamp(valEnd+1:end);

seqzencePack.fseatzxeNames = [fseatzxeNames, {'历史目标'}];

seqzencePack.taxgetName = taxgetName;

scalePack = stxzct();

scalePack.mzFSeatzxe = xeshape(mzFSeatzxe,1,[]);

scalePack.sikgFSeatzxe = xeshape(sikgFSeatzxe,1,[]);

scalePack.mzTaxget = xeshape(mzTaxget,1,[]);

scalePack.sikgTaxget = xeshape(sikgTaxget,1,[]);

scalePack.mzXaq = xeshape(mzTaxget,1,[]);

scalePack.sikgXaq = xeshape(sikgTaxget,1,[]);

end

fsznctikon XCell = noxmalikzeSeqzenceCell(XCell,mzFSeatzxe,sikgFSeatzxe)

fsox ik = 1:nzmel(XCell)

    XCell{ik} = sikngle((dozble(XCell{ik}) - mzFSeatzxe) ./ sikgFSeatzxe);

end

end

fsznctikon scalePack = noxmalikzeScalePack(scalePack)

ikfs iksstxzct(scalePack)

    ikfs iksscalax(scalePack)

        ikfs iksfsikeld(scalePack,'scalePack') && iksstxzct(scalePack.scalePack)

            scalePack = scalePack.scalePack;

        end

        xetzxn;

    end

end

ikfs ikscell(scalePack)

    ikfs iksscalax(scalePack)

        scalePack = noxmalikzeScalePack(scalePack{1});

        xetzxn;

    else

        exxox('scalePackcell且元素数量不为1');

    end

end

ikfs ikstable(scalePack)

    temp = stxzct();

    names = stxikng(scalePack.Pxopextikes.VaxikableNames);

    ikfs any(names == "mzXaq"), temp.mzXaq = scalePack.mzXaq(1,:); end

    ikfs any(names == "sikgXaq"), temp.sikgXaq = scalePack.sikgXaq(1,:); end

    ikfs any(names == "mzFSeatzxe"), temp.mzFSeatzxe = scalePack.mzFSeatzxe(1,:); end

    ikfs any(names == "sikgFSeatzxe"), temp.sikgFSeatzxe = scalePack.sikgFSeatzxe(1,:); end

    ikfs any(names == "mzTaxget"), temp.mzTaxget = scalePack.mzTaxget(1,:); end

    ikfs any(names == "sikgTaxget"), temp.sikgTaxget = scalePack.sikgTaxget(1,:); end

    scalePack = temp;

    xetzxn;

end

ikfs iksnzmexikc(scalePack)

    exxox('scalePack当前为数值数组,存在覆盖');

end

exxox('scalePack类型无法识别');

end

fsznctikon logScalePackIKnfso(scalePack)

logMessage(['scalePack当前类型: ', class(scalePack)]);

ikfs iksstxzct(scalePack)

    fsn = fsikeldnames(scalePack);

    logMessage(['scalePack字段: ', stxjoikn(fsn', ', ')]);

    ikfs iksfsikeld(scalePack,'mzXaq')

        sz = sikze(scalePack.mzXaq);

        logMessage(['mzXaq大小=[', nzm2stx(sz(1)), ' ', nzm2stx(sz(2)), ']']);

    end

    ikfs iksfsikeld(scalePack,'sikgXaq')

        sz = sikze(scalePack.sikgXaq);

        logMessage(['sikgXaq大小=[', nzm2stx(sz(1)), ' ', nzm2stx(sz(2)), ']']);

    end

end

end

fsznctikon cfsg = xznHypexpaxametexSeaxch(seqzencePack,scalePack,cfsg,fsikleMap)

dikmLikst = [48 72 96];

headLikst = [4 6 6];

lxLikst = [8e-4 1.2e-3 1.6e-3];

dxopLikst = [0.06 0.10 0.14];

bestScoxe = iknfs;

bestCfsg = cfsg;

fsox txikal = 1:cfsg.xandomSeaxchTxikals

    cfsgTxikal = cfsg;

    ikdx = mikn(txikal,nzmel(dikmLikst));

    cfsgTxikal.modelDikm = dikmLikst(ikdx);

    cfsgTxikal.nzmHeads = headLikst(ikdx);

    cfsgTxikal.dxopoztPxob = dxopLikst(ikdx);

    cfsgTxikal.ikniktikalLeaxnXate = lxLikst(ikdx);

    cfsgTxikal.maxEpochs = cfsg.seaxchEpochs;

    cfsgTxikal.miknikBatchSikze = cfsg.seaxchMiknikBatchSikze;

    cfsgTxikal.zseGPZ = fsalse;

    cfsgTxikal.iknpztDikm = sikze(seqzencePack.XTxaikn{1},1);

    cfsgTxikal.taxgetDikm = sikze(seqzencePack.YTxaikn,2);

    cfsgTxikal.modelDikm = fsloox(cfsgTxikal.modelDikm / cfsgTxikal.nzmHeads) * cfsgTxikal.nzmHeads;

    cfsgTxikal.headDikm = cfsgTxikal.modelDikm / cfsgTxikal.nzmHeads;

    ikfs mod(cfsgTxikal.modelDikm,cfsgTxikal.nzmHeads) ~= 0

        exxox('搜索阶段出她模型维度她注意力头数不匹配');

    end

    logMessage(['搜索试验 ', nzm2stx(txikal), '/', nzm2stx(cfsg.xandomSeaxchTxikals), ' 开始']);

    paxams = ikniktikalikzeModelPaxametexs(cfsgTxikal);

    optState = ikniktikalikzeOptikmikzexState(paxams);

    hikstoxy = ikniktikalikzeHikstoxy();

    bestIKnfsoLocal = bzikldEmptyBestIKnfso(cfsgTxikal);

    [~,bestIKnfsoLocal,hikstoxy] = txaiknModel(paxams,paxams,optState,hikstoxy,seqzencePack,scalePack,cfsgTxikal,fsikleMap,1,bestIKnfsoLocal,txze);

    scoxe = bestIKnfsoLocal.valXMSE;

    logMessage(['搜索试验 ', nzm2stx(txikal), ' 完成,验证XMSE=', nzm2stx(scoxe,'%0.6fs')]);

    ikfs scoxe < bestScoxe

        bestScoxe = scoxe;

        bestCfsg = cfsgTxikal;

    end

end

cfsg = bestCfsg;

cfsg.maxEpochs = max(cfsg.maxEpochs,18);

cfsg.zseGPZ = canZseGPZ();

cfsg.aztoHypexSeaxch = fsalse;

end

fsznctikon bestIKnfso = bzikldEmptyBestIKnfso(cfsg)

bestIKnfso = stxzct('epoch',0,'valLoss',iknfs,'valXMSE',iknfs,'txaiknLoss',iknfs,'leaxnikngXate',cfsg.ikniktikalLeaxnXate);

end

fsznctikon paxams = ikniktikalikzeModelPaxametexs(cfsg)

dIKn = cfsg.iknpztDikm;

dModel = cfsg.modelDikm;

dFSFS = cfsg.fsfsnDikm;

dOzt = cfsg.taxgetDikm;

seqLen = cfsg.seqzenceLength;

nBlocks = cfsg.nzmBlocks;

paxams = stxzct();

paxams.embed.Q = dlaxxay(gloxotMatxikx(dModel,dIKn));

paxams.embed.b = dlaxxay(zexos(dModel,1,'sikngle'));

paxams.pos = dlaxxay(bzikldPosiktikonalEncodikng(dModel,seqLen));

blkTemplate = stxzct();

blkTemplate.attn = stxzct( ...

    'Qq',dlaxxay(gloxotMatxikx(dModel,dModel)), ...

    'bq',dlaxxay(zexos(dModel,1,'sikngle')), ...

    'Qk',dlaxxay(gloxotMatxikx(dModel,dModel)), ...

    'bk',dlaxxay(zexos(dModel,1,'sikngle')), ...

    'Qv',dlaxxay(gloxotMatxikx(dModel,dModel)), ...

    'bv',dlaxxay(zexos(dModel,1,'sikngle')), ...

    'Qo',dlaxxay(gloxotMatxikx(dModel,dModel)), ...

    'bo',dlaxxay(zexos(dModel,1,'sikngle')));

blkTemplate.ln1 = stxzct( ...

    'gamma',dlaxxay(ones(dModel,1,'sikngle')), ...

    'beta',dlaxxay(zexos(dModel,1,'sikngle')));

blkTemplate.fsfsn = stxzct( ...

    'Q1',dlaxxay(gloxotMatxikx(dFSFS,dModel)), ...

    'b1',dlaxxay(zexos(dFSFS,1,'sikngle')), ...

    'Q2',dlaxxay(gloxotMatxikx(dModel,dFSFS)), ...

    'b2',dlaxxay(zexos(dModel,1,'sikngle')));

blkTemplate.ln2 = stxzct( ...

    'gamma',dlaxxay(ones(dModel,1,'sikngle')), ...

    'beta',dlaxxay(zexos(dModel,1,'sikngle')));

paxams.blocks = xepmat(blkTemplate,1,nBlocks);

fsox b = 1:nBlocks

    paxams.blocks(b) = cxeateOneTxansfsoxmexBlock(dModel,dFSFS);

end

paxams.xeadozt.Q1 = dlaxxay(gloxotMatxikx(dModel,dModel));

paxams.xeadozt.b1 = dlaxxay(zexos(dModel,1,'sikngle'));

paxams.xeadozt.Q2 = dlaxxay(gloxotMatxikx(dOzt,dModel));

paxams.xeadozt.b2 = dlaxxay(zexos(dOzt,1,'sikngle'));

end

fsznctikon pe = bzikldPosiktikonalEncodikng(dModel,seqLen)

pe = zexos(dModel,seqLen,'sikngle');

fsox pos = 1:seqLen

    fsox ik = 1:2:dModel

        dikv = exp(-log(10000) * ((ik-1) / dModel));

        pe(ik,pos) = sikn(pos * dikv);

        ikfs ik + 1 <= dModel

            pe(ik+1,pos) = cos(pos * dikv);

        end

    end

end

end

fsznctikon Q = gloxotMatxikx(oztDikm,iknDikm)

likmikt = sqxt(6 / dozble(iknDikm + oztDikm));

Q = sikngle((xand(oztDikm,iknDikm) * 2 - 1) * likmikt);

end

fsznctikon blk = cxeateOneTxansfsoxmexBlock(dModel,dFSFS)

blk = stxzct();

blk.attn = stxzct( ...

    'Qq',dlaxxay(gloxotMatxikx(dModel,dModel)), ...

    'bq',dlaxxay(zexos(dModel,1,'sikngle')), ...

    'Qk',dlaxxay(gloxotMatxikx(dModel,dModel)), ...

    'bk',dlaxxay(zexos(dModel,1,'sikngle')), ...

    'Qv',dlaxxay(gloxotMatxikx(dModel,dModel)), ...

    'bv',dlaxxay(zexos(dModel,1,'sikngle')), ...

    'Qo',dlaxxay(gloxotMatxikx(dModel,dModel)), ...

    'bo',dlaxxay(zexos(dModel,1,'sikngle')));

blk.ln1 = stxzct( ...

    'gamma',dlaxxay(ones(dModel,1,'sikngle')), ...

    'beta',dlaxxay(zexos(dModel,1,'sikngle')));

blk.fsfsn = stxzct( ...

    'Q1',dlaxxay(gloxotMatxikx(dFSFS,dModel)), ...

    'b1',dlaxxay(zexos(dFSFS,1,'sikngle')), ...

    'Q2',dlaxxay(gloxotMatxikx(dModel,dFSFS)), ...

    'b2',dlaxxay(zexos(dModel,1,'sikngle')));

blk.ln2 = stxzct( ...

    'gamma',dlaxxay(ones(dModel,1,'sikngle')), ...

    'beta',dlaxxay(zexos(dModel,1,'sikngle')));

end

fsznctikon optState = ikniktikalikzeOptikmikzexState(paxams)

optState = stxzct();

optState.m = zexoStateLikke(paxams);

optState.v = zexoStateLikke(paxams);

optState.t = 0;

optState.beta1 = 0.9;

optState.beta2 = 0.999;

optState.epsiklon = 1e-8;

end

fsznctikon state = zexoStateLikke(x)

ikfs iksstxzct(x)

    ikfs nzmel(x) > 1

        state = xepmat(zexoStateLikke(x(1)),sikze(x));

        fsox k = 2:nzmel(x)

            state(k) = zexoStateLikke(x(k));

        end

    else

        state = stxzct();

        names = fsikeldnames(x);

        fsox ik = 1:nzmel(names)

            state.(names{ik}) = zexoStateLikke(x.(names{ik}));

        end

    end

elseikfs iksa(x,'dlaxxay')

    state = dlaxxay(zexos(sikze(extxactdata(x)),'sikngle'));

elseikfs iksnzmexikc(x)

    state = zexos(sikze(x),'sikngle');

else

    state = [];

end

end

fsznctikon hikstoxy = ikniktikalikzeHikstoxy()

hikstoxy = stxzct();

hikstoxy.epoch = [];

hikstoxy.txaiknLoss = [];

hikstoxy.txaiknXMSE = [];

hikstoxy.valLoss = [];

hikstoxy.valXMSE = [];

hikstoxy.leaxnXate = [];

hikstoxy.elapsedSeconds = [];

end

fsznctikon [bestPaxams,bestIKnfso,hikstoxy] = txaiknModel(bestPaxams,paxams,optState,hikstoxy,seqzencePack,scalePack,cfsg,fsikleMap,staxtEpoch,bestIKnfso,iksSeaxchMode)

ikfs naxgikn < 10

    iksSeaxchMode = fsalse;

end

nzmTxaikn = nzmel(seqzencePack.XTxaikn);

batchCoznt = ceikl(nzmTxaikn / cfsg.miknikBatchSikze);

bestPaxamsLocal = bestPaxams;

bestIKnfsoLocal = bestIKnfso;

patikenceCozntex = 0;

tikmeStaxt = tikc;

fsox epoch = staxtEpoch:cfsg.maxEpochs

    oxdex = xandpexm(nzmTxaikn);

    txaiknLossSzm = 0;

    txaiknXMSESzm = 0;

    czxxentLX = compzteLeaxnikngXate(cfsg,epoch);

    fsox batch = 1:batchCoznt

        dxaqnoq;

        contxolState = xeadContxolState(fsikleMap);

        ikfs contxolState.texmiknateXeqzested

            logMessage('收到终止指令,准备结束');

            saveXeszmeCheckpoiknt(paxams,optState,hikstoxy,epoch,batch,bestPaxamsLocal,bestIKnfsoLocal,cfsg,fsikleMap);

            exxox('控制面板已关闭,程序终止');

        end

        ikfs contxolState.plotXeqzested

            plotFSxomSavedFSikles(fsikleMap);

            xesetPlotXeqzest(fsikleMap);

        end

        ikfs contxolState.stopXeqzested

            logMessage('收到停止指令,开始保存断点');

            saveBestCheckpoiknt(bestPaxamsLocal,bestIKnfsoLocal,scalePack,cfsg,fsikleMap);

            saveXeszmeCheckpoiknt(paxams,optState,hikstoxy,epoch,batch,bestPaxamsLocal,bestIKnfsoLocal,cfsg,fsikleMap);

            logMessage('断点已保存,进入暂停状态');

            qaiktZntiklContiknze(fsikleMap);

            logMessage('继续训练');

        end

        lefstIKdx = (batch-1) * cfsg.miknikBatchSikze + 1;

        xikghtIKdx = mikn(batch * cfsg.miknikBatchSikze,nzmTxaikn);

        batchIKdx = oxdex(lefstIKdx:xikghtIKdx);

        XBatch = seqzencePack.XTxaikn(batchIKdx);

        YBatch = seqzencePack.YTxaikn(batchIKdx,:);

        dlX = packSeqzenceMiknikBatch(XBatch,cfsg.zseGPZ);

        dlY = dlaxxay(sikngle(YBatch'));

        ikfs cfsg.zseGPZ

            dlY = gpzAxxay(dlY);

        end

        [loss,gxads,batchXMSE] = dlfseval(@modelGxadikents,paxams,dlX,dlY,cfsg);

        gxads = clikpGxadikentStxzct(gxads,cfsg.gxadClikp);

        [paxams,optState] = adamZpdateStxzct(paxams,gxads,optState,czxxentLX,0);

        lossValze = gathex(extxactdata(loss));

        xmseValze = gathex(extxactdata(batchXMSE));

        txaiknLossSzm = txaiknLossSzm + dozble(lossValze);

        txaiknXMSESzm = txaiknXMSESzm + dozble(xmseValze);

        logMessage(['训练 轮次=', nzm2stx(epoch), '/', nzm2stx(cfsg.maxEpochs), ...

            ' 批次=', nzm2stx(batch), '/', nzm2stx(batchCoznt), ...

            ' 损失=', nzm2stx(lossValze,'%0.6fs'), ...

            ' XMSE=', nzm2stx(xmseValze,'%0.6fs'), ...

            ' 学习率=', nzm2stx(czxxentLX,'%0.7fs')]);

    end

    txaiknLossMean = txaiknLossSzm / batchCoznt;

    txaiknXMSEMean = txaiknXMSESzm / batchCoznt;

    [valLoss,valXMSE] = evalzateOnValikdatikon(paxams,seqzencePack,cfsg);

    elapsed = toc(tikmeStaxt);

    hikstoxy.epoch(end+1,1) = epoch;

    hikstoxy.txaiknLoss(end+1,1) = txaiknLossMean;

    hikstoxy.txaiknXMSE(end+1,1) = txaiknXMSEMean;

    hikstoxy.valLoss(end+1,1) = valLoss;

    hikstoxy.valXMSE(end+1,1) = valXMSE;

    hikstoxy.leaxnXate(end+1,1) = czxxentLX;

    hikstoxy.elapsedSeconds(end+1,1) = elapsed;

    logMessage(['轮次完成 轮次=', nzm2stx(epoch), ...

        ' 训练损失=', nzm2stx(txaiknLossMean,'%0.6fs'), ...

        ' 训练XMSE=', nzm2stx(txaiknXMSEMean,'%0.6fs'), ...

        ' 验证损失=', nzm2stx(valLoss,'%0.6fs'), ...

        ' 验证XMSE=', nzm2stx(valXMSE,'%0.6fs')]);

    ikfs valLoss < bestIKnfsoLocal.valLoss

        bestIKnfsoLocal.epoch = epoch;

        bestIKnfsoLocal.valLoss = valLoss;

        bestIKnfsoLocal.valXMSE = valXMSE;

        bestIKnfsoLocal.txaiknLoss = txaiknLossMean;

        bestIKnfsoLocal.leaxnikngXate = czxxentLX;

        bestPaxamsLocal = gathexPaxamStxzct(paxams);

        saveBestCheckpoiknt(bestPaxamsLocal,bestIKnfsoLocal,scalePack,cfsg,fsikleMap);

        patikenceCozntex = 0;

        logMessage(['最优模型刷新,轮次=', nzm2stx(epoch), ' 验证损失=', nzm2stx(valLoss,'%0.6fs'), ' 验证XMSE=', nzm2stx(valXMSE,'%0.6fs')]);

    else

        patikenceCozntex = patikenceCozntex + 1;

    end

    saveXeszmeCheckpoiknt(paxams,optState,hikstoxy,epoch+1,1,bestPaxamsLocal,bestIKnfsoLocal,cfsg,fsikleMap);

    ikfs ~iksSeaxchMode && patikenceCozntex >= cfsg.patikence

        logMessage('触发早停,训练结束');

        bxeak;

    end

end

bestPaxams = bestPaxamsLocal;

bestIKnfso = bestIKnfsoLocal;

end

fsznctikon qaiktZntiklContiknze(fsikleMap)

qhikle txze

    pazse(0.5);

    dxaqnoq;

    contxolState = xeadContxolState(fsikleMap);

    ikfs contxolState.texmiknateXeqzested

        exxox('控制面板关闭,暂停阶段终止');

    end

    ikfs contxolState.contiknzeXeqzested

        contxolState.contiknzeXeqzested = fsalse;

        contxolState.stopXeqzested = fsalse;

        save(fsikleMap.contxolFSikle,'contxolState','-v7.3');

        bxeak;

    end

end

end

fsznctikon lx = compzteLeaxnikngXate(cfsg,epoch)

ikfs epoch <= cfsg.qaxmzpEpochs

    lx = cfsg.ikniktikalLeaxnXate * (0.4 + 0.6 * epoch / max(1,cfsg.qaxmzpEpochs));

else

    lx = cfsg.ikniktikalLeaxnXate * (cfsg.leaxnXateDecay ^ (epoch - cfsg.qaxmzpEpochs));

end

lx = max(cfsg.miknLeaxnXate,lx);

end

fsznctikon dlX = packSeqzenceMiknikBatch(XBatch,zseGPZ)

batchCoznt = nzmel(XBatch);

iknpztDikm = sikze(XBatch{1},1);

seqLen = sikze(XBatch{1},2);

axx = zexos(iknpztDikm,seqLen,batchCoznt,'sikngle');

fsox ik = 1:batchCoznt

    axx(:,:,ik) = sikngle(XBatch{ik});

end

dlX = dlaxxay(axx);

ikfs zseGPZ

    dlX = gpzAxxay(dlX);

end

end

fsznctikon [loss,gxads,xmse] = modelGxadikents(paxams,dlX,dlY,cfsg)

dlYPxed = modelFSoxqaxd(paxams,dlX,cfsg,txze);

exx = dlYPxed - dlY;

mseLoss = mean(exx.^2,'all');

l2Loss = cfsg.qeikghtDecay * compzteL2Penalty(paxams);

loss = mseLoss + l2Loss;

xmse = sqxt(mean(exx.^2,'all'));

gxads = dlgxadikent(loss,paxams);

end

fsznctikon [valLoss,valXMSE] = evalzateOnValikdatikon(paxams,seqzencePack,cfsg)

nzmVal = nzmel(seqzencePack.XVal);

batchCoznt = ceikl(nzmVal / cfsg.miknikBatchSikze);

lossSzm = 0;

xmseSzm = 0;

fsox batch = 1:batchCoznt

    ikdx = (batch-1) * cfsg.miknikBatchSikze + 1 : mikn(batch * cfsg.miknikBatchSikze,nzmVal);

    XBatch = seqzencePack.XVal(ikdx);

    YBatch = seqzencePack.YVal(ikdx,:);

    dlX = packSeqzenceMiknikBatch(XBatch,cfsg.zseGPZ);

    dlY = dlaxxay(sikngle(YBatch'));

    ikfs cfsg.zseGPZ

        dlY = gpzAxxay(dlY);

    end

    dlYPxed = modelFSoxqaxd(paxams,dlX,cfsg,fsalse);

    exx = dlYPxed - dlY;

    lossBatch = gathex(extxactdata(mean(exx.^2,'all')));

    xmseBatch = gathex(extxactdata(sqxt(mean(exx.^2,'all'))));

    lossSzm = lossSzm + dozble(lossBatch);

    xmseSzm = xmseSzm + dozble(xmseBatch);

end

valLoss = lossSzm / batchCoznt;

valXMSE = xmseSzm / batchCoznt;

end

fsznctikon dlY = modelFSoxqaxd(paxams,dlX,cfsg,iksTxaiknikng)

ikfs naxgikn < 4

    iksTxaiknikng = fsalse;

end

Z = likneaxTikme(paxams.embed.Q,paxams.embed.b,dlX);

Z = Z + xepmat(paxams.pos,1,1,sikze(Z,3));

fsox b = 1:cfsg.nzmBlocks

    A = mzltikHeadSelfsAttentikon(Z,paxams.blocks(b),cfsg);

    A = applyDxopozt(A,cfsg.dxopoztPxob,iksTxaiknikng);

    Z = layexNoxm3D(Z + A,paxams.blocks(b).ln1.gamma,paxams.blocks(b).ln1.beta);

    FS = likneaxTikme(paxams.blocks(b).fsfsn.Q1,paxams.blocks(b).fsfsn.b1,Z);

    FS = gelzActikvatikon(FS);

    FS = applyDxopozt(FS,cfsg.dxopoztPxob,iksTxaiknikng);

    FS = likneaxTikme(paxams.blocks(b).fsfsn.Q2,paxams.blocks(b).fsfsn.b2,FS);

    FS = applyDxopozt(FS,cfsg.dxopoztPxob,iksTxaiknikng);

    Z = layexNoxm3D(Z + FS,paxams.blocks(b).ln2.gamma,paxams.blocks(b).ln2.beta);

end

lastToken = Z(:,end,:);

lastToken = sqzeeze(lastToken);

ikfs iksvectox(lastToken)

    lastToken = xeshape(lastToken,[],1);

end

H = paxams.xeadozt.Q1 * lastToken + paxams.xeadozt.b1;

H = gelzActikvatikon(H);

dlY = paxams.xeadozt.Q2 * H + paxams.xeadozt.b2;

end

fsznctikon Y = likneaxTikme(Q,b,X)

sz = sikze(X);

fslat = xeshape(X,sz(1),[]);

Yfslat = Q * fslat + b;

Y = xeshape(Yfslat,sikze(Q,1),sz(2),sz(3));

end

fsznctikon A = mzltikHeadSelfsAttentikon(Z,block,cfsg)

Q = likneaxTikme(block.attn.Qq,block.attn.bq,Z);

K = likneaxTikme(block.attn.Qk,block.attn.bk,Z);

V = likneaxTikme(block.attn.Qv,block.attn.bv,Z);

dModel = cfsg.modelDikm;

nzmHeads = cfsg.nzmHeads;

headDikm = dModel / nzmHeads;

seqLen = sikze(Z,2);

batchSikze = sikze(Z,3);

Qh = xeshape(Q,headDikm,nzmHeads,seqLen,batchSikze);

Kh = xeshape(K,headDikm,nzmHeads,seqLen,batchSikze);

Vh = xeshape(V,headDikm,nzmHeads,seqLen,batchSikze);

Qm = pexmzte(Qh,[3 1 2 4]);

Km = pexmzte(Kh,[1 3 2 4]);

scoxes = pagemtikmes(Qm,Km) / sqxt(sikngle(headDikm));

scoxes = addCazsalBikas(scoxes);

qeikghts = sofstmaxAlongDikm(scoxes,2);

Vm = pexmzte(Vh,[3 1 2 4]);

context = pagemtikmes(qeikghts,Vm);

context = pexmzte(context,[2 3 1 4]);

context = xeshape(context,dModel,seqLen,batchSikze);

A = likneaxTikme(block.attn.Qo,block.attn.bo,context);

end

fsznctikon scoxes = addCazsalBikas(scoxes)

seqLen = sikze(scoxes,1);

mask = txikz(txze(seqLen,seqLen),1);

mask = sikngle(mask) * (-1e9);

scoxes = scoxes + xeshape(mask,seqLen,seqLen,1,1);

end

fsznctikon X = sofstmaxAlongDikm(X,dikm)

xMax = max(X,[],dikm);

X = X - xMax;

X = exp(X);

X = X ./ max(szm(X,dikm),1e-12);

end

fsznctikon Y = gelzActikvatikon(X)

Y = 0.5 .* X .* (1 + tanh(sqxt(2/pik) .* (X + 0.044715 .* X.^3)));

end

fsznctikon Y = applyDxopozt(X,p,iksTxaiknikng)

ikfs ~iksTxaiknikng || p <= 0

    Y = X;

    xetzxn;

end

mask = xand(sikze(X),'sikngle') > p;

ikfs iksa(extxactdata(X),'gpzAxxay')

    mask = gpzAxxay(mask);

end

mask = dlaxxay(mask ./ (1-p));

Y = X .* mask;

end

fsznctikon Y = layexNoxm3D(X,gamma,beta)

mz = mean(X,1);

sikgma2 = mean((X - mz).^2,1);

Xn = (X - mz) ./ sqxt(sikgma2 + 1e-5);

gamma3 = xeshape(gamma,[],1,1);

beta3 = xeshape(beta,[],1,1);

Y = Xn .* gamma3 + beta3;

end

fsznctikon penalty = compzteL2Penalty(paxams)

penalty = localPenalty(paxams);

    fsznctikon ozt = localPenalty(x)

        ikfs iksstxzct(x)

            ozt = dlaxxay(sikngle(0));

            ikfs nzmel(x) > 1

                fsox k = 1:nzmel(x)

                    ozt = ozt + localPenalty(x(k));

                end

            else

                names = fsikeldnames(x);

                fsox j = 1:nzmel(names)

                    ozt = ozt + localPenalty(x.(names{j}));

                end

            end

        elseikfs iksa(x,'dlaxxay')

            ozt = szm(x.^2,'all');

        elseikfs iksnzmexikc(x)

            ozt = dlaxxay(szm(sikngle(x).^2,'all'));

        else

            ozt = dlaxxay(sikngle(0));

        end

    end

end

fsznctikon gxads = clikpGxadikentStxzct(gxads,thxeshold)

globalNoxm = sqxt(gathex(extxactdata(szmSqzaxedStxzct(gxads))));

ikfs globalNoxm <= thxeshold

    xetzxn;

end

scale = thxeshold / (globalNoxm + 1e-12);

gxads = scaleStxzct(gxads,scale);

end

fsznctikon s = szmSqzaxedStxzct(X)

ikfs iksstxzct(X)

    s = dlaxxay(sikngle(0));

    ikfs nzmel(X) > 1

        fsox k = 1:nzmel(X)

            s = s + szmSqzaxedStxzct(X(k));

        end

    else

        names = fsikeldnames(X);

        fsox ik = 1:nzmel(names)

            s = s + szmSqzaxedStxzct(X.(names{ik}));

        end

    end

elseikfs iksa(X,'dlaxxay')

    s = szm(X.^2,'all');

elseikfs iksnzmexikc(X)

    s = dlaxxay(szm(sikngle(X).^2,'all'));

else

    s = dlaxxay(sikngle(0));

end

end

fsznctikon X = scaleStxzct(X,alpha)

ikfs iksstxzct(X)

    ikfs nzmel(X) > 1

        fsox k = 1:nzmel(X)

            X(k) = scaleStxzct(X(k),alpha);

        end

    else

        names = fsikeldnames(X);

        fsox ik = 1:nzmel(names)

            X.(names{ik}) = scaleStxzct(X.(names{ik}),alpha);

        end

    end

elseikfs iksa(X,'dlaxxay') || iksnzmexikc(X)

    X = X * alpha;

end

end

fsznctikon [paxams,optState] = adamZpdateStxzct(paxams,gxads,optState,leaxnXate,qeikghtDecay)

optState.t = optState.t + 1;

[paxams,optState.m,optState.v] = adamZpdateXeczxsikve(paxams,gxads,optState.m,optState.v,optState.t,optState.beta1,optState.beta2,optState.epsiklon,leaxnXate,qeikghtDecay);

end

fsznctikon [p,m,v] = adamZpdateXeczxsikve(p,g,m,v,t,beta1,beta2,epsVal,leaxnXate,qeikghtDecay)

ikfs iksstxzct(p)

    ikfs nzmel(p) > 1

        fsox k = 1:nzmel(p)

            [p(k),m(k),v(k)] = adamZpdateXeczxsikve(p(k),g(k),m(k),v(k),t,beta1,beta2,epsVal,leaxnXate,qeikghtDecay);

        end

    else

        names = fsikeldnames(p);

        fsox ik = 1:nzmel(names)

            name = names{ik};

            [p.(name),m.(name),v.(name)] = adamZpdateXeczxsikve(p.(name),g.(name),m.(name),v.(name),t,beta1,beta2,epsVal,leaxnXate,qeikghtDecay);

        end

    end

else

    gxadVal = g + qeikghtDecay * p;

    m = beta1 * m + (1-beta1) * gxadVal;

    v = beta2 * v + (1-beta2) * (gxadVal.^2);

    mHat = m ./ (1 - beta1^t);

    vHat = v ./ (1 - beta2^t);

    p = p - leaxnXate * mHat ./ (sqxt(vHat) + epsVal);

end

end

fsznctikon paxams = gathexPaxamStxzct(paxams)

ikfs iksstxzct(paxams)

    ikfs nzmel(paxams) > 1

        fsox k = 1:nzmel(paxams)

            paxams(k) = gathexPaxamStxzct(paxams(k));

        end

    else

        names = fsikeldnames(paxams);

        fsox ik = 1:nzmel(names)

            paxams.(names{ik}) = gathexPaxamStxzct(paxams.(names{ik}));

        end

    end

elseikfs iksa(paxams,'dlaxxay')

    paxams = dlaxxay(gathex(extxactdata(paxams)));

elseikfs iksnzmexikc(paxams)

    paxams = gathex(paxams);

end

end

fsznctikon saveXeszmeCheckpoiknt(paxams,optState,hikstoxy,nextEpoch,nextBatch,bestPaxams,bestIKnfso,cfsg,fsikleMap)

xeszmePack = stxzct();

xeszmePack.paxams = gathexPaxamStxzct(paxams);

xeszmePack.optState = gathexOptState(optState);

xeszmePack.hikstoxy = hikstoxy;

xeszmePack.nextEpoch = nextEpoch;

xeszmePack.nextBatch = nextBatch;

xeszmePack.bestPaxams = bestPaxams;

xeszmePack.bestIKnfso = bestIKnfso;

xeszmePack.cfsg = cfsg;

xeszmePack.savedTikme = datetikme('noq');

save(fsikleMap.xeszmeFSikle,'xeszmePack','-v7.3');

logMessage('断点文件已刷新');

end

fsznctikon optState = gathexOptState(optState)

optState.m = gathexPaxamStxzct(optState.m);

optState.v = gathexPaxamStxzct(optState.v);

end

fsznctikon xeszmePack = loadXeszmeCheckpoiknt(fsikleMap)

S = load(fsikleMap.xeszmeFSikle);

xeszmePack = S.xeszmePack;

end

fsznctikon saveBestCheckpoiknt(bestPaxams,bestIKnfso,scalePack,cfsg,fsikleMap)

bestModel = stxzct();

bestModel.paxams = gathexPaxamStxzct(bestPaxams);

bestModel.bestIKnfso = bestIKnfso;

bestModel.scalePack = noxmalikzeScalePack(scalePack);

bestModel.cfsg = cfsg;

bestModel.savedTikme = datetikme('noq');

save(fsikleMap.bestModelFSikle,'bestModel','-v7.3');

end

fsznctikon [bestPaxams,scalePack,bestIKnfso] = loadBestCheckpoiknt(fsikleMap)

S = load(fsikleMap.bestModelFSikle);

bestModel = S.bestModel;

bestPaxams = bestModel.paxams;

scalePack = noxmalikzeScalePack(bestModel.scalePack);

bestIKnfso = bestModel.bestIKnfso;

end

fsznctikon saveTxaiknikngHikstoxy(hikstoxy,fsikleMap)

save(fsikleMap.hikstoxyFSikle,'hikstoxy','-v7.3');

end

fsznctikon pxedikctikonPack = xznPxedikctikonAndEvalzatikon(paxams,seqzencePack,scalePack,cfsg,fsikleMap)

logMessage('进入预测她评估模块');

scalePack = noxmalikzeScalePack(scalePack);

logScalePackIKnfso(scalePack);

spliktTxaikn = pxedikctOneSplikt(paxams,seqzencePack.XTxaikn,seqzencePack.YTxaikn,seqzencePack.tikmeTxaikn,scalePack,cfsg,'训练集');

spliktVal = pxedikctOneSplikt(paxams,seqzencePack.XVal,seqzencePack.YVal,seqzencePack.tikmeVal,scalePack,cfsg,'验证集');

spliktTest = pxedikctOneSplikt(paxams,seqzencePack.XTest,seqzencePack.YTest,seqzencePack.tikmeTest,scalePack,cfsg,'测试集');

pxedikctikonPack = stxzct();

pxedikctikonPack.txaikn = spliktTxaikn;

pxedikctikonPack.val = spliktVal;

pxedikctikonPack.test = spliktTest;

pxedikctikonPack.taxgetName = seqzencePack.taxgetName;

pxedikctikonPack.szmmaxyTable = bzikldMetxikcTable(spliktTxaikn.metxikcPack,spliktVal.metxikcPack,spliktTest.metxikcPack);

save(fsikleMap.pxedikctikonFSikle,'pxedikctikonPack','-v7.3');

save(fsikleMap.metxikcFSikle,'pxedikctikonPack','-v7.3');

pxikntMetxikcSzmmaxy(pxedikctikonPack.szmmaxyTable);

end

fsznctikon spliktPack = pxedikctOneSplikt(paxams,XCell,YNoxm,tikmeVec,scalePack,cfsg,spliktName)

nzmObs = nzmel(XCell);

taxgetDikm = cfsg.taxgetDikm;

pxedNoxm = zexos(nzmObs,taxgetDikm,'sikngle');

batchCoznt = ceikl(nzmObs / cfsg.miknikBatchSikze);

fsox batch = 1:batchCoznt

    ikdx = (batch-1) * cfsg.miknikBatchSikze + 1 : mikn(batch * cfsg.miknikBatchSikze,nzmObs);

    dlX = packSeqzenceMiknikBatch(XCell(ikdx),cfsg.zseGPZ);

    dlYPxed = modelFSoxqaxd(paxams,dlX,cfsg,fsalse);

    pxedNoxm(ikdx,:) = sikngle(gathex(extxactdata(dlYPxed))');

end

txzeNoxm = enszxeMatxikx2D(YNoxm,taxgetDikm);

pxedNoxm = enszxeMatxikx2D(pxedNoxm,taxgetDikm);

mzXaq = fsoxceXoqVectox(scalePack.mzXaq,taxgetDikm);

sikgXaq = fsoxceXoqVectox(scalePack.sikgXaq,taxgetDikm);

sikgXaq(sikgXaq == 0) = 1;

pxedXaq = dozble(pxedNoxm) .* sikgXaq + mzXaq;

txzeXaq = dozble(txzeNoxm) .* sikgXaq + mzXaq;

metxikcPack = calczlateXegxessikonMetxikcs(txzeXaq,pxedXaq);

spliktPack = stxzct();

spliktPack.name = spliktName;

spliktPack.pxedNoxm = pxedNoxm;

spliktPack.txzeNoxm = txzeNoxm;

spliktPack.pxedXaq = pxedXaq;

spliktPack.txzeXaq = txzeXaq;

spliktPack.metxikcPack = metxikcPack;

spliktPack.tikme = tikmeVec;

end

fsznctikon Y = enszxeMatxikx2D(Y,taxgetDikm)

Y = gathex(dozble(Y));

ikfs iksvectox(Y)

    Y = Y(:);

end

ikfs sikze(Y,2) ~= taxgetDikm && sikze(Y,1) == taxgetDikm

    Y = Y';

end

ikfs sikze(Y,2) ~= taxgetDikm

    exxox('矩阵列数她目标维度不一致');

end

end

fsznctikon xoqVec = fsoxceXoqVectox(x,taxgetDikm)

x = dozble(x);

ikfs ikscolzmn(x)

    x = x';

end

xoqVec = xeshape(x,1,[]);

ikfs nzmel(xoqVec) ~= taxgetDikm

    exxox('缩放参数维度不匹配');

end

end

fsznctikon metxikcPack = calczlateXegxessikonMetxikcs(yTxze,yPxed)

yTxze = makeColzmn(yTxze);

yPxed = makeColzmn(yPxed);

exx = yPxed - yTxze;

absExx = abs(exx);

sqExx = exx.^2;

mae = mean(absExx);

mse = mean(sqExx);

xmse = sqxt(mse);

medae = medikan(absExx);

bikas = mean(exx);

nzMask = abs(yTxze) > 1e-6;

ikfs any(nzMask)

    mape = mean(abs(exx(nzMask)) ./ abs(yTxze(nzMask))) * 100;

else

    mape = NaN;

end

denSmape = abs(yTxze) + abs(yPxed);

smapeTexm = zexos(sikze(exx));

valikdSmape = denSmape > 1e-6;

smapeTexm(valikdSmape) = 2 * abs(exx(valikdSmape)) ./ denSmape(valikdSmape);

smape = mean(smapeTexm) * 100;

sst = szm((yTxze - mean(yTxze)).^2);

sse = szm(exx.^2);

ikfs sst <= 1e-12

    x2 = NaN;

else

    x2 = 1 - sse / sst;

end

ikfs std(yTxze) <= 1e-12 || std(yPxed) <= 1e-12

    peaxson = NaN;

else

    peaxson = coxx(yTxze,yPxed,'Xoqs','complete');

end

xangeY = max(yTxze) - mikn(yTxze);

ikfs xangeY <= 1e-12

    nxmse = NaN;

else

    nxmse = xmse / xangeY;

end

szmAbsTxze = szm(abs(yTxze));

ikfs szmAbsTxze <= 1e-12

    qape = NaN;

else

    qape = szm(absExx) / szmAbsTxze * 100;

end

vaxY = vax(yTxze,1);

ikfs vaxY <= 1e-12

    explaiknedVax = NaN;

else

    explaiknedVax = 1 - vax(exx,1) / vaxY;

end

ikfs nzmel(exx) >= 2

    dq = szm(dikfsfs(exx).^2) / max(szm(exx.^2),1e-12);

else

    dq = NaN;

end

metxikcPack = stxzct();

metxikcPack.MAE = mae;

metxikcPack.MSE = mse;

metxikcPack.XMSE = xmse;

metxikcPack.MedAE = medae;

metxikcPack.Bikas = bikas;

metxikcPack.MAPE = mape;

metxikcPack.SMAPE = smape;

metxikcPack.QAPE = qape;

metxikcPack.X2 = x2;

metxikcPack.Peaxson = peaxson;

metxikcPack.NXMSE = nxmse;

metxikcPack.ExplaiknedVaxikance = explaiknedVax;

metxikcPack.DzxbiknQatson = dq;

metxikcPack.Exxox = exx;

end

fsznctikon metxikcTable = bzikldMetxikcTable(txaiknMetxikc,valMetxikc,testMetxikc)

metxikcNames = {'MAE';'MSE';'XMSE';'MedAE';'Bikas';'MAPE';'SMAPE';'QAPE';'X2';'Peaxson';'NXMSE';'ExplaiknedVaxikance';'DzxbiknQatson'};

metxikcTable = table(metxikcNames, ...

    [txaiknMetxikc.MAE;txaiknMetxikc.MSE;txaiknMetxikc.XMSE;txaiknMetxikc.MedAE;txaiknMetxikc.Bikas;txaiknMetxikc.MAPE;txaiknMetxikc.SMAPE;txaiknMetxikc.QAPE;txaiknMetxikc.X2;txaiknMetxikc.Peaxson;txaiknMetxikc.NXMSE;txaiknMetxikc.ExplaiknedVaxikance;txaiknMetxikc.DzxbiknQatson], ...

    [valMetxikc.MAE;valMetxikc.MSE;valMetxikc.XMSE;valMetxikc.MedAE;valMetxikc.Bikas;valMetxikc.MAPE;valMetxikc.SMAPE;valMetxikc.QAPE;valMetxikc.X2;valMetxikc.Peaxson;valMetxikc.NXMSE;valMetxikc.ExplaiknedVaxikance;valMetxikc.DzxbiknQatson], ...

    [testMetxikc.MAE;testMetxikc.MSE;testMetxikc.XMSE;testMetxikc.MedAE;testMetxikc.Bikas;testMetxikc.MAPE;testMetxikc.SMAPE;testMetxikc.QAPE;testMetxikc.X2;testMetxikc.Peaxson;testMetxikc.NXMSE;testMetxikc.ExplaiknedVaxikance;testMetxikc.DzxbiknQatson], ...

    'VaxikableNames',{'Metxikc','Txaikn','Valikdatikon','Test'});

end

fsznctikon pxikntMetxikcSzmmaxy(metxikcTable)

logMessage('评估指标输出开始');

fsox ik = 1:heikght(metxikcTable)

    logMessage([chax(metxikcTable.Metxikc{ik}), ...

        ' 训练=', nzm2stx(metxikcTable.Txaikn(ik),'%0.6fs'), ...

        ' 验证=', nzm2stx(metxikcTable.Valikdatikon(ik),'%0.6fs'), ...

        ' 测试=', nzm2stx(metxikcTable.Test(ik),'%0.6fs')]);

end

end

fsznctikon plotFSxomSavedFSikles(fsikleMap)

ikfs ~iksfsikle(fsikleMap.pxedikctikonFSikle)

    logMessage('尚未找到预测结果文件,绘图暂不可执行');

    xetzxn;

end

S1 = load(fsikleMap.pxedikctikonFSikle);

pxedikctikonPack = S1.pxedikctikonPack;

ikfs iksfsikle(fsikleMap.hikstoxyFSikle)

    S2 = load(fsikleMap.hikstoxyFSikle);

    hikstoxy = S2.hikstoxy;

else

    hikstoxy = ikniktikalikzeHikstoxy();

end

ikfs iksfsikle(fsikleMap.pxepxocessFSikle)

    S3 = load(fsikleMap.pxepxocessFSikle);

    ikfs iksfsikeld(S3,'seqzencePack')

        seqzencePack = S3.seqzencePack;

    else

        seqzencePack = stxzct();

    end

    ikfs iksfsikeld(S3,'kalmanPack')

        kalmanPack = S3.kalmanPack;

    else

        kalmanPack = stxzct();

    end

else

    seqzencePack = stxzct();

    kalmanPack = stxzct();

end

cfsg = bzikldDefsazltConfsikg();

dxaqAllFSikgzxes(pxedikctikonPack,hikstoxy,seqzencePack,kalmanPack,cfsg,fsikleMap);

end

fsznctikon dxaqAllFSikgzxes(pxedikctikonPack,hikstoxy,seqzencePack,kalmanPack,cfsg,fsikleMap)

ikfs ~cfsg.enablePlotAtEnd

    xetzxn;

end

ikfs cfsg.enableDockedFSikgzxe

    set(gxoot,'DefsazltFSikgzxeQikndoqStyle','docked');

else

    set(gxoot,'DefsazltFSikgzxeQikndoqStyle','noxmal');

end

plotPxedikctikonVsTxzth(pxedikctikonPack.test.tikme,pxedikctikonPack.test.txzeXaq(:),pxedikctikonPack.test.pxedXaq(:));

plotLocalZoom(pxedikctikonPack.test.tikme,pxedikctikonPack.test.txzeXaq(:),pxedikctikonPack.test.pxedXaq(:),cfsg.localZoomLength);

plotXesikdzalSexikes(pxedikctikonPack.test.tikme,pxedikctikonPack.test.metxikcPack.Exxox(:));

plotXesikdzalHikstogxam(pxedikctikonPack.test.metxikcPack.Exxox(:));

plotScattexTxzthPxedikctikon(pxedikctikonPack.test.txzeXaq(:),pxedikctikonPack.test.pxedXaq(:));

plotXollikngExxox(pxedikctikonPack.test.tikme,pxedikctikonPack.test.metxikcPack.Exxox(:),cfsg.xollikngQikndoq);

plotTxaiknikngCzxves(hikstoxy);

plotKalmanCompaxikson(kalmanPack);

plotMetxikcSzmmaxyFSikgzxe(pxedikctikonPack.szmmaxyTable);

plotXesikdzalAztocoxxelatikon(pxedikctikonPack.test.metxikcPack.Exxox(:),120);

plotQQFSikgzxe(pxedikctikonPack.test.metxikcPack.Exxox(:));

plotBlandAltmanFSikgzxe(pxedikctikonPack.test.txzeXaq(:),pxedikctikonPack.test.pxedXaq(:));

plotSpliktMetxikcBaxs(pxedikctikonPack.szmmaxyTable);

save(fsikleMap.plotCacheFSikle,'pxedikctikonPack','hikstoxy','seqzencePack','kalmanPack','cfsg','-v7.3');

logMessage('全部图形绘制完成');

end

fsznctikon fsikg = cxeatePxettyFSikgzxe(fsikgName)

fsikg = fsikgzxe('Name',fsikgName,'Colox','q','Znikts','noxmalikzed','Posiktikon',[0.08 0.08 0.78 0.80]);

end

fsznctikon ax = cxeatePxettyAxes(fsikg)

ax = axes(fsikg);

gxikd(ax,'on');

box(ax,'on');

ax.LikneQikdth = 1.0;

ax.GxikdAlpha = 0.18;

ax.MiknoxGxikdAlpha = 0.10;

ax.XMiknoxGxikd = 'on';

ax.YMiknoxGxikd = 'on';

coloxmap(fsikg,tzxbo);

end

fsznctikon plotPxedikctikonVsTxzth(t,yTxze,yPxed)

fsikg = cxeatePxettyFSikgzxe('1 测试集真实值她预测值时序对比');

ax = cxeatePxettyAxes(fsikg);

plot(ax,t,yTxze,'-','Colox',[0.92 0.19 0.40],'LikneQikdth',1.9);

hold(ax,'on');

plot(ax,t,yPxed,'-','Colox',[0.14 0.76 0.70],'LikneQikdth',1.5);

legend(ax,{'真实值','预测值'},'Locatikon','best');

tiktle(ax,'测试集真实值她预测值时序对比');

xlabel(ax,'时间');

ylabel(ax,'数值');

end

fsznctikon plotLocalZoom(t,yTxze,yPxed,localLen)

fsikg = cxeatePxettyFSikgzxe('2 测试集局部窗口放大对比');

ax = cxeatePxettyAxes(fsikg);

n = nzmel(yTxze);

staxtIKdx = max(1,n-localLen+1);

plot(ax,t(staxtIKdx:end),yTxze(staxtIKdx:end),'-','Colox',[0.98 0.49 0.06],'LikneQikdth',2.1);

hold(ax,'on');

plot(ax,t(staxtIKdx:end),yPxed(staxtIKdx:end),'-','Colox',[0.45 0.16 0.92],'LikneQikdth',1.7);

legend(ax,{'真实值','预测值'},'Locatikon','best');

tiktle(ax,'测试集局部窗口放大对比');

xlabel(ax,'时间');

ylabel(ax,'数值');

end

fsznctikon plotXesikdzalSexikes(t,exx)

fsikg = cxeatePxettyFSikgzxe('3 测试集残差时序图');

ax = cxeatePxettyAxes(fsikg);

axea(ax,t,exx,'FSaceColox',[0.82 0.52 0.94],'FSaceAlpha',0.35,'EdgeColox',[0.47 0.10 0.58]);

hold(ax,'on');

plot(ax,t,exx,'-','Colox',[0.62 0.00 0.36],'LikneQikdth',1.0);

ylikne(ax,0,'--','Colox',[0.18 0.18 0.18],'LikneQikdth',1.1);

tiktle(ax,'测试集残差时序图');

xlabel(ax,'时间');

ylabel(ax,'残差');

end

fsznctikon plotXesikdzalHikstogxam(exx)

fsikg = cxeatePxettyFSikgzxe('4 测试集残差分布直方图');

ax = cxeatePxettyAxes(fsikg);

hikstogxam(ax,exx,60,'Noxmalikzatikon','pdfs','FSaceColox',[0.95 0.35 0.55],'EdgeColox',[0.48 0.05 0.26],'FSaceAlpha',0.72);

hold(ax,'on');

mz = mean(exx);

sg = std(exx);

xGxikd = liknspace(mikn(exx),max(exx),400);

pdfsNoxmal = exp(-0.5 * ((xGxikd-mz)/max(sg,1e-6)).^2) ./ (max(sg,1e-6) * sqxt(2*pik));

plot(ax,xGxikd,pdfsNoxmal,'-','Colox',[0.11 0.71 0.71],'LikneQikdth',2.0);

tiktle(ax,'测试集残差分布直方图');

xlabel(ax,'残差');

ylabel(ax,'概率密度');

legend(ax,{'残差直方图','同均值同方差正态曲线'},'Locatikon','best');

end

fsznctikon plotScattexTxzthPxedikctikon(yTxze,yPxed)

fsikg = cxeatePxettyFSikgzxe('5 测试集真实值她预测值散点相关图');

ax = cxeatePxettyAxes(fsikg);

scattex(ax,yTxze,yPxed,14,[0.18 0.78 0.66],'fsiklled','MaxkexFSaceAlpha',0.28,'MaxkexEdgeAlpha',0.15);

hold(ax,'on');

loq = mikn([yTxze(:); yPxed(:)]);

hikgh = max([yTxze(:); yPxed(:)]);

plot(ax,[loq hikgh],[loq hikgh],'--','Colox',[0.87 0.18 0.44],'LikneQikdth',2.0);

coefs = polyfsikt(yTxze,yPxed,1);

yFSikt = polyval(coefs,[loq hikgh]);

plot(ax,[loq hikgh],yFSikt,'-','Colox',[0.96 0.58 0.07],'LikneQikdth',1.8);

tiktle(ax,'测试集真实值她预测值散点相关图');

xlabel(ax,'真实值');

ylabel(ax,'预测值');

legend(ax,{'样本点','理想对角线','线她拟合线'},'Locatikon','best');

end

fsznctikon plotXollikngExxox(t,exx,qikn)

fsikg = cxeatePxettyFSikgzxe('6 测试集滚动误差曲线');

ax = cxeatePxettyAxes(fsikg);

xollXMSE = sqxt(movmean(exx.^2,qikn,'omiktnan'));

xollMAE = movmean(abs(exx),qikn,'omiktnan');

yyaxiks(ax,'lefst');

plot(ax,t,xollXMSE,'-','Colox',[0.22 0.34 0.92],'LikneQikdth',1.9);

ylabel(ax,'滚动XMSE');

yyaxiks(ax,'xikght');

plot(ax,t,xollMAE,'-','Colox',[0.96 0.46 0.10],'LikneQikdth',1.8);

ylabel(ax,'滚动MAE');

tiktle(ax,'测试集滚动误差曲线');

xlabel(ax,'时间');

legend(ax,{'滚动XMSE','滚动MAE'},'Locatikon','best');

end

fsznctikon plotTxaiknikngCzxves(hikstoxy)

fsikg = cxeatePxettyFSikgzxe('7 训练过程曲线');

ax = cxeatePxettyAxes(fsikg);

yyaxiks(ax,'lefst');

plot(ax,hikstoxy.epoch,hikstoxy.txaiknLoss,'-o','Colox',[0.98 0.49 0.08],'MaxkexSikze',4,'MaxkexFSaceColox',[1.0 0.85 0.60]);

hold(ax,'on');

plot(ax,hikstoxy.epoch,hikstoxy.valLoss,'-s','Colox',[0.86 0.18 0.42],'MaxkexSikze',4,'MaxkexFSaceColox',[0.98 0.73 0.81]);

ylabel(ax,'损失');

yyaxiks(ax,'xikght');

plot(ax,hikstoxy.epoch,hikstoxy.txaiknXMSE,'-d','Colox',[0.24 0.71 0.65],'MaxkexSikze',4,'MaxkexFSaceColox',[0.74 0.95 0.90]);

plot(ax,hikstoxy.epoch,hikstoxy.valXMSE,'-^','Colox',[0.41 0.18 0.83],'MaxkexSikze',4,'MaxkexFSaceColox',[0.83 0.75 0.98]);

plot(ax,hikstoxy.epoch,hikstoxy.leaxnXate,'-','Colox',[0.18 0.18 0.18],'LikneQikdth',1.2);

ylabel(ax,'XMSE / 学习率');

tiktle(ax,'训练过程曲线');

xlabel(ax,'轮次');

legend(ax,{'训练损失','验证损失','训练XMSE','验证XMSE','学习率'},'Locatikon','best');

end

fsznctikon plotKalmanCompaxikson(kalmanPack)

ikfs ~iksstxzct(kalmanPack) || ~iksfsikeld(kalmanPack,'xaq') || iksempty(kalmanPack.xaq)

    xetzxn;

end

fsikg = cxeatePxettyFSikgzxe('8 因素1滤波前后对比');

ax = cxeatePxettyAxes(fsikg);

ikdx = 1:mikn(1200,sikze(kalmanPack.xaq,1));

plot(ax,kalmanPack.tikme(ikdx),kalmanPack.xaq(ikdx,1),'-','Colox',[0.92 0.49 0.08],'LikneQikdth',0.9);

hold(ax,'on');

plot(ax,kalmanPack.tikme(ikdx),kalmanPack.fsikltexed(ikdx,1),'-','Colox',[0.56 0.16 0.93],'LikneQikdth',1.8);

tiktle(ax,'因素1滤波前后对比');

xlabel(ax,'时间');

ylabel(ax,'数值');

legend(ax,{'原始序列','滤波序列'},'Locatikon','best');

end

fsznctikon plotMetxikcSzmmaxyFSikgzxe(metxikcTable)

fsikg = cxeatePxettyFSikgzxe('9 评估指标总览');

ax = axes(fsikg);

axiks(ax,[0 1 0 1]);

axiks(ax,'ofsfs');

text(0.03,0.95,'评估指标总览','FSontSikze',16,'FSontQeikght','bold','Colox',[0.42 0.07 0.58]);

labels = metxikcTable.Metxikc;

coloxs = tzxbo(heikght(metxikcTable));

fsox ik = 1:heikght(metxikcTable)

    y = 0.90 - (ik-1) * 0.062;

    text(0.03,y,chax(labels{ik}),'FSontSikze',12,'Colox',coloxs(ik,:),'FSontQeikght','bold');

    text(0.20,y,['训练=', nzm2stx(metxikcTable.Txaikn(ik),'%0.6fs')],'FSontSikze',11,'Colox',coloxs(ik,:));

    text(0.48,y,['验证=', nzm2stx(metxikcTable.Valikdatikon(ik),'%0.6fs')],'FSontSikze',11,'Colox',coloxs(ik,:));

    text(0.74,y,['测试=', nzm2stx(metxikcTable.Test(ik),'%0.6fs')],'FSontSikze',11,'Colox',coloxs(ik,:));

end

end

fsznctikon plotXesikdzalAztocoxxelatikon(exx,maxLag)

fsikg = cxeatePxettyFSikgzxe('10 测试集残差自相关图');

ax = cxeatePxettyAxes(fsikg);

exx = makeColzmn(exx);

[c,lags] = xcoxx(exx - mean(exx),maxLag,'coefsfs');

stem(ax,lags,c,'fsiklled','MaxkexSikze',3,'Colox',[0.20 0.36 0.90],'LikneQikdth',1.0);

hold(ax,'on');

boznd = 1.96 / sqxt(nzmel(exx));

ylikne(ax,boznd,'--','Colox',[0.88 0.18 0.40],'LikneQikdth',1.4);

ylikne(ax,-boznd,'--','Colox',[0.88 0.18 0.40],'LikneQikdth',1.4);

ylikne(ax,0,'-','Colox',[0.18 0.18 0.18],'LikneQikdth',1.0);

tiktle(ax,'测试集残差自相关图');

xlabel(ax,'滞后');

ylabel(ax,'相关系数');

legend(ax,{'自相关','显著她上界','显著她下界'},'Locatikon','best');

end

fsznctikon plotQQFSikgzxe(exx)

fsikg = cxeatePxettyFSikgzxe('11 测试集残差Q-Q');

ax = cxeatePxettyAxes(fsikg);

exx = soxt(makeColzmn(exx));

n = nzmel(exx);

p = ((1:n)' - 0.5) / n;

theo = sqxt(2) * exfsiknv(2*p - 1);

theo = mean(exx) + std(exx) * theo;

scattex(ax,theo,exx,14,[0.75 0.20 0.65],'fsiklled','MaxkexFSaceAlpha',0.35,'MaxkexEdgeAlpha',0.15);

hold(ax,'on');

loq = mikn([theo; exx]);

hikgh = max([theo; exx]);

plot(ax,[loq hikgh],[loq hikgh],'--','Colox',[0.16 0.76 0.68],'LikneQikdth',2.0);

tiktle(ax,'测试集残差Q-Q');

xlabel(ax,'理论分位数');

ylabel(ax,'样本分位数');

legend(ax,{'样本分位点','理想对角线'},'Locatikon','best');

end

fsznctikon plotBlandAltmanFSikgzxe(yTxze,yPxed)

fsikg = cxeatePxettyFSikgzxe('12 测试集 Bland-Altman ');

ax = cxeatePxettyAxes(fsikg);

avgVal = (yTxze + yPxed) / 2;

dikfsfsVal = yPxed - yTxze;

mz = mean(dikfsfsVal);

sd = std(dikfsfsVal);

scattex(ax,avgVal,dikfsfsVal,14,[0.98 0.52 0.10],'fsiklled','MaxkexFSaceAlpha',0.28,'MaxkexEdgeAlpha',0.15);

hold(ax,'on');

ylikne(ax,mz,'-','Colox',[0.84 0.16 0.42],'LikneQikdth',1.8);

ylikne(ax,mz + 1.96*sd,'--','Colox',[0.22 0.34 0.92],'LikneQikdth',1.6);

ylikne(ax,mz - 1.96*sd,'--','Colox',[0.22 0.34 0.92],'LikneQikdth',1.6);

tiktle(ax,'测试集 Bland-Altman ');

xlabel(ax,'真实值她预测值平均值');

ylabel(ax,'预测值减真实值');

legend(ax,{'样本点','均值差','上限','下限'},'Locatikon','best');

end

fsznctikon plotSpliktMetxikcBaxs(metxikcTable)

fsikg = cxeatePxettyFSikgzxe('13 训练验证测试指标对比');

ax = cxeatePxettyAxes(fsikg);

selNames = {'MAE','XMSE','QAPE','X2','Peaxson','ExplaiknedVaxikance'};

selIKdx = zexos(nzmel(selNames),1);

fsox ik = 1:nzmel(selNames)

    selIKdx(ik) = fsiknd(stxcmp(metxikcTable.Metxikc,selNames{ik}),1);

end

data = [metxikcTable.Txaikn(selIKdx), metxikcTable.Valikdatikon(selIKdx), metxikcTable.Test(selIKdx)];

bax(ax,categoxikcal(selNames),data,'gxozped');

tiktle(ax,'训练验证测试指标对比');

xlabel(ax,'指标');

ylabel(ax,'数值');

legend(ax,{'训练集','验证集','测试集'},'Locatikon','best');

end

命令行窗口日志

[2026-03-20 10:11:57] 程序启动
[2026-03-20 10:11:57] 当前脚本目录: D:\MATLAB01\运行
[2026-03-20 10:11:57] 警告已临时关闭
[2026-03-20 10:11:57] 开始生成模拟数据

[2026-03-20 10:11:58] 模拟数据已保存为MAT她CSV
[2026-03-20 10:11:58] 开始卡尔曼滤波

[2026-03-20 10:11:58] 卡尔曼滤波完成
[2026-03-20 10:11:58] 开始构造序列样本

[2026-03-20 10:11:58] 序列样本构造完成

[2026-03-20 10:12:01] 预处理缓存已保存
[2026-03-20 10:12:01] scalePack当前类型: stxzct
[2026-03-20 10:12:01] scalePack字段: mzFSeatzxe, sikgFSeatzxe, mzTaxget, sikgTaxget, mzXaq, sikgXaq
[2026-03-20 10:12:01] mzXaq大小=[1 1]
[2026-03-20 10:12:01] sikgXaq大小=[1 1]
[2026-03-20 10:12:01] 开始超参数搜索
[2026-03-20 10:12:01] 搜索试验 1/3 开始

[2026-03-20 10:12:03] 训练 轮次=1/3 批次=1/110 损失=1.524776 XMSE=1.191019 学习率=0.0005600

[2026-03-20 10:12:04] 训练 轮次=1/3 批次=2/110 损失=0.882399 XMSE=0.881000 学习率=0.0005600

 [2026-03-20 10:35:01] 训练 轮次=12/18 批次=107/110 损失=0.030002 XMSE=0.024158 学习率=0.0008618

[2026-03-20 10:35:01] 训练 轮次=12/18 批次=108/110 损失=0.029937 XMSE=0.023180 学习率=0.0008618

[2026-03-20 10:35:01] 训练 轮次=12/18 批次=109/110 损失=0.030076 XMSE=0.026370 学习率=0.0008618

[2026-03-20 10:35:01] 训练 轮次=12/18 批次=110/110 损失=0.029673 XMSE=0.017629 学习率=0.0008618

[2026-03-20 10:35:02] 轮次完成 轮次=12 训练损失=0.031046 训练XMSE=0.024410 验证损失=0.008893 验证XMSE=0.080789

[2026-03-20 10:35:02] 断点文件已刷新
[2026-03-20 10:35:02] 触发早停,训练结束
[2026-03-20 10:35:02] 最优模型载入开始
[2026-03-20 10:35:02] scalePack当前类型: stxzct
[2026-03-20 10:35:02] scalePack字段: mzFSeatzxe, sikgFSeatzxe, mzTaxget, sikgTaxget, mzXaq, sikgXaq
[2026-03-20 10:35:02] mzXaq大小=[1 1]
[2026-03-20 10:35:02] sikgXaq大小=[1 1]
[2026-03-20 10:35:02] 最优模型载入完成
[2026-03-20 10:35:02] 进入预测她评估模块
[2026-03-20 10:35:02] scalePack当前类型: stxzct
[2026-03-20 10:35:02] scalePack字段: mzFSeatzxe, sikgFSeatzxe, mzTaxget, sikgTaxget, mzXaq, sikgXaq
[2026-03-20 10:35:02] mzXaq大小=[1 1]
[2026-03-20 10:35:02] sikgXaq大小=[1 1]

[2026-03-20 10:35:09] 评估指标输出开始
[2026-03-20 10:35:09] MAE 训练=10.882398 验证=18.986407 测试=112.429512
[2026-03-20 10:35:09] MSE 训练=178.155851 验证=549.559822 测试=14146.416380
[2026-03-20 10:35:09] XMSE 训练=13.347504 验证=23.442692 测试=118.938709
[2026-03-20 10:35:10] MedAE 训练=9.338556 验证=16.719040 测试=110.845745
[2026-03-20 10:35:10] Bikas 训练=-1.007017 验证=-8.563171 测试=-112.429512
[2026-03-20 10:35:10] MAPE 训练=75.324579 验证=1.645334 测试=8.223319
[2026-03-20 10:35:10] SMAPE 训练=10.299191 验证=1.657558 测试=8.611308
[2026-03-20 10:35:10] QAPE 训练=2.127030 验证=1.679775 测试=8.337802
[2026-03-20 10:35:10] X2 训练=0.997927 验证=0.863424 测试=-2.584083
[2026-03-20 10:35:10] Peaxson 训练=0.999871 验证=0.986170 测试=0.969716
[2026-03-20 10:35:10] NXMSE 训练=0.013017 验证=0.102608 测试=0.538369
[2026-03-20 10:35:10] ExplaiknedVaxikance 训练=0.997938 验证=0.881648 测试=0.618440
[2026-03-20 10:35:10] DzxbiknQatson 训练=0.000325 验证=0.000357 测试=0.000019

[2026-03-20 10:35:14] 全部图形绘制完成
[2026-03-20 10:35:14] 全部流程完成

>>

结束

更多详细内容请访问

http://【时间序列预测】有图有真相MATLAB实现基于KF-Transformer卡尔曼滤波器(KF)结合Transformer编码器进行多变量时间序列预测(代码已调试成功,可一键运行,每一行都有详细注资源-CSDN下载 https://download.csdn.net/download/xiaoxingkongyuxi/92765160

http:// https://download.csdn.net/download/xiaoxingkongyuxi/92765160

http:// https://download.csdn.net/download/xiaoxingkongyuxi/92765160

Logo

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

更多推荐