正在加载中...

展开本页目录
算法教程TCN-时序卷积网络

TCN-时序卷积网络

No.157 · 在线教程

TCN-时序卷积网络 模块在当前项目中的真实实现,是一个简化版 TCN(Temporal Convolutional Network)。它的主后端使用 PyTorch,核心结构是“因果一维卷积 + 空洞卷积 + 残差连接 + 末步线性输出”;若运行环境没有 torch,则会退化…

TCN-时序卷积网络

1. 方法概述

TCN-时序卷积网络 模块在当前项目中的真实实现,是一个简化版 TCN(Temporal Convolutional Network)。它的主后端使用 PyTorch,核心结构是“因果一维卷积 + 空洞卷积 + 残差连接 + 末步线性输出”;若运行环境没有 torch,则会退化为基于滑窗展平向量的 MLPClassifier/MLPRegressor

设原始按行排列的数据为

$$ \mathcal{D}=\{(x_t,y_t)\}_{t=1}^{N},\qquad x_t\in\mathbb{R}^{d},\ y_t\in\mathcal{Y} \tag{1} $$

其中 \(x_t\) 为第 \(t\) 行样本对应的特征向量,\(y_t\) 为目标变量。该实现默认数据行顺序就是时间顺序,不会专门解析时间列,也不会自动构造日历特征。

需要特别说明两点:

  • 项目根目录中的 README.md 是另一套 SVM 系统的错拷,不能代表当前 TCN 实现;
  • 当前模块更准确地说是“面向单点预测的 TCN 风格序列分类/回归器”,而不是带严格时间留出验证的标准实验框架。

2. 数据预处理与监督样本构造

2.1 特征筛选

程序先删除目标列,再从剩余列中仅保留数值型特征,记为

