尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

TCN-Transformer+LSTM双输入时间序列预测的MATLAB实现

TCN-Transformer+LSTM双输入时间序列预测的MATLAB实现 简介一份基于MATLAB的TCN-TransformerLSTM双输入神经网络时间序列预测项目实例核心面向具备一定深度学习基础、希望解决复杂时序预测难题的开发者、科研人员与研究生。资源为1个docx文档压缩包仅57KB虽体量不大但内容完整覆盖项目设计、实现与部署全链路从环境配置、数据预处理到TCN、Transformer与LSTM多模型融合搭建、模型训练再到结果评估与可视化并配有GUI设计思路和逐段代码详解。针对金融、气象、能源等行业的长时间依赖与非线性特征文档详细讲解了融合多头自注意力、膨胀卷积和循环门控的建模策略同时给出防止过拟合、超参数调优以及引入GAN或强化学习实现模型扩展的进阶建议帮助读者举一反三。目前已有81人学习下载适合想深入理解混合深度学习模型并快速落地应用的工程与研究人员参考。1. TCN-TransformerLSTM双输入架构时间序列预测的融合解法很多时序预测项目做到后半程会发现单模型的天花板很明显LSTM能记忆长期状态但对局部突变不敏感TCN靠膨胀卷积可以拉大感受野却缺少全局注意力Transformer把注意力铺满序列计算开销又高。于是就有了把三者串并联的融合思路。这个项目给出的是一套完整的MATLAB实现TCN和Transformer处理主序列LSTM分支处理辅助特征序列双输入融合后经全连接层输出预测值。它解决的是一类实际问题即同时捕捉长时间依赖、局部模式与外部特征之间的联合影响适合手里有中等规模数据、想直接落地跑通的开发者和研究生。整个链条涉及数据窗口化、模型装配、训练评估和GUI交互下面按实操顺序逐块拆开。2. 数据入口与序列构造窗口怎么切、维度怎么对齐融合模型的收益首先取决于样本怎么构造。窗口长度、预测步长、归一化方式直接决定模型能看到什么这一章把数据侧的关键步骤拆开讲清楚尤其是双输入的数据格式如何组织。2.1 数据预处理归一化与异常值处理不管用TCN还是LSTM输入数据先做归一化几乎是必须的。Transformer的注意力机制依赖点积计算特征尺度差异过大会让注意力权重被大数值特征主导LSTM的遗忘门和输入门同样受输入尺度影响。常见做法是用mapminmax把数据缩放到[0,1]或[-1,1]同时保留ps结构体用于预测结束后反归一化% 读取原始序列假设数据为列向量 dataRaw dataRaw load(series.mat).data; % 或 readmatrix(data.xlsx) % 归一化到 [0,1]ps 保存归一化参数供反变换使用 [dataNorm, ps] mapminmax(dataRaw, 0, 1); dataNorm dataNorm;mapminmax是按行计算的所以输入数据先转成行向量归一化完成后再转回列向量。ps里保存了xmin、xmax、ymin、ymax等参数测试集预测完成后用同一组ps做反归一化才能回到原始量纲。特别要注意的是ps只能由训练集拟合如果先用全量数据算min/max再切分验证集和测试集的信息就已经泄漏进了训练过程后续所有评估指标都会偏乐观。异常值处理上我一般先用isoutlier配合movmedian做滑动中位数检测把超过三倍MAD的点替换成邻域中位数避免个别坏点把归一化边界拉偏这一步对金融和传感器数据尤其重要因为TCN的卷积核会同时扫过异常点和正常点异常值带来的局部梯度容易被当成有效时序模式。缺失值则用fillmissing的spline插值补齐线性插值会破坏序列原有的波动形态。2.2 滑动窗口构建从一维序列到监督样本时间序列预测的第一步是把序列变成(X, Y)监督样本。窗口长度windowSize表示用过去多少个点预测未来horizon步的值窗口越长模型能看到的上下文越完整但样本数会减少训练负担也变大。下面的函数把一维数据切分成dlnetwork训练用的四维数组function [XMain, XAux, Y] createSamples(dataNorm, windowSize, horizon, diffData) numSamples length(dataNorm) - windowSize - horizon 1; % dlnetwork 输入约定[特征维度, 时间步, 通道数, 样本数] XMain zeros(1, windowSize, 1, numSamples); Y zeros(1, 1, 1, numSamples); XAux zeros(1, windowSize, 1, numSamples); for i 1:numSamples XMain(1, :, 1, i) dataNorm(i:iwindowSize-1); % 差分序列作为 LSTM 分支的辅助输入 XAux(1, :, 1, i) diffData(i:iwindowSize-1); Y(1, 1, 1, i) dataNorm(iwindowSizehorizon-1); end end这段代码把原始窗口和差分窗口组织成两路输入。差分序列提供一阶变化信息与原始水平值互补比如原始序列在一段时间内趋势平缓但波动加剧差分值能反映出这种局部变化而水平值本身看不出差异。四维数组的维度顺序是MATLAB深度学习工具箱的标准约定第一维特征数、第二维时间步、第三维通道数、第四维样本数后续卷积核沿第二维做时间方向滑动。窗口大小与样本数的关系可以这样估算1000个数据点windowSize取48、horizon取1时样本数为1000-48-11952个配合batch size 32每轮约29个迭代步训练80轮的总迭代量在2300次左右中等配置的GPU几分钟内可以跑完。窗口长度预测步长生成样本数(N1000)适用场景241976小时级、日级短期预测481952跨天模式明显的数据723926需要远期预测的对齐窗口窗口越长样本越少两者需要根据数据量平衡。若样本量不足可以用重叠方式取窗但重叠会让相邻样本强相关做验证集划分时要注意不能与训练集窗口重叠否则验证集等于变相看到了训练数据。2.3 训练集与测试集划分的时间顺序问题划分数据时不能随机打乱。时间序列样本之间有强自相关性随机划分会造成数据泄漏验证集里混入训练集相邻时间段的样本评估指标会虚高。正确做法是按时间顺序切分前70%做训练、中间15%做验证、最后15%做测试验证集用于early stopping和调参测试集只在最终评估时碰一次% 按时间顺序切分不要用 cvpartition 或 randperm numTotal size(XMain, 4); numTrain floor(numTotal * 0.7); numVal floor(numTotal * 0.15); idxTrain 1:numTrain; idxVal numTrain1:numTrainnumVal; idxTest numTrainnumVal1:numTotal;idxTest落在时间轴末端代表真实预测场景下最接近当前时刻的数据。如果数据存在概念漂移训练集与测试集分布差异较大可以考虑在测试集上做滑动回测每次只预测一个点然后把预测值加入历史窗口继续滚动这样更接近线上预测的实际情况也能减少一次性长段预测带来的滞后误差。3. TCN与Transformer、LSTM如何搭成可训练网络模型核心在这一章。双输入融合架构里三条路径分别承担不同类型特征提取最后用拼接完成融合。这部分的难点不在单个层怎么选而在各层输出形状如何对齐。3.1 三条路径的分工与信息流TCN路径负责局部因果建模用膨胀卷积按时间顺序扫描每个输出位置只能看到当前及之前的输入不引入未来信息Transformer路径对TCN输出做全局自注意力计算任意两个时间步之间的关联权重LSTM路径接收第二路输入比如差分序列或外部协变量保留长期记忆状态。最后把Transformer输出与LSTM输出拼接经全连接层得到预测值。这个信息流的合理性在于TCN把原始序列编码成更高层的局部特征相当于先做了一次特征压缩让后续注意力计算聚焦在更有语义的表示上Transformer补全了TCN感受野之外的远距离依赖LSTM则独立处理另一路特征避免辅助信息被主序列的卷积池化过程稀释。三条路径各管一段融合后对序列形态变化的鲁棒性高于任何单一模型。3.2 TCN分支的实现细节TCN的核心是因果膨胀卷积。普通卷积在计算时会看到未来数据因果卷积通过左侧补零保证t时刻的输出只依赖t及以前的输入。膨胀系数d让卷积核在时间轴上隔d个点取值感受野随层数指数扩大计算公式为receptiveField 1 sum((kernelSize - 1) * dilation_i)kernelSize为卷积核大小dilation_i是第i层的膨胀系数。常见配置是kernelSize取3膨胀系数按1、2、4、8递增四层后感受野覆盖约30个时间步。MATLAB里用convolution1dLayer实现tcnsBlock [ convolution1dLayer(3, 32, Padding, causal, DilationFactor, 1, Name, tcn_conv1) layerNormalizationLayer(Name, tcn_norm1) reluLayer(Name, tcn_relu1) convolution1dLayer(3, 32, Padding, causal, DilationFactor, 2, Name, tcn_conv2) layerNormalizationLayer(Name, tcn_norm2) reluLayer(Name, tcn_relu2) ];convolution1dLayer第一个参数3是卷积核大小第二个参数32是输出通道数Padding设为causal保证因果性DilationFactor控制膨胀系数。每层卷积后接layerNormalization和ReLU层归一化在batch size较小时比batch normalization更稳定因为BN在小批量上的均值和方差估计波动大而LN只依赖当前样本自身统计量。需要注意causal选项在R2021a及以后版本可用老版本需要手动在序列左侧补d*(k-1)个零达到相同效果。参数取值示例作用FilterSize3卷积核覆盖的时间步数越大感受野越大NumFilters32输出特征通道数决定TCN输出维度DilationFactor1,2,4,8逐层膨胀控制感受野扩张速度Paddingcausal左侧补零不泄露未来信息3.3 Transformer编码器自注意力怎么接在TCN后面Transformer段负责全局依赖建模。TCN输出的每个时间步是一个长度为32的特征向量把这些向量按时间顺序组织成序列送入自注意力层计算任意两个时间步之间的关联权重。MATLAB从R2023b开始提供transformerLayer可以直接使用参数名称在不同版本略有差异% R2023b及以上版本可用 transformerLayer参数以当前版本文档为准 transformerBlock [ transformerLayer(4, 32, PreLayerNorm, true, Name, transformer_enc) ];第一个参数4是注意力头数第二个参数32是特征维度需要与TCN输出通道数保持一致。注意力头数为4意味着把特征分成4个子空间并行计算注意力每个子空间关注不同的时序依赖模式。PreLayerNorm设为true表示在注意力计算前先做层归一化这是Transformer训练中常用的做法能缓解深层网络训练初期的梯度不稳定问题。如果不支持这个选项去掉即可。较老版本没有transformerLayer时可以用attentionLayer自建多头注意力先用三个全连接层把特征投影为query、key、value再调用attentionLayer计算加权和最后拼接多头结果过一层全连接效果等价但代码量会多出几十行。Transformer输出保持序列长度不变每个时间步仍对应一个特征向量。到这一步主序列路径已经拿到了同时包含局部模式与全局依赖的表示接下来要与LSTM分支的辅助特征融合。3.4 LSTM分支与融合层LSTM分支接收第二路输入即2.2节构造的差分序列窗口也可以是滚动均值、外部协变量等多维特征。LSTM的隐藏单元数需要和主路径输出维度搭配通常取32到128之间过大容易过拟合过小则记不住长程依赖。这里设置64并只输出最后一个时间步的隐藏状态lstmBranch [ lstmLayer(64, OutputMode, last, Name, lstm_branch) dropoutLayer(0.2, Name, lstm_dropout) ];OutputMode设为last后LSTM输出形状是[64, 1, 1, N]与Transformer路径的[32, T, 1, N]在时间维上不一致直接拼接会报维度错误。常见做法是先对Transformer输出做全局平均池化把时间维压缩成1得到[32, 1, 1, N]的向量再与LSTM输出拼接成[96, 1, 1, N]。如果保留Transformer全部时间步也可以但拼接后维度会变成[96, T, 1, N]需要再接flatten层或池化层降维计算量和过拟合风险都会增加。融合部分用深度学习工具箱的深度拼接层fusionLayers [ globalAveragePooling1dLayer(Name, transformer_gap) concatenationLayer(1, 2, Name, fusion_cat) fullyConnectedLayer(32, Name, fc1) reluLayer(Name, fc_relu) dropoutLayer(0.3, Name, fc_dropout) fullyConnectedLayer(1, Name, fc_out) regressionLayer(Name, output) ];concatenationLayer(1, 2)表示在第一维即特征维拼接两个输入一个来自transformer_gap一个来自lstm_dropout。globalAveragePooling1dLayer沿时间维做平均输出形状变成[32, 1, 1, N]与LSTM对齐。全连接层先压到32维再做二次映射避免高维特征直接映射到1维输出时出现过拟合。3.5 完整网络组装与双输入绑定上面这些层必须通过layerGraph组合起来再用dlnetwork封装成可训练网络。装配的核心是把两个输入层分别绑定到TCN分支和LSTM分支再把各分支末端连到融合层lgraph layerGraph(); % 主序列输入 - TCN - Transformer lgraph addLayers(lgraph, sequenceInputLayer(1, Name, input_main)); lgraph addLayers(lgraph, tcnsBlock); lgraph addLayers(lgraph, transformerBlock); % 辅助序列输入 - LSTM lgraph addLayers(lgraph, sequenceInputLayer(1, Name, input_aux)); lgraph addLayers(lgraph, lstmBranch); % 融合与输出 lgraph addLayers(lgraph, fusionLayers); lgraph connectLayers(lgraph, input_main, tcn_conv1); lgraph connectLayers(lgraph, tcn_relu2, transformer_enc); lgraph connectLayers(lgraph, transformer_enc, transformer_gap); lgraph connectLayers(lgraph, transformer_gap, fusion_cat/in1); lgraph connectLayers(lgraph, input_aux, lstm_branch); lgraph connectLayers(lgraph, lstm_dropout, fusion_cat/in2); dlnet dlnetwork(lgraph);connectLayers里fusion_cat/in1和fusion_cat/in2对应concatenationLayer的两个输入端口。组装完成后先做一次前向传导用随机数据确认各层形状匹配再进入训练。这一步能提前暴露维度问题比如Transformer输出与池化层不匹配、LSTM时间步与辅助输入不对齐等避免训练到一半才报错。常见报错是维度不匹配或format字符串错误定位方式是把每一层输出用size函数打印出来逐个比对。4. 训练配置、评估指标与GUI可视化模型架构确定之后训练策略直接决定收敛质量。融合网络的不同分支梯度量级差异较大训练配置和评估方式都需要相应调整。4.1 训练超参数与优化器用Adam优化器训练融合网络初始学习率0.001梯度衰减因子0.9二阶矩衰减因子0.999这两个参数沿用各框架默认值即可。LSTM分支的梯度范数通常比TCN路径小训练过程中若出现损失尖峰根因往往是梯度爆炸而非学习率过大因此梯度裁剪是必要的learnRate 0.001; maxEpochs 80; miniBatchSize 32; clipThreshold 2; % 梯度裁剪阈值 for epoch 1:maxEpochs shuffledIdx randperm(size(XTrain, 4)); numIterPerEpoch floor(numel(shuffledIdx) / miniBatchSize); for iter 1:numIterPerEpoch idx shuffledIdx((iter-1)*miniBatchSize1 : iter*miniBatchSize); [loss, grads] dlfeval(modelLoss, dlnet, ... dlarray(XTrain(:,:,:,idx), SSCB), ... dlarray(XAux(:,:,:,idx), SSCB), ... dlarray(YTrain(:,:,:,idx), SSCB)); % 逐参数梯度裁剪 grads dlupdate((g) min(max(g, -clipThreshold), clipThreshold), grads); [dlnet, avgGrad, avgSqGrad] adamupdate(dlnet, grads, ... avgGrad, avgSqGrad, iter, learnRate, 0.9, 0.999); end end模型损失函数里直接用均方误差即可时间序列回归不需要自定义复杂损失function [loss, grads] modelLoss(dlnet, dlX1, dlX2, dlY) dlYPred forward(dlnet, dlX1, dlX2); loss mse(dlYPred, dlY); grads dlgradient(loss, dlnet.Learnables); end梯度裁剪阈值2的含义是每个参数的梯度更新量被限制在[-2,2]区间内防止LSTM长程反向传播时的梯度爆炸。损失曲线出现尖峰时把阈值降到1.0训练过慢则适当提高到3.0。学习率衰减方面每20个epoch乘0.5比cosine schedule更直观验证集损失连续10个epoch不下降时提前终止训练。batch size取32是兼顾稳定性和速度的起点样本量只有几千时降到16。这里dlarray的格式串SSCB对应[特征、时间、通道、样本]四个维度不同MATLAB版本对卷积层与LSTM层的format要求略有差异前向时报维度不匹配时优先检查输入矩阵各维顺序与format字符串是否一致。4.2 评估指标怎么算、怎么看测试集预测完成后先用训练时保存的ps做反归一化再计算指标。归一化参数只能由训练集拟合验证集和测试集共用同一组ps这是评估逻辑里最容易出错的地方YPredNum extractdata(dlYPred); YPredNum squeeze(YPredNum); % 转成 [1, N]mapminmax 按行处理 YPredRaw mapminmax(reverse, YPredNum, ps); yTestNum extractdata(dlYTest); yTestNum squeeze(yTestNum); yTestRaw mapminmax(reverse, yTestNum, ps); rmseVal sqrt(mean((yTestRaw - YPredRaw).^2)); maeVal mean(abs(yTestRaw - YPredRaw)); mapeVal mean(abs((yTestRaw - YPredRaw) ./ yTestRaw)) * 100; ssRes sum((yTestRaw - YPredRaw).^2); ssTot sum((yTestRaw - mean(yTestRaw)).^2); r2Val 1 - ssRes / ssTot;指标公式说明RMSEsqrt(mean((y-ŷ)²))对大误差敏感量纲与原始数据一致MAEmean(abs(y-ŷ))平均绝对偏差受异常点影响小MAPEmean(abs((y-ŷ)/y))*100%相对误差真实值接近0时不可用R²1 - SS_res/SS_tot越接近1表示模型解释度越高MAPE在样本真实值接近0时会产出异常大的值这类数据建议改用sMAPE。预测曲线与真实曲线叠加绘图只是第一步更有效的验证是画残差图残差在零线附近均匀分布说明模型没有系统性偏差残差随预测值增大呈漏斗状发散说明模型在高值区间不稳定可考虑对目标值做log变换后再训练。4.3 GUI可视化与交互操作项目自带的GUI用uifigure加uigridlayout实现核心交互包含文件选择、参数设置、训练启动、结果展示四块。训练耗时较长按钮回调里要用timer或并行池避免界面卡死否则点击训练按钮后整个窗口失去响应fig uifigure(Name, TCN-TransformerLSTM 时间序列预测, ... Position, [100 100 1100 700]); g uigridlayout(fig, [3 2]); g.RowHeight {40, 1x, 180}; g.ColumnWidth {1x, 1x}; btnTrain uibutton(g, Text, 开始训练, ... ButtonPushedFcn, (btn, event) startTraining()); axRaw uiaxes(g); axPred uiaxes(g); axRaw.Layout.Row 2; axRaw.Layout.Column 1; axPred.Layout.Row 2; axPred.Layout.Column 2;文件选择模块用uigetfile读取Excel或.mat格式数据参数设置模块提供窗口长度、隐藏单元数、学习率、epochs四个输入框。参数提交后要做范围校验比如窗口长度不能大于数据长度的一半学习率不能大于0.1否则无效配置会浪费整轮训练时间。训练结束后把预测曲线、残差图、评估指标表分别渲染到右侧绘图区。结果展示里建议加一张误差热图按时间窗口分组统计预测误差能直观定位模型表现差的时间段这类时间段通常对应数据中的突变段或缺失段。5. 防过拟合与超参数调优的实操清单融合模型的参数量比单模型大过拟合风险相应更高。判断过拟合的标准简单直接训练损失持续下降而验证损失在第N轮开始回升就是过拟合的起点。三条对策优先级最高早停、dropout、数据扩充。早停阈值设为10个epoch验证损失连续10轮不下降就终止dropout推荐在TCN输出后加0.2LSTM输出后加0.2全连接前加0.3数据扩充在时间序列里常用加噪声和窗口抖动两种方式窗口抖动比加噪声更稳定做法是随机微调窗口起点让模型看到更多变体但样本间的相关性会增加验证集划分时要留出足够间隔。几个关键超参数的调整经验整理如下超参数推荐范围调整方向窗口长度预测周期的1~3倍偏小欠拟合长期模式偏大引入噪声TCN卷积核大小3或5数据平滑用5突变多用3膨胀系数序列1,2,4,8序列越长最大膨胀系数越大注意力头数4或8特征维度低时头数不要超过8LSTM隐藏单元数32~128和输入特征量级匹配过大易过拟合学习率0.0005~0.002损失震荡就降一半TCN的感受野要覆盖至少一个完整周期。日粒度数据预测月趋势窗口至少30到60膨胀卷积层数按感受野公式反推。调参时R²高到0.9以上要优先怀疑数据泄漏最常见的泄漏点是归一化参数用了全量数据的min/max正确做法是只用训练集拟合ps验证集和测试集复用同一组ps。收敛速度方面前30个epoch观察验证损失曲线完全不动说明学习率太小或梯度消失前几个epoch就冲到Inf说明学习率过大或裁剪阈值太高。这两件事排查完剩下的就是组合结构参数并用早停控制训练轮次每轮实验记录窗口长度、隐藏单元数、RMSE三个值横向对比比凭感觉调参效率高得多。本文还有配套的精品资源点击获取
返回列表