TCN-时序卷积网络
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} $$
若给定的 dilations 比 channels 短,代码会直接用最后一个空洞率补齐剩余层,因此真实空洞率序列不一定是论文里常见的严格指数增长。
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 回归指标
回归任务输出 rmse、mae 和 r2:
$$ \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 分类指标
分类任务输出 accuracy 与 f1_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.pngpred_vs_true.png
其中分类任务下的 pred_vs_true.png 画的是编码后的类别整数,而不是原始标签文本。
5.4 自动生成 repro 脚本
结果页在计算完成后会自动生成 repro_*.py 复现脚本。该脚本会:
- 优先把原始输入文件复制到
repro_inputs/; - 若没有原始路径,则把内存中的
raw_data导出为 CSV; - 重新读取数据并调用同一个
TCNCalculator.run(); - 再次执行
save_to_excel()生成*_repro.xlsx。
因此,这个复现脚本本质上是“重新调用当前源码”,并不会固化模型权重或训练完成后的网络参数。
6. 实现说明与注意事项
结合 core/tcn_calculator.py、ui/upload_widget.py、ui/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 张,不应再虚构ProcessedData、ValidationPreds或额外注意力权重表。 - 真实图文件集中在
*_plots/目录下,代表性图只有loss_curve.png和pred_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.xlsxTCN-时序卷积网络_results_20260313_232310_repro.xlsx
两者实测工作表一致,均包含:
RawDataTestPredsTraining_LogMetricsParametersWindowedMetaCharts
因此这一轮应把主结果与 repro 输出分开描述,不能写成单一结果文件。
当前目录中的真实图文件为:
tcn_results_20260313_232310_plots/loss_curve.pngtcn_results_20260313_232310_plots/pred_vs_true.pngTCN-时序卷积网络_results_20260313_232310_repro_plots/loss_curve.pngTCN-时序卷积网络_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。 - 正文应围绕
RawData、ProcessedData、TestPreds、Training_Log、Metrics、Parameters、WindowedMeta、Charts来写。 - 图证应对应
loss_curve.png与pred_vs_true.png,并把主结果和 repro 输出区分开。 - 复现脚本应按
repro_TCN-时序卷积网络_20260313_232310.py + repro_inputs/tcn_window2_sample.csv的口径说明。