junc_WHU f989f54839 feat:1. 重新训练了锡山与龙亭的模型 2.优化了膜阻力相关的奖励计算,更新了兰考和安镇的模型 3 周之前
..
dqn_model d86a3e990d feat:增加了数据处理与物理模型中吨水电耗与药耗的计算逻辑 4 周之前
uf_decide d86a3e990d feat:增加了数据处理与物理模型中吨水电耗与药耗的计算逻辑 4 周之前
uf_train f989f54839 feat:1. 重新训练了锡山与龙亭的模型 2.优化了膜阻力相关的奖励计算,更新了兰考和安镇的模型 3 周之前
README.md 1680beca39 拆分模型训练/调用文件夹 1 月之前
UF_RL_架构问题与优化方案.md 1680beca39 拆分模型训练/调用文件夹 1 月之前
UF_RL_训练与预测流程详解.md 1680beca39 拆分模型训练/调用文件夹 1 月之前
UF_RL_详细技术文档.md 1680beca39 拆分模型训练/调用文件夹 1 月之前
__init__.py 1680beca39 拆分模型训练/调用文件夹 1 月之前

README.md

UF超滤系统强化学习决策模型训练逻辑说明

模型概述

这是一个基于深度强化学习(DQN)的超滤系统运行参数优化模型。不同于前两个"预测模型",这个模型的目标是决策:在给定当前跨膜压差(TMP)的情况下,自动决定最优的产水时长和反洗时长。

核心问题:如何平衡产水量、回收率、能耗和膜寿命?

问题背景

超滤运行周期

超滤系统运行遵循"小周期"模式:

[产水L秒] → [反洗t_bw秒] → [产水L秒] → [反洗t_bw秒] → ... → [化学清洗CEB]
  • 产水阶段:过滤原水,TMP逐渐升高(膜污染)
  • 反洗阶段:反向冲洗,TMP部分恢复
  • 化学清洗(CEB):每48小时一次,TMP完全恢复

决策难题

调节杠杆

  • L_s:单次产水时长(3600-6000秒)
  • t_bw_s:单次反洗时长(40-60秒)

矛盾目标

  1. 产水量↑:希望L_s长、t_bw_s短(多产水、少反洗)
  2. 回收率↑:希望t_bw_s短(减少反洗水耗)
  3. 膜保护↓:希望L_s短、t_bw_s长(频繁反洗、TMP不升太高)
  4. 能耗↓:产水时间越长,单位吨水的泵能耗越低

传统方法:人工经验+固定参数,难以在复杂约束下找到最优解
强化学习方法:让AI自己探索,学习在不同TMP下的最佳决策

核心思路:强化学习框架

1. 强化学习是什么?

把决策问题想象成玩游戏:

游戏状态(TMP)→ AI选择动作(L_s, t_bw_s)→ 执行动作 → 获得奖励(回收率、净供水率)→ 新状态(TMP更新)

AI通过反复试错,学习哪些动作能获得高奖励。

2. Markov决策过程(MDP)建模

状态(State)

state = [
    TMP0_normalized,           # 当前初始TMP(归一化到0-1)
    last_L_s_normalized,       # 上一次产水时长(归一化)
    last_t_bw_s_normalized,    # 上一次反洗时长(归一化)
    max_TMP_normalized         # 本周期最高TMP(归一化)
]

4维状态向量描述当前系统状态

动作(Action)

# 离散动作空间:L_s × t_bw_s的网格
L_s范围:3800-6000秒,步长60秒 → 37个选项
t_bw_s范围:40-60秒,步长5秒 → 5个选项

总动作数 = 37 × 5 = 185个

每个动作对应一个(L_s, t_bw_s)组合

奖励(Reward)

# 多目标加权奖励
reward = 0.8 × recovery           # 回收率(主要目标)
       + 0.2 × rate_normalized    # 净供水率
       - 0.2 × headroom_penalty   # TMP贴边惩罚

奖励设计原则

  • 高回收率 → 高奖励
  • 高净供水率 → 高奖励
  • TMP接近上限 → 负奖励(膜风险)
  • 违反约束 → 大负奖励(-20)

