目录
有图有真相 代码已调试成功,可一键运行,每一行都有详细注释,运行结果详细见实际效果图 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); % 构建超参数搜索空间(学习率、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
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); % 计算决定系数X²(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); % 设置x和y轴标签及字体大小
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); % 设置x和y轴标签及字体大小
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); % 设置x和y轴标签及字体大小
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); % 设置x和y轴标签及字体大小
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); % 设置x和y轴标签及字体大小
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); % 设置x和y轴标签及字体大小
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); % 设置x和y轴标签及字体大小
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); % 设置x和y轴标签及字体大小
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('【评估】源域 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);
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('【评估】目标域 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;
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 窗口
【完成】流程已完成:模型、指标、图形已生成
>>







