zhanghao 884ead9507 新增预测逻辑,避免nan преди 5 месеца
..
20min_predict.py 884ead9507 新增预测逻辑,避免nan преди 5 месеца
README.md 574c973f3b 1:项目结构修正 преди 5 месеца
args.py 574a5d969b 修正命名 преди 5 месеца
data_export.py 574a5d969b 修正命名 преди 5 месеца
data_preprocessor.py 574a5d969b 修正命名 преди 5 месеца
data_trainer.py 574a5d969b 修正命名 преди 5 месеца
edge_index.pt 574a5d969b 修正命名 преди 5 месеца
gat_lstm.py 574a5d969b 修正命名 преди 5 месеца
main.py 574a5d969b 修正命名 преди 5 месеца
model.pth 574a5d969b 修正命名 преди 5 месеца
scaler.pkl 574a5d969b 修正命名 преди 5 месеца

README.md

20分钟TMP预测模型训练逻辑说明

模型概述

这是一个用于预测超滤(UF)和反渗透(RO)系统未来20分钟压力和流量变化的时间序列预测模型。

预测目标:16个关键指标

  • 4个UF跨膜压差(TMP):C.M.UF1-4_DB@press_PV
  • 8个RO压力差:C.M.RO1-4_DB@DPT_1C.M.RO1-4_DB@DPT_2
  • 4个RO浓水流量:RO1-4_CSFlow

核心思路

1. 模型架构:16个"专家"并行工作

想象有16个专家,每个专家只负责预测一个指标。虽然他们看到的输入数据相同(79个传感器数据),但各自独立学习预测自己负责的那一个指标。

输入(79个特征) → [专家1预测UF1压力]
                 → [专家2预测UF2压力]
                 → ...
                 → [专家16预测RO4流量]

为什么这样设计?

  • 每个指标的变化规律可能不同,独立建模更精准
  • 但它们共享输入特征,仍能捕捉系统的整体状态

2. 时间窗口:用过去预测未来

输入窗口:过去60个时间点(4小时历史数据,每4分钟一个点) 输出窗口:未来5个时间点(20分钟,每4分钟预测一次)

历史:t-60 → t-59 → ... → t-1 → t
                              ↓
                        [LSTM处理]
                              ↓
未来:      t+1 → t+2 → t+3 → t+4 → t+5

3. 网络结构:LSTM捕捉时间依赖

每个"专家"内部使用LSTM(长短期记忆网络):

LSTM层(64隐藏单元) → 取最后时刻状态 → 全连接层 → 输出5步预测

LSTM的作用

  • 记住长期趋势(比如压力缓慢上升)
  • 捕捉短期波动(比如突然的流量变化)
  • 自动提取时间序列中的重要模式

训练流程详解