状态转移

# 模拟器:根据物理模型计算下一个状态
def simulate_one_supercycle(TMP0, L_s, t_bw_s):
    # 1. 计算产水阶段TMP上升
    delta_TMP = model_fp(L_s)  # 调用TMP增长模型
    TMP_peak = TMP0 + delta_TMP
    
    # 2. 计算反洗恢复
    phi = model_bw(L_s, t_bw_s)  # 调用反洗恢复模型
    TMP_after_bw = TMP_peak - phi × (TMP_peak - TMP0)
    
    # 3. 多次小周期后CEB
    TMP_new = TMP0  # 化学清洗后完全恢复
    
    # 4. 计算指标
    recovery = (产水 - 反洗水耗 - CEB水耗) / 产水
    net_rate = 净产水 / 总时间
    
    return TMP_new, recovery, net_rate, ...

DQN算法详解

什么是DQN?

Deep Q-Network(深度Q网络)

  • 用神经网络估计Q值函数Q(state, action) = 预期累积奖励
  • 最优策略:在每个状态选择Q值最大的动作

    状态 → [神经网络] → 每个动作的Q值 → 选择最大Q值的动作
    

神经网络结构

# Stable-Baselines3的MlpPolicy默认结构
输入层:4维状态
隐藏层1:64神经元 + ReLU
隐藏层2:64神经元 + ReLU
输出层:185个动作的Q值