$$ \tilde{x}_t\in\mathbb{R}^{d'} \tag{2} $$

若去掉目标列后不存在数值特征,或某个特征列含有 NaN / inf,程序会直接报错,而不会做 One-Hot 编码、缺失值填补或类别特征自动转换。

2.2 滑动窗口

设回看窗口长度为 \(L=\text{lookback}\),预测步长为 \(H=\text{horizon}\)。对每个可行位置 \(i\),程序构造输入窗口

$$ \mathbf{X}_i= \begin{bmatrix} \tilde{x}_{i-L}\\ \tilde{x}_{i-L+1}\\ \vdots\\ \tilde{x}_{i-1} \end{bmatrix} \in\mathbb{R}^{L\times d'} \tag{3} $$

并把未来第 \(H\) 步单点目标定义为

$$ z_i=y_{i+H-1} \tag{4} $$

因此可用的监督样本数为

$$ M=N-L-H+1 \tag{5} $$

这说明当前实现是典型的 sequence-to-one 结构,horizon 只控制“预测未来第几步的那个单点”,并不会一次输出长度为 \(H\) 的未来序列。

2.3 分类标签编码

分类任务中,代码通过 pd.factorize(sort=False) 将原始标签映射为整数类别:

$$ \phi:\mathcal{Y}\to\{0,1,\ldots,C-1\} \tag{6} $$

其中 \(C\) 是类别数。映射关系会被记录到 class_mapping 中。结合 问题检查报告.md 可以看出,这部分是后续补上的稳定性修复,用来避免字符串标签、1/2 标签等情况直接送入 CrossEntropyLoss 时出错。

2.4 全量窗口标准化

如果勾选 normalize=True,程序会在全部窗口样本构造完之后、划分训练测试集之前,对特征做标准化:

$$ \mu=\frac{1}{ML}\sum_{i=1}^{M}\sum_{\tau=1}^{L}\mathbf{X}_{i,\tau} \tag{7} $$

$$ \sigma=\sqrt{\frac{1}{ML}\sum_{i=1}^{M}\sum_{\tau=1}^{L}\left(\mathbf{X}_{i,\tau}-\mu\right)^2} \tag{8} $$

$$ \mathbf{X}_i^{\ast}=\frac{\mathbf{X}_i-\mu}{\sigma} \tag{9} $$

其中零方差维度会被强制替换为 1。由于 \(\mu,\sigma\) 使用了全部窗口样本,故这里存在信息泄漏;它不是“只用训练集统计量拟合,再应用到测试集”的标准做法。

2.5 随机训练测试切分

完成标准化后,程序调用 train_test_split(..., shuffle=True) 随机切分训练集和测试集:

$$ (\mathcal{X}_{\mathrm{tr}},\mathcal{X}_{\mathrm{te}},\mathcal{y}_{\mathrm{tr}},\mathcal{y}_{\mathrm{te}}) =\mathrm{Split}(\{\mathbf{X}_i^{\ast},z_i\}_{i=1}^{M}) \tag{10} $$

分类任务中,如果类别数大于 1,则切分时还会使用分层抽样。切分完成后,若训练集中只剩 1 个类别,程序会直接报错。

这一步意味着该模块虽然处理的是时间序列窗口,但评估阶段并未保持时间顺序留出测试集;窗口被随机打散后再评估,因此测试结果更接近“随机监督学习拆分”,而不是严格时序外推。

3. 简化版 TCN 结构

3.1 因果空洞卷积块

PyTorch 主实现中的 TemporalBlock 由两层 Conv1d 组成。对输入张量 \(U\in\mathbb{R}^{B\times c_{\mathrm{in}}\times L}\),第 1 层卷积可写为

$$ V^{(1)}=\mathrm{Conv1D}_{k,\delta}(U) \tag{11} $$

其中卷积核大小为 \(k=\text{kernel\_size}\),空洞率为 \(\delta\)。代码采用左侧因果所需的 padding 长度

$$ p=(k-1)\delta \tag{12} $$

然后在卷积后把末尾多出的 \(p\) 个时间步裁掉,以保持“当前输出不看未来”这一因果性近似。经过激活和 dropout 后得到

$$ H^{(1)}=\mathrm{Dropout}(\mathrm{ReLU}(\mathrm{Crop}(V^{(1)}))) \tag{13} $$

第 2 层卷积重复相同过程:

$$ H^{(2)}=\mathrm{ReLU}\!\left(\mathrm{Crop}\left(\mathrm{Conv1D}_{k,\delta}(H^{(1)})\right)\right) \tag{14} $$

3.2 残差连接

若输入通道数与输出通道数不同,程序通过 \(1\times1\) 卷积做通道对齐,记为

$$ R= \begin{cases} W_{1\times1}\ast U,& c_{\mathrm{in}}\neq c_{\mathrm{out}}\\ U,& c_{\mathrm{in}}=c_{\mathrm{out}} \end{cases} \tag{15} $$

若残差分支与主分支长度不一致,则代码会截取残差张量最后一段时间轴,使两者长度一致。最终块输出为

$$ O=\mathrm{ReLU}(H^{(2)}+R) \tag{16} $$

3.3 多层堆叠

设卷积通道列表为 \((c_1,c_2,\ldots,c_K)\),空洞率列表为 \((\delta_1,\delta_2,\ldots)\)。程序会顺序堆叠 \(K\) 个残差块:

$$ U^{(k)}=\mathrm{TemporalBlock}^{(k)}(U^{(k-1)}),\qquad k=1,\ldots,K \tag{17} $$

若给定的 dilationschannels 短,代码会直接用最后一个空洞率补齐剩余层,因此真实空洞率序列不一定是论文里常见的严格指数增长。

3.4 末步读出

所有卷积块结束后,模型只取最后一个时间步的隐藏表示:

$$ h_i=U^{(K)}_{:,:,L} \tag{18} $$

再通过线性层产生输出:

$$ \hat{y}_i=W h_i+b \tag{19} $$

回归任务中,\(\hat{y}_i\in\mathbb{R}\);分类任务中,\(\hat{y}_i\in\mathbb{R}^{C}\),随后由 argmax 选出预测类别。

4. 训练目标与后备实现

4.1 PyTorch 主后端

若环境中安装了 torch,程序使用 Adam 优化器训练整个网络。回归任务损失函数为

$$ \mathcal{L}_{\mathrm{reg}}=\frac{1}{|\mathcal{X}_{\mathrm{tr}}|}\sum_{i}(z_i-\hat{y}_i)^2 \tag{20} $$

分类任务则使用交叉熵损失:

$$ \mathcal{L}_{\mathrm{cls}}=-\frac{1}{|\mathcal{X}_{\mathrm{tr}}|}\sum_{i}\log\frac{\exp(\hat{y}_{i,z_i})}{\sum_{c=1}^{C}\exp(\hat{y}_{i,c})} \tag{21} $$

当前版本只有训练集 train_loss 日志,不单独划分验证集,也没有早停或学习率调度。

4.2 无 torch 时的后备路径

若 PyTorch 不可用,模块会退化为 sklearn 的多层感知机。此时输入窗口会先展平为

$$ \bar{x}_i=\mathrm{vec}(\mathbf{X}_i^{\ast})\in\mathbb{R}^{Ld'} \tag{22} $$

然后交给:

  • 回归:MLPRegressor
  • 分类:MLPClassifier

其隐藏层规模直接取 channels,训练轮数由 epochs 映射为 max_iter。因此没有 torch 时,程序虽然界面名称仍然叫 TCN,但实际模型已经不再是卷积网络。

5. 评价指标与输出结果解释

5.1 回归指标

回归任务输出 rmsemaer2

$$ \mathrm{RMSE}=\sqrt{\frac{1}{|\mathcal{X}_{\mathrm{te}}|}\sum_i(y_i-\hat{y}_i)^2} \tag{23} $$

$$ \mathrm{MAE}=\frac{1}{|\mathcal{X}_{\mathrm{te}}|}\sum_i|y_i-\hat{y}_i| \tag{24} $$

$$ R^2=1-\frac{\sum_i(y_i-\hat{y}_i)^2}{\sum_i(y_i-\bar{y})^2} \tag{25} $$

5.2 分类指标

分类任务输出 accuracyf1_weighted。其中准确率定义为

$$ \mathrm{Accuracy}=\frac{1}{|\mathcal{X}_{\mathrm{te}}|}\sum_i\mathbf{1}(\hat{y}_i=y_i) \tag{26} $$

加权 F1 可写为

$$ \mathrm{F1}_{\mathrm{weighted}}=\sum_{c=1}^{C}\frac{n_c}{\sum_j n_j}\cdot \mathrm{F1}_c \tag{27} $$

其中 \(n_c\) 为测试集中第 \(c\) 类的样本数。

5.3 输出结果说明

save_to_excel() 导出的 Excel 工作簿包含以下工作表:

  • RawData:原始输入数据;
  • TestPreds:测试集真实值 actual 与预测值 predicted
  • Training_Log:按 epoch 保存的 train_loss
  • Metrics:最终评价指标;
  • Parameters:运行参数与后端信息;
  • WindowedMeta:窗口数量、特征列、class_mapping 等元信息;
  • Charts:已导出图表的磁盘路径。

图像文件会保存在与 Excel 同级的 *_plots/ 目录中,当前实现会输出:

  • loss_curve.png
  • pred_vs_true.png

其中分类任务下的 pred_vs_true.png 画的是编码后的类别整数,而不是原始标签文本。

5.4 自动生成 repro 脚本

结果页在计算完成后会自动生成 repro_*.py 复现脚本。该脚本会:

  1. 优先把原始输入文件复制到 repro_inputs/
  2. 若没有原始路径,则把内存中的 raw_data 导出为 CSV;
  3. 重新读取数据并调用同一个 TCNCalculator.run()
  4. 再次执行 save_to_excel() 生成 *_repro.xlsx

因此,这个复现脚本本质上是“重新调用当前源码”,并不会固化模型权重或训练完成后的网络参数。

6. 实现说明与注意事项

结合 core/tcn_calculator.pyui/upload_widget.pyui/results_widget.py 与实际导出结果,可以把该模块概括为:

  • 一个支持回归/分类的简化 TCN 风格序列模型;
  • 输入来自滑动窗口,目标是未来第 horizon 步单点;
  • 主实现确实使用了因果空洞卷积和残差连接;
  • 但数据标准化发生在全量窗口上,随后又做随机打乱切分,因此存在信息泄漏与时序评估失真;
  • 若缺少 torch,则模型会自动退化成 MLP 后备实现;
  • 导出层较完整,能够输出预测表、训练日志、参数表、元信息表和图表路径。

所以,在撰写论文或实验报告时,更合适的表述应是:该软件实现了一个工程化的 TCN 风格时序预测/分类模块,但其数据切分与归一化流程并非严格的时序预测实验范式。

7. 论文写作模板

7.1 方法描述模板

可在论文“方法部分”中写为:

“本文采用 TCN 风格的时序卷积网络对序列样本进行预测或分类。首先,将按时间顺序排列的原始数据构造成固定长度的滑动窗口监督样本,并对数值特征执行标准化处理;其次,利用因果空洞卷积与残差连接构建时序卷积主干,并以窗口最后一个时间步的隐藏表示作为输出读出;随后,根据任务类型分别采用均方误差损失或交叉熵损失训练模型;最后,在测试样本上输出预测结果与评价指标,用于评估模型的时序建模能力。”

7.2 结果解释模板

结果部分可写为:TCN 借助空洞卷积扩大感受野,在保持卷积并行优势的同时捕捉较长时序依赖。若模型在测试集上的误差指标较优,说明卷积残差结构对当前时序任务具有较好的适配性;若自动生成的复现实验脚本与正文结果一致,则可进一步说明实验可复现。

7.3 表格标题模板

表题可写为:TCN 时序卷积模型预测结果与性能指标汇总表。

7.4 图表题注模板

图注可写为:TCN 模型真实值与预测值对比曲线。

7.5 表格示例

建议列名:时间点、真实值、预测值、残差、RMSE、MAE、\(R^2\) 或分类评价指标。

8. 论文写作建议

论文中建议把该模块表述为“工程化 TCN 风格网络”,并补充说明其数据切分和标准化流程带有工程简化。结果部分建议展示:模型参数表、测试集指标、预测对比图以及训练日志摘要。若环境缺少 torch 而启用了后备 MLP,正文中不能继续写成 TCN 实验。

9. 单篇终审补充

9.1 图题与表题对齐建议

  • RawData 表可写为:表X TCN 原始输入数据表。
  • TestPreds 表可写为:表X TCN 测试集真实值与预测值对照。
  • Training_Log 表可写为:表X TCN 训练过程损失记录。
  • Metrics 表可写为:表X TCN 测试集性能指标汇总。
  • Parameters 表可写为:表X TCN 参数设置与运行后端。
  • WindowedMeta 表可写为:表X TCN 滑动窗口与类别映射元信息。
  • Charts 表可写为:表X TCN 图表索引与路径清单。
  • loss_curve.png 建议写为:图X TCN 训练损失曲线。
  • pred_vs_true.png 建议写为:图X TCN 真实值与预测值对比图。

9.2 终审说明

  • 当前代表性结果目录中的真实主工作簿为 tcn_results_20260313_232310.xlsx,复现输出为 TCN-时序卷积网络_results_20260313_232310_repro.xlsx。论文若附文件名或结果清单,应把主运行与 repro 结果区分开。
  • 当前真实工作表只有 RawData/TestPreds/Training_Log/Metrics/Parameters/WindowedMeta/Charts 这 7 张,不应再虚构 ProcessedDataValidationPreds 或额外注意力权重表。
  • 真实图文件集中在 *_plots/ 目录下,代表性图只有 loss_curve.pngpred_vs_true.png。正文若描述分类任务,还应补充说明分类场景下 pred_vs_true.png 展示的是编码后类别整数,而不是原始标签文本。
  • 真实 repro 脚本为 repro_TCN-时序卷积网络_20260313_232310.py,并通过 INPUT_FILE = 'repro_inputs/tcn_window2_sample.csv' 读取输入副本。附录中的复现实验路径应保持这一相对路径口径。
  • 当前实现在导出层面较完整,但复现实质上是重新调用当前源码重新训练,不是加载已训练权重重跑推理。论文中若写“复现实验”,应避免表述成“模型权重已固化”。

9.3 全量强化补充

本篇终审补充绑定的真实算法目录为 具体的算法3/深度学习与时序网络/TCN-时序卷积网络,本次采用的代表性结果目录为 具体的算法3/深度学习与时序网络/TCN-时序卷积网络/results/TCN-时序卷积网络分析结果_20260313_232310

当前目录中真实存在两份工作簿:

  • tcn_results_20260313_232310.xlsx
  • TCN-时序卷积网络_results_20260313_232310_repro.xlsx

两者实测工作表一致,均包含:

  • RawData
  • TestPreds
  • Training_Log
  • Metrics
  • Parameters
  • WindowedMeta
  • Charts

因此这一轮应把主结果与 repro 输出分开描述,不能写成单一结果文件。

当前目录中的真实图文件为:

  • tcn_results_20260313_232310_plots/loss_curve.png
  • tcn_results_20260313_232310_plots/pred_vs_true.png
  • TCN-时序卷积网络_results_20260313_232310_repro_plots/loss_curve.png
  • TCN-时序卷积网络_results_20260313_232310_repro_plots/pred_vs_true.png

这说明当前磁盘同时保留了主结果图和 repro 图,图型只有训练损失曲线和预测对比图两类。

复现实物方面,该目录实际包含:

  • 具体的算法3/深度学习与时序网络/TCN-时序卷积网络/results/TCN-时序卷积网络分析结果_20260313_232310/repro_TCN-时序卷积网络_20260313_232310.py
  • 具体的算法3/深度学习与时序网络/TCN-时序卷积网络/results/TCN-时序卷积网络分析结果_20260313_232310/repro_inputs/tcn_window2_sample.csv

脚本中明确写成 INPUT_FILE = 'repro_inputs/tcn_window2_sample.csv'OUTPUT_FILE = 'TCN-时序卷积网络_results_20260313_232310_repro.xlsx'。因此这一篇当前已经是目录内相对输入副本复现口径。

10. 软件实现核查补充(2026-07)

  • 当前主结果目录应写作 具体的算法3/深度学习与时序网络/TCN-时序卷积网络/results/TCN-时序卷积网络分析结果_20260313_232310
  • 正文应围绕 RawDataProcessedDataTestPredsTraining_LogMetricsParametersWindowedMetaCharts 来写。
  • 图证应对应 loss_curve.pngpred_vs_true.png,并把主结果和 repro 输出区分开。
  • 复现脚本应按 repro_TCN-时序卷积网络_20260313_232310.py + repro_inputs/tcn_window2_sample.csv 的口径说明。