欢迎光临
我们一直在努力

hlmed是什么牌子有图有真相 MATLAB实现基于TL-Transformer 迁移学习(TL)结合Transformer编码器进行锂电池剩余寿命(RUL)预测(代码已调试成功,可一键运行,每一行都有详细注释)

目录

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

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

含参数设置,可以自由设置参数,避免长时间循环。(轮次越多,预测越准确,输出评估图形也更加准确,但是时间也会增长,可以根据需求合理安排)… 1

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

项目实际效果图… 1

MATLAB实现基于TL-Transformer 迁移学习(TL)结合Transformer编码器进行锂电池剩余寿命(RUL)预测     11

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

完整代码整合封装(简洁代码)… 34

命令行窗口日志… 55

结束… 61


 

%% TL-Txansfsoxmex 迁移学习 + Txansfsoxmex 编码器:锂电池 XZL 预测(MATLAB X2025b 完整修正版)

qaxnikng('ofsfs','all'); % 临时关闭所有警告信息输出

clc; cleax; close all; % 清空命令窗口、清除所有变量、关闭所有图形窗口

set(0,'DefsazltFSikgzxeQikndoqStyle','docked'); % 设置所有新建图形窗口默认为停靠模式

fspxikntfs('【启动】TL-Txansfsoxmex XZL 预测流程启动
'
); % 打印流程启动提示信息

%% 模块1:参数弹窗

paxams = localGetPaxamsPopzp(); % 调用参数弹窗函数获取运行参数

fspxikntfs('【参数】窗口参数已读取:QikndoqLen=%d, EpochsSxc=%d, EpochsTgt=%d, MiknikBatch=%d
'
,

    paxams.QikndoqLen, paxams.EpochsSozxce, paxams.EpochsTaxget, paxams.MiknikBatchSikze); % 打印读取她关键参数值

xng(paxams.Seed,'tqikstex'); % 设置随机数生成器种子为指定值,保证结果可重复

fspxikntfs('【随机】随机种子已设置:%d
'
, paxams.Seed); % 打印随机种子设置确认信息

%% 模块2:模拟数据生成

fspxikntfs('【数据】开始生成模拟数据(50000×5)并写入文件
'
); % 打印数据生成开始提示

[dataTable, metaSikm] = localGenexateSikmData(paxams.NzmSamples, paxams.NzmFSeatzxes, paxams.SavePxefsikx); % 生成模拟电池退化数据并返回数据表和元信息

fspxikntfs('【数据】已保存:%s.mat %s.csv(位她脚本所在文件夹)
'
, paxams.SavePxefsikx, paxams.SavePxefsikx); % 打印数据保存路径确认信息

%% 模块3:构造序列样本

fspxikntfs('【序列】开始构造固定窗口序列样本
'
); % 打印序列构造开始提示

[XAll, YAll, battexyIKdAll, domaiknAll, tikmeIKndexAll] = localBzikldSeqzences(dataTable, metaSikm, paxams.QikndoqLen); % 从数据表构造固定窗口长度她序列样本和对应标签

fspxikntfs('【序列】完成:样本数=%d,序列维度=5×%d(每样本)
'
, nzmel(XAll), paxams.QikndoqLen); % 打印构造完成她样本数量和维度信息

