冰箱温度控制任务
任务概述
假设我们需要一个温度控制系统来将冰箱温度控制在理想的目标温度(本示例中设置为 -2°C),以便更好地保存食物。如下图所示,冰箱控制系统通过调节用电功率来控制温度。用电功率越高,制冷效果越强;用电功率越低,制冷效果越弱。需要注意的是,当前温度控制系统(PID 控制策略)的控制效果不够稳定,且存在冰箱门不定时开启的情况,导致冰箱温度在目标温度附近产生较大波动。我们希望改进当前系统的温度控制策略,提升冰箱的温度控制效果。
在上述冰箱温控系统中,我们可以观察到冰箱内部温度、当前用电功率、冰箱门开关状态等数据。收集到的历史数据包含四列:door_open
(冰箱门开关状态,1 表示打开,0 表示关闭)、temperature
(冰箱内部温度)、action
(用电功率)和 next_temperature
(冰箱内部下一时刻温度)。
任务目标
控制策略的任务目标是使冰箱内温度尽可能接近目标温度(本示例中为 -2°C)。
训练流程
REVIVE 是一个基于历史数据的离线强化学习工具。在冰箱温控任务上使用 REVIVE 的完整流程如下:
- 收集历史决策数据:收集冰箱温控任务的历史运行数据
- 构建决策流图和训练数据:
- 结合业务场景和历史数据构建 决策流图
- 决策流图使用
.yaml
文件描述业务数据的交互逻辑 - 训练数据使用
.npz
或.h5
文件存储决策流图中定义的节点数据
- 定义奖励函数:
- 根据任务目标设计 奖励函数
- 奖励函数指导控制策略优化,确保冰箱温度稳定在目标温度附近
- 开始模型训练:
- 完成决策流图、训练数据和奖励函数定义后
- 使用 REVIVE 进行虚拟环境模型训练和策略模型训练
- 上线测试:
- 将训练好的策略模型部署到实际环境进行测试
收集历史数据
PID 控制是一种常见的温控策略,基于比例、积分和微分三个方面对温度进行调节。PID 控制器通过测量冰箱当前温度与预设温度之间的差异(称为误差),将误差转换为输出信号来控制用电功率以调节温度。我们首先使用 PID 策略在冰箱仿真环境中进行控制,获得历史控制数据。收集到的历史数据包含四列:door_open
(冰箱门开关状态,1 表示打开,0 表示关闭)、temperature
(冰箱内部温度)、action
(用电功率)和 next_temperature
(冰箱内部下一时刻温度)。
定义决策流图和准备数据
完成历史数据收集后,需要根据冰箱温度控制的业务场景构建决策流图和训练数据。决策流图准确描述了数据之间的因果关系。在冰箱温度控制系统中,可以划分为四个数据节点:door_open
(冰箱门开关状态)、temperature
(冰箱内部温度)、action
(用电功率)和 next_temperature
(冰箱内部下一时刻温度)。
根据常识和物理原理,我们可以推断出以下因果关系:
- 冰箱门开启影响:当冰箱门打开时,外部空气进入冰箱内部,导致温度上升
- 温度时序关系:冰箱内部温度与下一时刻温度存在时序关系,当前时刻温度会影响下一时刻温度
- 功率控制影响:用电功率大小与冰箱制冷效率相关,会影响下一时刻温度
- 控制策略限制:冰箱温度控制策略只能根据当前温度进行调控,无法感知冰箱门开关状态(外部变量)和下一时刻温度(未来变量)
根据上述冰箱温度控制业务的逻辑描述,可以定义如下决策流图:
其中 action
节点是策略控制节点,输入为 temperature
节点,表示 action
的值(功率)由当前温度决定。door_open
是外部变量,作为 next_temperature
节点的输入,能够影响下一时刻冰箱内温度变化,但不会被图中其他节点影响。action
、temperature
和 door_open
三个节点共同作为 next_temperature
节点的输入,表示这三个节点共同影响下一时刻冰箱内温度。上述 .yaml
文件描述的决策流图符合冰箱温度控制系统的场景逻辑。
该决策流图对应的 .yaml
配置文件如下:
metadata:
graph:
action:
- temperature
next_temperature:
- action
- temperature
- door_open
columns:
- obs_temp:
dim: temperature
type: continuous
max: 20
min: -20
- power_action:
dim: action
type: continuous
max: 10
min: 0
- factor_door_state:
dim: door_open
type: continuous
在构建决策流图的过程中,我们将原始数据转换为 .npz
格式进行存储。
定义决策流图和准备数据的更多细节请参考 准备数据 章节。
定义奖励函数
奖励函数的设计对策略学习至关重要。良好的奖励函数能够有效指导策略向预期方向学习。REVIVE SDK 支持以 Python 源文件的方式定义奖励函数。
为了获得更好的冰箱制冷策略,我们可以定义一个奖励函数来度量温度控制效果(文件名为 refrigeration_reward.py
)。该奖励函数根据当前温度和目标温度之间的差异计算奖励值,差异越小,奖励值越高。奖励函数定义如下:
import torch
from typing import Dict
def get_reward(data: Dict[str, torch.Tensor]) -> torch.Tensor:
"""
冰箱温控任务奖励函数
Args:
data: 包含下一时刻温度的字典
Returns:
计算得到的奖励值
"""
target_temperature = -2 # 目标温度
reward = -torch.abs(data['next_temperature'][...,0:1] - target_temperature)
return reward
上述奖励函数的目标是将冰箱温度控制在指定温度(-2°C)。定义奖励函数的更多细节请参考 奖励函数 章节。
训练冰箱温度控制策略
REVIVE SDK 提供了上述数据和奖励函数文件,详情请参考 REVIVE SDK 源码库。完成 REVIVE SDK 安装后,可以切换到 examples/task/Refrigerator
目录下,运行以下命令进行虚拟环境模型训练和策略模型训练。训练过程中可以使用 TensorBoard 监控训练进度。训练完成后,您可以在 logs/<run_id>
目录下找到保存的模型文件(.pkl
或 .onnx
格式)。
开始训练的命令如下:
python train.py \
-df refrigeration.npz \
-cf refrigeration.yaml \
-rf refrigeration_reward.py \
--run_id refrigeration
重要提示
REVIVE SDK 已提供该示例的完整数据和代码,支持一键运行。数据和代码可在 SDK 源代码存储库 获取。
测试模型
最后,我们需要使用训练好的模型来控制冰箱。下面提供一个在冰箱环境中测试模型的示例。 有关使用训练好的模型或策略的更多信息,请参考:部署模型。
import os
import pickle
import numpy as np
# 获取模型文件路径
policy_model_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
"logs/run_id", "policy.pkl")
# 加载模型文件
with open(policy_model_path, 'rb') as f:
policy_model = pickle.load(f, encoding='utf-8')
# 随机生成状态信息
state = {'temperature': np.random.rand(2, 1)}
print("模型输入状态:", state)
# 使用策略模型进行推理
action = policy_model.infer(state)
print("模型输出动作:", action)
也可以直接使用 REVIVE SDK 提供的 Notebook 脚本进行策略控制效果测试。详情请参考 refrigerator.ipynb。