步骤1:数据预处理(data_preprocessor.py

1.1 数据读取和采样

# 多线程读取51个CSV文件,提速明显
read_and_combine_csv_files()
  • 原始数据每4秒一条,采样后每4分钟一条(resolution=60
  • 这样做减少数据量,同时保留关键变化趋势

1.2 时间特征编码

# 把时间转成周期性特征
minute_sin = sin(2π × 分钟数 / 1440)  # 一天的周期
day_sin = sin(2π × 天数 / 366)        # 一年的周期

为什么这样做?

  • 模型能理解"早上8点"和"第二天早上8点"是类似的时刻
  • 能捕捉季节性变化(比如夏天和冬天的水质差异)

1.3 归一化

# 把所有数据缩放到0-1之间
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(data)
joblib.dump(scaler, 'scaler.pkl')  # 保存归一化器供预测时使用

作用:让不同量级的特征(压力0.03MPa vs 流量360m³/h)在训练时权重平衡

1.4 构建监督学习样本

# 滑动窗口生成样本
输入:t-60到t的所有特征(60×79=4740维)
输出:t+1到t+5的16个目标(5×16=80维)

步骤2:模型初始化(gat_lstm.py

单个专家模型结构

class SingleGATLSTM:
    def __init__(self):
        # LSTM层:处理时间序列
        self.lstm = nn.LSTM(input_size=79, hidden_size=64, num_layers=1)
        
        # 输出层:LSTM输出 → 5步预测
        self.final_linear = nn.Sequential(
            nn.Linear(64, 64),       # 第一层全连接
            nn.LeakyReLU(0.01),     # 激活函数
            nn.Dropout(0),          # Dropout防止过拟合(这里设为0)
            nn.Linear(64, 5)        # 输出5个时间步
        )

16个专家组合

class GAT_LSTM:
    def __init__(self):
        # 创建16个独立的专家
        self.models = nn.ModuleList([SingleGATLSTM() for _ in range(16)])
    
    def forward(self, x):
        # 每个专家独立预测
        outputs = [model(x) for model in self.models]
        # 拼接结果:[batch, 5] × 16 → [batch, 80]
        return torch.cat(outputs, dim=1)

步骤3:联合训练(data_trainer.py

训练循环

for epoch in range(max_epochs):
    for inputs, targets in train_loader:
        # 1. 前向传播:所有16个专家并行预测
        outputs = model(inputs)  # [batch, 80]
        
        # 2. 计算整体损失:MSE(均方误差)
        loss = MSELoss(outputs, targets)
        
        # 3. 反向传播:更新所有16个专家的参数
        loss.backward()
        optimizer.step()

关键设计

  • 虽然有16个专家,但用一个损失函数联合优化
  • 好处:专家之间能通过共享梯度信息"互相学习"

早停机制

# 如果验证集损失连续500轮不下降,提前停止
if val_loss没有改善 > patience(500轮):
    停止训练,加载最优模型权重

防止过拟合,保存泛化能力最强的模型

学习率调度

# 每100轮学习率乘以0.9
scheduler = StepLR(step_size=100, gamma=0.9)

训练后期降低学习率,让模型更稳定地收敛

训练参数说明

参数 说明
seq_len 60 输入历史长度(4小时)
output_size 5 预测未来步数(20分钟)
feature_num 79 输入特征数
labels_num 16 预测目标数
hidden_size 64 LSTM隐藏层大小
batch_size 1024 每批训练样本数
lr 0.01 初始学习率
epochs 1000 最大训练轮数
patience 500 早停耐心值

预测流程(predict.py

实时预测步骤

  1. 加载最新数据:读取最近4小时的传感器数据
  2. 预处理
    • 按分辨率下采样(每4分钟一个点)
    • 时间特征编码(正弦/余弦)
    • 归一化(使用训练时保存的scaler)
  3. 模型推理

    model.eval()  # 切换到评估模式
    with torch.no_grad():  # 不计算梯度
       predictions = model(inputs)
    
  4. 反归一化:将0-1范围的预测值还原到真实物理量

  5. 可选后处理

    • 异常值检测(四分位法)
    • 平滑处理(加权平均)

模型性能评估

训练完成后,在测试集上计算:

  • R²(决定系数):越接近1越好,表示预测值与真实值的拟合程度
  • RMSE(均方根误差):越小越好,单位与目标变量相同
  • MAPE(平均绝对百分比误差):越小越好,百分比形式更直观

文件结构说明

20分钟TMP预测模型源码/
├── args.py              # 参数配置(数据集日期、模型超参数)
├── data_preprocessor.py # 数据预处理(读取、归一化、构建样本)
├── gat_lstm.py          # 模型定义(16个专家模型架构)
├── data_trainer.py      # 训练器(训练循环、早停、评估)
├── main.py              # 训练入口(整合所有流程)
├── predict.py           # 预测接口(加载模型、实时推理)
├── model.pth            # 训练好的模型权重
├── scaler.pkl           # 归一化器(保证预测时数据处理一致)
└── edge_index.pt        # 图结构索引(如果使用GAT则需要)

使用建议

训练新模型

python main.py

会自动完成:数据加载 → 预处理 → 训练 → 验证 → 测试 → 保存模型

使用模型预测

from predict import Predictor

predictor = Predictor()
predictions = predictor.predict(df)  # df是最新的传感器数据
predictor.save_predictions(predictions)

调参建议

  1. 数据量不足时

    • 减小 hidden_size(比如32)
    • 增大 dropout(比如0.2)
    • 减少 epochs
  2. 预测效果不好时

    • 检查数据质量(异常值、缺失值)
    • 增加 seq_len(更长历史窗口)
    • 调整 resolution(尝试不同采样率)
  3. 训练太慢时

    • 减小 batch_size
    • 减少数据文件范围(start_files - end_files
    • 使用GPU(自动检测)

常见问题

Q:为什么用16个独立模型而不是一个大模型?
A:每个指标的变化模式不同,独立建模能让每个专家专注于自己的任务,预测更准确。

Q:为什么输入79个特征,只预测16个?
A:79个特征包含系统的全面信息(流量、压力、温度、化学指标等),但我们只关心16个关键指标的未来变化。

Q:如何判断模型训练好了?
A:看验证集R²是否>0.9,MAPE是否<5%,以及预测曲线是否与真实值吻合。

Q:模型能预测多远?
A:设计是20分钟,时间越远精度越低。如果需要更长预测(比如1小时),建议增加output_size并调整模型结构。