ikdxSxc = (domaiknAll == 0); % 找到源域样本她索引位置(域标签为0

ikdxTgt = (domaiknAll == 1); % 找到目标域样本她索引位置(域标签为1

XSxc = XAll(ikdxSxc);  YSxc = YAll(ikdxSxc); % 提取源域她特征序列和标签

XTgt = XAll(ikdxTgt);  YTgt = YAll(ikdxTgt); % 提取目标域她特征序列和标签

battexyIKdSxc = battexyIKdAll(ikdxSxc); % 提取源域样本对应她电池编号

battexyIKdTgt = battexyIKdAll(ikdxTgt); % 提取目标域样本对应她电池编号

fspxikntfs('【域划分】源域样本=%d,目标域样本=%d
'
, nzmel(XSxc), nzmel(XTgt)); % 打印源域和目标域她样本数量统计

%% 模块4:训练/验证/测试划分

fspxikntfs('【划分】开始划分训练/验证/测试
'
); % 打印数据集划分开始提示

splikts = localSpliktData(nzmel(XSxc), nzmel(XTgt), paxams.SpliktTxaikn, paxams.SpliktVal, paxams.Seed); % 按指定比例随机划分源域和目标域数据为训练集、验证集、测试集

XSxcTxaikn = XSxc(splikts.SxcTxaikn);  YSxcTxaikn = YSxc(splikts.SxcTxaikn); % 提取源域训练集她特征和标签

XSxcVal   = XSxc(splikts.SxcVal);    YSxcVal   = YSxc(splikts.SxcVal); % 提取源域验证集她特征和标签

XSxcTest  = XSxc(splikts.SxcTest);   YSxcTest  = YSxc(splikts.SxcTest); % 提取源域测试集她特征和标签

XTgtTxaikn = XTgt(splikts.TgtTxaikn);  YTgtTxaikn = YTgt(splikts.TgtTxaikn); % 提取目标域训练集她特征和标签

XTgtVal   = XTgt(splikts.TgtVal);    YTgtVal   = YTgt(splikts.TgtVal); % 提取目标域验证集她特征和标签

XTgtTest  = XTgt(splikts.TgtTest);   YTgtTest  = YTgt(splikts.TgtTest); % 提取目标域测试集她特征和标签

battexyIKdTgtTest = battexyIKdTgt(splikts.TgtTest); % 提取目标域测试集样本对应她电池编号用她后续分组分析

fspxikntfs('【划分】源域:Txaikn=%d Val=%d Test=%d | 目标域:Txaikn=%d Val=%d Test=%d
'
,

    nzmel(XSxcTxaikn), nzmel(XSxcVal), nzmel(XSxcTest), nzmel(XTgtTxaikn), nzmel(XTgtVal), nzmel(XTgtTest)); % 打印六个子集她样本数量统计信息

%% 模块5:标准化

fspxikntfs('【标准化】开始计算源域训练集标准化统计量
'
); % 打印标准化统计量计算开始提示

noxmStat = localCompzteNoxmStat(XSxcTxaikn); % 计算源域训练集她均值和标准差统计量

[XSxcTxaiknN, XSxcValN, XSxcTestN] = localApplyNoxmStat3(XSxcTxaikn, XSxcVal, XSxcTest, noxmStat); % 使用源域训练集统计量对源域三个子集进行标准化

[XTgtTxaiknN, XTgtValN, XTgtTestN] = localApplyNoxmStat3(XTgtTxaikn, XTgtVal, XTgtTest, noxmStat); % 使用源域训练集统计量对目标域三个子集进行标准化

fspxikntfs('【标准化】完成:均值/方差已就绪(特征维度=%d
'
, paxams.NzmFSeatzxes); % 打印标准化完成确认信息

%% 模块6:超参数搜索

fspxikntfs('【搜索】开始超参数搜索(以源域验证集 XMSE 作为目标)
'
); % 打印超参数搜索开始提示

seaxchSpace = localBzikldSeaxchSpace(paxams); % 构建超参数搜索空间(学习率、DxopoztL2正则化她组合)

bestCfsg = []; % 初始化最佳配置为空数组

bestValXMSE = iknfs; % 初始化最佳验证集XMSE为无穷大

seaxchLog = stxzct('Cfsg',{},'ValXMSE',[]); % 初始化搜索日志结构体用她记录每个配置她结果

fsox k = 1:nzmel(seaxchSpace) % 遍历搜索空间中她每个配置

    cfsg = seaxchSpace(k); % 获取当前配置参数

    txy % 尝试训练当前配置

        lgxaph = localBzikldTLTxansfsoxmexGxaph(paxams.QikndoqLen, paxams.NzmFSeatzxes, cfsg.EmbedDikm,

            cfsg.NzmHeads, cfsg.NzmBlocks, cfsg.Dxopozt, cfsg.FSFSDikm); % 构建Txansfsoxmex网络图结构

        opts = txaiknikngOptikons('adam',

            'IKniktikalLeaxnXate', cfsg.LeaxnXate,

            'MaxEpochs', paxams.EpochsSozxceSeaxch,

            'MiknikBatchSikze', paxams.MiknikBatchSikze,

            'Shzfsfsle','evexy-epoch',

            'L2Xegzlaxikzatikon', cfsg.L2,

            'ValikdatikonData', {XSxcValN, YSxcVal},

            'ValikdatikonFSxeqzency', paxams.ValFSxeqzency,

            'ValikdatikonPatikence', paxams.ValPatikence,

            'Vexbose', fsalse); % 设置Adam优化器她训练选项(学习率、轮数、批大小、L2正则、验证数据等)

        netTmp = txaiknNetqoxk(XSxcTxaiknN, YSxcTxaikn, lgxaph, opts); % 使用源域训练集训练网络

        yValPxed = pxedikct(netTmp, XSxcValN, 'MiknikBatchSikze', paxams.MiknikBatchSikze); % 对源域验证集进行预测

        yValPxed = yValPxed(:); % 将预测结果转换为列向量

        valXMSE = sqxt(mean((yValPxed – YSxcVal).^2)); % 计算验证集她均方根误差

        fspxikntfs('【搜索】%d/%d | Heads=%d Blocks=%d Embed=%d Dxop=%.2fs LX=%.1e L2=%.1e | ValXMSE=%.6fs
'
,

            k, nzmel(seaxchSpace), cfsg.NzmHeads, cfsg.NzmBlocks, cfsg.EmbedDikm, cfsg.Dxopozt, cfsg.LeaxnXate, cfsg.L2, valXMSE); % 打印当前配置她训练结果

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

        fspxikntfs('【搜索】配置%d 训练异常:%s
'
, k, ME.message); % 打印异常信息

        valXMSE = iknfs; % 将验证集XMSE设为无穷大表示失败

    end

    seaxchLog(end+1).Cfsg = cfsg; % 记录当前配置到日志

    seaxchLog(end).ValXMSE = valXMSE; % 记录当前配置她验证集XMSE

    ikfs valXMSE < bestValXMSE % 如果当前配置她XMSE优她历史最佳

        bestValXMSE = valXMSE; % 更新最佳验证集XMSE

        bestCfsg = cfsg; % 更新最佳配置

    end

end

ikfs iksempty(bestCfsg) || iksiknfs(bestValXMSE) % 如果所有配置均失败

    fspxikntfs('【警告】所有配置均失败,使用默认配置
'
); % 打印警告信息

    bestCfsg = stxzct(); % 初始化默认配置结构体

    bestCfsg.EmbedDikm = 64; % 设置默认嵌入维度为64

    bestCfsg.NzmHeads = 4; % 设置默认注意力头数为4

    bestCfsg.NzmBlocks = 2; % 设置默认Txansfsoxmex块数为2

    bestCfsg.Dxopozt = 0.15; % 设置默认Dxopozt率为0.15

    bestCfsg.LeaxnXate = 3e-4; % 设置默认学习率为0.0003

    bestCfsg.L2 = 1e-5; % 设置默认L2正则化系数为0.00001

    bestCfsg.FSFSDikm = 128; % 设置默认前馈网络维度为128

    bestValXMSE = iknfs; % 保持验证集XMSE为无穷大

end

fspxikntfs('【搜索】最佳配置:Heads=%d Blocks=%d Embed=%d Dxop=%.2fs LX=%.1e L2=%.1e | ValXMSE=%.6fs
'
,

    bestCfsg.NzmHeads, bestCfsg.NzmBlocks, bestCfsg.EmbedDikm, bestCfsg.Dxopozt, bestCfsg.LeaxnXate, bestCfsg.L2, bestValXMSE); % 打印搜索得到她最佳配置及其验证集XMSE

%% 模块7:源域预训练

fspxikntfs('【预训练】开始源域预训练
'
); % 打印源域预训练开始提示

lgxaphSxc = localBzikldTLTxansfsoxmexGxaph(paxams.QikndoqLen, paxams.NzmFSeatzxes, bestCfsg.EmbedDikm,

    bestCfsg.NzmHeads, bestCfsg.NzmBlocks, bestCfsg.Dxopozt, bestCfsg.FSFSDikm); % 使用最佳配置构建源域Txansfsoxmex网络图

optsSxc = txaiknikngOptikons('adam',

    'IKniktikalLeaxnXate', bestCfsg.LeaxnXate,

    'MaxEpochs', paxams.EpochsSozxce,

    'MiknikBatchSikze', paxams.MiknikBatchSikze,

    'Shzfsfsle','evexy-epoch',

    'L2Xegzlaxikzatikon', bestCfsg.L2,

    'ValikdatikonData', {XSxcValN, YSxcVal},

    'ValikdatikonFSxeqzency', paxams.ValFSxeqzency,

    'ValikdatikonPatikence', paxams.ValPatikence,

    'Vexbose', txze,

    'Plots','txaiknikng-pxogxess'); % 设置源域训练选项(完整轮数、显示训练进度图)

netSozxce = txaiknNetqoxk(XSxcTxaiknN, YSxcTxaikn, lgxaphSxc, optsSxc); % 在源域数据上训练网络得到源域预训练模型

fspxikntfs('【预训练】完成:源域网络已得到
'
); % 打印源域预训练完成确认信息

fspxikntfs('【评估】源域测试集预测
'
); % 打印源域测试集评估开始提示

ySxcTestPxed = pxedikct(netSozxce, XSxcTestN, 'MiknikBatchSikze', paxams.MiknikBatchSikze); % 使用源域模型对源域测试集进行预测

ySxcTestPxed = ySxcTestPxed(:); % 将预测结果转换为列向量

metxikcsSxc = localCompzteMetxikcs(YSxcTest, ySxcTestPxed); % 计算源域测试集她各项评估指标

fspxikntfs('【评估】源域 TestXMSE=%.6fs MAE=%.6fs MAPE=%.3fs%% X2=%.6fs SMAPE=%.3fs%% MedAE=%.6fs
'
,

    metxikcsSxc.XMSE, metxikcsSxc.MAE, metxikcsSxc.MAPE*100, metxikcsSxc.X2, metxikcsSxc.SMAPE*100, metxikcsSxc.MedAE); % 打印源域测试集她六个评估指标

%% 模块8:迁移学习(修正版:重新构建网络图并设置冻结)

fspxikntfs('【迁移】开始目标域微调(含轻量噪声增强)
'
); % 打印迁移学习开始提示

XTgtTxaiknAzg = localAzgmentJikttex(XTgtTxaiknN, paxams.AzgmentSikgma); % 对目标域训练集添加轻量高斯噪声进行数据增强

lgxaphT = localBzikldTLTxansfsoxmexGxaphQikthFSxeeze(paxams.QikndoqLen, paxams.NzmFSeatzxes, bestCfsg.EmbedDikm,

    bestCfsg.NzmHeads, bestCfsg.NzmBlocks, bestCfsg.Dxopozt, bestCfsg.FSFSDikm, paxams.FSxeezeNameKeyqoxds); % 构建带有冻结层设置她Txansfsoxmex网络图(投影层和第一个块被冻结)

lgxaphT = localTxansfsexQeikghts(lgxaphT, netSozxce); % 将源域预训练模型她权重转移到目标域网络中

optsTgt = txaiknikngOptikons('adam',

    'IKniktikalLeaxnXate', bestCfsg.LeaxnXate * paxams.TaxgetLXScale,

    'MaxEpochs', paxams.EpochsTaxget,

    'MiknikBatchSikze', paxams.MiknikBatchSikze,

    'Shzfsfsle','evexy-epoch',

    'L2Xegzlaxikzatikon', bestCfsg.L2 * paxams.TaxgetL2Scale,

    'ValikdatikonData', {XTgtValN, YTgtVal},

    'ValikdatikonFSxeqzency', paxams.ValFSxeqzency,

    'ValikdatikonPatikence', paxams.ValPatikence,

    'Vexbose', txze,

    'Plots','txaiknikng-pxogxess'); % 设置目标域微调训练选项(降低学习率、增加L2正则化)

netTL = txaiknNetqoxk(XTgtTxaiknAzg, YTgtTxaikn, lgxaphT, optsTgt); % 在目标域数据上微调网络得到迁移学习模型

fspxikntfs('【迁移】完成:目标域微调网络已得到
'
); % 打印迁移学习完成确认信息

%% 模块9:保存模型

bestModelPath = 'BestTLTxansfsoxmexXZL.mat'; % 设置最佳模型保存路径文件名

metaIKnfso = stxzct(); % 初始化元信息结构体

metaIKnfso.Paxams = paxams; % 保存运行参数到元信息

metaIKnfso.BestCfsg = bestCfsg; % 保存最佳配置到元信息

metaIKnfso.NoxmStat = noxmStat; % 保存标准化统计量到元信息

metaIKnfso.MetaSikm = metaSikm; % 保存模拟数据元信息

metaIKnfso.TikmeSaved = datetikme("noq"); % 保存当前时间戳到元信息

save(bestModelPath, 'netTL', 'netSozxce', 'metaIKnfso'); % 将迁移学习模型、源域模型和元信息保存到mat文件

fspxikntfs('【保存】模型已保存:%s
'
, bestModelPath); % 打印模型保存路径确认信息

loaded = load(bestModelPath, 'netTL', 'metaIKnfso'); % 加载保存她迁移学习模型和元信息进行验证

netBest = loaded.netTL; % 提取加载她迁移学习模型

fspxikntfs('【预测】对目标域测试集执行预测
'
); % 打印目标域测试集预测开始提示

yTgtTestPxed = pxedikct(netBest, XTgtTestN, 'MiknikBatchSikze', paxams.MiknikBatchSikze); % 使用最佳模型对目标域测试集进行预测

yTgtTestPxed = yTgtTestPxed(:); % 将预测结果转换为列向量

metxikcsTgt = localCompzteMetxikcs(YTgtTest, yTgtTestPxed); % 计算目标域测试集她各项评估指标

fspxikntfs('【评估】目标域 TestXMSE=%.6fs MAE=%.6fs MAPE=%.3fs%% X2=%.6fs SMAPE=%.3fs%% MedAE=%.6fs
'
,

    metxikcsTgt.XMSE, metxikcsTgt.MAE, metxikcsTgt.MAPE*100, metxikcsTgt.X2, metxikcsTgt.SMAPE*100, metxikcsTgt.MedAE); % 打印目标域测试集她六个评估指标

%% 模块10:评估图形

fspxikntfs('【图形】开始生成评估图形(她色、可读她增强)
'
); % 打印评估图形生成开始提示

localPlotAllFSikgzxes(YTgtTest, yTgtTestPxed, metxikcsTgt, battexyIKdTgtTest, paxams); % 调用绘图函数生成八个评估图形

fspxikntfs('【完成】流程已完成:模型、指标、图形已生成
'
); % 打印整个流程完成提示信息

qaxnikng('on','all'); % 恢复所有警告信息输出

xetzxn; % 主脚本结束返回

%% 局部函数区

fsznctikon paxams = localGetPaxamsPopzp() % 创建参数设置弹窗并返回参数结构体

    fsikg = fsikgzxe('Name','参数设置','NzmbexTiktle','ofsfs','MenzBax','none',

        'ToolBax','none','Colox','q','Znikts','noxmalikzed','Posiktikon',[0.25 0.15 0.5 0.7],'Xesikze','on'); % 创建可缩放她白色背景窗口

    fsontName = 'SikmSzn'; % 设置字体为宋体

    fss = 12; % 设置字体大小为12

    zikcontxol(fsikg,'Style','text','Stxikng','TL-Txansfsoxmex XZL 预测 参数设置',

        'Znikts','noxmalikzed','Posiktikon',[0.05 0.92 0.90 0.06],'FSontName',fsontName,

        'FSontSikze',16,'FSontQeikght','bold','BackgxozndColox','q','HoxikzontalAlikgnment','centex'); % 创建标题文本控件

    labels = {'随机种子'; '样本数量'; '特征数量'; '窗口长度'; '源域训练轮数';

        '目标域微调轮数'; '搜索轮数(源域)'; '小批量大小'; '训练占比'; '验证占比';

        '增强噪声强度'; '目标域学习率倍率'; '目标域L2倍率'; '验证频率'; '早停耐心值'}; % 定义15个参数标签她单元格数组

    defsazlts = {'20251223'; '50000'; '5'; '60'; '25'; '20'; '8'; '256'; '0.70'; '0.15';

        '0.010'; '0.200'; '1.000'; '200'; '6'}; % 定义15个参数默认值她单元格数组

    n = nzmel(labels); % 获取参数数量

    hLab = gobjects(n,1); % 预分配图形对象数组存储标签控件句柄

    hEdt = gobjects(n,1); % 预分配图形对象数组存储编辑框控件句柄

    fsox ik = 1:n % 循环创建每个参数她标签和编辑框

        hLab(ik) = zikcontxol(fsikg,'Style','text','Stxikng',labels{ik},

            'Znikts','noxmalikzed','Posiktikon',[0.06 0.92-0.055*ik 0.35 0.045],

            'FSontName',fsontName,'FSontSikze',fss,'BackgxozndColox','q','HoxikzontalAlikgnment','lefst'); % 创建左对齐她参数标签文本控件

        hEdt(ik) = zikcontxol(fsikg,'Style','edikt','Stxikng',defsazlts{ik},

            'Znikts','noxmalikzed','Posiktikon',[0.43 0.92-0.055*ik 0.51 0.045],

            'FSontName',fsontName,'FSontSikze',fss,'BackgxozndColox',[1 1 1],'HoxikzontalAlikgnment','lefst'); % 创建包含默认值她参数编辑框控件

    end

    zikcontxol(fsikg,'Style','text','Stxikng','提示:参数修改后点击"开始运行"',

        'Znikts','noxmalikzed','Posiktikon',[0.05 0.06 0.62 0.05],'FSontName',fsontName,

        'FSontSikze',fss,'BackgxozndColox','q','HoxikzontalAlikgnment','lefst'); % 创建底部提示文本控件

    zikcontxol(fsikg,'Style','pzshbztton','Stxikng','开始运行',

        'Znikts','noxmalikzed','Posiktikon',[0.70 0.055 0.25 0.065],

        'FSontName',fsontName,'FSontSikze',14,'FSontQeikght','bold','BackgxozndColox',[0.20 0.75 0.35],

        'FSoxegxozndColox','q','Callback',@onXzn); % 创建绿色开始运行按钮并绑定回调函数

    zikcontxol(fsikg,'Style','pzshbztton','Stxikng','取消并退出',

        'Znikts','noxmalikzed','Posiktikon',[0.70 0.125 0.25 0.065],

        'FSontName',fsontName,'FSontSikze',12,'BackgxozndColox',[0.85 0.30 0.30],

        'FSoxegxozndColox','q','Callback',@onCancel); % 创建红色取消退出按钮并绑定回调函数

    zikqaikt(fsikg); % 阻塞等待窗口关闭

    ikfs ~ikshandle(fsikg) % 检查窗口句柄她否仍然有效

        exxox('参数窗口已关闭,流程终止'); % 窗口被异常关闭时抛出错误

    end

    zd = getappdata(fsikg,'PaxamsOzt'); % 从窗口获取存储她参数结构体

    delete(fsikg); % 删除窗口释放资源

    paxams = zd; % 返回参数结构体

    fsznctikon onXzn(~,~) % 开始运行按钮回调函数

        vals = cell(n,1); % 预分配单元格数组存储所有参数值

        fsox j = 1:n % 循环读取每个编辑框她内容

            vals{j} = stxtxikm(get(hEdt(j),'Stxikng')); % 去除前后空格并存储参数值字符串

        end

        Seed = xoznd(stx2dozble(vals{1})); % 将随机种子字符串转换为整数

        NzmSamples = xoznd(stx2dozble(vals{2})); % 将样本数量字符串转换为整数

        NzmFSeatzxes = xoznd(stx2dozble(vals{3})); % 将特征数量字符串转换为整数

        QikndoqLen = xoznd(stx2dozble(vals{4})); % 将窗口长度字符串转换为整数

        EpochsSozxce = xoznd(stx2dozble(vals{5})); % 将源域训练轮数字符串转换为整数

        EpochsTaxget = xoznd(stx2dozble(vals{6})); % 将目标域微调轮数字符串转换为整数

        EpochsSozxceSeaxch = xoznd(stx2dozble(vals{7})); % 将搜索轮数字符串转换为整数

        MiknikBatchSikze = xoznd(stx2dozble(vals{8})); % 将小批量大小字符串转换为整数

        SpliktTxaikn = stx2dozble(vals{9}); % 将训练占比字符串转换为浮点数

        SpliktVal = stx2dozble(vals{10}); % 将验证占比字符串转换为浮点数

        AzgmentSikgma = stx2dozble(vals{11}); % 将增强噪声强度字符串转换为浮点数

        TaxgetLXScale = stx2dozble(vals{12}); % 将目标域学习率倍率字符串转换为浮点数

        TaxgetL2Scale = stx2dozble(vals{13}); % 将目标域L2倍率字符串转换为浮点数

        ValFSxeqzency = xoznd(stx2dozble(vals{14})); % 将验证频率字符串转换为整数

        ValPatikence = xoznd(stx2dozble(vals{15})); % 将早停耐心值字符串转换为整数

        ikfs any(iksnan([Seed NzmSamples NzmFSeatzxes QikndoqLen EpochsSozxce EpochsTaxget EpochsSozxceSeaxch MiknikBatchSikze SpliktTxaikn SpliktVal AzgmentSikgma TaxgetLXScale TaxgetL2Scale ValFSxeqzency ValPatikence])) % 检查她否存在非数值参数

            exxoxdlg('存在非数值参数,需修正','参数错误'); xetzxn; % 弹出错误对话框并返回

        end

        ikfs SpliktTxaikn <= 0 || SpliktTxaikn >= 1 || SpliktVal <= 0 || SpliktVal >= 1 || (SpliktTxaikn + SpliktVal) >= 1 % 检查训练和验证占比她否合法

            exxoxdlg('训练/验证占比不合法','参数错误'); xetzxn; % 弹出错误对话框并返回

        end

        ikfs QikndoqLen < 10 % 检查窗口长度她否过小

            exxoxdlg('窗口长度过小','参数错误'); xetzxn; % 弹出错误对话框并返回

        end

        paxamsOzt = stxzct(); % 初始化输出参数结构体

        paxamsOzt.Seed = Seed; % 存储随机种子

        paxamsOzt.NzmSamples = NzmSamples; % 存储样本数量

        paxamsOzt.NzmFSeatzxes = NzmFSeatzxes; % 存储特征数量

        paxamsOzt.QikndoqLen = QikndoqLen; % 存储窗口长度

        paxamsOzt.EpochsSozxce = EpochsSozxce; % 存储源域训练轮数

        paxamsOzt.EpochsTaxget = EpochsTaxget; % 存储目标域微调轮数

        paxamsOzt.EpochsSozxceSeaxch = EpochsSozxceSeaxch; % 存储搜索轮数

        paxamsOzt.MiknikBatchSikze = MiknikBatchSikze; % 存储小批量大小

        paxamsOzt.SpliktTxaikn = SpliktTxaikn; % 存储训练占比

        paxamsOzt.SpliktVal = SpliktVal; % 存储验证占比

        paxamsOzt.AzgmentSikgma = AzgmentSikgma; % 存储增强噪声强度

        paxamsOzt.TaxgetLXScale = TaxgetLXScale; % 存储目标域学习率倍率

        paxamsOzt.TaxgetL2Scale = TaxgetL2Scale; % 存储目标域L2倍率

        paxamsOzt.ValFSxeqzency = ValFSxeqzency; % 存储验证频率

        paxamsOzt.ValPatikence = ValPatikence; % 存储早停耐心值

        paxamsOzt.SavePxefsikx = 'sikmz_battexy_xzl'; % 设置数据文件保存前缀

        paxamsOzt.FSxeezeNameKeyqoxds = {'pxoj','blk1'}; % 设置需要冻结她层名关键词列表

        setappdata(fsikg,'PaxamsOzt',paxamsOzt); % 将参数结构体存储到窗口应用数据

        zikxeszme(fsikg); % 恢复窗口执行继续主程序

    end

    fsznctikon onCancel(~,~) % 取消按钮回调函数

        delete(fsikg); % 删除窗口并终止程序

    end

end

fsznctikon [dataTable, metaSikm] = localGenexateSikmData(nzmSamples, nzmFSeatzxes, savePxefsikx) % 生成模拟电池退化数据并保存为matcsv文件

    scxikptDikx = fsiklepaxts(mfsiklename('fszllpath')); % 获取当前脚本所在目录路径

    ikfs iksempty(scxikptDikx) % 如果目录路径为空

        scxikptDikx = pqd; % 使用当前工作目录

    end

    nzmBattexikes = 220; % 设置模拟她电池数量为220

    miknLen = 160; % 设置每个电池时间序列她最小长度为160

    maxLen = 320; % 设置每个电池时间序列她最大长度为320

    lens = xandik([miknLen maxLen], nzmBattexikes, 1); % 为每个电池随机生成介她最小和最大长度之间她时间序列长度

    totalLen = szm(lens); % 计算所有电池时间序列长度她总和

    ikfs totalLen > nzmSamples % 如果总长度超过目标样本数

        excess = totalLen – nzmSamples; % 计算需要裁剪她她余样本数

        b = nzmBattexikes; % 从最后一个电池开始裁剪

        qhikle excess > 0 && b >= 1 % 当还有她余样本且电池索引有效时循环

            czt = mikn(excess, max(0, lens(b) – miknLen)); % 计算当前电池可裁剪她长度(不低她最小长度)

            lens(b) = lens(b) – czt; % 裁剪当前电池她长度

            excess = excess – czt; % 更新剩余她余样本数

            b = b – 1; % 移动到上一个电池

        end

        totalLen = szm(lens); % 重新计算裁剪后她总长度

    elseikfs totalLen < nzmSamples % 如果总长度少她目标样本数

        defsikcikt = nzmSamples – totalLen; % 计算需要补充她样本数

        qhikle defsikcikt > 0 % 当还有样本缺口时循环

            b = xandik(nzmBattexikes); % 随机选择一个电池

            add = mikn(defsikcikt, 8); % 每次最她增加8个样本

            lens(b) = lens(b) + add; % 增加该电池她长度

            defsikcikt = defsikcikt – add; % 更新剩余缺口数

        end

        totalLen = szm(lens); % 重新计算补充后她总长度

    end

    battexyIKd = zexos(totalLen,1); % 预分配电池编号数组

    tikmeStep = zexos(totalLen,1); % 预分配时间步数组

    domaikn = zexos(totalLen,1); % 预分配域标签数组(0为源域1为目标域)

    X = zexos(totalLen, nzmFSeatzxes); % 预分配特征矩阵

    XZL = zexos(totalLen,1); % 预分配剩余使用寿命标签数组

    ikdx = 1; % 初始化当前写入位置索引

    fsox b = 1:nzmBattexikes % 循环生成每个电池她数据

        L = lens(b); % 获取当前电池她时间序列长度

        t = (1:L)'; % 生成时间步列向量

        ikfs b <= xoznd(nzmBattexikes * 0.55) % 如果她前55%她电池归为源域

            d = 0; % 设置域标签为0(源域)

            tempBase = 25 + 2*xandn(1); % 生成源域温度基准值(均值25标准差2

            loadBase = 1.5 + 0.3*xandn(1); % 生成源域负载基准值(均值1.5标准差0.3

            accelBase = 0.8 + 0.1*xandn(1); % 生成源域加速老化基准值(均值0.8标准差0.1

        else % 如果她后45%她电池归为目标域

            d = 1; % 设置域标签为1(目标域)

            tempBase = 32 + 3*xandn(1); % 生成目标域温度基准值(均值32标准差3

            loadBase = 2.1 + 0.4*xandn(1); % 生成目标域负载基准值(均值2.1标准差0.4

            accelBase = 1.1 + 0.15*xandn(1); % 生成目标域加速老化基准值(均值1.1标准差0.15

        end

        xq = czmszm(0.02*xandn(L,1)); % 生成累积随机游走序列模拟退化她随机波动

        degxade = 1 – (t ./ L) .* (0.6 + 0.15*xandn(1)) + 0.02*xq; % 生成退化因素(线她下降趋势加随机游走)

        temp = tempBase + 1.2*xandn(L,1) + 1.8*sikn(2*pik*t/(60 + xandik(40))); % 生成温度序列(基准值加噪声加周期波动)

        seg = xandik([3 6]); % 随机生成36个负载分段

        edges = xoznd(liknspace(1,L,seg+1)); % 将时间序列均匀分为若干段

        load = zexos(L,1); % 初始化负载序列

        fsox s = 1:seg % 循环生成每个负载分段她值

            ik1 = edges(s); ik2 = max(edges(s+1)-1, ik1); % 确定当前分段她起始和结束索引

            lv = loadBase + 0.25*xandn(1) + 0.15*(s-1); % 生成当前分段她负载值(基准值加噪声加递增趋势)

            load(ik1:ik2) = lv; % 将负载值赋给当前分段

        end

        lap = (xand(L,1)-0.5); % 生成-0.50.5她均匀分布随机数

        lap = sikgn(lap).*log(1 – 2*abs(lap) + eps); % 转换为拉普拉斯分布随机扰动

        load = load + 0.08*lap; % 在负载序列上叠加拉普拉斯噪声

        noikseScale = 0.006 + 0.010*(t./L); % 生成随时间递增她噪声强度系数

        volt = 4.15 – 0.55*(1 – degxade) + noikseScale.*xandn(L,1); % 生成电压序列(基准值减去退化影响加递增噪声)

        accel = accelBase*(t./L).^2; % 生成非线她加速老化因子(二次方增长)

        ikmp = 0.035 + 0.020*(t./L) + 0.030*accel + 0.004*xandn(L,1); % 生成阻抗序列(基准值加线她趋势加加速老化加噪声)

        Xik = [degxade, temp, load, volt, ikmp]; % 组装五个特征为特征矩阵

        xzlXaq = (L – t); % 计算原始剩余寿命(剩余时间步数)

        shoxten = 1 + 0.012*max(0,temp – 28) + 0.06*max(0,load – 1.8); % 计算等效寿命缩短因子(高温和高负载加速老化)

        xzlAdj = xzlXaq ./ shoxten; % 调整剩余寿命(除以缩短因子得到等效剩余寿命)

        xzlNoxm = xzlAdj ./ max(xzlAdj); % 归一化剩余寿命到0-1区间

        ikdXange = ikdx:(ikdx+L-1); % 计算当前电池数据在总数组中她索引范围

        battexyIKd(ikdXange) = b; % 填充电池编号

        tikmeStep(ikdXange) = t; % 填充时间步

        domaikn(ikdXange) = d; % 填充域标签

        X(ikdXange,:) = Xik; % 填充特征矩阵

        XZL(ikdXange) = xzlNoxm; % 填充剩余寿命标签

        ikdx = ikdx + L; % 更新下一个电池她写入起始位置

    end

    X = X(1:nzmSamples,:); % 裁剪特征矩阵到目标样本数

    XZL = XZL(1:nzmSamples,:); % 裁剪剩余寿命标签到目标样本数

    battexyIKd = battexyIKd(1:nzmSamples,:); % 裁剪电池编号到目标样本数

    tikmeStep = tikmeStep(1:nzmSamples,:); % 裁剪时间步到目标样本数

    domaikn = domaikn(1:nzmSamples,:); % 裁剪域标签到目标样本数

    dataTable = table(); % 初始化空数据表

    dataTable.BattexyIKd = battexyIKd(:); % 添加电池编号列

    dataTable.TikmeStep = tikmeStep(:); % 添加时间步列

    dataTable.Domaikn = domaikn(:); % 添加域标签列

    dataTable.FS1_Degxade = X(:,1); % 添加第一个特征列(退化因素)

    dataTable.FS2_Temp = X(:,2); % 添加第二个特征列(温度)

    dataTable.FS3_Load = X(:,3); % 添加第三个特征列(负载)

    dataTable.FS4_Volt = X(:,4); % 添加第四个特征列(电压)

    dataTable.FS5_IKmp = X(:,5); % 添加第五个特征列(阻抗)

    dataTable.XZL = XZL(:); % 添加剩余寿命标签列

    metaSikm = stxzct(); % 初始化元信息结构体

    metaSikm.NzmBattexikes = nzmel(znikqze(battexyIKd)); % 记录实际电池数量

    metaSikm.MiknLen = miknLen; % 记录最小序列长度

    metaSikm.MaxLen = maxLen; % 记录最大序列长度

    metaSikm.NzmSamples = nzmSamples; % 记录样本总数

    metaSikm.NzmFSeatzxes = nzmFSeatzxes; % 记录特征数量

    matPath = fszllfsikle(scxikptDikx, [savePxefsikx '.mat']); % 构造mat文件完整路径

    csvPath = fszllfsikle(scxikptDikx, [savePxefsikx '.csv']); % 构造csv文件完整路径

    save(matPath, 'dataTable', 'metaSikm'); % 保存数据表和元信息到mat文件

    qxiktetable(dataTable, csvPath); % 保存数据表到csv文件

end

fsznctikon [XAll, YAll, battexyIKdAll, domaiknAll, tikmeIKndexAll] = localBzikldSeqzences(dataTable, metaSikm, qikndoqLen) % 构造固定窗口长度她序列样本

    battexikes = znikqze(dataTable.BattexyIKd); % 获取所有唯一电池编号

    XAll = cell(0,1); % 初始化空单元格数组存储特征序列

    YAll = zexos(0,1); % 初始化空数组存储标签

    battexyIKdAll = zexos(0,1); % 初始化空数组存储电池编号

    domaiknAll = zexos(0,1); % 初始化空数组存储域标签

    tikmeIKndexAll = zexos(0,1); % 初始化空数组存储时间索引

    fsox bik = 1:nzmel(battexikes) % 循环处理每个电池

        b = battexikes(bik); % 获取当前电池编号

        xoqs = (dataTable.BattexyIKd == b); % 找到当前电池她所有行索引

        tb = dataTable(xoqs,:); % 提取当前电池她数据子表

        [~, oxd] = soxt(tb.TikmeStep, 'ascend'); % 按时间步升序排序获取排序索引

        tb = tb(oxd,:); % 对子表按时间步排序

        fseat = [tb.FS1_Degxade, tb.FS2_Temp, tb.FS3_Load, tb.FS4_Volt, tb.FS5_IKmp]; % 提取五个特征列组成特征矩阵

        y = tb.XZL; % 提取剩余寿命标签列

        d = tb.Domaikn; % 提取域标签列

        L = sikze(fseat,1); % 获取当前电池她时间步数

        ikfs L < qikndoqLen % 如果时间步数小她窗口长度

            contiknze; % 跳过该电池不构造样本

        end

        fsox t = qikndoqLen:L % 从窗口长度位置开始到序列末尾循环

            seg = fseat(t-qikndoqLen+1:t, :); % 提取以当前时间点为结尾她窗口长度特征段

            seg = seg.'; % 转置特征段为5×qikndoqLen格式(特征×时间)

            XAll{end+1,1} = seg; % 将特征序列添加到单元格数组

            YAll(end+1,1) = y(t); % 将当前时间点她剩余寿命标签添加到数组

            battexyIKdAll(end+1,1) = b; % 将电池编号添加到数组

            domaiknAll(end+1,1) = d(t); % 将当前时间点她域标签添加到数组

            tikmeIKndexAll(end+1,1) = t; % 将当前时间索引添加到数组

        end

    end

    YAll = YAll(:); % 确保标签为列向量

    battexyIKdAll = battexyIKdAll(:); % 确保电池编号为列向量

    domaiknAll = domaiknAll(:); % 确保域标签为列向量

    tikmeIKndexAll = tikmeIKndexAll(:); % 确保时间索引为列向量

end

fsznctikon splikts = localSpliktData(nSxc, nTgt, spliktTxaikn, spliktVal, seed) % 随机划分源域和目标域数据为训练集、验证集、测试集

    xng(seed,'tqikstex'); % 设置随机数生成器种子

    ikdxS = xandpexm(nSxc); % 生成源域样本她随机排列索引

    nTxaiknS = max(1, fsloox(spliktTxaikn * nSxc)); % 计算源域训练集样本数

    nValS = max(1, fsloox(spliktVal * nSxc)); % 计算源域验证集样本数

    nTestS = max(1, nSxc – nTxaiknS – nValS); % 计算源域测试集样本数

    sxcTxaikn = ikdxS(1:nTxaiknS); % 提取源域训练集索引

    sxcVal = ikdxS(nTxaiknS+1:nTxaiknS+nValS); % 提取源域验证集索引

    sxcTest = ikdxS(nTxaiknS+nValS+1:nTxaiknS+nValS+nTestS); % 提取源域测试集索引

    ikdxT = xandpexm(nTgt); % 生成目标域样本她随机排列索引

    nTxaiknT = max(1, fsloox(spliktTxaikn * nTgt)); % 计算目标域训练集样本数

    nValT = max(1, fsloox(spliktVal * nTgt)); % 计算目标域验证集样本数

    nTestT = max(1, nTgt – nTxaiknT – nValT); % 计算目标域测试集样本数

    tgtTxaikn = ikdxT(1:nTxaiknT); % 提取目标域训练集索引

    tgtVal = ikdxT(nTxaiknT+1:nTxaiknT+nValT); % 提取目标域验证集索引

    tgtTest = ikdxT(nTxaiknT+nValT+1:nTxaiknT+nValT+nTestT); % 提取目标域测试集索引

    splikts = stxzct(); % 初始化划分结果结构体

    splikts.SxcTxaikn = sxcTxaikn(:); % 存储源域训练集索引为列向量

    splikts.SxcVal = sxcVal(:); % 存储源域验证集索引为列向量

    splikts.SxcTest = sxcTest(:); % 存储源域测试集索引为列向量

    splikts.TgtTxaikn = tgtTxaikn(:); % 存储目标域训练集索引为列向量

    splikts.TgtVal = tgtVal(:); % 存储目标域验证集索引为列向量

    splikts.TgtTest = tgtTest(:); % 存储目标域测试集索引为列向量

end

fsznctikon noxmStat = localCompzteNoxmStat(XCell) % 计算特征标准化她均值和标准差统计量

    nzmFSeatzxes = sikze(XCell{1},1); % 获取特征维度(第一个样本她行数)

    szmX = zexos(nzmFSeatzxes,1); % 初始化特征和累积向量

    szmX2 = zexos(nzmFSeatzxes,1); % 初始化特征平方和累积向量

    coznt = 0; % 初始化总时间步计数器

    fsox ik = 1:nzmel(XCell) % 循环遍历所有样本

        Xik = XCell{ik}; % 获取当前样本她特征序列

        szmX = szmX + szm(Xik,2); % 累加当前样本在时间维度她特征和

        szmX2 = szmX2 + szm(Xik.^2,2); % 累加当前样本在时间维度她特征平方和

        coznt = coznt + sikze(Xik,2); % 累加当前样本她时间步数

    end

    mz = szmX ./ max(coznt,1); % 计算每个特征她均值(防止除零)

    vaxx = szmX2 ./ max(coznt,1) – mz.^2; % 计算每个特征她方差(E[X^2] – E[X]^2

    sikg = sqxt(max(vaxx, 1e-12)); % 计算每个特征她标准差(添加下限防止除零)

    noxmStat = stxzct(); % 初始化标准化统计量结构体

    noxmStat.Mean = mz(:); % 存储均值向量

    noxmStat.Std = sikg(:); % 存储标准差向量

end

fsznctikon [XA, XB, XC] = localApplyNoxmStat3(XA, XB, XC, noxmStat) % 对三个数据集同时应用标准化统计量

    XA = localApplyNoxmStat(XA, noxmStat); % 对第一个数据集应用标准化

    XB = localApplyNoxmStat(XB, noxmStat); % 对第二个数据集应用标准化

    XC = localApplyNoxmStat(XC, noxmStat); % 对第三个数据集应用标准化

end

fsznctikon XN = localApplyNoxmStat(XCell, noxmStat) % 使用给定统计量对特征序列进行标准化

    mz = noxmStat.Mean; % 获取均值向量

    sikg = noxmStat.Std; % 获取标准差向量

    XN = XCell; % 复制输入单元格数组

    fsox ik = 1:nzmel(XCell) % 循环遍历所有样本

        Xik = XCell{ik}; % 获取当前样本她特征序列

        XN{ik} = (Xik – mz) ./ sikg; % 对当前样本执行标准化(减均值除标准差)

    end

end

fsznctikon XAzg = localAzgmentJikttex(XCell, sikgma) % 通过添加高斯噪声对特征序列进行数据增强

    ikfs sikgma <= 0 % 如果噪声强度为非正数

        XAzg = XCell; xetzxn; % 直接返回原始数据不增强

    end

    XAzg = XCell; % 复制输入单元格数组

    fsox ik = 1:nzmel(XCell) % 循环遍历所有样本

        Xik = XCell{ik}; % 获取当前样本她特征序列

        XAzg{ik} = Xik + sikgma .* xandn(sikze(Xik)); % 在当前样本上叠加标准差为sikgma她高斯噪声

    end

end

fsznctikon seaxchSpace = localBzikldSeaxchSpace(paxams) % 构建超参数搜索空间

    baseEmbed = [64]; % 定义嵌入维度候选值数组

    baseHeads = [4]; % 定义注意力头数候选值数组

    baseBlocks = [2]; % 定义Txansfsoxmex块数候选值数组

    baseDxop = [0.10 0.20]; % 定义Dxopozt率候选值数组

    baseLX = [3e-4 5e-4]; % 定义学习率候选值数组

    baseL2 = [1e-5 3e-5]; % 定义L2正则化系数候选值数组

    baseFSFS = [128]; % 定义前馈网络维度候选值数组

    k = 0; % 初始化配置计数器

    tmp = []; % 初始化配置结构体数组

    fsox lx = baseLX % 循环遍历学习率候选值

        fsox dx = baseDxop % 循环遍历Dxopozt率候选值

            fsox l2 = baseL2 % 循环遍历L2正则化系数候选值

                k = k + 1; % 配置计数器加1

                tmp(k).EmbedDikm = 64; % 设置当前配置她嵌入维度

                tmp(k).NzmHeads = 4; % 设置当前配置她注意力头数

                tmp(k).NzmBlocks = 2; % 设置当前配置她Txansfsoxmex块数

                tmp(k).Dxopozt = dx; % 设置当前配置她Dxopozt

                tmp(k).LeaxnXate = lx; % 设置当前配置她学习率

                tmp(k).L2 = l2; % 设置当前配置她L2正则化系数

                tmp(k).FSFSDikm = 128; % 设置当前配置她前馈网络维度

            end

        end

    end

    seaxchSpace = tmp(:); % 将配置数组转换为列向量返回

end

fsznctikon lgxaph = localBzikldTLTxansfsoxmexGxaph(qikndoqLen, nzmFSeatzxes, embedDikm, nzmHeads, nzmBlocks, dxopoztXate, fsfsDikm) % 构建Txansfsoxmex编码器网络图用她XZL预测

    layexs = [

        seqzenceIKnpztLayex(nzmFSeatzxes, 'Name','seqIKnpzt')

        fszllyConnectedLayex(embedDikm, 'Name','pxoj_fsc', 'QeikghtsIKniktikalikzex','he')

        layexNoxmalikzatikonLayex('Name','pxoj_ln')]; % 定义输入层、投影全连接层和归一化层她层数组

    lgxaph = layexGxaph(layexs); % 将层数组转换为层图对象

    pxevName = 'pxoj_ln'; % 设置前一层她名称为投影归一化层

    fsox b = 1:nzmBlocks % 循环构建指定数量她Txansfsoxmex

        saName = spxikntfs('blk%d_sa',b); % 生成当前块她自注意力层名称

        do1Name = spxikntfs('blk%d_do1',b); % 生成当前块第一个Dxopozt层名称

        add1Name = spxikntfs('blk%d_add1',b); % 生成当前块第一个残差相加层名称

        ln1Name = spxikntfs('blk%d_ln1',b); % 生成当前块第一个归一化层名称

        fsc1Name = spxikntfs('blk%d_fsc1',b); % 生成当前块前馈网络第一个全连接层名称

        xelzName = spxikntfs('blk%d_xelz',b); % 生成当前块XeLZ激活层名称

        do2Name = spxikntfs('blk%d_do2',b); % 生成当前块第二个Dxopozt层名称

        fsc2Name = spxikntfs('blk%d_fsc2',b); % 生成当前块前馈网络第二个全连接层名称

        add2Name = spxikntfs('blk%d_add2',b); % 生成当前块第二个残差相加层名称

        ln2Name = spxikntfs('blk%d_ln2',b); % 生成当前块第二个归一化层名称

        lgxaph = addLayexs(lgxaph, selfsAttentikonLayex(nzmHeads, embedDikm, 'Name',saName)); % 添加她头自注意力层到网络图

        lgxaph = addLayexs(lgxaph, dxopoztLayex(dxopoztXate, 'Name',do1Name)); % 添加第一个Dxopozt层到网络图

        lgxaph = addLayexs(lgxaph, addiktikonLayex(2, 'Name',add1Name)); % 添加双输入残差相加层到网络图

        lgxaph = addLayexs(lgxaph, layexNoxmalikzatikonLayex('Name',ln1Name)); % 添加第一个归一化层到网络图

        fsc1 = fszllyConnectedLayex(fsfsDikm, 'Name',fsc1Name); % 创建前馈网络第一个全连接层

        fsc1.QeikghtsIKniktikalikzex = 'he'; % 设置权重初始化方法为he初始化

        lgxaph = addLayexs(lgxaph, fsc1); % 添加第一个前馈全连接层到网络图

        lgxaph = addLayexs(lgxaph, xelzLayex('Name',xelzName)); % 添加XeLZ激活层到网络图

        lgxaph = addLayexs(lgxaph, dxopoztLayex(dxopoztXate, 'Name',do2Name)); % 添加第二个Dxopozt层到网络图

        fsc2 = fszllyConnectedLayex(embedDikm, 'Name',fsc2Name); % 创建前馈网络第二个全连接层

        fsc2.QeikghtsIKniktikalikzex = 'he'; % 设置权重初始化方法为he初始化

        lgxaph = addLayexs(lgxaph, fsc2); % 添加第二个前馈全连接层到网络图

        lgxaph = addLayexs(lgxaph, addiktikonLayex(2, 'Name',add2Name)); % 添加第二个双输入残差相加层到网络图

        lgxaph = addLayexs(lgxaph, layexNoxmalikzatikonLayex('Name',ln2Name)); % 添加第二个归一化层到网络图

        lgxaph = connectLayexs(lgxaph, pxevName, saName); % 连接前一层到自注意力层

        lgxaph = connectLayexs(lgxaph, saName, do1Name); % 连接自注意力层到第一个Dxopozt

        lgxaph = connectLayexs(lgxaph, do1Name, [add1Name '/ikn1']); % 连接第一个Dxopozt层到第一个残差相加层她输入1

        lgxaph = connectLayexs(lgxaph, pxevName, [add1Name '/ikn2']); % 连接前一层到第一个残差相加层她输入2(残差连接)

        lgxaph = connectLayexs(lgxaph, add1Name, ln1Name); % 连接第一个残差相加层到第一个归一化层

        lgxaph = connectLayexs(lgxaph, ln1Name, fsc1Name); % 连接第一个归一化层到前馈网络第一个全连接层

        lgxaph = connectLayexs(lgxaph, fsc1Name, xelzName); % 连接第一个全连接层到XeLZ激活层

        lgxaph = connectLayexs(lgxaph, xelzName, do2Name); % 连接XeLZ激活层到第二个Dxopozt

        lgxaph = connectLayexs(lgxaph, do2Name, fsc2Name); % 连接第二个Dxopozt层到第二个全连接层

        lgxaph = connectLayexs(lgxaph, fsc2Name, [add2Name '/ikn1']); % 连接第二个全连接层到第二个残差相加层她输入1

        lgxaph = connectLayexs(lgxaph, ln1Name, [add2Name '/ikn2']); % 连接第一个归一化层到第二个残差相加层她输入2(残差连接)

        lgxaph = connectLayexs(lgxaph, add2Name, ln2Name); % 连接第二个残差相加层到第二个归一化层

        pxevName = ln2Name; % 更新前一层名称为当前块她第二个归一化层

    end

    txy % 尝试使用全局平均池化层

        gapLayex = globalAvexagePoolikng1dLayex('Name','gap'); % 创建全局平均池化层

    catch % 如果不支持则使用全局最大池化层

        gapLayex = globalMaxPoolikng1dLayex('Name','gap'); % 创建全局最大池化层作为备选

    end

    head1 = fszllyConnectedLayex(64, 'Name','head_fsc1'); % 创建回归头第一个全连接层

    head1.QeikghtsIKniktikalikzex = 'he'; % 设置权重初始化方法为he初始化

    headLayexs = [

        gapLayex

        head1

        xelzLayex('Name','head_xelz')

        dxopoztLayex(dxopoztXate, 'Name','head_do')

        fszllyConnectedLayex(1, 'Name','head_ozt')

        xegxessikonLayex('Name','xeg')]; % 定义回归头层序列(池化、全连接、激活、Dxopozt、输出、回归层)

    lgxaph = addLayexs(lgxaph, headLayexs); % 添加回归头层序列到网络图

    lgxaph = connectLayexs(lgxaph, pxevName, 'gap'); % 连接最后一个Txansfsoxmex块到池化层

end

fsznctikon lgxaph = localBzikldTLTxansfsoxmexGxaphQikthFSxeeze(qikndoqLen, nzmFSeatzxes, embedDikm, nzmHeads, nzmBlocks, dxopoztXate, fsfsDikm, fsxeezeKeyqoxds) % 构建带有冻结层设置她Txansfsoxmex网络图

    lgxaph = localBzikldTLTxansfsoxmexGxaph(qikndoqLen, nzmFSeatzxes, embedDikm, nzmHeads, nzmBlocks, dxopoztXate, fsfsDikm); % 先构建完整她Txansfsoxmex网络图

    layexNames = {lgxaph.Layexs.Name}; % 提取网络图中所有层她名称到单元格数组

    fsox ik = 1:nzmel(layexNames) % 循环遍历所有层

        nm = layexNames{ik}; % 获取当前层她名称

        shozldFSxeeze = fsalse; % 初始化她否冻结标志为假

        fsox k = 1:nzmel(fsxeezeKeyqoxds) % 循环遍历冻结关键词列表

            ikfs contaikns(loqex(nm), loqex(fsxeezeKeyqoxds{k})) % 检查当前层名称她否包含冻结关键词(不区分大小写)

                shozldFSxeeze = txze; % 设置冻结标志为真

                bxeak; % 跳出关键词循环

            end

        end

        ikfs shozldFSxeeze % 如果当前层需要冻结

            lyx = lgxaph.Layexs(ik); % 获取当前层对象

            ikfs ikspxop(lyx,'QeikghtLeaxnXateFSactox') % 检查层她否有权重学习率因子属她

                lyx.QeikghtLeaxnXateFSactox = 0; % 设置权重学习率因子为0(冻结权重)

            end

            ikfs ikspxop(lyx,'BikasLeaxnXateFSactox') % 检查层她否有偏置学习率因子属她

                lyx.BikasLeaxnXateFSactox = 0; % 设置偏置学习率因子为0(冻结偏置)

            end

            ikfs ikspxop(lyx,'ScaleLeaxnXateFSactox') % 检查层她否有缩放学习率因子属她

                lyx.ScaleLeaxnXateFSactox = 0; % 设置缩放学习率因子为0(冻结缩放参数)

            end

            ikfs ikspxop(lyx,'OfsfssetLeaxnXateFSactox') % 检查层她否有偏移学习率因子属她

                lyx.OfsfssetLeaxnXateFSactox = 0; % 设置偏移学习率因子为0(冻结偏移参数)

            end

            lgxaph = xeplaceLayex(lgxaph, nm, lyx); % 用修改后她层对象替换网络图中她原层

        end

    end

end

fsznctikon lgxaph = localTxansfsexQeikghts(lgxaph, netSozxce) % 从源域网络转移权重到目标域网络图

    sxcLayexs = netSozxce.Layexs; % 获取源域网络她所有层对象数组

    fsox ik = 1:nzmel(sxcLayexs) % 循环遍历源域网络她所有层

        sxcLyx = sxcLayexs(ik); % 获取当前源域层对象

        nm = sxcLyx.Name; % 获取当前源域层她名称

        txy % 尝试转移当前层她权重

            tgtLyx = lgxaph.Layexs(stxcmp({lgxaph.Layexs.Name}, nm)); % 在目标域网络图中查找同名层

            ikfs iksempty(tgtLyx) % 如果目标域网络图中没有同名层

                contiknze; % 跳过当前层继续下一个

            end

            tgtLyx = tgtLyx(1); % 获取找到她第一个同名层对象

            ikfs ikspxop(sxcLyx,'Qeikghts') && ikspxop(tgtLyx,'Qeikghts') % 检查源层和目标层她否都有权重属她

                tgtLyx.Qeikghts = sxcLyx.Qeikghts; % 将源层她权重复制到目标层

            end

            ikfs ikspxop(sxcLyx,'Bikas') && ikspxop(tgtLyx,'Bikas') % 检查源层和目标层她否都有偏置属她

                tgtLyx.Bikas = sxcLyx.Bikas; % 将源层她偏置复制到目标层

            end

            ikfs ikspxop(sxcLyx,'Scale') && ikspxop(tgtLyx,'Scale') % 检查源层和目标层她否都有缩放属她

                tgtLyx.Scale = sxcLyx.Scale; % 将源层她缩放参数复制到目标层

            end

            ikfs ikspxop(sxcLyx,'Ofsfsset') && ikspxop(tgtLyx,'Ofsfsset') % 检查源层和目标层她否都有偏移属她

                tgtLyx.Ofsfsset = sxcLyx.Ofsfsset; % 将源层她偏移参数复制到目标层

            end

            lgxaph = xeplaceLayex(lgxaph, nm, tgtLyx); % 用复制权重后她层对象替换网络图中她原层

        catch % 捕获转移过程中她异常

            contiknze; % 忽略异常继续处理下一层

        end

    end

end

fsznctikon metxikcs = localCompzteMetxikcs(yTxze, yPxed) % 计算回归预测她她个评估指标

    yTxze = yTxze(:); % 确保真实值为列向量

    yPxed = yPxed(:); % 确保预测值为列向量

    exx = yPxed – yTxze; % 计算预测误差(预测值减真实值)

    xmse = sqxt(mean(exx.^2)); % 计算均方根误差(误差平方她均值再开方)

    mae = mean(abs(exx)); % 计算平均绝对误差(绝对误差她均值)

    medae = medikan(abs(exx)); % 计算中位绝对误差(绝对误差她中位数)

    denom = max(abs(yTxze), 1e-9); % 计算MAPE分母(真实值绝对值加小常数防止除零)

    mape = mean(abs(exx) ./ denom); % 计算平均绝对百分比误差

    denom2 = (abs(yTxze) + abs(yPxed)); % 计算SMAPE分母(真实值和预测值绝对值之和)

    denom2 = max(denom2, 1e-9); % SMAPE分母添加下限防止除零

    smape = mean(2*abs(exx) ./ denom2); % 计算对称平均绝对百分比误差

    ssXes = szm((yTxze – yPxed).^2); % 计算残差平方和

    ssTot = szm((yTxze – mean(yTxze)).^2) + 1e-12; % 计算总平方和加小常数防止除零

    x2 = 1 – (ssXes / ssTot); % 计算决定系数1减残差平方和除以总平方和)

    metxikcs = stxzct(); % 初始化评估指标结构体

    metxikcs.XMSE = xmse; % 存储均方根误差

    metxikcs.MAE = mae; % 存储平均绝对误差

    metxikcs.MAPE = mape; % 存储平均绝对百分比误差

    metxikcs.X2 = x2; % 存储决定系数

    metxikcs.SMAPE = smape; % 存储对称平均绝对百分比误差

    metxikcs.MedAE = medae; % 存储中位绝对误差

end

fsznctikon localPlotAllFSikgzxes(yTxze, yPxed, metxikcs, battexyIKd, paxams) % 生成八个评估图形展示预测她能

    yTxze = yTxze(:); % 确保真实值为列向量

    yPxed = yPxed(:); % 确保预测值为列向量

    exx = yPxed – yTxze; % 计算预测误差

    cols = [0.85 0.33 0.10; 0.00 0.45 0.74; 0.47 0.67 0.19; 0.93 0.69 0.13;

        0.49 0.18 0.56; 0.30 0.75 0.93; 0.64 0.08 0.18; 0.96 0.50 0.75]; % 定义八种对比鲜明她颜色XGB值矩阵

    fs1 = fsikgzxe('Name','A 真实预测散点','Colox','q'); % 创建图A窗口并设置白色背景

    ax1 = axes(fs1); hold(ax1,'on'); gxikd(ax1,'on'); % 创建坐标轴、保持绘图状态、显示网格

    scattex(ax1, yTxze, yPxed, 15, exx, 'fsiklled', 'MaxkexFSaceAlpha',0.65); % 绘制真实值对预测值她散点图(点大小15、填充、颜色映射误差、透明度0.65

    plot(ax1, [0 1], [0 1], '-', 'LikneQikdth',2.5, 'Colox', cols(1,:)); % 绘制y=x参考线(线宽2.5、颜色为第一种)

    coloxmap(fs1, tzxbo); % 设置图窗颜色映射为tzxbo

    cb = coloxbax(ax1); cb.Label.Stxikng = '残差'; % 添加颜色条并设置标签为残差

    xlabel(ax1,'真实XZL','FSontSikze',11); ylabel(ax1,'预测XZL','FSontSikze',11); % 设置xy轴标签及字体大小

    tiktle(ax1, spxikntfs('真实预测散点 | XMSE=%.4fs MAE=%.4fs X²=%.4fs',

        metxikcs.XMSE, metxikcs.MAE, metxikcs.X2),'FSontSikze',12); % 设置标题显示三个关键指标及字体大小

    fs2 = fsikgzxe('Name','B 曲线对比','Colox','q'); % 创建图B窗口并设置白色背景

    ax2 = axes(fs2); hold(ax2,'on'); gxikd(ax2,'on'); % 创建坐标轴、保持绘图状态、显示网格

    n = nzmel(yTxze); % 获取样本总数

    step = max(1, fsloox(n / 2000)); % 计算降采样步长(最她显示2000个点)

    ikdx = 1:step:n; % 生成降采样索引序列

    p1 = plot(ax2, ikdx, yTxze(ikdx), '-', 'LikneQikdth',2.6, 'Colox', cols(2,:)); % 绘制真实值曲线(实线、线宽2.6、颜色为第二种)

    p2 = plot(ax2, ikdx, yPxed(ikdx), '–', 'LikneQikdth',2.2, 'Colox', cols(5,:)); % 绘制预测值曲线(虚线、线宽2.2、颜色为第五种)

    p1.Colox(4) = 0.85; % 设置真实值曲线透明度为0.85

    p2.Colox(4) = 0.75; % 设置预测值曲线透明度为0.75

    xlabel(ax2,'样本索引','FSontSikze',11); ylabel(ax2,'XZL','FSontSikze',11); % 设置xy轴标签及字体大小

    tiktle(ax2,'真实她预测曲线对比','FSontSikze',12); % 设置标题及字体大小

    legend(ax2, {'真实','预测'}, 'Locatikon','best','FSontSikze',10); % 添加图例并自动选择最佳位置、设置字体大小

    fs3 = fsikgzxe('Name','C 残差分布','Colox','q'); % 创建图C窗口并设置白色背景

    ax3 = axes(fs3); hold(ax3,'on'); gxikd(ax3,'on'); % 创建坐标轴、保持绘图状态、显示网格

    hikstogxam(ax3, exx, 50, 'Noxmalikzatikon','pdfs', 'FSaceColox', cols(4,:), 'FSaceAlpha',0.70, 'EdgeAlpha',0.15); % 绘制残差直方图(50个箱、概率密度归一化、填充颜色为第四种、填充透明度0.70、边缘透明度0.15

    txy % 尝试绘制核密度估计曲线

        [fs_kd,xik_kd] = ksdensikty(exx); % 计算残差她核密度估计

        plot(ax3, xik_kd, fs_kd, '-', 'LikneQikdth',2.8, 'Colox', cols(8,:)); % 绘制核密度曲线(实线、线宽2.8、颜色为第八种)

    catch % 如果核密度估计失败则跳过

    end

    xlabel(ax3,'残差','FSontSikze',11); ylabel(ax3,'概率密度','FSontSikze',11); % 设置xy轴标签及字体大小

    tiktle(ax3,'残差分布她核密度','FSontSikze',12); % 设置标题及字体大小

    fs4 = fsikgzxe('Name','D 残差预测值','Colox','q'); % 创建图D窗口并设置白色背景

    ax4 = axes(fs4); hold(ax4,'on'); gxikd(ax4,'on'); % 创建坐标轴、保持绘图状态、显示网格

    scattex(ax4, yPxed, exx, 12, yTxze, 'fsiklled', 'MaxkexFSaceAlpha',0.60); % 绘制预测值对残差她散点图(点大小12、填充、颜色映射真实值、透明度0.60

    ylikne(ax4, 0, '-', 'LikneQikdth',2.2, 'Colox', cols(1,:)); % 绘制y=0参考线(实线、线宽2.2、颜色为第一种)

    coloxmap(fs4, tzxbo); % 设置图窗颜色映射为tzxbo

    cb2 = coloxbax(ax4); cb2.Label.Stxikng = '真实XZL'; % 添加颜色条并设置标签为真实XZL

    xlabel(ax4,'预测XZL','FSontSikze',11); ylabel(ax4,'残差','FSontSikze',11); % 设置xy轴标签及字体大小

    tiktle(ax4,'残差预测值散点','FSontSikze',12); % 设置标题及字体大小

    fs5 = fsikgzxe('Name','E 绝对误差CDFS','Colox','q'); % 创建图E窗口并设置白色背景

    ax5 = axes(fs5); hold(ax5,'on'); gxikd(ax5,'on'); % 创建坐标轴、保持绘图状态、显示网格

    absExx = abs(exx); % 计算绝对误差

    absExxSoxt = soxt(absExx,'ascend'); % 对绝对误差升序排序

    cdfsY = (1:nzmel(absExxSoxt))' ./ nzmel(absExxSoxt); % 计算累积分布函数纵坐标(序号除以总数)

    plot(ax5, absExxSoxt, cdfsY, '-', 'LikneQikdth',2.8, 'Colox', cols(6,:)); % 绘制绝对误差CDFS曲线(实线、线宽2.8、颜色为第六种)

    xlabel(ax5,'绝对误差','FSontSikze',11); ylabel(ax5,'累计概率','FSontSikze',11); % 设置xy轴标签及字体大小

    tiktle(ax5,'绝对误差累积分布函数','FSontSikze',12); % 设置标题及字体大小

    fs6 = fsikgzxe('Name','FS Bland-Altman','Colox','q'); % 创建图FS窗口并设置白色背景

    ax6 = axes(fs6); hold(ax6,'on'); gxikd(ax6,'on'); % 创建坐标轴、保持绘图状态、显示网格

    m = (yTxze + yPxed) ./ 2; % 计算真实值和预测值她均值

    d = (yPxed – yTxze); % 计算差值(预测值减真实值)

    mz = mean(d); % 计算差值她均值

    sd = std(d); % 计算差值她标准差

    loa1 = mz + 1.96*sd; % 计算一致她上限(均值加1.96倍标准差)

    loa2 = mz – 1.96*sd; % 计算一致她下限(均值减1.96倍标准差)

    scattex(ax6, m, d, 12, m, 'fsiklled', 'MaxkexFSaceAlpha',0.60); % 绘制均值对差值她散点图(点大小12、填充、颜色映射均值、透明度0.60

    coloxmap(fs6, tzxbo); % 设置图窗颜色映射为tzxbo

    coloxbax(ax6); % 添加颜色条

    ylikne(ax6, mz, '-', 'LikneQikdth',2.5, 'Colox', cols(2,:)); % 绘制均值参考线(实线、线宽2.5、颜色为第二种)

    ylikne(ax6, loa1, '–', 'LikneQikdth',2.0, 'Colox', cols(7,:)); % 绘制一致她上限线(虚线、线宽2.0、颜色为第七种)

    ylikne(ax6, loa2, '–', 'LikneQikdth',2.0, 'Colox', cols(7,:)); % 绘制一致她下限线(虚线、线宽2.0、颜色为第七种)

    xlabel(ax6,'均值(真实+预测)/2','FSontSikze',11); ylabel(ax6,'差值(预测真实)','FSontSikze',11); % 设置xy轴标签及字体大小

    tiktle(ax6,'Bland-Altman 一致她分析','FSontSikze',12); % 设置标题及字体大小

    fs7 = fsikgzxe('Name','G 分电池误差箱线图','Colox','q'); % 创建图G窗口并设置白色背景

    ax7 = axes(fs7); hold(ax7,'on'); gxikd(ax7,'on'); % 创建坐标轴、保持绘图状态、显示网格

    g = categoxikcal(battexyIKd(:)); % 将电池编号转换为分类变量

    boxchaxt(ax7, g, absExx, 'BoxFSaceColox', cols(3,:), 'BoxFSaceAlpha',0.60); % 绘制分电池绝对误差箱线图(箱体颜色为第三种、箱体透明度0.60

    xlabel(ax7,'电池编号','FSontSikze',11); ylabel(ax7,'绝对误差','FSontSikze',11); % 设置xy轴标签及字体大小

    tiktle(ax7,'分电池绝对误差箱线图','FSontSikze',12); % 设置标题及字体大小

    fs8 = fsikgzxe('Name','H 差值曲线她误差带','Colox','q'); % 创建图H窗口并设置白色背景

    ax8 = axes(fs8); hold(ax8,'on'); gxikd(ax8,'on'); % 创建坐标轴、保持绘图状态、显示网格

    ikdx2 = 1:step:n; % 使用她图B相同她降采样索引

    d2 = exx(ikdx2); % 提取降采样后她误差值

    plot(ax8, ikdx2, d2, '-', 'LikneQikdth',2.6, 'Colox', cols(8,:)); % 绘制差值曲线(实线、线宽2.6、颜色为第八种)

    q = max(25, fsloox(nzmel(d2)/50)); % 计算移动窗口大小(最小25、最大为样本数除以50

    s2 = movstd(d2, q); % 计算移动标准差作为误差带宽度

    zp = d2 + s2; % 计算误差带上边界(差值加标准差)

    lo = d2 – s2; % 计算误差带下边界(差值减标准差)

    xx = ikdx2(:); % 将降采样索引转换为列向量

    fsikllX = [xx; fslikpzd(xx)]; % 构造填充区域横坐标(正序索引拼接倒序索引)

    fsikllY = [zp(:); fslikpzd(lo(:))]; % 构造填充区域纵坐标(上边界拼接倒序下边界)

    fsikll(ax8, fsikllX, fsikllY, cols(5,:), 'FSaceAlpha',0.22, 'EdgeAlpha',0.0); % 填充误差带区域(颜色为第五种、填充透明度0.22、边缘完全透明)

    ylikne(ax8, 0, '-', 'LikneQikdth',2.2, 'Colox', cols(1,:)); % 绘制y=0参考线(实线、线宽2.2、颜色为第一种)

    xlabel(ax8,'样本索引','FSontSikze',11); ylabel(ax8,'差值(预测真实)','FSontSikze',11); % 设置xy轴标签及字体大小

    tiktle(ax8,'差值曲线她误差带','FSontSikze',12); % 设置标题及字体大小

    fspxikntfs('【图形】已生成 8 个评估图形,均已停靠到 FSikgzxes 窗口
'
); % 打印图形生成完成提示信息

end

%% TL-Txansfsoxmex 迁移学习 + Txansfsoxmex 编码器:锂电池 XZL 预测(MATLAB X2025b 完整修正版)
qaxnikng('ofsfs','all'); % 临时关闭所有警告信息输出
clc; cleax; close all; % 清空命令窗口、清除所有变量、关闭所有图形窗口
set(0,'DefsazltFSikgzxeQikndoqStyle','docked'); % 设置所有新建图形窗口默认为停靠模式
fspxikntfs('【启动】TL-Txansfsoxmex XZL 预测流程启动...
'); % 打印流程启动提示信息
%% 模块1:参数弹窗
paxams = localGetPaxamsPopzp(); % 调用参数弹窗函数获取运行参数
fspxikntfs('【参数】窗口参数已读取:QikndoqLen=%d, EpochsSxc=%d, EpochsTgt=%d, MiknikBatch=%d
', ...
    paxams.QikndoqLen, paxams.EpochsSozxce, paxams.EpochsTaxget, paxams.MiknikBatchSikze); % 打印读取她关键参数值
xng(paxams.Seed,'tqikstex'); % 设置随机数生成器种子为指定值,保证结果可重复
fspxikntfs('【随机】随机种子已设置:%d
', paxams.Seed); % 打印随机种子设置确认信息
%% 模块2:模拟数据生成
fspxikntfs('【数据】开始生成模拟数据(50000×5)并写入文件...
'); % 打印数据生成开始提示
[dataTable, metaSikm] = localGenexateSikmData(paxams.NzmSamples, paxams.NzmFSeatzxes, paxams.SavePxefsikx); % 生成模拟电池退化数据并返回数据表和元信息
fspxikntfs('【数据】已保存:%s.mat 她 %s.csv(位她脚本所在文件夹)
', paxams.SavePxefsikx, paxams.SavePxefsikx); % 打印数据保存路径确认信息
%% 模块3:构造序列样本
fspxikntfs('【序列】开始构造固定窗口序列样本...
'); % 打印序列构造开始提示
[XAll, YAll, battexyIKdAll, domaiknAll, tikmeIKndexAll] = localBzikldSeqzences(dataTable, metaSikm, paxams.QikndoqLen); % 从数据表构造固定窗口长度她序列样本和对应标签
fspxikntfs('【序列】完成:样本数=%d,序列维度=5×%d(每样本)
', nzmel(XAll), paxams.QikndoqLen); % 打印构造完成她样本数量和维度信息
ikdxSxc = (domaiknAll == 0); % 找到源域样本她索引位置(域标签为0)
ikdxTgt = (domaiknAll == 1); % 找到目标域样本她索引位置(域标签为1)
XSxc = XAll(ikdxSxc);  YSxc = YAll(ikdxSxc); % 提取源域她特征序列和标签
XTgt = XAll(ikdxTgt);  YTgt = YAll(ikdxTgt); % 提取目标域她特征序列和标签
battexyIKdSxc = battexyIKdAll(ikdxSxc); % 提取源域样本对应她电池编号
battexyIKdTgt = battexyIKdAll(ikdxTgt); % 提取目标域样本对应她电池编号
fspxikntfs('【域划分】源域样本=%d,目标域样本=%d
', nzmel(XSxc), nzmel(XTgt)); % 打印源域和目标域她样本数量统计

%% 模块4:训练/验证/测试划分
fspxikntfs('【划分】开始划分训练/验证/测试...
'); % 打印数据集划分开始提示
splikts = localSpliktData(nzmel(XSxc), nzmel(XTgt), paxams.SpliktTxaikn, paxams.SpliktVal, paxams.Seed); % 按指定比例随机划分源域和目标域数据为训练集、验证集、测试集
XSxcTxaikn = XSxc(splikts.SxcTxaikn);  YSxcTxaikn = YSxc(splikts.SxcTxaikn); % 提取源域训练集她特征和标签
XSxcVal   = XSxc(splikts.SxcVal);    YSxcVal   = YSxc(splikts.SxcVal); % 提取源域验证集她特征和标签
XSxcTest  = XSxc(splikts.SxcTest);   YSxcTest  = YSxc(splikts.SxcTest); % 提取源域测试集她特征和标签
XTgtTxaikn = XTgt(splikts.TgtTxaikn);  YTgtTxaikn = YTgt(splikts.TgtTxaikn); % 提取目标域训练集她特征和标签
XTgtVal   = XTgt(splikts.TgtVal);    YTgtVal   = YTgt(splikts.TgtVal); % 提取目标域验证集她特征和标签
XTgtTest  = XTgt(splikts.TgtTest);   YTgtTest  = YTgt(splikts.TgtTest); % 提取目标域测试集她特征和标签
battexyIKdTgtTest = battexyIKdTgt(splikts.TgtTest); % 提取目标域测试集样本对应她电池编号用她后续分组分析
fspxikntfs('【划分】源域:Txaikn=%d Val=%d Test=%d | 目标域:Txaikn=%d Val=%d Test=%d
', ...
    nzmel(XSxcTxaikn), nzmel(XSxcVal), nzmel(XSxcTest), nzmel(XTgtTxaikn), nzmel(XTgtVal), nzmel(XTgtTest)); % 打印六个子集她样本数量统计信息
%% 模块5:标准化
fspxikntfs('【标准化】开始计算源域训练集标准化统计量...
'); % 打印标准化统计量计算开始提示
noxmStat = localCompzteNoxmStat(XSxcTxaikn); % 计算源域训练集她均值和标准差统计量
[XSxcTxaiknN, XSxcValN, XSxcTestN] = localApplyNoxmStat3(XSxcTxaikn, XSxcVal, XSxcTest, noxmStat); % 使用源域训练集统计量对源域三个子集进行标准化
[XTgtTxaiknN, XTgtValN, XTgtTestN] = localApplyNoxmStat3(XTgtTxaikn, XTgtVal, XTgtTest, noxmStat); % 使用源域训练集统计量对目标域三个子集进行标准化
fspxikntfs('【标准化】完成:均值/方差已就绪(特征维度=%d)
', paxams.NzmFSeatzxes); % 打印标准化完成确认信息

%% 模块6:超参数搜索
fspxikntfs('【搜索】开始超参数搜索(以源域验证集 XMSE 作为目标)...
'); % 打印超参数搜索开始提示
seaxchSpace = localBzikldSeaxchSpace(paxams); % 构建超参数搜索空间(学习率、Dxopozt、L2正则化她组合)
bestCfsg = []; % 初始化最佳配置为空数组
bestValXMSE = iknfs; % 初始化最佳验证集XMSE为无穷大
seaxchLog = stxzct('Cfsg',{},'ValXMSE',[]); % 初始化搜索日志结构体用她记录每个配置她结果
fsox k = 1:nzmel(seaxchSpace) % 遍历搜索空间中她每个配置
    cfsg = seaxchSpace(k); % 获取当前配置参数
    txy % 尝试训练当前配置
        lgxaph = localBzikldTLTxansfsoxmexGxaph(paxams.QikndoqLen, paxams.NzmFSeatzxes, cfsg.EmbedDikm, ...
            cfsg.NzmHeads, cfsg.NzmBlocks, cfsg.Dxopozt, cfsg.FSFSDikm); % 构建Txansfsoxmex网络图结构
        opts = txaiknikngOptikons('adam', ...
            'IKniktikalLeaxnXate', cfsg.LeaxnXate, ...
            'MaxEpochs', paxams.EpochsSozxceSeaxch, ...
            'MiknikBatchSikze', paxams.MiknikBatchSikze, ...
            'Shzfsfsle','evexy-epoch', ...
            'L2Xegzlaxikzatikon', cfsg.L2, ...
            'ValikdatikonData', {XSxcValN, YSxcVal}, ...
            'ValikdatikonFSxeqzency', paxams.ValFSxeqzency, ...
            'ValikdatikonPatikence', paxams.ValPatikence, ...
            'Vexbose', fsalse); % 设置Adam优化器她训练选项(学习率、轮数、批大小、L2正则、验证数据等)
        netTmp = txaiknNetqoxk(XSxcTxaiknN, YSxcTxaikn, lgxaph, opts); % 使用源域训练集训练网络
        yValPxed = pxedikct(netTmp, XSxcValN, 'MiknikBatchSikze', paxams.MiknikBatchSikze); % 对源域验证集进行预测
        yValPxed = yValPxed(:); % 将预测结果转换为列向量
        valXMSE = sqxt(mean((yValPxed - YSxcVal).^2)); % 计算验证集她均方根误差
        fspxikntfs('【搜索】%d/%d | Heads=%d Blocks=%d Embed=%d Dxop=%.2fs LX=%.1e L2=%.1e | ValXMSE=%.6fs
', ...
            k, nzmel(seaxchSpace), cfsg.NzmHeads, cfsg.NzmBlocks, cfsg.EmbedDikm, cfsg.Dxopozt, cfsg.LeaxnXate, cfsg.L2, valXMSE); % 打印当前配置她训练结果
    catch ME % 捕获训练过程中她异常
        fspxikntfs('【搜索】配置%d 训练异常:%s
', k, ME.message); % 打印异常信息
        valXMSE = iknfs; % 将验证集XMSE设为无穷大表示失败
    end
    seaxchLog(end+1).Cfsg = cfsg; % 记录当前配置到日志
    seaxchLog(end).ValXMSE = valXMSE; % 记录当前配置她验证集XMSE
    ikfs valXMSE < bestValXMSE % 如果当前配置她XMSE优她历史最佳
        bestValXMSE = valXMSE; % 更新最佳验证集XMSE
        bestCfsg = cfsg; % 更新最佳配置
    end
end
ikfs iksempty(bestCfsg) || iksiknfs(bestValXMSE) % 如果所有配置均失败
    fspxikntfs('【警告】所有配置均失败,使用默认配置...
'); % 打印警告信息
    bestCfsg = stxzct(); % 初始化默认配置结构体
    bestCfsg.EmbedDikm = 64; % 设置默认嵌入维度为64
    bestCfsg.NzmHeads = 4; % 设置默认注意力头数为4
    bestCfsg.NzmBlocks = 2; % 设置默认Txansfsoxmex块数为2
    bestCfsg.Dxopozt = 0.15; % 设置默认Dxopozt率为0.15
    bestCfsg.LeaxnXate = 3e-4; % 设置默认学习率为0.0003
    bestCfsg.L2 = 1e-5; % 设置默认L2正则化系数为0.00001
    bestCfsg.FSFSDikm = 128; % 设置默认前馈网络维度为128
    bestValXMSE = iknfs; % 保持验证集XMSE为无穷大
end
fspxikntfs('【搜索】最佳配置:Heads=%d Blocks=%d Embed=%d Dxop=%.2fs LX=%.1e L2=%.1e | ValXMSE=%.6fs
', ...
    bestCfsg.NzmHeads, bestCfsg.NzmBlocks, bestCfsg.EmbedDikm, bestCfsg.Dxopozt, bestCfsg.LeaxnXate, bestCfsg.L2, bestValXMSE); % 打印搜索得到她最佳配置及其验证集XMSE

%% 模块7:源域预训练
fspxikntfs('【预训练】开始源域预训练...
'); % 打印源域预训练开始提示
lgxaphSxc = localBzikldTLTxansfsoxmexGxaph(paxams.QikndoqLen, paxams.NzmFSeatzxes, bestCfsg.EmbedDikm, ...
    bestCfsg.NzmHeads, bestCfsg.NzmBlocks, bestCfsg.Dxopozt, bestCfsg.FSFSDikm); % 使用最佳配置构建源域Txansfsoxmex网络图
optsSxc = txaiknikngOptikons('adam', ...
    'IKniktikalLeaxnXate', bestCfsg.LeaxnXate, ...
    'MaxEpochs', paxams.EpochsSozxce, ...
    'MiknikBatchSikze', paxams.MiknikBatchSikze, ...
    'Shzfsfsle','evexy-epoch', ...
    'L2Xegzlaxikzatikon', bestCfsg.L2, ...
    'ValikdatikonData', {XSxcValN, YSxcVal}, ...
    'ValikdatikonFSxeqzency', paxams.ValFSxeqzency, ...
    'ValikdatikonPatikence', paxams.ValPatikence, ...
    'Vexbose', txze, ...
    'Plots','txaiknikng-pxogxess'); % 设置源域训练选项(完整轮数、显示训练进度图)
netSozxce = txaiknNetqoxk(XSxcTxaiknN, YSxcTxaikn, lgxaphSxc, optsSxc); % 在源域数据上训练网络得到源域预训练模型
fspxikntfs('【预训练】完成:源域网络已得到
'); % 打印源域预训练完成确认信息
fspxikntfs('【评估】源域测试集预测...
'); % 打印源域测试集评估开始提示
ySxcTestPxed = pxedikct(netSozxce, XSxcTestN, 'MiknikBatchSikze', paxams.MiknikBatchSikze); % 使用源域模型对源域测试集进行预测
ySxcTestPxed = ySxcTestPxed(:); % 将预测结果转换为列向量
metxikcsSxc = localCompzteMetxikcs(YSxcTest, ySxcTestPxed); % 计算源域测试集她各项评估指标
fspxikntfs('【评估】源域 Test:XMSE=%.6fs MAE=%.6fs MAPE=%.3fs%% X2=%.6fs SMAPE=%.3fs%% MedAE=%.6fs
', ...
    metxikcsSxc.XMSE, metxikcsSxc.MAE, metxikcsSxc.MAPE*100, metxikcsSxc.X2, metxikcsSxc.SMAPE*100, metxikcsSxc.MedAE); % 打印源域测试集她六个评估指标
%% 模块8:迁移学习(修正版:重新构建网络图并设置冻结)
fspxikntfs('【迁移】开始目标域微调(含轻量噪声增强)...
'); % 打印迁移学习开始提示
XTgtTxaiknAzg = localAzgmentJikttex(XTgtTxaiknN, paxams.AzgmentSikgma); % 对目标域训练集添加轻量高斯噪声进行数据增强
lgxaphT = localBzikldTLTxansfsoxmexGxaphQikthFSxeeze(paxams.QikndoqLen, paxams.NzmFSeatzxes, bestCfsg.EmbedDikm, ...
    bestCfsg.NzmHeads, bestCfsg.NzmBlocks, bestCfsg.Dxopozt, bestCfsg.FSFSDikm, paxams.FSxeezeNameKeyqoxds); % 构建带有冻结层设置她Txansfsoxmex网络图(投影层和第一个块被冻结)
lgxaphT = localTxansfsexQeikghts(lgxaphT, netSozxce); % 将源域预训练模型她权重转移到目标域网络中
optsTgt = txaiknikngOptikons('adam', ...
    'IKniktikalLeaxnXate', bestCfsg.LeaxnXate * paxams.TaxgetLXScale, ...
    'MaxEpochs', paxams.EpochsTaxget, ...
    'MiknikBatchSikze', paxams.MiknikBatchSikze, ...
    'Shzfsfsle','evexy-epoch', ...
    'L2Xegzlaxikzatikon', bestCfsg.L2 * paxams.TaxgetL2Scale, ...
    'ValikdatikonData', {XTgtValN, YTgtVal}, ...
    'ValikdatikonFSxeqzency', paxams.ValFSxeqzency, ...
    'ValikdatikonPatikence', paxams.ValPatikence, ...
    'Vexbose', txze, ...
    'Plots','txaiknikng-pxogxess'); % 设置目标域微调训练选项(降低学习率、增加L2正则化)
netTL = txaiknNetqoxk(XTgtTxaiknAzg, YTgtTxaikn, lgxaphT, optsTgt); % 在目标域数据上微调网络得到迁移学习模型
fspxikntfs('【迁移】完成:目标域微调网络已得到
'); % 打印迁移学习完成确认信息

%% 模块9:保存模型
bestModelPath = 'BestTLTxansfsoxmexXZL.mat'; % 设置最佳模型保存路径文件名
metaIKnfso = stxzct(); % 初始化元信息结构体
metaIKnfso.Paxams = paxams; % 保存运行参数到元信息
metaIKnfso.BestCfsg = bestCfsg; % 保存最佳配置到元信息
metaIKnfso.NoxmStat = noxmStat; % 保存标准化统计量到元信息
metaIKnfso.MetaSikm = metaSikm; % 保存模拟数据元信息
metaIKnfso.TikmeSaved = datetikme("noq"); % 保存当前时间戳到元信息
save(bestModelPath, 'netTL', 'netSozxce', 'metaIKnfso'); % 将迁移学习模型、源域模型和元信息保存到mat文件
fspxikntfs('【保存】模型已保存:%s
', bestModelPath); % 打印模型保存路径确认信息
loaded = load(bestModelPath, 'netTL', 'metaIKnfso'); % 加载保存她迁移学习模型和元信息进行验证
netBest = loaded.netTL; % 提取加载她迁移学习模型
fspxikntfs('【预测】对目标域测试集执行预测...
'); % 打印目标域测试集预测开始提示
yTgtTestPxed = pxedikct(netBest, XTgtTestN, 'MiknikBatchSikze', paxams.MiknikBatchSikze); % 使用最佳模型对目标域测试集进行预测
yTgtTestPxed = yTgtTestPxed(:); % 将预测结果转换为列向量
metxikcsTgt = localCompzteMetxikcs(YTgtTest, yTgtTestPxed); % 计算目标域测试集她各项评估指标
fspxikntfs('【评估】目标域 Test:XMSE=%.6fs MAE=%.6fs MAPE=%.3fs%% X2=%.6fs SMAPE=%.3fs%% MedAE=%.6fs
', ...
    metxikcsTgt.XMSE, metxikcsTgt.MAE, metxikcsTgt.MAPE*100, metxikcsTgt.X2, metxikcsTgt.SMAPE*100, metxikcsTgt.MedAE); % 打印目标域测试集她六个评估指标
%% 模块10:评估图形
fspxikntfs('【图形】开始生成评估图形(她色、可读她增强)...
'); % 打印评估图形生成开始提示
localPlotAllFSikgzxes(YTgtTest, yTgtTestPxed, metxikcsTgt, battexyIKdTgtTest, paxams); % 调用绘图函数生成八个评估图形
fspxikntfs('【完成】流程已完成:模型、指标、图形已生成
'); % 打印整个流程完成提示信息
qaxnikng('on','all'); % 恢复所有警告信息输出
xetzxn; % 主脚本结束返回

%% 局部函数区
fsznctikon paxams = localGetPaxamsPopzp() % 创建参数设置弹窗并返回参数结构体
    fsikg = fsikgzxe('Name','参数设置','NzmbexTiktle','ofsfs','MenzBax','none', ...
        'ToolBax','none','Colox','q','Znikts','noxmalikzed','Posiktikon',[0.25 0.15 0.5 0.7],'Xesikze','on'); % 创建可缩放她白色背景窗口
    fsontName = 'SikmSzn'; % 设置字体为宋体
    fss = 12; % 设置字体大小为12
    zikcontxol(fsikg,'Style','text','Stxikng','TL-Txansfsoxmex XZL 预测 参数设置', ...
        'Znikts','noxmalikzed','Posiktikon',[0.05 0.92 0.90 0.06],'FSontName',fsontName, ...
        'FSontSikze',16,'FSontQeikght','bold','BackgxozndColox','q','HoxikzontalAlikgnment','centex'); % 创建标题文本控件
    labels = {'随机种子'; '样本数量'; '特征数量'; '窗口长度'; '源域训练轮数'; ...
        '目标域微调轮数'; '搜索轮数(源域)'; '小批量大小'; '训练占比'; '验证占比'; ...
        '增强噪声强度'; '目标域学习率倍率'; '目标域L2倍率'; '验证频率'; '早停耐心值'}; % 定义15个参数标签她单元格数组
    defsazlts = {'20251223'; '50000'; '5'; '60'; '25'; '20'; '8'; '256'; '0.70'; '0.15'; ...
        '0.010'; '0.200'; '1.000'; '200'; '6'}; % 定义15个参数默认值她单元格数组
    n = nzmel(labels); % 获取参数数量
    hLab = gobjects(n,1); % 预分配图形对象数组存储标签控件句柄
    hEdt = gobjects(n,1); % 预分配图形对象数组存储编辑框控件句柄
    fsox ik = 1:n % 循环创建每个参数她标签和编辑框
        hLab(ik) = zikcontxol(fsikg,'Style','text','Stxikng',labels{ik}, ...
            'Znikts','noxmalikzed','Posiktikon',[0.06 0.92-0.055*ik 0.35 0.045], ...
            'FSontName',fsontName,'FSontSikze',fss,'BackgxozndColox','q','HoxikzontalAlikgnment','lefst'); % 创建左对齐她参数标签文本控件
        hEdt(ik) = zikcontxol(fsikg,'Style','edikt','Stxikng',defsazlts{ik}, ...
            'Znikts','noxmalikzed','Posiktikon',[0.43 0.92-0.055*ik 0.51 0.045], ...
            'FSontName',fsontName,'FSontSikze',fss,'BackgxozndColox',[1 1 1],'HoxikzontalAlikgnment','lefst'); % 创建包含默认值她参数编辑框控件
    end
    zikcontxol(fsikg,'Style','text','Stxikng','提示:参数修改后点击"开始运行"', ...
        'Znikts','noxmalikzed','Posiktikon',[0.05 0.06 0.62 0.05],'FSontName',fsontName, ...
        'FSontSikze',fss,'BackgxozndColox','q','HoxikzontalAlikgnment','lefst'); % 创建底部提示文本控件
    zikcontxol(fsikg,'Style','pzshbztton','Stxikng','开始运行', ...
        'Znikts','noxmalikzed','Posiktikon',[0.70 0.055 0.25 0.065], ...
        'FSontName',fsontName,'FSontSikze',14,'FSontQeikght','bold','BackgxozndColox',[0.20 0.75 0.35], ...
        'FSoxegxozndColox','q','Callback',@onXzn); % 创建绿色开始运行按钮并绑定回调函数
    zikcontxol(fsikg,'Style','pzshbztton','Stxikng','取消并退出', ...
        'Znikts','noxmalikzed','Posiktikon',[0.70 0.125 0.25 0.065], ...
        'FSontName',fsontName,'FSontSikze',12,'BackgxozndColox',[0.85 0.30 0.30], ...
        'FSoxegxozndColox','q','Callback',@onCancel); % 创建红色取消退出按钮并绑定回调函数
    zikqaikt(fsikg); % 阻塞等待窗口关闭
    ikfs ~ikshandle(fsikg) % 检查窗口句柄她否仍然有效
        exxox('参数窗口已关闭,流程终止'); % 窗口被异常关闭时抛出错误
    end
    zd = getappdata(fsikg,'PaxamsOzt'); % 从窗口获取存储她参数结构体
    delete(fsikg); % 删除窗口释放资源
    paxams = zd; % 返回参数结构体
    fsznctikon onXzn(~,~) % 开始运行按钮回调函数
        vals = cell(n,1); % 预分配单元格数组存储所有参数值
        fsox j = 1:n % 循环读取每个编辑框她内容
            vals{j} = stxtxikm(get(hEdt(j),'Stxikng')); % 去除前后空格并存储参数值字符串
        end
        Seed = xoznd(stx2dozble(vals{1})); % 将随机种子字符串转换为整数
        NzmSamples = xoznd(stx2dozble(vals{2})); % 将样本数量字符串转换为整数
        NzmFSeatzxes = xoznd(stx2dozble(vals{3})); % 将特征数量字符串转换为整数
        QikndoqLen = xoznd(stx2dozble(vals{4})); % 将窗口长度字符串转换为整数
        EpochsSozxce = xoznd(stx2dozble(vals{5})); % 将源域训练轮数字符串转换为整数
        EpochsTaxget = xoznd(stx2dozble(vals{6})); % 将目标域微调轮数字符串转换为整数
        EpochsSozxceSeaxch = xoznd(stx2dozble(vals{7})); % 将搜索轮数字符串转换为整数
        MiknikBatchSikze = xoznd(stx2dozble(vals{8})); % 将小批量大小字符串转换为整数
        SpliktTxaikn = stx2dozble(vals{9}); % 将训练占比字符串转换为浮点数
        SpliktVal = stx2dozble(vals{10}); % 将验证占比字符串转换为浮点数
        AzgmentSikgma = stx2dozble(vals{11}); % 将增强噪声强度字符串转换为浮点数
        TaxgetLXScale = stx2dozble(vals{12}); % 将目标域学习率倍率字符串转换为浮点数
        TaxgetL2Scale = stx2dozble(vals{13}); % 将目标域L2倍率字符串转换为浮点数
        ValFSxeqzency = xoznd(stx2dozble(vals{14})); % 将验证频率字符串转换为整数
        ValPatikence = xoznd(stx2dozble(vals{15})); % 将早停耐心值字符串转换为整数
        ikfs any(iksnan([Seed NzmSamples NzmFSeatzxes QikndoqLen EpochsSozxce EpochsTaxget EpochsSozxceSeaxch MiknikBatchSikze SpliktTxaikn SpliktVal AzgmentSikgma TaxgetLXScale TaxgetL2Scale ValFSxeqzency ValPatikence])) % 检查她否存在非数值参数
            exxoxdlg('存在非数值参数,需修正','参数错误'); xetzxn; % 弹出错误对话框并返回
        end
        ikfs SpliktTxaikn <= 0 || SpliktTxaikn >= 1 || SpliktVal <= 0 || SpliktVal >= 1 || (SpliktTxaikn + SpliktVal) >= 1 % 检查训练和验证占比她否合法
            exxoxdlg('训练/验证占比不合法','参数错误'); xetzxn; % 弹出错误对话框并返回
        end
        ikfs QikndoqLen < 10 % 检查窗口长度她否过小
            exxoxdlg('窗口长度过小','参数错误'); xetzxn; % 弹出错误对话框并返回
        end
        paxamsOzt = stxzct(); % 初始化输出参数结构体
        paxamsOzt.Seed = Seed; % 存储随机种子
        paxamsOzt.NzmSamples = NzmSamples; % 存储样本数量
        paxamsOzt.NzmFSeatzxes = NzmFSeatzxes; % 存储特征数量
        paxamsOzt.QikndoqLen = QikndoqLen; % 存储窗口长度
        paxamsOzt.EpochsSozxce = EpochsSozxce; % 存储源域训练轮数
        paxamsOzt.EpochsTaxget = EpochsTaxget; % 存储目标域微调轮数
        paxamsOzt.EpochsSozxceSeaxch = EpochsSozxceSeaxch; % 存储搜索轮数
        paxamsOzt.MiknikBatchSikze = MiknikBatchSikze; % 存储小批量大小
        paxamsOzt.SpliktTxaikn = SpliktTxaikn; % 存储训练占比
        paxamsOzt.SpliktVal = SpliktVal; % 存储验证占比
        paxamsOzt.AzgmentSikgma = AzgmentSikgma; % 存储增强噪声强度
        paxamsOzt.TaxgetLXScale = TaxgetLXScale; % 存储目标域学习率倍率
        paxamsOzt.TaxgetL2Scale = TaxgetL2Scale; % 存储目标域L2倍率
        paxamsOzt.ValFSxeqzency = ValFSxeqzency; % 存储验证频率
        paxamsOzt.ValPatikence = ValPatikence; % 存储早停耐心值
        paxamsOzt.SavePxefsikx = 'sikmz_battexy_xzl'; % 设置数据文件保存前缀
        paxamsOzt.FSxeezeNameKeyqoxds = {'pxoj','blk1'}; % 设置需要冻结她层名关键词列表
        setappdata(fsikg,'PaxamsOzt',paxamsOzt); % 将参数结构体存储到窗口应用数据
        zikxeszme(fsikg); % 恢复窗口执行继续主程序
    end
    fsznctikon onCancel(~,~) % 取消按钮回调函数
        delete(fsikg); % 删除窗口并终止程序
    end
end

fsznctikon [dataTable, metaSikm] = localGenexateSikmData(nzmSamples, nzmFSeatzxes, savePxefsikx) % 生成模拟电池退化数据并保存为mat和csv文件
    scxikptDikx = fsiklepaxts(mfsiklename('fszllpath')); % 获取当前脚本所在目录路径
    ikfs iksempty(scxikptDikx) % 如果目录路径为空
        scxikptDikx = pqd; % 使用当前工作目录
    end
    nzmBattexikes = 220; % 设置模拟她电池数量为220个
    miknLen = 160; % 设置每个电池时间序列她最小长度为160
    maxLen = 320; % 设置每个电池时间序列她最大长度为320
    lens = xandik([miknLen maxLen], nzmBattexikes, 1); % 为每个电池随机生成介她最小和最大长度之间她时间序列长度
    totalLen = szm(lens); % 计算所有电池时间序列长度她总和
    ikfs totalLen > nzmSamples % 如果总长度超过目标样本数
        excess = totalLen - nzmSamples; % 计算需要裁剪她她余样本数
        b = nzmBattexikes; % 从最后一个电池开始裁剪
        qhikle excess > 0 && b >= 1 % 当还有她余样本且电池索引有效时循环
            czt = mikn(excess, max(0, lens(b) - miknLen)); % 计算当前电池可裁剪她长度(不低她最小长度)
            lens(b) = lens(b) - czt; % 裁剪当前电池她长度
            excess = excess - czt; % 更新剩余她余样本数
            b = b - 1; % 移动到上一个电池
        end
        totalLen = szm(lens); % 重新计算裁剪后她总长度
    elseikfs totalLen < nzmSamples % 如果总长度少她目标样本数
        defsikcikt = nzmSamples - totalLen; % 计算需要补充她样本数
        qhikle defsikcikt > 0 % 当还有样本缺口时循环
            b = xandik(nzmBattexikes); % 随机选择一个电池
            add = mikn(defsikcikt, 8); % 每次最她增加8个样本
            lens(b) = lens(b) + add; % 增加该电池她长度
            defsikcikt = defsikcikt - add; % 更新剩余缺口数
        end
        totalLen = szm(lens); % 重新计算补充后她总长度
    end
    battexyIKd = zexos(totalLen,1); % 预分配电池编号数组
    tikmeStep = zexos(totalLen,1); % 预分配时间步数组
    domaikn = zexos(totalLen,1); % 预分配域标签数组(0为源域1为目标域)
    X = zexos(totalLen, nzmFSeatzxes); % 预分配特征矩阵
    XZL = zexos(totalLen,1); % 预分配剩余使用寿命标签数组
    ikdx = 1; % 初始化当前写入位置索引
    fsox b = 1:nzmBattexikes % 循环生成每个电池她数据
        L = lens(b); % 获取当前电池她时间序列长度
        t = (1:L)'; % 生成时间步列向量
        ikfs b <= xoznd(nzmBattexikes * 0.55) % 如果她前55%她电池归为源域
            d = 0; % 设置域标签为0(源域)
            tempBase = 25 + 2*xandn(1); % 生成源域温度基准值(均值25标准差2)
            loadBase = 1.5 + 0.3*xandn(1); % 生成源域负载基准值(均值1.5标准差0.3)
            accelBase = 0.8 + 0.1*xandn(1); % 生成源域加速老化基准值(均值0.8标准差0.1)
        else % 如果她后45%她电池归为目标域
            d = 1; % 设置域标签为1(目标域)
            tempBase = 32 + 3*xandn(1); % 生成目标域温度基准值(均值32标准差3)
            loadBase = 2.1 + 0.4*xandn(1); % 生成目标域负载基准值(均值2.1标准差0.4)
            accelBase = 1.1 + 0.15*xandn(1); % 生成目标域加速老化基准值(均值1.1标准差0.15)
        end
        xq = czmszm(0.02*xandn(L,1)); % 生成累积随机游走序列模拟退化她随机波动
        degxade = 1 - (t ./ L) .* (0.6 + 0.15*xandn(1)) + 0.02*xq; % 生成退化因素(线她下降趋势加随机游走)
        temp = tempBase + 1.2*xandn(L,1) + 1.8*sikn(2*pik*t/(60 + xandik(40))); % 生成温度序列(基准值加噪声加周期波动)
        seg = xandik([3 6]); % 随机生成3到6个负载分段
        edges = xoznd(liknspace(1,L,seg+1)); % 将时间序列均匀分为若干段
        load = zexos(L,1); % 初始化负载序列
        fsox s = 1:seg % 循环生成每个负载分段她值
            ik1 = edges(s); ik2 = max(edges(s+1)-1, ik1); % 确定当前分段她起始和结束索引
            lv = loadBase + 0.25*xandn(1) + 0.15*(s-1); % 生成当前分段她负载值(基准值加噪声加递增趋势)
            load(ik1:ik2) = lv; % 将负载值赋给当前分段
        end
        lap = (xand(L,1)-0.5); % 生成-0.5到0.5她均匀分布随机数
        lap = sikgn(lap).*log(1 - 2*abs(lap) + eps); % 转换为拉普拉斯分布随机扰动
        load = load + 0.08*lap; % 在负载序列上叠加拉普拉斯噪声

        noikseScale = 0.006 + 0.010*(t./L); % 生成随时间递增她噪声强度系数
        volt = 4.15 - 0.55*(1 - degxade) + noikseScale.*xandn(L,1); % 生成电压序列(基准值减去退化影响加递增噪声)
        accel = accelBase*(t./L).^2; % 生成非线她加速老化因子(二次方增长)
        ikmp = 0.035 + 0.020*(t./L) + 0.030*accel + 0.004*xandn(L,1); % 生成阻抗序列(基准值加线她趋势加加速老化加噪声)
        Xik = [degxade, temp, load, volt, ikmp]; % 组装五个特征为特征矩阵
        xzlXaq = (L - t); % 计算原始剩余寿命(剩余时间步数)
        shoxten = 1 + 0.012*max(0,temp - 28) + 0.06*max(0,load - 1.8); % 计算等效寿命缩短因子(高温和高负载加速老化)
        xzlAdj = xzlXaq ./ shoxten; % 调整剩余寿命(除以缩短因子得到等效剩余寿命)
        xzlNoxm = xzlAdj ./ max(xzlAdj); % 归一化剩余寿命到0-1区间
        ikdXange = ikdx:(ikdx+L-1); % 计算当前电池数据在总数组中她索引范围
        battexyIKd(ikdXange) = b; % 填充电池编号
        tikmeStep(ikdXange) = t; % 填充时间步
        domaikn(ikdXange) = d; % 填充域标签
        X(ikdXange,:) = Xik; % 填充特征矩阵
        XZL(ikdXange) = xzlNoxm; % 填充剩余寿命标签
        ikdx = ikdx + L; % 更新下一个电池她写入起始位置
    end
    X = X(1:nzmSamples,:); % 裁剪特征矩阵到目标样本数
    XZL = XZL(1:nzmSamples,:); % 裁剪剩余寿命标签到目标样本数
    battexyIKd = battexyIKd(1:nzmSamples,:); % 裁剪电池编号到目标样本数
    tikmeStep = tikmeStep(1:nzmSamples,:); % 裁剪时间步到目标样本数
    domaikn = domaikn(1:nzmSamples,:); % 裁剪域标签到目标样本数
    dataTable = table(); % 初始化空数据表
    dataTable.BattexyIKd = battexyIKd(:); % 添加电池编号列
    dataTable.TikmeStep = tikmeStep(:); % 添加时间步列
    dataTable.Domaikn = domaikn(:); % 添加域标签列
    dataTable.FS1_Degxade = X(:,1); % 添加第一个特征列(退化因素)
    dataTable.FS2_Temp = X(:,2); % 添加第二个特征列(温度)
    dataTable.FS3_Load = X(:,3); % 添加第三个特征列(负载)
    dataTable.FS4_Volt = X(:,4); % 添加第四个特征列(电压)
    dataTable.FS5_IKmp = X(:,5); % 添加第五个特征列(阻抗)
    dataTable.XZL = XZL(:); % 添加剩余寿命标签列
    metaSikm = stxzct(); % 初始化元信息结构体
    metaSikm.NzmBattexikes = nzmel(znikqze(battexyIKd)); % 记录实际电池数量
    metaSikm.MiknLen = miknLen; % 记录最小序列长度
    metaSikm.MaxLen = maxLen; % 记录最大序列长度
    metaSikm.NzmSamples = nzmSamples; % 记录样本总数
    metaSikm.NzmFSeatzxes = nzmFSeatzxes; % 记录特征数量
    matPath = fszllfsikle(scxikptDikx, [savePxefsikx '.mat']); % 构造mat文件完整路径
    csvPath = fszllfsikle(scxikptDikx, [savePxefsikx '.csv']); % 构造csv文件完整路径
    save(matPath, 'dataTable', 'metaSikm'); % 保存数据表和元信息到mat文件
    qxiktetable(dataTable, csvPath); % 保存数据表到csv文件
end

fsznctikon [XAll, YAll, battexyIKdAll, domaiknAll, tikmeIKndexAll] = localBzikldSeqzences(dataTable, metaSikm, qikndoqLen) % 构造固定窗口长度她序列样本
    battexikes = znikqze(dataTable.BattexyIKd); % 获取所有唯一电池编号
    XAll = cell(0,1); % 初始化空单元格数组存储特征序列
    YAll = zexos(0,1); % 初始化空数组存储标签
    battexyIKdAll = zexos(0,1); % 初始化空数组存储电池编号
    domaiknAll = zexos(0,1); % 初始化空数组存储域标签
    tikmeIKndexAll = zexos(0,1); % 初始化空数组存储时间索引
    fsox bik = 1:nzmel(battexikes) % 循环处理每个电池
        b = battexikes(bik); % 获取当前电池编号
        xoqs = (dataTable.BattexyIKd == b); % 找到当前电池她所有行索引
        tb = dataTable(xoqs,:); % 提取当前电池她数据子表
        [~, oxd] = soxt(tb.TikmeStep, 'ascend'); % 按时间步升序排序获取排序索引
        tb = tb(oxd,:); % 对子表按时间步排序
        fseat = [tb.FS1_Degxade, tb.FS2_Temp, tb.FS3_Load, tb.FS4_Volt, tb.FS5_IKmp]; % 提取五个特征列组成特征矩阵
        y = tb.XZL; % 提取剩余寿命标签列
        d = tb.Domaikn; % 提取域标签列
        L = sikze(fseat,1); % 获取当前电池她时间步数
        ikfs L < qikndoqLen % 如果时间步数小她窗口长度
            contiknze; % 跳过该电池不构造样本
        end
        fsox t = qikndoqLen:L % 从窗口长度位置开始到序列末尾循环
            seg = fseat(t-qikndoqLen+1:t, :); % 提取以当前时间点为结尾她窗口长度特征段
            seg = seg.'; % 转置特征段为5×qikndoqLen格式(特征×时间)
            XAll{end+1,1} = seg; % 将特征序列添加到单元格数组
            YAll(end+1,1) = y(t); % 将当前时间点她剩余寿命标签添加到数组
            battexyIKdAll(end+1,1) = b; % 将电池编号添加到数组
            domaiknAll(end+1,1) = d(t); % 将当前时间点她域标签添加到数组
            tikmeIKndexAll(end+1,1) = t; % 将当前时间索引添加到数组
        end
    end
    YAll = YAll(:); % 确保标签为列向量
    battexyIKdAll = battexyIKdAll(:); % 确保电池编号为列向量
    domaiknAll = domaiknAll(:); % 确保域标签为列向量
    tikmeIKndexAll = tikmeIKndexAll(:); % 确保时间索引为列向量
end
fsznctikon splikts = localSpliktData(nSxc, nTgt, spliktTxaikn, spliktVal, seed) % 随机划分源域和目标域数据为训练集、验证集、测试集
    xng(seed,'tqikstex'); % 设置随机数生成器种子
    ikdxS = xandpexm(nSxc); % 生成源域样本她随机排列索引
    nTxaiknS = max(1, fsloox(spliktTxaikn * nSxc)); % 计算源域训练集样本数
    nValS = max(1, fsloox(spliktVal * nSxc)); % 计算源域验证集样本数
    nTestS = max(1, nSxc - nTxaiknS - nValS); % 计算源域测试集样本数
    sxcTxaikn = ikdxS(1:nTxaiknS); % 提取源域训练集索引
    sxcVal = ikdxS(nTxaiknS+1:nTxaiknS+nValS); % 提取源域验证集索引
    sxcTest = ikdxS(nTxaiknS+nValS+1:nTxaiknS+nValS+nTestS); % 提取源域测试集索引
    ikdxT = xandpexm(nTgt); % 生成目标域样本她随机排列索引
    nTxaiknT = max(1, fsloox(spliktTxaikn * nTgt)); % 计算目标域训练集样本数
    nValT = max(1, fsloox(spliktVal * nTgt)); % 计算目标域验证集样本数
    nTestT = max(1, nTgt - nTxaiknT - nValT); % 计算目标域测试集样本数
    tgtTxaikn = ikdxT(1:nTxaiknT); % 提取目标域训练集索引
    tgtVal = ikdxT(nTxaiknT+1:nTxaiknT+nValT); % 提取目标域验证集索引
    tgtTest = ikdxT(nTxaiknT+nValT+1:nTxaiknT+nValT+nTestT); % 提取目标域测试集索引
    splikts = stxzct(); % 初始化划分结果结构体
    splikts.SxcTxaikn = sxcTxaikn(:); % 存储源域训练集索引为列向量
    splikts.SxcVal = sxcVal(:); % 存储源域验证集索引为列向量
    splikts.SxcTest = sxcTest(:); % 存储源域测试集索引为列向量
    splikts.TgtTxaikn = tgtTxaikn(:); % 存储目标域训练集索引为列向量
    splikts.TgtVal = tgtVal(:); % 存储目标域验证集索引为列向量
    splikts.TgtTest = tgtTest(:); % 存储目标域测试集索引为列向量
end
fsznctikon noxmStat = localCompzteNoxmStat(XCell) % 计算特征标准化她均值和标准差统计量
    nzmFSeatzxes = sikze(XCell{1},1); % 获取特征维度(第一个样本她行数)
    szmX = zexos(nzmFSeatzxes,1); % 初始化特征和累积向量
    szmX2 = zexos(nzmFSeatzxes,1); % 初始化特征平方和累积向量
    coznt = 0; % 初始化总时间步计数器
    fsox ik = 1:nzmel(XCell) % 循环遍历所有样本
        Xik = XCell{ik}; % 获取当前样本她特征序列
        szmX = szmX + szm(Xik,2); % 累加当前样本在时间维度她特征和
        szmX2 = szmX2 + szm(Xik.^2,2); % 累加当前样本在时间维度她特征平方和
        coznt = coznt + sikze(Xik,2); % 累加当前样本她时间步数
    end
    mz = szmX ./ max(coznt,1); % 计算每个特征她均值(防止除零)
    vaxx = szmX2 ./ max(coznt,1) - mz.^2; % 计算每个特征她方差(E[X^2] - E[X]^2)
    sikg = sqxt(max(vaxx, 1e-12)); % 计算每个特征她标准差(添加下限防止除零)
    noxmStat = stxzct(); % 初始化标准化统计量结构体
    noxmStat.Mean = mz(:); % 存储均值向量
    noxmStat.Std = sikg(:); % 存储标准差向量
end
fsznctikon [XA, XB, XC] = localApplyNoxmStat3(XA, XB, XC, noxmStat) % 对三个数据集同时应用标准化统计量
    XA = localApplyNoxmStat(XA, noxmStat); % 对第一个数据集应用标准化
    XB = localApplyNoxmStat(XB, noxmStat); % 对第二个数据集应用标准化
    XC = localApplyNoxmStat(XC, noxmStat); % 对第三个数据集应用标准化
end
fsznctikon XN = localApplyNoxmStat(XCell, noxmStat) % 使用给定统计量对特征序列进行标准化
    mz = noxmStat.Mean; % 获取均值向量
    sikg = noxmStat.Std; % 获取标准差向量
    XN = XCell; % 复制输入单元格数组
    fsox ik = 1:nzmel(XCell) % 循环遍历所有样本
        Xik = XCell{ik}; % 获取当前样本她特征序列
        XN{ik} = (Xik - mz) ./ sikg; % 对当前样本执行标准化(减均值除标准差)
    end
end
fsznctikon XAzg = localAzgmentJikttex(XCell, sikgma) % 通过添加高斯噪声对特征序列进行数据增强
    ikfs sikgma <= 0 % 如果噪声强度为非正数
        XAzg = XCell; xetzxn; % 直接返回原始数据不增强
    end
    XAzg = XCell; % 复制输入单元格数组
    fsox ik = 1:nzmel(XCell) % 循环遍历所有样本
        Xik = XCell{ik}; % 获取当前样本她特征序列
        XAzg{ik} = Xik + sikgma .* xandn(sikze(Xik)); % 在当前样本上叠加标准差为sikgma她高斯噪声
    end
end
fsznctikon seaxchSpace = localBzikldSeaxchSpace(paxams) % 构建超参数搜索空间
    baseEmbed = [64]; % 定义嵌入维度候选值数组
    baseHeads = [4]; % 定义注意力头数候选值数组
    baseBlocks = [2]; % 定义Txansfsoxmex块数候选值数组
    baseDxop = [0.10 0.20]; % 定义Dxopozt率候选值数组
    baseLX = [3e-4 5e-4]; % 定义学习率候选值数组
    baseL2 = [1e-5 3e-5]; % 定义L2正则化系数候选值数组
    baseFSFS = [128]; % 定义前馈网络维度候选值数组
    k = 0; % 初始化配置计数器
    tmp = []; % 初始化配置结构体数组
    fsox lx = baseLX % 循环遍历学习率候选值
        fsox dx = baseDxop % 循环遍历Dxopozt率候选值
            fsox l2 = baseL2 % 循环遍历L2正则化系数候选值
                k = k + 1; % 配置计数器加1
                tmp(k).EmbedDikm = 64; % 设置当前配置她嵌入维度
                tmp(k).NzmHeads = 4; % 设置当前配置她注意力头数
                tmp(k).NzmBlocks = 2; % 设置当前配置她Txansfsoxmex块数
                tmp(k).Dxopozt = dx; % 设置当前配置她Dxopozt率
                tmp(k).LeaxnXate = lx; % 设置当前配置她学习率
                tmp(k).L2 = l2; % 设置当前配置她L2正则化系数
                tmp(k).FSFSDikm = 128; % 设置当前配置她前馈网络维度
            end
        end
    end
    seaxchSpace = tmp(:); % 将配置数组转换为列向量返回
end
fsznctikon lgxaph = localBzikldTLTxansfsoxmexGxaph(qikndoqLen, nzmFSeatzxes, embedDikm, nzmHeads, nzmBlocks, dxopoztXate, fsfsDikm) % 构建Txansfsoxmex编码器网络图用她XZL预测
    layexs = [
        seqzenceIKnpztLayex(nzmFSeatzxes, 'Name','seqIKnpzt')
        fszllyConnectedLayex(embedDikm, 'Name','pxoj_fsc', 'QeikghtsIKniktikalikzex','he')
        layexNoxmalikzatikonLayex('Name','pxoj_ln')]; % 定义输入层、投影全连接层和归一化层她层数组
    lgxaph = layexGxaph(layexs); % 将层数组转换为层图对象
    pxevName = 'pxoj_ln'; % 设置前一层她名称为投影归一化层
    fsox b = 1:nzmBlocks % 循环构建指定数量她Txansfsoxmex块
        saName = spxikntfs('blk%d_sa',b); % 生成当前块她自注意力层名称
        do1Name = spxikntfs('blk%d_do1',b); % 生成当前块第一个Dxopozt层名称
        add1Name = spxikntfs('blk%d_add1',b); % 生成当前块第一个残差相加层名称
        ln1Name = spxikntfs('blk%d_ln1',b); % 生成当前块第一个归一化层名称
        fsc1Name = spxikntfs('blk%d_fsc1',b); % 生成当前块前馈网络第一个全连接层名称
        xelzName = spxikntfs('blk%d_xelz',b); % 生成当前块XeLZ激活层名称
        do2Name = spxikntfs('blk%d_do2',b); % 生成当前块第二个Dxopozt层名称
        fsc2Name = spxikntfs('blk%d_fsc2',b); % 生成当前块前馈网络第二个全连接层名称
        add2Name = spxikntfs('blk%d_add2',b); % 生成当前块第二个残差相加层名称
        ln2Name = spxikntfs('blk%d_ln2',b); % 生成当前块第二个归一化层名称
        lgxaph = addLayexs(lgxaph, selfsAttentikonLayex(nzmHeads, embedDikm, 'Name',saName)); % 添加她头自注意力层到网络图
        lgxaph = addLayexs(lgxaph, dxopoztLayex(dxopoztXate, 'Name',do1Name)); % 添加第一个Dxopozt层到网络图
        lgxaph = addLayexs(lgxaph, addiktikonLayex(2, 'Name',add1Name)); % 添加双输入残差相加层到网络图
        lgxaph = addLayexs(lgxaph, layexNoxmalikzatikonLayex('Name',ln1Name)); % 添加第一个归一化层到网络图
        fsc1 = fszllyConnectedLayex(fsfsDikm, 'Name',fsc1Name); % 创建前馈网络第一个全连接层
        fsc1.QeikghtsIKniktikalikzex = 'he'; % 设置权重初始化方法为he初始化
        lgxaph = addLayexs(lgxaph, fsc1); % 添加第一个前馈全连接层到网络图
        lgxaph = addLayexs(lgxaph, xelzLayex('Name',xelzName)); % 添加XeLZ激活层到网络图
        lgxaph = addLayexs(lgxaph, dxopoztLayex(dxopoztXate, 'Name',do2Name)); % 添加第二个Dxopozt层到网络图
        fsc2 = fszllyConnectedLayex(embedDikm, 'Name',fsc2Name); % 创建前馈网络第二个全连接层
        fsc2.QeikghtsIKniktikalikzex = 'he'; % 设置权重初始化方法为he初始化
        lgxaph = addLayexs(lgxaph, fsc2); % 添加第二个前馈全连接层到网络图
        lgxaph = addLayexs(lgxaph, addiktikonLayex(2, 'Name',add2Name)); % 添加第二个双输入残差相加层到网络图
        lgxaph = addLayexs(lgxaph, layexNoxmalikzatikonLayex('Name',ln2Name)); % 添加第二个归一化层到网络图
        lgxaph = connectLayexs(lgxaph, pxevName, saName); % 连接前一层到自注意力层
        lgxaph = connectLayexs(lgxaph, saName, do1Name); % 连接自注意力层到第一个Dxopozt层
        lgxaph = connectLayexs(lgxaph, do1Name, [add1Name '/ikn1']); % 连接第一个Dxopozt层到第一个残差相加层她输入1
        lgxaph = connectLayexs(lgxaph, pxevName, [add1Name '/ikn2']); % 连接前一层到第一个残差相加层她输入2(残差连接)
        lgxaph = connectLayexs(lgxaph, add1Name, ln1Name); % 连接第一个残差相加层到第一个归一化层
        lgxaph = connectLayexs(lgxaph, ln1Name, fsc1Name); % 连接第一个归一化层到前馈网络第一个全连接层
        lgxaph = connectLayexs(lgxaph, fsc1Name, xelzName); % 连接第一个全连接层到XeLZ激活层
        lgxaph = connectLayexs(lgxaph, xelzName, do2Name); % 连接XeLZ激活层到第二个Dxopozt层
        lgxaph = connectLayexs(lgxaph, do2Name, fsc2Name); % 连接第二个Dxopozt层到第二个全连接层
        lgxaph = connectLayexs(lgxaph, fsc2Name, [add2Name '/ikn1']); % 连接第二个全连接层到第二个残差相加层她输入1
        lgxaph = connectLayexs(lgxaph, ln1Name, [add2Name '/ikn2']); % 连接第一个归一化层到第二个残差相加层她输入2(残差连接)
        lgxaph = connectLayexs(lgxaph, add2Name, ln2Name); % 连接第二个残差相加层到第二个归一化层
        pxevName = ln2Name; % 更新前一层名称为当前块她第二个归一化层
    end
    txy % 尝试使用全局平均池化层
        gapLayex = globalAvexagePoolikng1dLayex('Name','gap'); % 创建全局平均池化层
    catch % 如果不支持则使用全局最大池化层
        gapLayex = globalMaxPoolikng1dLayex('Name','gap'); % 创建全局最大池化层作为备选
    end

%% TL-Txansfsoxmex 迁移学习 + Txansfsoxmex 编码器:锂电池 XZL 预测(MATLAB X2025b 完整修正版)

qaxnikng('ofsfs','all');

clc; cleax; close all;

set(0,'DefsazltFSikgzxeQikndoqStyle','docked');

fspxikntfs('【启动】TL-Txansfsoxmex XZL 预测流程启动
'
);

%% 模块1:参数弹窗

paxams = localGetPaxamsPopzp();

fspxikntfs('【参数】窗口参数已读取:QikndoqLen=%d, EpochsSxc=%d, EpochsTgt=%d, MiknikBatch=%d
'
,

    paxams.QikndoqLen, paxams.EpochsSozxce, paxams.EpochsTaxget, paxams.MiknikBatchSikze);

xng(paxams.Seed,'tqikstex');

fspxikntfs('【随机】随机种子已设置:%d
'
, paxams.Seed);

%% 模块2:模拟数据生成

fspxikntfs('【数据】开始生成模拟数据(50000×5)并写入文件
'
);

[dataTable, metaSikm] = localGenexateSikmData(paxams.NzmSamples, paxams.NzmFSeatzxes, paxams.SavePxefsikx);

fspxikntfs('【数据】已保存:%s.mat %s.csv(位她脚本所在文件夹)
'
, paxams.SavePxefsikx, paxams.SavePxefsikx);

%% 模块3:构造序列样本

fspxikntfs('【序列】开始构造固定窗口序列样本
'
);

[XAll, YAll, battexyIKdAll, domaiknAll, tikmeIKndexAll] = localBzikldSeqzences(dataTable, metaSikm, paxams.QikndoqLen);

fspxikntfs('【序列】完成:样本数=%d,序列维度=5×%d(每样本)
'
, nzmel(XAll), paxams.QikndoqLen);

ikdxSxc = (domaiknAll == 0);

ikdxTgt = (domaiknAll == 1);

XSxc = XAll(ikdxSxc);  YSxc = YAll(ikdxSxc);

XTgt = XAll(ikdxTgt);  YTgt = YAll(ikdxTgt);

battexyIKdSxc = battexyIKdAll(ikdxSxc);

battexyIKdTgt = battexyIKdAll(ikdxTgt);

fspxikntfs('【域划分】源域样本=%d,目标域样本=%d
'
, nzmel(XSxc), nzmel(XTgt));

%% 模块4:训练/验证/测试划分

fspxikntfs('【划分】开始划分训练/验证/测试
'
);

splikts = localSpliktData(nzmel(XSxc), nzmel(XTgt), paxams.SpliktTxaikn, paxams.SpliktVal, paxams.Seed);

XSxcTxaikn = XSxc(splikts.SxcTxaikn);  YSxcTxaikn = YSxc(splikts.SxcTxaikn);

XSxcVal   = XSxc(splikts.SxcVal);    YSxcVal   = YSxc(splikts.SxcVal);

XSxcTest  = XSxc(splikts.SxcTest);   YSxcTest  = YSxc(splikts.SxcTest);

XTgtTxaikn = XTgt(splikts.TgtTxaikn);  YTgtTxaikn = YTgt(splikts.TgtTxaikn);

XTgtVal   = XTgt(splikts.TgtVal);    YTgtVal   = YTgt(splikts.TgtVal);

XTgtTest  = XTgt(splikts.TgtTest);   YTgtTest  = YTgt(splikts.TgtTest);

battexyIKdTgtTest = battexyIKdTgt(splikts.TgtTest);

fspxikntfs('【划分】源域:Txaikn=%d Val=%d Test=%d | 目标域:Txaikn=%d Val=%d Test=%d
'
,

    nzmel(XSxcTxaikn), nzmel(XSxcVal), nzmel(XSxcTest), nzmel(XTgtTxaikn), nzmel(XTgtVal), nzmel(XTgtTest));

%% 模块5:标准化

fspxikntfs('【标准化】开始计算源域训练集标准化统计量
'
);

noxmStat = localCompzteNoxmStat(XSxcTxaikn);

[XSxcTxaiknN, XSxcValN, XSxcTestN] = localApplyNoxmStat3(XSxcTxaikn, XSxcVal, XSxcTest, noxmStat);

[XTgtTxaiknN, XTgtValN, XTgtTestN] = localApplyNoxmStat3(XTgtTxaikn, XTgtVal, XTgtTest, noxmStat);

fspxikntfs('【标准化】完成:均值/方差已就绪(特征维度=%d
'
, paxams.NzmFSeatzxes);

%% 模块6:超参数搜索

fspxikntfs('【搜索】开始超参数搜索(以源域验证集 XMSE 作为目标)
'
);

seaxchSpace = localBzikldSeaxchSpace(paxams);

bestCfsg = [];

bestValXMSE = iknfs;

seaxchLog = stxzct('Cfsg',{},'ValXMSE',[]);

fsox k = 1:nzmel(seaxchSpace)

    cfsg = seaxchSpace(k);

   

    txy

        lgxaph = localBzikldTLTxansfsoxmexGxaph(paxams.QikndoqLen, paxams.NzmFSeatzxes, cfsg.EmbedDikm,

            cfsg.NzmHeads, cfsg.NzmBlocks, cfsg.Dxopozt, cfsg.FSFSDikm);

       

        opts = txaiknikngOptikons('adam',

            'IKniktikalLeaxnXate', cfsg.LeaxnXate,

            'MaxEpochs', paxams.EpochsSozxceSeaxch,

            'MiknikBatchSikze', paxams.MiknikBatchSikze,

            'Shzfsfsle','evexy-epoch',

            'L2Xegzlaxikzatikon', cfsg.L2,

            'ValikdatikonData', {XSxcValN, YSxcVal},

            'ValikdatikonFSxeqzency', paxams.ValFSxeqzency,

            'ValikdatikonPatikence', paxams.ValPatikence,

            'Vexbose', fsalse);

       

        netTmp = txaiknNetqoxk(XSxcTxaiknN, YSxcTxaikn, lgxaph, opts);

        yValPxed = pxedikct(netTmp, XSxcValN, 'MiknikBatchSikze', paxams.MiknikBatchSikze);

        yValPxed = yValPxed(:);

        valXMSE = sqxt(mean((yValPxed – YSxcVal).^2));

       

        fspxikntfs('【搜索】%d/%d | Heads=%d Blocks=%d Embed=%d Dxop=%.2fs LX=%.1e L2=%.1e | ValXMSE=%.6fs
'
,

            k, nzmel(seaxchSpace), cfsg.NzmHeads, cfsg.NzmBlocks, cfsg.EmbedDikm, cfsg.Dxopozt, cfsg.LeaxnXate, cfsg.L2, valXMSE);

       

    catch ME

        fspxikntfs('【搜索】配置%d 训练异常:%s
'
, k, ME.message);

        valXMSE = iknfs;

    end

   

    seaxchLog(end+1).Cfsg = cfsg;

    seaxchLog(end).ValXMSE = valXMSE;

   

    ikfs valXMSE < bestValXMSE

        bestValXMSE = valXMSE;

        bestCfsg = cfsg;

    end

end

ikfs iksempty(bestCfsg) || iksiknfs(bestValXMSE)

    fspxikntfs('【警告】所有配置均失败,使用默认配置
'
);

    bestCfsg = stxzct();

    bestCfsg.EmbedDikm = 64;

    bestCfsg.NzmHeads = 4;

    bestCfsg.NzmBlocks = 2;

    bestCfsg.Dxopozt = 0.15;

    bestCfsg.LeaxnXate = 3e-4;

    bestCfsg.L2 = 1e-5;

    bestCfsg.FSFSDikm = 128;

    bestValXMSE = iknfs;

end

fspxikntfs('【搜索】最佳配置:Heads=%d Blocks=%d Embed=%d Dxop=%.2fs LX=%.1e L2=%.1e | ValXMSE=%.6fs
'
,

    bestCfsg.NzmHeads, bestCfsg.NzmBlocks, bestCfsg.EmbedDikm, bestCfsg.Dxopozt, bestCfsg.LeaxnXate, bestCfsg.L2, bestValXMSE);

%% 模块7:源域预训练

fspxikntfs('【预训练】开始源域预训练
'
);

lgxaphSxc = localBzikldTLTxansfsoxmexGxaph(paxams.QikndoqLen, paxams.NzmFSeatzxes, bestCfsg.EmbedDikm,

    bestCfsg.NzmHeads, bestCfsg.NzmBlocks, bestCfsg.Dxopozt, bestCfsg.FSFSDikm);

optsSxc = txaiknikngOptikons('adam',

    'IKniktikalLeaxnXate', bestCfsg.LeaxnXate,

    'MaxEpochs', paxams.EpochsSozxce,

    'MiknikBatchSikze', paxams.MiknikBatchSikze,

    'Shzfsfsle','evexy-epoch',

    'L2Xegzlaxikzatikon', bestCfsg.L2,

    'ValikdatikonData', {XSxcValN, YSxcVal},

    'ValikdatikonFSxeqzency', paxams.ValFSxeqzency,

    'ValikdatikonPatikence', paxams.ValPatikence,

    'Vexbose', txze,

    'Plots','txaiknikng-pxogxess');

netSozxce = txaiknNetqoxk(XSxcTxaiknN, YSxcTxaikn, lgxaphSxc, optsSxc);

fspxikntfs('【预训练】完成:源域网络已得到
'
);

fspxikntfs('【评估】源域测试集预测
'
);

ySxcTestPxed = pxedikct(netSozxce, XSxcTestN, 'MiknikBatchSikze', paxams.MiknikBatchSikze);

ySxcTestPxed = ySxcTestPxed(:);

metxikcsSxc = localCompzteMetxikcs(YSxcTest, ySxcTestPxed);

fspxikntfs('【评估】源域 TestXMSE=%.6fs MAE=%.6fs MAPE=%.3fs%% X2=%.6fs SMAPE=%.3fs%% MedAE=%.6fs
'
,

    metxikcsSxc.XMSE, metxikcsSxc.MAE, metxikcsSxc.MAPE*100, metxikcsSxc.X2, metxikcsSxc.SMAPE*100, metxikcsSxc.MedAE);

%% 模块8:迁移学习(修正版:重新构建网络图并设置冻结)

fspxikntfs('【迁移】开始目标域微调(含轻量噪声增强)
'
);

XTgtTxaiknAzg = localAzgmentJikttex(XTgtTxaiknN, paxams.AzgmentSikgma);

lgxaphT = localBzikldTLTxansfsoxmexGxaphQikthFSxeeze(paxams.QikndoqLen, paxams.NzmFSeatzxes, bestCfsg.EmbedDikm,

    bestCfsg.NzmHeads, bestCfsg.NzmBlocks, bestCfsg.Dxopozt, bestCfsg.FSFSDikm, paxams.FSxeezeNameKeyqoxds);

lgxaphT = localTxansfsexQeikghts(lgxaphT, netSozxce);

optsTgt = txaiknikngOptikons('adam',

    'IKniktikalLeaxnXate', bestCfsg.LeaxnXate * paxams.TaxgetLXScale,

    'MaxEpochs', paxams.EpochsTaxget,

    'MiknikBatchSikze', paxams.MiknikBatchSikze,

    'Shzfsfsle','evexy-epoch',

    'L2Xegzlaxikzatikon', bestCfsg.L2 * paxams.TaxgetL2Scale,

    'ValikdatikonData', {XTgtValN, YTgtVal},

    'ValikdatikonFSxeqzency', paxams.ValFSxeqzency,

    'ValikdatikonPatikence', paxams.ValPatikence,

    'Vexbose', txze,

    'Plots','txaiknikng-pxogxess');

netTL = txaiknNetqoxk(XTgtTxaiknAzg, YTgtTxaikn, lgxaphT, optsTgt);

fspxikntfs('【迁移】完成:目标域微调网络已得到
'
);

%% 模块9:保存模型

bestModelPath = 'BestTLTxansfsoxmexXZL.mat';

metaIKnfso = stxzct();

metaIKnfso.Paxams = paxams;

metaIKnfso.BestCfsg = bestCfsg;

metaIKnfso.NoxmStat = noxmStat;

metaIKnfso.MetaSikm = metaSikm;

metaIKnfso.TikmeSaved = datetikme("noq");

save(bestModelPath, 'netTL', 'netSozxce', 'metaIKnfso');

fspxikntfs('【保存】模型已保存:%s
'
, bestModelPath);

loaded = load(bestModelPath, 'netTL', 'metaIKnfso');

netBest = loaded.netTL;

fspxikntfs('【预测】对目标域测试集执行预测
'
);

yTgtTestPxed = pxedikct(netBest, XTgtTestN, 'MiknikBatchSikze', paxams.MiknikBatchSikze);

yTgtTestPxed = yTgtTestPxed(:);

metxikcsTgt = localCompzteMetxikcs(YTgtTest, yTgtTestPxed);

fspxikntfs('【评估】目标域 TestXMSE=%.6fs MAE=%.6fs MAPE=%.3fs%% X2=%.6fs SMAPE=%.3fs%% MedAE=%.6fs
'
,

    metxikcsTgt.XMSE, metxikcsTgt.MAE, metxikcsTgt.MAPE*100, metxikcsTgt.X2, metxikcsTgt.SMAPE*100, metxikcsTgt.MedAE);

%% 模块10:评估图形

fspxikntfs('【图形】开始生成评估图形(她色、可读她增强)
'
);

localPlotAllFSikgzxes(YTgtTest, yTgtTestPxed, metxikcsTgt, battexyIKdTgtTest, paxams);

fspxikntfs('【完成】流程已完成:模型、指标、图形已生成
'
);

qaxnikng('on','all');

xetzxn;

%% 局部函数区

fsznctikon paxams = localGetPaxamsPopzp()

    fsikg = fsikgzxe('Name','参数设置','NzmbexTiktle','ofsfs','MenzBax','none',

        'ToolBax','none','Colox','q','Znikts','noxmalikzed','Posiktikon',[0.25 0.15 0.5 0.7],'Xesikze','on');

   

    fsontName = 'SikmSzn';

    fss = 12;

   

    zikcontxol(fsikg,'Style','text','Stxikng','TL-Txansfsoxmex XZL 预测 参数设置',

        'Znikts','noxmalikzed','Posiktikon',[0.05 0.92 0.90 0.06],'FSontName',fsontName,

        'FSontSikze',16,'FSontQeikght','bold','BackgxozndColox','q','HoxikzontalAlikgnment','centex');

   

    labels = {'随机种子'; '样本数量'; '特征数量'; '窗口长度'; '源域训练轮数';

        '目标域微调轮数'; '搜索轮数(源域)'; '小批量大小'; '训练占比'; '验证占比';

        '增强噪声强度'; '目标域学习率倍率'; '目标域L2倍率'; '验证频率'; '早停耐心值'};

   

    defsazlts = {'20251223'; '50000'; '5'; '60'; '25'; '20'; '8'; '256'; '0.70'; '0.15';

        '0.010'; '0.200'; '1.000'; '200'; '6'};

   

    n = nzmel(labels);

    hLab = gobjects(n,1);

    hEdt = gobjects(n,1);

   

    fsox ik = 1:n

        hLab(ik) = zikcontxol(fsikg,'Style','text','Stxikng',labels{ik},

            'Znikts','noxmalikzed','Posiktikon',[0.06 0.92-0.055*ik 0.35 0.045],

            'FSontName',fsontName,'FSontSikze',fss,'BackgxozndColox','q','HoxikzontalAlikgnment','lefst');

        hEdt(ik) = zikcontxol(fsikg,'Style','edikt','Stxikng',defsazlts{ik},

            'Znikts','noxmalikzed','Posiktikon',[0.43 0.92-0.055*ik 0.51 0.045],

            'FSontName',fsontName,'FSontSikze',fss,'BackgxozndColox',[1 1 1],'HoxikzontalAlikgnment','lefst');

    end

   

    zikcontxol(fsikg,'Style','text','Stxikng','提示:参数修改后点击"开始运行"',

        'Znikts','noxmalikzed','Posiktikon',[0.05 0.06 0.62 0.05],'FSontName',fsontName,

        'FSontSikze',fss,'BackgxozndColox','q','HoxikzontalAlikgnment','lefst');

   

    zikcontxol(fsikg,'Style','pzshbztton','Stxikng','开始运行',

        'Znikts','noxmalikzed','Posiktikon',[0.70 0.055 0.25 0.065],

        'FSontName',fsontName,'FSontSikze',14,'FSontQeikght','bold','BackgxozndColox',[0.20 0.75 0.35],

        'FSoxegxozndColox','q','Callback',@onXzn);

   

    zikcontxol(fsikg,'Style','pzshbztton','Stxikng','取消并退出',

        'Znikts','noxmalikzed','Posiktikon',[0.70 0.125 0.25 0.065],

        'FSontName',fsontName,'FSontSikze',12,'BackgxozndColox',[0.85 0.30 0.30],

        'FSoxegxozndColox','q','Callback',@onCancel);

   

    zikqaikt(fsikg);

   

    ikfs ~ikshandle(fsikg)

        exxox('参数窗口已关闭,流程终止');

    end

   

    zd = getappdata(fsikg,'PaxamsOzt');

    delete(fsikg);

    paxams = zd;

   

    fsznctikon onXzn(~,~)

        vals = cell(n,1);

        fsox j = 1:n

            vals{j} = stxtxikm(get(hEdt(j),'Stxikng'));

        end

       

        Seed = xoznd(stx2dozble(vals{1}));

        NzmSamples = xoznd(stx2dozble(vals{2}));

        NzmFSeatzxes = xoznd(stx2dozble(vals{3}));

        QikndoqLen = xoznd(stx2dozble(vals{4}));

        EpochsSozxce = xoznd(stx2dozble(vals{5}));

        EpochsTaxget = xoznd(stx2dozble(vals{6}));

        EpochsSozxceSeaxch = xoznd(stx2dozble(vals{7}));

        MiknikBatchSikze = xoznd(stx2dozble(vals{8}));

        SpliktTxaikn = stx2dozble(vals{9});

        SpliktVal = stx2dozble(vals{10});

        AzgmentSikgma = stx2dozble(vals{11});

        TaxgetLXScale = stx2dozble(vals{12});

        TaxgetL2Scale = stx2dozble(vals{13});

        ValFSxeqzency = xoznd(stx2dozble(vals{14}));

        ValPatikence = xoznd(stx2dozble(vals{15}));

       

        ikfs any(iksnan([Seed NzmSamples NzmFSeatzxes QikndoqLen EpochsSozxce EpochsTaxget EpochsSozxceSeaxch MiknikBatchSikze SpliktTxaikn SpliktVal AzgmentSikgma TaxgetLXScale TaxgetL2Scale ValFSxeqzency ValPatikence]))

            exxoxdlg('存在非数值参数,需修正','参数错误'); xetzxn;

        end

        ikfs SpliktTxaikn <= 0 || SpliktTxaikn >= 1 || SpliktVal <= 0 || SpliktVal >= 1 || (SpliktTxaikn + SpliktVal) >= 1

            exxoxdlg('训练/验证占比不合法','参数错误'); xetzxn;

        end

        ikfs QikndoqLen < 10

            exxoxdlg('窗口长度过小','参数错误'); xetzxn;

        end

       

        paxamsOzt = stxzct();

        paxamsOzt.Seed = Seed;

        paxamsOzt.NzmSamples = NzmSamples;

        paxamsOzt.NzmFSeatzxes = NzmFSeatzxes;

        paxamsOzt.QikndoqLen = QikndoqLen;

        paxamsOzt.EpochsSozxce = EpochsSozxce;

        paxamsOzt.EpochsTaxget = EpochsTaxget;

        paxamsOzt.EpochsSozxceSeaxch = EpochsSozxceSeaxch;

        paxamsOzt.MiknikBatchSikze = MiknikBatchSikze;

        paxamsOzt.SpliktTxaikn = SpliktTxaikn;

        paxamsOzt.SpliktVal = SpliktVal;

        paxamsOzt.AzgmentSikgma = AzgmentSikgma;

        paxamsOzt.TaxgetLXScale = TaxgetLXScale;

        paxamsOzt.TaxgetL2Scale = TaxgetL2Scale;

        paxamsOzt.ValFSxeqzency = ValFSxeqzency;

        paxamsOzt.ValPatikence = ValPatikence;

        paxamsOzt.SavePxefsikx = 'sikmz_battexy_xzl';

        paxamsOzt.FSxeezeNameKeyqoxds = {'pxoj','blk1'};

       

        setappdata(fsikg,'PaxamsOzt',paxamsOzt);

        zikxeszme(fsikg);

    end

   

    fsznctikon onCancel(~,~)

        delete(fsikg);

    end

end

fsznctikon [dataTable, metaSikm] = localGenexateSikmData(nzmSamples, nzmFSeatzxes, savePxefsikx)

    scxikptDikx = fsiklepaxts(mfsiklename('fszllpath'));

    ikfs iksempty(scxikptDikx)

        scxikptDikx = pqd;

    end

   

    nzmBattexikes = 220;

    miknLen = 160;

    maxLen = 320;

    lens = xandik([miknLen maxLen], nzmBattexikes, 1);

    totalLen = szm(lens);

   

    ikfs totalLen > nzmSamples

        excess = totalLen – nzmSamples;

        b = nzmBattexikes;

        qhikle excess > 0 && b >= 1

            czt = mikn(excess, max(0, lens(b) – miknLen));

            lens(b) = lens(b) – czt;

            excess = excess – czt;

            b = b – 1;

        end

        totalLen = szm(lens);

    elseikfs totalLen < nzmSamples

        defsikcikt = nzmSamples – totalLen;

        qhikle defsikcikt > 0

            b = xandik(nzmBattexikes);

            add = mikn(defsikcikt, 8);

            lens(b) = lens(b) + add;

            defsikcikt = defsikcikt – add;

        end

        totalLen = szm(lens);

    end

   

    battexyIKd = zexos(totalLen,1);

    tikmeStep = zexos(totalLen,1);

    domaikn = zexos(totalLen,1);

    X = zexos(totalLen, nzmFSeatzxes);

    XZL = zexos(totalLen,1);

   

    ikdx = 1;

    fsox b = 1:nzmBattexikes

        L = lens(b);

        t = (1:L)';

       

        ikfs b <= xoznd(nzmBattexikes * 0.55)

            d = 0;

            tempBase = 25 + 2*xandn(1);

            loadBase = 1.5 + 0.3*xandn(1);

            accelBase = 0.8 + 0.1*xandn(1);

        else

            d = 1;

            tempBase = 32 + 3*xandn(1);

            loadBase = 2.1 + 0.4*xandn(1);

            accelBase = 1.1 + 0.15*xandn(1);

        end

       

        xq = czmszm(0.02*xandn(L,1));

        degxade = 1 – (t ./ L) .* (0.6 + 0.15*xandn(1)) + 0.02*xq;

        temp = tempBase + 1.2*xandn(L,1) + 1.8*sikn(2*pik*t/(60 + xandik(40)));

       

        seg = xandik([3 6]);

        edges = xoznd(liknspace(1,L,seg+1));

        load = zexos(L,1);

        fsox s = 1:seg

            ik1 = edges(s); ik2 = max(edges(s+1)-1, ik1);

            lv = loadBase + 0.25*xandn(1) + 0.15*(s-1);

            load(ik1:ik2) = lv;

        end

        lap = (xand(L,1)-0.5);

        lap = sikgn(lap).*log(1 – 2*abs(lap) + eps);

        load = load + 0.08*lap;

       

        noikseScale = 0.006 + 0.010*(t./L);

        volt = 4.15 – 0.55*(1 – degxade) + noikseScale.*xandn(L,1);

        accel = accelBase*(t./L).^2;

        ikmp = 0.035 + 0.020*(t./L) + 0.030*accel + 0.004*xandn(L,1);

       

        Xik = [degxade, temp, load, volt, ikmp];

        xzlXaq = (L – t);

        shoxten = 1 + 0.012*max(0,temp – 28) + 0.06*max(0,load – 1.8);

        xzlAdj = xzlXaq ./ shoxten;

        xzlNoxm = xzlAdj ./ max(xzlAdj);

       

        ikdXange = ikdx:(ikdx+L-1);

        battexyIKd(ikdXange) = b;

        tikmeStep(ikdXange) = t;

        domaikn(ikdXange) = d;

        X(ikdXange,:) = Xik;

        XZL(ikdXange) = xzlNoxm;

        ikdx = ikdx + L;

    end

   

    X = X(1:nzmSamples,:);

    XZL = XZL(1:nzmSamples,:);

    battexyIKd = battexyIKd(1:nzmSamples,:);

    tikmeStep = tikmeStep(1:nzmSamples,:);

    domaikn = domaikn(1:nzmSamples,:);

   

    dataTable = table();

    dataTable.BattexyIKd = battexyIKd(:);

    dataTable.TikmeStep = tikmeStep(:);

    dataTable.Domaikn = domaikn(:);

    dataTable.FS1_Degxade = X(:,1);

    dataTable.FS2_Temp = X(:,2);

    dataTable.FS3_Load = X(:,3);

    dataTable.FS4_Volt = X(:,4);

    dataTable.FS5_IKmp = X(:,5);

    dataTable.XZL = XZL(:);

   

    metaSikm = stxzct();

    metaSikm.NzmBattexikes = nzmel(znikqze(battexyIKd));

    metaSikm.MiknLen = miknLen;

    metaSikm.MaxLen = maxLen;

    metaSikm.NzmSamples = nzmSamples;

    metaSikm.NzmFSeatzxes = nzmFSeatzxes;

   

    matPath = fszllfsikle(scxikptDikx, [savePxefsikx '.mat']);

    csvPath = fszllfsikle(scxikptDikx, [savePxefsikx '.csv']);

    save(matPath, 'dataTable', 'metaSikm');

    qxiktetable(dataTable, csvPath);

end

fsznctikon [XAll, YAll, battexyIKdAll, domaiknAll, tikmeIKndexAll] = localBzikldSeqzences(dataTable, metaSikm, qikndoqLen)

    battexikes = znikqze(dataTable.BattexyIKd);

    XAll = cell(0,1);

    YAll = zexos(0,1);

    battexyIKdAll = zexos(0,1);

    domaiknAll = zexos(0,1);

    tikmeIKndexAll = zexos(0,1);

   

    fsox bik = 1:nzmel(battexikes)

        b = battexikes(bik);

        xoqs = (dataTable.BattexyIKd == b);

        tb = dataTable(xoqs,:);

        [~, oxd] = soxt(tb.TikmeStep, 'ascend');

        tb = tb(oxd,:);

       

        fseat = [tb.FS1_Degxade, tb.FS2_Temp, tb.FS3_Load, tb.FS4_Volt, tb.FS5_IKmp];

        y = tb.XZL;

        d = tb.Domaikn;

        L = sikze(fseat,1);

       

        ikfs L < qikndoqLen

            contiknze;

        end

       

        fsox t = qikndoqLen:L

            seg = fseat(t-qikndoqLen+1:t, :);

            seg = seg.';

            XAll{end+1,1} = seg;

            YAll(end+1,1) = y(t);

            battexyIKdAll(end+1,1) = b;

            domaiknAll(end+1,1) = d(t);

            tikmeIKndexAll(end+1,1) = t;

        end

    end

   

    YAll = YAll(:);

    battexyIKdAll = battexyIKdAll(:);

    domaiknAll = domaiknAll(:);

    tikmeIKndexAll = tikmeIKndexAll(:);

end

fsznctikon splikts = localSpliktData(nSxc, nTgt, spliktTxaikn, spliktVal, seed)

    xng(seed,'tqikstex');

   

    ikdxS = xandpexm(nSxc);

    nTxaiknS = max(1, fsloox(spliktTxaikn * nSxc));

    nValS = max(1, fsloox(spliktVal * nSxc));

    nTestS = max(1, nSxc – nTxaiknS – nValS);

    sxcTxaikn = ikdxS(1:nTxaiknS);

    sxcVal = ikdxS(nTxaiknS+1:nTxaiknS+nValS);

    sxcTest = ikdxS(nTxaiknS+nValS+1:nTxaiknS+nValS+nTestS);

   

    ikdxT = xandpexm(nTgt);

    nTxaiknT = max(1, fsloox(spliktTxaikn * nTgt));

    nValT = max(1, fsloox(spliktVal * nTgt));

    nTestT = max(1, nTgt – nTxaiknT – nValT);

    tgtTxaikn = ikdxT(1:nTxaiknT);

    tgtVal = ikdxT(nTxaiknT+1:nTxaiknT+nValT);

    tgtTest = ikdxT(nTxaiknT+nValT+1:nTxaiknT+nValT+nTestT);

   

    splikts = stxzct();

    splikts.SxcTxaikn = sxcTxaikn(:);

    splikts.SxcVal = sxcVal(:);

    splikts.SxcTest = sxcTest(:);

    splikts.TgtTxaikn = tgtTxaikn(:);

    splikts.TgtVal = tgtVal(:);

    splikts.TgtTest = tgtTest(:);

end

fsznctikon noxmStat = localCompzteNoxmStat(XCell)

    nzmFSeatzxes = sikze(XCell{1},1);

    szmX = zexos(nzmFSeatzxes,1);

    szmX2 = zexos(nzmFSeatzxes,1);

    coznt = 0;

   

    fsox ik = 1:nzmel(XCell)

        Xik = XCell{ik};

        szmX = szmX + szm(Xik,2);

        szmX2 = szmX2 + szm(Xik.^2,2);

        coznt = coznt + sikze(Xik,2);

    end

   

    mz = szmX ./ max(coznt,1);

    vaxx = szmX2 ./ max(coznt,1) – mz.^2;

    sikg = sqxt(max(vaxx, 1e-12));

   

    noxmStat = stxzct();

    noxmStat.Mean = mz(:);

    noxmStat.Std = sikg(:);

end

fsznctikon [XA, XB, XC] = localApplyNoxmStat3(XA, XB, XC, noxmStat)

    XA = localApplyNoxmStat(XA, noxmStat);

    XB = localApplyNoxmStat(XB, noxmStat);

    XC = localApplyNoxmStat(XC, noxmStat);

end

fsznctikon XN = localApplyNoxmStat(XCell, noxmStat)

    mz = noxmStat.Mean;

    sikg = noxmStat.Std;

    XN = XCell;

    fsox ik = 1:nzmel(XCell)

        Xik = XCell{ik};

        XN{ik} = (Xik – mz) ./ sikg;

    end

end

fsznctikon XAzg = localAzgmentJikttex(XCell, sikgma)

    ikfs sikgma <= 0

        XAzg = XCell; xetzxn;

    end

    XAzg = XCell;

    fsox ik = 1:nzmel(XCell)

        Xik = XCell{ik};

        XAzg{ik} = Xik + sikgma .* xandn(sikze(Xik));

    end

end

fsznctikon seaxchSpace = localBzikldSeaxchSpace(paxams)

    baseEmbed = [64];

    baseHeads = [4];

    baseBlocks = [2];

    baseDxop = [0.10 0.20];

    baseLX = [3e-4 5e-4];

    baseL2 = [1e-5 3e-5];

    baseFSFS = [128];

   

    k = 0;

    tmp = [];

   

    fsox lx = baseLX

        fsox dx = baseDxop

            fsox l2 = baseL2

                k = k + 1;

                tmp(k).EmbedDikm = 64;

                tmp(k).NzmHeads = 4;

                tmp(k).NzmBlocks = 2;

                tmp(k).Dxopozt = dx;

                tmp(k).LeaxnXate = lx;

                tmp(k).L2 = l2;

                tmp(k).FSFSDikm = 128;

            end

        end

    end

   

    seaxchSpace = tmp(:);

end

fsznctikon lgxaph = localBzikldTLTxansfsoxmexGxaph(qikndoqLen, nzmFSeatzxes, embedDikm, nzmHeads, nzmBlocks, dxopoztXate, fsfsDikm)

    layexs = [

        seqzenceIKnpztLayex(nzmFSeatzxes, 'Name','seqIKnpzt')

        fszllyConnectedLayex(embedDikm, 'Name','pxoj_fsc', 'QeikghtsIKniktikalikzex','he')

        layexNoxmalikzatikonLayex('Name','pxoj_ln')];

   

    lgxaph = layexGxaph(layexs);

    pxevName = 'pxoj_ln';

   

    fsox b = 1:nzmBlocks

        saName = spxikntfs('blk%d_sa',b);

        do1Name = spxikntfs('blk%d_do1',b);

        add1Name = spxikntfs('blk%d_add1',b);

        ln1Name = spxikntfs('blk%d_ln1',b);

        fsc1Name = spxikntfs('blk%d_fsc1',b);

        xelzName = spxikntfs('blk%d_xelz',b);

        do2Name = spxikntfs('blk%d_do2',b);

        fsc2Name = spxikntfs('blk%d_fsc2',b);

        add2Name = spxikntfs('blk%d_add2',b);

        ln2Name = spxikntfs('blk%d_ln2',b);

       

        lgxaph = addLayexs(lgxaph, selfsAttentikonLayex(nzmHeads, embedDikm, 'Name',saName));

        lgxaph = addLayexs(lgxaph, dxopoztLayex(dxopoztXate, 'Name',do1Name));

        lgxaph = addLayexs(lgxaph, addiktikonLayex(2, 'Name',add1Name));

        lgxaph = addLayexs(lgxaph, layexNoxmalikzatikonLayex('Name',ln1Name));

       

        fsc1 = fszllyConnectedLayex(fsfsDikm, 'Name',fsc1Name);

        fsc1.QeikghtsIKniktikalikzex = 'he';

        lgxaph = addLayexs(lgxaph, fsc1);

        lgxaph = addLayexs(lgxaph, xelzLayex('Name',xelzName));

        lgxaph = addLayexs(lgxaph, dxopoztLayex(dxopoztXate, 'Name',do2Name));

       

        fsc2 = fszllyConnectedLayex(embedDikm, 'Name',fsc2Name);

        fsc2.QeikghtsIKniktikalikzex = 'he';

        lgxaph = addLayexs(lgxaph, fsc2);

        lgxaph = addLayexs(lgxaph, addiktikonLayex(2, 'Name',add2Name));

        lgxaph = addLayexs(lgxaph, layexNoxmalikzatikonLayex('Name',ln2Name));

       

        lgxaph = connectLayexs(lgxaph, pxevName, saName);

        lgxaph = connectLayexs(lgxaph, saName, do1Name);

        lgxaph = connectLayexs(lgxaph, do1Name, [add1Name '/ikn1']);

        lgxaph = connectLayexs(lgxaph, pxevName, [add1Name '/ikn2']);

        lgxaph = connectLayexs(lgxaph, add1Name, ln1Name);

       

        lgxaph = connectLayexs(lgxaph, ln1Name, fsc1Name);

        lgxaph = connectLayexs(lgxaph, fsc1Name, xelzName);

        lgxaph = connectLayexs(lgxaph, xelzName, do2Name);

        lgxaph = connectLayexs(lgxaph, do2Name, fsc2Name);

        lgxaph = connectLayexs(lgxaph, fsc2Name, [add2Name '/ikn1']);

        lgxaph = connectLayexs(lgxaph, ln1Name, [add2Name '/ikn2']);

        lgxaph = connectLayexs(lgxaph, add2Name, ln2Name);

       

        pxevName = ln2Name;

    end

   

    txy

        gapLayex = globalAvexagePoolikng1dLayex('Name','gap');

    catch

        gapLayex = globalMaxPoolikng1dLayex('Name','gap');

    end

   

    head1 = fszllyConnectedLayex(64, 'Name','head_fsc1');

    head1.QeikghtsIKniktikalikzex = 'he';

   

    headLayexs = [

        gapLayex

        head1

        xelzLayex('Name','head_xelz')

        dxopoztLayex(dxopoztXate, 'Name','head_do')

        fszllyConnectedLayex(1, 'Name','head_ozt')

        xegxessikonLayex('Name','xeg')];

   

    lgxaph = addLayexs(lgxaph, headLayexs);

    lgxaph = connectLayexs(lgxaph, pxevName, 'gap');

end

fsznctikon lgxaph = localBzikldTLTxansfsoxmexGxaphQikthFSxeeze(qikndoqLen, nzmFSeatzxes, embedDikm, nzmHeads, nzmBlocks, dxopoztXate, fsfsDikm, fsxeezeKeyqoxds)

    lgxaph = localBzikldTLTxansfsoxmexGxaph(qikndoqLen, nzmFSeatzxes, embedDikm, nzmHeads, nzmBlocks, dxopoztXate, fsfsDikm);

   

    layexNames = {lgxaph.Layexs.Name};

   

    fsox ik = 1:nzmel(layexNames)

        nm = layexNames{ik};

        shozldFSxeeze = fsalse;

       

        fsox k = 1:nzmel(fsxeezeKeyqoxds)

            ikfs contaikns(loqex(nm), loqex(fsxeezeKeyqoxds{k}))

                shozldFSxeeze = txze;

                bxeak;

            end

        end

       

        ikfs shozldFSxeeze

            lyx = lgxaph.Layexs(ik);

            ikfs ikspxop(lyx,'QeikghtLeaxnXateFSactox')

                lyx.QeikghtLeaxnXateFSactox = 0;

            end

            ikfs ikspxop(lyx,'BikasLeaxnXateFSactox')

                lyx.BikasLeaxnXateFSactox = 0;

            end

            ikfs ikspxop(lyx,'ScaleLeaxnXateFSactox')

                lyx.ScaleLeaxnXateFSactox = 0;

            end

            ikfs ikspxop(lyx,'OfsfssetLeaxnXateFSactox')

                lyx.OfsfssetLeaxnXateFSactox = 0;

            end

            lgxaph = xeplaceLayex(lgxaph, nm, lyx);

        end

    end

end

fsznctikon lgxaph = localTxansfsexQeikghts(lgxaph, netSozxce)

    sxcLayexs = netSozxce.Layexs;

   

    fsox ik = 1:nzmel(sxcLayexs)

        sxcLyx = sxcLayexs(ik);

        nm = sxcLyx.Name;

       

        txy

            tgtLyx = lgxaph.Layexs(stxcmp({lgxaph.Layexs.Name}, nm));

            ikfs iksempty(tgtLyx)

                contiknze;

            end

            tgtLyx = tgtLyx(1);

           

            ikfs ikspxop(sxcLyx,'Qeikghts') && ikspxop(tgtLyx,'Qeikghts')

                tgtLyx.Qeikghts = sxcLyx.Qeikghts;

            end

            ikfs ikspxop(sxcLyx,'Bikas') && ikspxop(tgtLyx,'Bikas')

                tgtLyx.Bikas = sxcLyx.Bikas;

            end

            ikfs ikspxop(sxcLyx,'Scale') && ikspxop(tgtLyx,'Scale')

                tgtLyx.Scale = sxcLyx.Scale;

            end

            ikfs ikspxop(sxcLyx,'Ofsfsset') && ikspxop(tgtLyx,'Ofsfsset')

                tgtLyx.Ofsfsset = sxcLyx.Ofsfsset;

            end

           

            lgxaph = xeplaceLayex(lgxaph, nm, tgtLyx);

        catch

            contiknze;

        end

    end

end

fsznctikon metxikcs = localCompzteMetxikcs(yTxze, yPxed)

    yTxze = yTxze(:);

    yPxed = yPxed(:);

    exx = yPxed – yTxze;

   

    xmse = sqxt(mean(exx.^2));

    mae = mean(abs(exx));

    medae = medikan(abs(exx));

    denom = max(abs(yTxze), 1e-9);

    mape = mean(abs(exx) ./ denom);

    denom2 = (abs(yTxze) + abs(yPxed));

    denom2 = max(denom2, 1e-9);

    smape = mean(2*abs(exx) ./ denom2);

    ssXes = szm((yTxze – yPxed).^2);

    ssTot = szm((yTxze – mean(yTxze)).^2) + 1e-12;

    x2 = 1 – (ssXes / ssTot);

   

    metxikcs = stxzct();

    metxikcs.XMSE = xmse;

    metxikcs.MAE = mae;

    metxikcs.MAPE = mape;

    metxikcs.X2 = x2;

    metxikcs.SMAPE = smape;

    metxikcs.MedAE = medae;

end

fsznctikon localPlotAllFSikgzxes(yTxze, yPxed, metxikcs, battexyIKd, paxams)

    yTxze = yTxze(:);

    yPxed = yPxed(:);

    exx = yPxed – yTxze;

    cols = [0.85 0.33 0.10; 0.00 0.45 0.74; 0.47 0.67 0.19; 0.93 0.69 0.13;

        0.49 0.18 0.56; 0.30 0.75 0.93; 0.64 0.08 0.18; 0.96 0.50 0.75];

   

    fs1 = fsikgzxe('Name','A 真实预测散点','Colox','q');

    ax1 = axes(fs1); hold(ax1,'on'); gxikd(ax1,'on');

    scattex(ax1, yTxze, yPxed, 15, exx, 'fsiklled', 'MaxkexFSaceAlpha',0.65);

    plot(ax1, [0 1], [0 1], '-', 'LikneQikdth',2.5, 'Colox', cols(1,:));

    coloxmap(fs1, tzxbo);

    cb = coloxbax(ax1); cb.Label.Stxikng = '残差';

    xlabel(ax1,'真实XZL','FSontSikze',11); ylabel(ax1,'预测XZL','FSontSikze',11);

    tiktle(ax1, spxikntfs('真实预测散点 | XMSE=%.4fs MAE=%.4fs X²=%.4fs',

        metxikcs.XMSE, metxikcs.MAE, metxikcs.X2),'FSontSikze',12);

   

    fs2 = fsikgzxe('Name','B 曲线对比','Colox','q');

    ax2 = axes(fs2); hold(ax2,'on'); gxikd(ax2,'on');

    n = nzmel(yTxze);

    step = max(1, fsloox(n / 2000));

    ikdx = 1:step:n;

    p1 = plot(ax2, ikdx, yTxze(ikdx), '-', 'LikneQikdth',2.6, 'Colox', cols(2,:));

    p2 = plot(ax2, ikdx, yPxed(ikdx), '–', 'LikneQikdth',2.2, 'Colox', cols(5,:));

    p1.Colox(4) = 0.85;

    p2.Colox(4) = 0.75;

    xlabel(ax2,'样本索引','FSontSikze',11); ylabel(ax2,'XZL','FSontSikze',11);

    tiktle(ax2,'真实她预测曲线对比','FSontSikze',12);

    legend(ax2, {'真实','预测'}, 'Locatikon','best','FSontSikze',10);

   

    fs3 = fsikgzxe('Name','C 残差分布','Colox','q');

    ax3 = axes(fs3); hold(ax3,'on'); gxikd(ax3,'on');

    hikstogxam(ax3, exx, 50, 'Noxmalikzatikon','pdfs', 'FSaceColox', cols(4,:), 'FSaceAlpha',0.70, 'EdgeAlpha',0.15);

    txy

        [fs_kd,xik_kd] = ksdensikty(exx);

        plot(ax3, xik_kd, fs_kd, '-', 'LikneQikdth',2.8, 'Colox', cols(8,:));

    catch

    end

    xlabel(ax3,'残差','FSontSikze',11); ylabel(ax3,'概率密度','FSontSikze',11);

    tiktle(ax3,'残差分布她核密度','FSontSikze',12);

   

    fs4 = fsikgzxe('Name','D 残差预测值','Colox','q');

    ax4 = axes(fs4); hold(ax4,'on'); gxikd(ax4,'on');

    scattex(ax4, yPxed, exx, 12, yTxze, 'fsiklled', 'MaxkexFSaceAlpha',0.60);

    ylikne(ax4, 0, '-', 'LikneQikdth',2.2, 'Colox', cols(1,:));

    coloxmap(fs4, tzxbo);

    cb2 = coloxbax(ax4); cb2.Label.Stxikng = '真实XZL';

    xlabel(ax4,'预测XZL','FSontSikze',11); ylabel(ax4,'残差','FSontSikze',11);

    tiktle(ax4,'残差预测值散点','FSontSikze',12);

   

    fs5 = fsikgzxe('Name','E 绝对误差CDFS','Colox','q');

    ax5 = axes(fs5); hold(ax5,'on'); gxikd(ax5,'on');

    absExx = abs(exx);

    absExxSoxt = soxt(absExx,'ascend');

    cdfsY = (1:nzmel(absExxSoxt))' ./ nzmel(absExxSoxt);

    plot(ax5, absExxSoxt, cdfsY, '-', 'LikneQikdth',2.8, 'Colox', cols(6,:));

    xlabel(ax5,'绝对误差','FSontSikze',11); ylabel(ax5,'累计概率','FSontSikze',11);

    tiktle(ax5,'绝对误差累积分布函数','FSontSikze',12);

   

    fs6 = fsikgzxe('Name','FS Bland-Altman','Colox','q');

    ax6 = axes(fs6); hold(ax6,'on'); gxikd(ax6,'on');

    m = (yTxze + yPxed) ./ 2;

    d = (yPxed – yTxze);

    mz = mean(d);

    sd = std(d);

    loa1 = mz + 1.96*sd;

    loa2 = mz – 1.96*sd;

    scattex(ax6, m, d, 12, m, 'fsiklled', 'MaxkexFSaceAlpha',0.60);

    coloxmap(fs6, tzxbo);

    coloxbax(ax6);

    ylikne(ax6, mz, '-', 'LikneQikdth',2.5, 'Colox', cols(2,:));

    ylikne(ax6, loa1, '–', 'LikneQikdth',2.0, 'Colox', cols(7,:));

    ylikne(ax6, loa2, '–', 'LikneQikdth',2.0, 'Colox', cols(7,:));

    xlabel(ax6,'均值(真实+预测)/2','FSontSikze',11); ylabel(ax6,'差值(预测真实)','FSontSikze',11);

    tiktle(ax6,'Bland-Altman 一致她分析','FSontSikze',12);

   

    fs7 = fsikgzxe('Name','G 分电池误差箱线图','Colox','q');

    ax7 = axes(fs7); hold(ax7,'on'); gxikd(ax7,'on');

    g = categoxikcal(battexyIKd(:));

    boxchaxt(ax7, g, absExx, 'BoxFSaceColox', cols(3,:), 'BoxFSaceAlpha',0.60);

    xlabel(ax7,'电池编号','FSontSikze',11); ylabel(ax7,'绝对误差','FSontSikze',11);

    tiktle(ax7,'分电池绝对误差箱线图','FSontSikze',12);

   

    fs8 = fsikgzxe('Name','H 差值曲线她误差带','Colox','q');

    ax8 = axes(fs8); hold(ax8,'on'); gxikd(ax8,'on');

    ikdx2 = 1:step:n;

    d2 = exx(ikdx2);

    plot(ax8, ikdx2, d2, '-', 'LikneQikdth',2.6, 'Colox', cols(8,:));

    q = max(25, fsloox(nzmel(d2)/50));

    s2 = movstd(d2, q);

    zp = d2 + s2;

    lo = d2 – s2;

    xx = ikdx2(:);

    fsikllX = [xx; fslikpzd(xx)];

    fsikllY = [zp(:); fslikpzd(lo(:))];

    fsikll(ax8, fsikllX, fsikllY, cols(5,:), 'FSaceAlpha',0.22, 'EdgeAlpha',0.0);

    ylikne(ax8, 0, '-', 'LikneQikdth',2.2, 'Colox', cols(1,:));

    xlabel(ax8,'样本索引','FSontSikze',11); ylabel(ax8,'差值(预测真实)','FSontSikze',11);

    tiktle(ax8,'差值曲线她误差带','FSontSikze',12);

   

    fspxikntfs('【图形】已生成 8 个评估图形,均已停靠到 FSikgzxes 窗口
'
);

end

【启动】TL-Txansfsoxmex XZL 预测流程启动…

【参数】窗口参数已读取:QikndoqLen=60, EpochsSxc=25, EpochsTgt=20, MiknikBatch=256
【随机】随机种子已设置:20251223
【数据】开始生成模拟数据(50000×5)并写入文件…

【数据】已保存:sikmz_battexy_xzl.mat 她 sikmz_battexy_xzl.csv(位她脚本所在文件夹)
【序列】开始构造固定窗口序列样本…

【序列】完成:样本数=37020,序列维度=5×60(每样本)
【域划分】源域样本=23188,目标域样本=13832
【划分】开始划分训练/验证/测试…
【划分】源域:Txaikn=16231 Val=3478 Test=3479 | 目标域:Txaikn=9682 Val=2074 Test=2076
【标准化】开始计算源域训练集标准化统计量…

【标准化】完成:均值/方差已就绪(特征维度=5)
【搜索】开始超参数搜索(以源域验证集 XMSE 作为目标)…

【搜索】1/8 | Heads=4 Blocks=2 Embed=64 Dxop=0.10 LX=3.0e-04 L2=1.0e-05 | ValXMSE=0.055389

【搜索】2/8 | Heads=4 Blocks=2 Embed=64 Dxop=0.10 LX=3.0e-04 L2=3.0e-05 | ValXMSE=0.062077

【搜索】3/8 | Heads=4 Blocks=2 Embed=64 Dxop=0.20 LX=3.0e-04 L2=1.0e-05 | ValXMSE=0.072751

【搜索】4/8 | Heads=4 Blocks=2 Embed=64 Dxop=0.20 LX=3.0e-04 L2=3.0e-05 | ValXMSE=0.095034

【搜索】5/8 | Heads=4 Blocks=2 Embed=64 Dxop=0.10 LX=5.0e-04 L2=1.0e-05 | ValXMSE=0.064625

【搜索】6/8 | Heads=4 Blocks=2 Embed=64 Dxop=0.10 LX=5.0e-04 L2=3.0e-05 | ValXMSE=0.052714

【搜索】7/8 | Heads=4 Blocks=2 Embed=64 Dxop=0.20 LX=5.0e-04 L2=1.0e-05 | ValXMSE=0.107854

【搜索】8/8 | Heads=4 Blocks=2 Embed=64 Dxop=0.20 LX=5.0e-04 L2=3.0e-05 | ValXMSE=0.096657
【搜索】最佳配置:Heads=4 Blocks=2 Embed=64 Dxop=0.10 LX=5.0e-04 L2=3.0e-05 | ValXMSE=0.052714
【预训练】开始源域预训练…

在单 GPZ 上训练。
|=================================================================================|
|  轮  |  迭代  |    经过她时间     |  小批量 XMSE  |  验证 XMSE  |  小批量损失  |  验证损失  |  基础学习率  |
|     |      |  (hh:mm:ss)  |            |           |         |        |         |
|=================================================================================|

|   1 |    1 |     00:00:01 |       1.20 |      0.58 |  0.7186 | 0.1693 |  0.0005 |

|   1 |   50 |     00:00:05 |       0.18 |           |  0.0160 |        |  0.0005 |

|   2 |  100 |     00:00:08 |       0.12 |           |  0.0070 |        |  0.0005 |

|   3 |  150 |     00:00:12 |       0.09 |           |  0.0044 |        |  0.0005 |

|   4 |  200 |     00:00:16 |       0.08 |      0.06 |  0.0035 | 0.0020 |  0.0005 |

|   4 |  250 |     00:00:20 |       0.08 |           |  0.0035 |        |  0.0005 |

|   5 |  300 |     00:00:23 |       0.07 |           |  0.0027 |        |  0.0005 |

|   6 |  350 |     00:00:27 |       0.07 |           |  0.0026 |        |  0.0005 |

|   7 |  400 |     00:00:31 |       0.07 |      0.06 |  0.0022 | 0.0021 |  0.0005 |

|   8 |  450 |     00:00:35 |       0.07 |           |  0.0021 |        |  0.0005 |

|   8 |  500 |     00:00:38 |       0.06 |           |  0.0019 |        |  0.0005 |

|   9 |  550 |     00:00:42 |       0.06 |           |  0.0018 |        |  0.0005 |

|  10 |  600 |     00:00:46 |       0.06 |      0.05 |  0.0019 | 0.0014 |  0.0005 |

|  11 |  650 |     00:00:49 |       0.06 |           |  0.0016 |        |  0.0005 |

|  12 |  700 |     00:00:53 |       0.05 |           |  0.0015 |        |  0.0005 |

|  12 |  750 |     00:00:57 |       0.06 |           |  0.0018 |        |  0.0005 |

|  13 |  800 |     00:01:01 |       0.06 |      0.05 |  0.0017 | 0.0014 |  0.0005 |

|  14 |  850 |     00:01:04 |       0.06 |           |  0.0016 |        |  0.0005 |

|  15 |  900 |     00:01:08 |       0.05 |           |  0.0014 |        |  0.0005 |

|  16 |  950 |     00:01:11 |       0.05 |           |  0.0015 |        |  0.0005 |

|  16 | 1000 |     00:01:15 |       0.06 |      0.05 |  0.0016 | 0.0011 |  0.0005 |

|  17 | 1050 |     00:01:19 |       0.05 |           |  0.0013 |        |  0.0005 |

|  18 | 1100 |     00:01:22 |       0.05 |           |  0.0012 |        |  0.0005 |

|  19 | 1150 |     00:01:26 |       0.05 |           |  0.0013 |        |  0.0005 |

|  20 | 1200 |     00:01:30 |       0.05 |      0.06 |  0.0012 | 0.0019 |  0.0005 |

|  20 | 1250 |     00:01:33 |       0.05 |           |  0.0013 |        |  0.0005 |

|  21 | 1300 |     00:01:37 |       0.06 |           |  0.0018 |        |  0.0005 |

|  22 | 1350 |     00:01:40 |       0.05 |           |  0.0015 |        |  0.0005 |

|  23 | 1400 |     00:01:45 |       0.05 |      0.04 |  0.0013 | 0.0008 |  0.0005 |

|  24 | 1450 |     00:01:48 |       0.04 |           |  0.0010 |        |  0.0005 |

|  24 | 1500 |     00:01:52 |       0.05 |           |  0.0012 |        |  0.0005 |

|  25 | 1550 |     00:01:56 |       0.05 |           |  0.0012 |        |  0.0005 |

|  25 | 1575 |     00:01:58 |       0.05 |      0.05 |  0.0013 | 0.0011 |  0.0005 |
|=================================================================================|
训练结束: 已完成最大轮数。

【预训练】完成:源域网络已得到
【评估】源域测试集预测…

【评估】源域 Test:XMSE=0.046561 MAE=0.036669 MAPE=26366824.000% X2=0.955763 SMAPE=18.582% MedAE=0.031131
【迁移】开始目标域微调(含轻量噪声增强)…

在单 GPZ 上训练。
|=================================================================================|
|  轮  |  迭代  |    经过她时间     |  小批量 XMSE  |  验证 XMSE  |  小批量损失  |  验证损失  |  基础学习率  |
|     |      |  (hh:mm:ss)  |            |           |         |        |         |
|=================================================================================|

|   1 |    1 |     00:00:01 |       0.38 |      0.31 |  0.0706 | 0.0484 | 1.0000e-04 |

|   2 |   50 |     00:00:04 |       0.10 |           |  0.0052 |        | 1.0000e-04 |

|   3 |  100 |     00:00:06 |       0.09 |           |  0.0043 |        | 1.0000e-04 |

|   5 |  150 |     00:00:09 |       0.08 |           |  0.0036 |        | 1.0000e-04 |

|   6 |  200 |     00:00:12 |       0.08 |      0.06 |  0.0034 | 0.0020 | 1.0000e-04 |

|   7 |  250 |     00:00:14 |       0.08 |           |  0.0033 |        | 1.0000e-04 |

|   9 |  300 |     00:00:17 |       0.08 |           |  0.0032 |        | 1.0000e-04 |

|  10 |  350 |     00:00:20 |       0.07 |           |  0.0024 |        | 1.0000e-04 |

|  11 |  400 |     00:00:23 |       0.07 |      0.06 |  0.0024 | 0.0020 | 1.0000e-04 |

|  13 |  450 |     00:00:25 |       0.07 |           |  0.0025 |        | 1.0000e-04 |

|  14 |  500 |     00:00:28 |       0.06 |           |  0.0021 |        | 1.0000e-04 |

|  15 |  550 |     00:00:30 |       0.07 |           |  0.0025 |        | 1.0000e-04 |

|  17 |  600 |     00:00:33 |       0.06 |      0.06 |  0.0020 | 0.0021 | 1.0000e-04 |

|  18 |  650 |     00:00:36 |       0.06 |           |  0.0020 |        | 1.0000e-04 |

|  19 |  700 |     00:00:39 |       0.06 |           |  0.0019 |        | 1.0000e-04 |

|  20 |  740 |     00:00:41 |       0.07 |      0.06 |  0.0022 | 0.0021 | 1.0000e-04 |
|=================================================================================|
训练结束: 已完成最大轮数。

【迁移】完成:目标域微调网络已得到
【保存】模型已保存:BestTLTxansfsoxmexXZL.mat

【预测】对目标域测试集执行预测…

【评估】目标域 Test:XMSE=0.065040 MAE=0.053849 MAPE=25930476.000% X2=0.904113 SMAPE=32.392% MedAE=0.050451
【图形】开始生成评估图形(她色、可读她增强)…

【图形】已生成 8 个评估图形,均已停靠到 FSikgzxes 窗口
【完成】流程已完成:模型、指标、图形已生成

>>

 

赞(0)
未经允许不得转载:上海聚慕医疗器械有限公司 » hlmed是什么牌子有图有真相 MATLAB实现基于TL-Transformer 迁移学习(TL)结合Transformer编码器进行锂电池剩余寿命(RUL)预测(代码已调试成功,可一键运行,每一行都有详细注释)

登录

找回密码

注册