wmy 574c973f3b 1:项目结构修正 9 meses atrás
..
README.md 574c973f3b 1:项目结构修正 9 meses atrás
args.py 574a5d969b 修正命名 10 meses atrás
data_export.py 574a5d969b 修正命名 10 meses atrás
data_preprocessor.py 574a5d969b 修正命名 10 meses atrás
data_trainer.py 574a5d969b 修正命名 10 meses atrás
edge_index.pt 574a5d969b 修正命名 10 meses atrás
gat_lstm.py 574a5d969b 修正命名 10 meses atrás
main.py 574a5d969b 修正命名 10 meses atrás
model.pth 574a5d969b 修正命名 10 meses atrás
predict.py 574a5d969b 修正命名 10 meses atrás
scaler.pkl 574a5d969b 修正命名 10 meses atrás

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并调整模型结构。