正在加载中...

展开本页目录
算法教程GRU-门控循环单元

GRU-门控循环单元

No.152 · 在线教程

GRU-门控循环单元 模块在当前项目中的真实实现,是一个基于 TensorFlow/Keras 的 sequence-to-one 时序建模组件,支持回归与分类两类任务。系统不单独读取时间列,而是默认数据已经按时间顺序排好;随后通过滑动窗口把“连续 L 个时间步特征”映射为“未…

GRU-门控循环单元

1. 方法概述

GRU-门控循环单元 模块在当前项目中的真实实现,是一个基于 TensorFlow/Keras 的 sequence-to-one 时序建模组件,支持回归分类两类任务。系统不单独读取时间列,而是默认数据已经按时间顺序排好;随后通过滑动窗口把“连续 \(L\) 个时间步特征”映射为“未来第 \(H\) 步目标”,再训练单层或多层 GRU 网络,并可选双向结构。

设预先按时间顺序整理后的样本为

$$ \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\) 为目标变量。回归任务中 \(\mathcal{Y}\subseteq\mathbb{R}\),分类任务中 \(\mathcal{Y}\) 为有限类别集合。

2. 数据预处理与滑动窗口

2.1 特征列筛选与目标编码

程序要求先指定目标列 target_column。若用户未手动指定特征列,则默认将除目标列外的所有列都视为候选特征。对特征矩阵,代码会逐列执行数值化转换;若某列转换后全为空,则记入 dropped_feature_columns 并直接删除;若仍存在部分非数值或缺失值,则立即报错。

分类任务中,目标标签会通过编码函数映射为整数类别:

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

其中 \(C\ge 2\) 为类别数。回归任务中,目标列会尝试转成数值;若个别值转换失败,当前实现会用该列均值填补,而不是直接报错。

2.2 序列窗口构造

设窗口长度为 \(L\),预测步长为 \(H\),滑动步长为 \(s\)。对每个可用起点 \(i\),构造输入序列

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