训练流程(DQN_train.py

1. 经验回放(Experience Replay)

buffer_size = 10000  # 存储10000条经验

# 交互过程
for step in range(total_timesteps):
    action = model.select_action(state)        # ε-贪心选择动作
    next_state, reward = env.step(action)      # 执行动作
    buffer.store(state, action, reward, next_state)  # 存入缓冲区
    
    # 从缓冲区随机采样训练
    if step > learning_starts:
        batch = buffer.sample(batch_size=32)
        model.train_on_batch(batch)

为什么需要经验回放?

  • 打破数据相关性(连续状态往往相似)
  • 提高样本利用效率(同一条经验可多次使用)

2. ε-贪心探索

# 随机探索 vs 利用已学知识
if random() < epsilon:
    action = random_action()   # 探索:随机选
else:
    action = argmax(Q(state))  # 利用:选Q值最大的

# epsilon从1.0衰减到0.02
epsilon = 1.0 → 0.8 → ... → 0.02

探索-利用权衡

  • 初期多探索(发现好动作)
  • 后期多利用(稳定在最优策略)

3. 目标网络(Target Network)

# 两个网络:当前网络 + 目标网络
Q_current(state, action)  # 每步更新
Q_target(next_state, a')   # 每2000步同步一次

# TD误差
loss = MSE(Q_current(s,a), reward + γ × max(Q_target(s', a')))

为什么需要目标网络?

  • 稳定训练(避免"追逐移动目标"问题)
  • 减少Q值估计的震荡

4. 训练超参数

class DQNParams:
    learning_rate = 1e-4          # 学习率
    buffer_size = 10000           # 经验池大小
    learning_starts = 200         # 200步后开始学习
    batch_size = 32               # 每次训练32个样本
    gamma = 0.95                  # 折扣因子(重视长期奖励)
    train_freq = 4                # 每4步训练一次
    target_update_interval = 2000 # 每2000步更新目标网络
    exploration_fraction = 0.3    # 前30%训练时间用于探索
    exploration_final_eps = 0.02  # 最终保留2%探索

模拟环境(DQN_env.py

UFSuperCycleEnv类

class UFSuperCycleEnv(gym.Env):
    def reset(self):
        # 重置环境:随机初始TMP
        self.TMP0 = random.uniform(0.01, 0.03)
        return self._get_obs()
    
    def step(self, action):
        # 执行动作
        L_s, t_bw_s = self._decode_action(action)
        
        # 调用模拟器
        feasible, info = simulate_one_supercycle(self.TMP0, L_s, t_bw_s)
        
        if feasible:
            reward = _score(info)  # 计算奖励
            self.TMP0 = info["TMP_after_ceb"]  # 更新TMP
            done = False
        else:
            reward = -20  # 违反约束,大负奖励
            done = True   # episode终止
        
        return next_state, reward, done, info

约束检查

# 硬约束1:TMP峰值不得超过0.06 MPa
if TMP_peak > 0.06:
    return False

# 硬约束2:单次残余增量不得超过0.001 MPa
if (TMP_after_bw - TMP0) > 0.001:
    return False

# 硬约束3:TMP不得超过上限的98%
if TMP_peak / TMP_max > 0.98:
    return False

物理模型集成

# TMP增长模型(uf_fp.pth)
def _delta_tmp(L_h):
    return model_fp(params, L_h)  # 产水时长 → TMP增量

# 反洗恢复模型(uf_bw.pth)
def phi_bw_of(L_s, t_bw_s):
    return model_bw(params, L_s, t_bw_s)  # (产水时长, 反洗时长) → 恢复比例

这两个模型是基于数据拟合或物理建模得到的。

决策使用(DQN_decide.py

单步决策接口

def run_uf_DQN_decide(uf_params, TMP0_value):
    # 1. 创建环境
    env = UFSuperCycleEnv(uf_params)
    env.current_params.TMP0 = TMP0_value  # 设置当前TMP
    
    # 2. 加载训练好的模型
    model = DQN.load("dqn_model.zip")
    
    # 3. 预测动作(确定性,不探索)
    action, _ = model.predict(state, deterministic=True)
    
    # 4. 解码动作
    L_s, t_bw_s = decode_action(action)
    
    return {
        "action": action,
        "L_s": L_s,
        "t_bw_s": t_bw_s,
        "expected_recovery": info["recovery"],
        ...
    }

PLC指令生成

为了避免频繁大幅调整(工艺稳定性),使用渐进式调整

def generate_plc_instructions(current, model_prev, model_current):
    # 计算差异
    diff = model_current - effective_current
    
    # 渐进调整:每次只调整一个步长
    if abs(diff) >= threshold:
        adjustment = +step_size if diff > 0 else -step_size
    else:
        adjustment = 0
    
    next_value = effective_current + adjustment
    return next_value

示例

当前L_s = 4000秒
模型建议 = 4300秒
步长 = 60秒

第1轮下发:4060秒(+60)
第2轮下发:4120秒(+60)
...
第5轮下发:4300秒(到达目标)

性能指标计算(DQN_decide.py

def calc_uf_cycle_metrics(TMP0, L_s, t_bw_s):
    # 模拟一个超级周期
    feasible, info = simulate_one_supercycle(params, L_s, t_bw_s)
    
    return {
        "k_bw_per_ceb": 小周期次数,
        "recovery": 回收率,
        "net_delivery_rate_m3ph": 净供水率(m³/h),
        "daily_prod_time_h": 日均产水时间(h/天),
        "ton_water_energy_kWh_per_m3": 吨水电耗(kWh/m³),
        "max_permeability": 最高渗透率(lmh/bar)
    }

文件结构说明

uf-rl/
├── DQN_train.py         # 强化学习训练脚本(DQN算法)
├── DQN_env.py           # 模拟环境(MDP定义、物理模拟)
├── DQN_decide.py        # 决策接口(加载模型、生成指令)
├── UF_decide.py         # 传统优化方法(网格搜索,用于对比)
├── UF_models.py         # 物理模型定义(TMP增长、反洗恢复)
├── uf_fp.pth            # TMP增长模型权重
├── uf_bw.pth            # 反洗恢复模型权重
└── dqn_model.zip        # 训练好的DQN模型

训练流程总结

graph LR
    A[初始化环境] --> B[随机初始TMP]
    B --> C{ε-贪心选择动作}
    C -->|探索| D[随机动作]
    C -->|利用| E[Q值最大动作]
    D --> F[模拟执行]
    E --> F
    F --> G{约束检查}
    G -->|可行| H[计算奖励]
    G -->|不可行| I[负奖励-20]
    H --> J[存入经验池]
    I --> J
    J --> K{达到学习步数?}
    K -->|是| L[采样训练]
    K -->|否| M[继续交互]
    L --> N{episode结束?}
    M --> N
    N -->|否| C
    N -->|是| B

与传统方法对比

传统网格搜索(UF_decide.py

# 穷举所有(L_s, t_bw_s)组合
for L_s in [3600, 3660, ..., 4200]:
    for t_bw_s in [90, 92, ..., 100]:
        feasible, metrics = simulate(L_s, t_bw_s)
        if feasible and score > best_score:
            best = (L_s, t_bw_s)

优点:简单、可解释、保证找到网格上的最优解
缺点

  • 计算量大(数百次模拟)
  • 参数空间离散化(可能错过真正最优点)
  • 无法泛化(每个TMP都要重新搜索)

强化学习(DQN)

优点

  • 训练后推理快(一次前向传播)
  • 能泛化到不同TMP(学到状态-动作映射)
  • 可处理更复杂的状态(如历史趋势)

缺点

  • 训练耗时(需要大量交互)
  • 黑盒性(难以解释为何选择某动作)
  • 性能受模拟器精度影响

训练建议

提升策略性能

  1. 改进奖励设计

    # 添加渗透率奖励
    reward += 0.1 × permeability
       
    # 添加稳定性奖励(动作变化小)
    reward -= 0.05 × |action - last_action|
    
  2. 增加状态信息

    state = [
       TMP0, last_L, last_t_bw, max_TMP,
       water_quality,  # 水质指标
       days_since_ceb, # 距上次CEB天数
       ...
    ]
    
  3. 课程学习(Curriculum Learning)

    # 阶段1:简单场景(TMP变化小)
    env.TMP_range = [0.025, 0.035]
    train(10000 steps)
       
    # 阶段2:中等场景
    env.TMP_range = [0.01, 0.04]
    train(20000 steps)
       
    # 阶段3:困难场景(全范围)
    env.TMP_range = [0.01, 0.05]
    train(20000 steps)
    

加速训练

# 1. 减少训练步数
total_timesteps = 10000  # 从50000降到10000

# 2. 增大batch_size(如果内存足够)
batch_size = 64

# 3. 调高learning_rate(小心不稳定)
learning_rate = 5e-4

# 4. 预训练:从传统方法生成初始数据
buffer.load_from_grid_search()

常见问题

Q:为什么用强化学习而不是监督学习?
A:监督学习需要"正确答案"标签,但这里没有标准答案(最优策略本身就是要学习的)。强化学习通过奖励信号自己探索最优策略。

Q:模拟器不准确怎么办?
A:这是强化学习最大风险。解决方法:

  • 用真实数据校准模拟器
  • Sim-to-Real迁移(在真实系统上微调)
  • 保守策略(加大安全裕度)

Q:能否用于在线学习?
A:可以,但需谨慎:

  • 设置安全约束(避免危险动作)
  • 分阶段部署(先离线验证)
  • 人工监督(关键决策需人工确认)

Q:为什么动作空间是离散的?
A:DQN擅长离散动作(每个动作一个Q值)。如果需要连续动作,可用DDPG、SAC等算法。

Q:如何评估策略好坏?
A:

  • 离线:在验证集上计算平均回收率、净供水率
  • 在线:实际运行后对比历史数据
  • 对比基线:与传统固定参数、网格搜索比较

未来优化方向

  1. 多智能体协同:多个UF模组联合优化
  2. 分层强化学习:高层决策策略,低层决策参数
  3. 模型预测控制(MPC)集成:结合物理模型和学习策略
  4. 安全强化学习:硬约束保证(Safety RL)
  5. 离线强化学习:仅用历史数据训练(Offline RL)

总结

UF-RL模型是一个决策优化系统,通过深度强化学习学习在不同跨膜压差下的最优运行策略。相比传统方法:

  • 更智能:能适应不同状态,无需人工调参
  • 更高效:训练后推理快速
  • 更全面:平衡多个矛盾目标

但同时也需要:

  • 准确的模拟器:保证学到的策略有效
  • 充分的训练:探索足够多的状态-动作组合
  • 谨慎的部署:实际应用前充分验证