其中 \(d'\) 为保留下来的数值特征维度。对应监督目标为

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

代码要求

$$ L\ge 2,\qquad H\ge 1,\qquad s\ge 1 \tag{5} $$

若清洗后的有效样本数为 \(N'\),则可构造的窗口样本数为

$$ M=\left\lfloor\frac{N'-L-H}{s}\right\rfloor+1 \tag{6} $$

当 \(M<3\) 时,程序会直接终止,因为它至少要求训练、验证、测试三个子集各保留 1 个样本。

2.3 按时间顺序切分训练集、验证集与测试集

设训练比例与验证比例分别为 \(r_{\mathrm{tr}}\) 和 \(r_{\mathrm{va}}\)。当前实现不会随机打乱窗口,而是先按时间顺序排列,再近似切分为

$$ n_{\mathrm{tr}}\approx Mr_{\mathrm{tr}},\qquad n_{\mathrm{va}}\approx Mr_{\mathrm{va}},\qquad n_{\mathrm{te}}=M-n_{\mathrm{tr}}-n_{\mathrm{va}} \tag{7} $$

代码进一步做边界修正,保证

$$ n_{\mathrm{tr}}\ge 1,\qquad n_{\mathrm{va}}\ge 1,\qquad n_{\mathrm{te}}\ge 1 \tag{8} $$

若用户输入的 train_ratioval_ratio 非法,例如 train_ratio + val_ratio >= 1,程序会回退到默认的 0.7 / 0.15。因此该模块本质上是按窗口时间顺序切分的 sequence-to-one 预测器

2.4 窗口缩放

特征缩放器仅在训练集上拟合,但它不是按“原始特征列”逐列拟合,而是先把每个窗口展平成向量:

$$ \mathrm{vec}(\mathbf{X}_i)\in\mathbb{R}^{Ld'} \tag{9} $$

再执行 standardminmaxnone 缩放。因此,严格来说,模型是对“窗口中每个时间位置的每个特征坐标”分别做缩放。若以标准化为例,可写为

$$ \mathrm{vec}(\mathbf{X}_i)^{\ast}=\frac{\mathrm{vec}(\mathbf{X}_i)-\boldsymbol{\mu}_x}{\boldsymbol{\sigma}_x} \tag{10} $$

回归任务下,目标值还可选择做 standardminmax 缩放:

$$ z_i^{\ast}=\mathcal{S}_y(z_i) \tag{11} $$

最终评价阶段会将回归预测值逆变换回原始量纲后再计算误差。

3. GRU 网络结构

3.1 单个 GRU 单元

对序列中的第 \(t\) 个时间步,当前实现遵循标准 GRU 门控形式:

$$ z_t=\sigma(W_z x_t+U_z h_{t-1}+b_z) \tag{12} $$

$$ r_t=\sigma(W_r x_t+U_r h_{t-1}+b_r) \tag{13} $$

$$ \tilde h_t=\tanh(W_h x_t+U_h(r_t\odot h_{t-1})+b_h) \tag{14} $$

$$ h_t=(1-z_t)\odot h_{t-1}+z_t\odot \tilde h_t \tag{15} $$

其中 \(z_t\) 为更新门,\(r_t\) 为重置门,\(h_t\) 为当前隐藏状态。

3.2 多层堆叠与双向结构

若设置 layers=K,则程序串联 \(K\) 层 GRU。前 \(K-1\) 层使用 return_sequences=True,最后一层只输出最终时刻表示。第 \(\ell\) 层可抽象写为

$$ H^{(\ell)}=\mathrm{GRU}^{(\ell)}\!\left(H^{(\ell-1)}\right),\qquad \ell=1,2,\ldots,K \tag{16} $$

其中 \(H^{(0)}=\mathbf{X}_i\)。若勾选 bidirectional=True,则每层 GRU 会被包装成双向结构,最后输出为

$$ h_t^{\mathrm{bi}}= \begin{bmatrix} \overrightarrow{h}_t\\ \overleftarrow{h}_t \end{bmatrix} \tag{17} $$

3.3 输出层

回归任务使用线性输出层:

$$ \hat z_i=w^\top h_i+b \tag{18} $$

分类任务无论是二分类还是多分类,当前代码都统一采用 Dense(C, activation="softmax"),即

$$ P(y_i=c\mid \mathbf{X}_i)=\frac{\exp(o_{i,c})}{\sum_{k=1}^{C}\exp(o_{i,k})} \tag{19} $$

这意味着二分类任务这里也不是 Sigmoid 单输出,而是 2 类 Softmax 实现。

4. 训练目标与优化

回归任务的损失函数为均方误差:

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

分类任务的损失函数为稀疏交叉熵:

$$ \mathcal{L}_{\mathrm{cls}}=-\frac{1}{n_{\mathrm{tr}}}\sum_{i=1}^{n_{\mathrm{tr}}}\ln P(y_i=z_i\mid \mathbf{X}_i) \tag{21} $$

模型使用 Adam 优化器,学习率由 learning_rate 给定;若 early_stopping_patience>0,则会对验证集 val_loss 进行 EarlyStopping,并启用 restore_best_weights=True 恢复最佳参数。

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

5.1 回归指标

回归任务输出 MSEMAERMSER2。其定义分别为

$$ \mathrm{MSE}=\frac{1}{n_{\mathrm{te}}}\sum_{i=1}^{n_{\mathrm{te}}}(y_i-\hat y_i)^2 \tag{22} $$

$$ \mathrm{MAE}=\frac{1}{n_{\mathrm{te}}}\sum_{i=1}^{n_{\mathrm{te}}}|y_i-\hat y_i| \tag{23} $$

$$ \mathrm{RMSE}=\sqrt{\mathrm{MSE}} \tag{24} $$

$$ R^2=1-\frac{\sum_{i=1}^{n_{\mathrm{te}}}(y_i-\hat y_i)^2}{\sum_{i=1}^{n_{\mathrm{te}}}(y_i-\bar y)^2} \tag{25} $$

5.2 分类指标

分类任务输出 AccuracyPrecision_macroRecall_macroF1_macro。准确率定义为

$$ \mathrm{Accuracy}=\frac{1}{n_{\mathrm{te}}}\sum_{i=1}^{n_{\mathrm{te}}}\mathbf{1}(\hat y_i=y_i) \tag{26} $$

sklearn.metrics 可用,宏平均精确率、召回率和 F1 会按标准方式计算;否则代码会退化为仅正确计算准确率,其余三项记为 0。

5.3 输出结果说明

当前模块导出的 Excel 工作表包括:

  • Parameters:参数字典;
  • Processed_Info:任务类型、目标列、特征列、输入形状、训练/验证/测试样本数;
  • Data_Head:原始数据前 10 行预览;
  • Data_Windowing:前 10 个滑窗样本对应的 window_start_rowtarget_row_index
  • Training_Log:逐 epoch 的 lossmaeval_lossval_mae 等;
  • Metrics:测试集评价指标;
  • Predictions:测试集预测结果;
  • Model_Summary:Keras 网络结构摘要;
  • Chart_Index:预期图表路径索引。

其中,回归任务的 Predictions 至少包含 row_indexy_truey_prederror;分类任务则输出整数类别,并在可用时附加 y_true_labely_pred_label。图表方面,代码会尝试生成:

  • training_curve.png:训练曲线;
  • pred_vs_truth.png:预测对比图;
  • error_hist.png:误差直方图,仅回归任务稳定存在。

需要注意,Chart_Index 工作表会先写入这 3 个图表的相对路径,即使某些图在当前任务下并未真正生成。

6. 算法流程

按照当前项目实现,GRU-门控循环单元 的计算流程如下:

  1. 读取 Excel/CSV/TXT 数据,并由用户选择任务类型、目标列和特征列;
  2. 对特征列执行严格数值检查,分类目标做标签编码,回归目标转数值;
  3. sequence_lengthhorizonstride 构造 sequence-to-one 滑动窗口;
  4. 按时间顺序切分训练集、验证集与测试集,并保证三个子集都非空;
  5. 在训练集上拟合特征缩放器;回归任务可同步拟合目标缩放器;
  6. 构建单层或多层 GRU 网络,并按需启用双向结构;
  7. 采用 Adam 优化器训练模型,并基于验证集 val_loss 可选早停;
  8. 在测试集上输出回归或分类预测结果与评价指标;
  9. 自动导出 Excel、多张图表与 repro_*.py 复现脚本。

7. 关键参数说明

表 1 关键参数及含义

参数 含义 当前默认值
task 任务类型 regression
target_column 目标列 用户指定
feature_columns 特征列列表 默认目标列外全选
sequence_length 滑窗长度 \(L\) 12
horizon 预测步长 \(H\) 1
stride 滑窗步长 1
train_ratio 训练集比例 0.70
val_ratio 验证集比例 0.15
feature_scaler 特征缩放方式 standard
target_scaler 回归目标缩放方式 standard
layers GRU 层数 1
hidden_size 隐藏单元数 64
bidirectional 是否启用双向 GRU False
dropout GRU 层内部 dropout 0.0
epochs 最大训练轮数 50
batch_size 批大小 32
learning_rate 学习率 \(10^{-3}\)
early_stopping_patience 早停容忍轮数 10
random_state 随机种子 42

8. 论文写作模板

8.1 方法描述模板

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

“本文采用基于门控循环单元(GRU)的时序建模方法对目标变量进行预测。首先,将按时间顺序排列的样本数据构造为长度为 \(L\) 的输入序列窗口,并将第 \(H\) 个未来时间步的目标值作为监督信号;其次,对输入窗口执行训练集统计量下的缩放处理,并构建由单层或多层 GRU 组成的神经网络,在需要时进一步采用双向结构增强时序表示能力;随后,针对回归任务使用均方误差损失,针对分类任务使用稀疏交叉熵损失,并通过 Adam 优化器完成参数学习;最后,在测试集上输出点预测结果与评价指标,从而评价模型对时序动态模式的刻画能力。”

8.2 结果解释模板

结果部分可写为:GRU 在较少门控参数下实现了对时序依赖的有效建模。若其性能接近或优于更复杂模型,可说明当前任务中较轻量的循环结构已经足以捕捉主要动态特征;若分类与回归任务表现差异较大,则需结合目标属性进一步解释。

8.3 表格标题模板

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

8.4 图表题注模板

图注可写为:GRU 模型真实值与预测值对比曲线或分类结果可视化图。

8.5 表格示例

建议列名:时间点、真实值、预测值、残差、RMSE、MAE、\(R^2\) 或 Accuracy、F1。

9. 实现说明与注意事项

  • 该模块适用于行顺序已经按时间排列好的数据;它没有单独的时间列排序逻辑,因此原始数据若乱序,必须先在外部排好。
  • 当前实现既支持回归也支持分类,论文写作时应根据实际任务选择对应的损失函数、输出层与评价指标,不能直接套用单一 GRU 回归模板。
  • 分类任务统一使用 Softmax 输出,即使是二分类也不是 Sigmoid 单输出,这一点应与真实代码保持一致。
  • 训练依赖 tensorflow;分类还依赖 scikit-learn 中的 LabelEncoder。当前模块没有像某些其他算法那样提供 sklearn 或轻量模式后备训练路径。
  • 特征缩放是在展平后的窗口向量上进行的,而非简单按原始特征列逐列缩放;如果论文需要严格复现实验,应按该实现描述或在复现实验中保持一致。
  • Data_Head 只保存前 10 行原始数据预览,不是全量原表;row_indextarget_row_index 对应的是清洗后数据中的行位置。
  • 回归目标列若存在少量无法数值化的值,当前代码会用均值填补;这属于工程性容错,而不是严格统计建模中的标准预处理流程,正式实验前最好先在源数据层面清洗干净。

10. 论文写作建议

论文中建议把该模块写成“基于 GRU 的滑动窗口时序建模方法”,并明确分类与回归的不同输出层和损失函数。结果部分可重点展示测试集指标、预测结果图和参数设置表。若需要严格复现,方法部分最好补充“窗口展平后再缩放”的实现细节。

11. 单篇终审补充

11.1 图题与表题对齐建议

  • Parameters 表可写为:表X GRU 模型参数设置。
  • Processed_Info 表可写为:表X GRU 数据清洗与缩放信息。
  • Data_Head 表可写为:表X 原始数据前 10 行预览。
  • Data_Windowing 表可写为:表X GRU 滑动窗口构造结果。
  • Training_Log 表可写为:表X GRU 训练过程记录。
  • Metrics 表可写为:表X GRU 测试集性能指标汇总。
  • Predictions 表可写为:表X GRU 测试样本真实值与预测值对照。
  • Model_Summary 表可写为:表X GRU 网络结构摘要。
  • Chart_Index 表可写为:表X GRU 图表索引与路径清单。
  • training_curve.png 建议写为:图X GRU 训练与验证损失曲线。
  • pred_vs_truth.png 建议写为:图X GRU 真实值与预测值对比图。
  • error_hist.png 建议写为:图X GRU 预测误差分布图。

11.2 终审说明

  • 当前代表性结果目录采用 baseline_export/repro_runtime/ 双层结构,真实主工作簿分别是 baseline_export/GRU_results.xlsxrepro_runtime/GRU_results.xlsx。论文若引用结果目录,应明确区分“基线导出”和“复现运行导出”。
  • 真实工作表名称以 Processed_InfoData_HeadData_WindowingModel_SummaryChart_Index 为准,不应擅自替换为其他 RNN 算法常见的 ProcessedDataTraining_HistoryCharts
  • 当前图表实体文件位于 charts/ 子目录下,主要包括 training_curve.pngpred_vs_truth.pngerror_hist.png。其中 error_hist.png 更适合回归任务,若是分类任务,正文中应避免把它写成必然存在的通用图。
  • Data_Head 只保存数据预览而非全量原表,这一点应在论文附录说明中写清楚;完整复现实验输入应以 repro_runtime/repro_inputs/window1_rnn_input.csv 为准。
  • 真实 repro 脚本位于 repro_runtime/repro_GRU_门控循环单元_*.py,并通过 INPUT_FILE = 'repro_inputs/window1_rnn_input.csv' 读取相对路径输入。若正文或附录给出复现实验步骤,应直接沿用该口径。

11.3 全量强化补充

本篇终审补充绑定的真实算法目录为 具体的算法3/深度学习与时序网络/GRU-门控循环单元,本次采用的代表性结果目录为 具体的算法3/深度学习与时序网络/GRU-门控循环单元/results/GRU-门控循环单元分析结果_20260320_004039_enhanced

该目录明确拆成两层:

  • baseline_export/
  • repro_runtime/

其中 baseline 主结果工作簿为:

  • baseline_export/GRU_results.xlsx

repro 运行结果工作簿为:

  • repro_runtime/GRU_results.xlsx

因此这一篇应明确区分“基线导出目录”和“repro 运行目录”,不能写成单目录单文件结构。

当前目录中的真实图文件也分两套:

  • baseline_export/charts/training_curve.png
  • baseline_export/charts/pred_vs_truth.png
  • baseline_export/charts/error_hist.png
  • repro_runtime/charts/training_curve.png
  • repro_runtime/charts/pred_vs_truth.png
  • repro_runtime/charts/error_hist.png

这说明当前磁盘同时保留了基线图与 repro 图,两套图型一致。

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

  • 具体的算法3/深度学习与时序网络/GRU-门控循环单元/results/GRU-门控循环单元分析结果_20260320_004039_enhanced/repro_runtime/repro_GRU_门控循环单元_20260320_004041.py
  • 具体的算法3/深度学习与时序网络/GRU-门控循环单元/results/GRU-门控循环单元分析结果_20260320_004039_enhanced/repro_runtime/repro_inputs/window1_rnn_input.csv

这里需要按真实文件名说明:当前 repro 脚本时间戳是 004041,而不是主目录名中的 004039。因此文档里不应把脚本名写死成与目录时间戳完全相同。可复现性口径应写成“repro_runtime/ 目录内带相对输入副本的重跑脚本”。

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

  • 当前主结果目录应写作 具体的算法3/深度学习与时序网络/GRU-门控循环单元/results/GRU-门控循环单元分析结果_20260320_004039_enhanced
  • 正文应围绕 原始数据处理后数据模型指标训练历史预测结果参数图表索引 来写。
  • 图证应对应 training_curve.pngpred_vs_truth.pngerror_hist.png,并把基线导出与 repro 运行区分开。
  • 复现脚本应按 repro_GRU_门控循环单元_20260320_004041.py + repro_inputs/window1_rnn_input.csv 的口径说明。