跳转到内容

引入专家约束

引入专家约束可以为模型的训练和推断提供专业领域知识支持,避免从数据中学习到的环境模型违背约束的知识,减少任务难度,并提高环境模型预测精度。

在冰箱温度控制任务中,存在一个专家先验,即冰箱功率增大会导致冰箱温度下降的负相关关系。将这个负相关关系作为一个专家约束,对模型的训练和推断可以提供专业领域知识的支持,有效地避免了从数据中学习到的环境模型与约束知识违背的情况。在模型中引入这个约束可以降低任务难度并提高预测精度,在实践中具有很高的应用价值。

REVIVE SDK支持以函数的形式引入专家约束。构建的方式类似于奖励函数,约束函数根据环境转移是否违背约束来给予一个奖励。

下面是一个为冰箱示例引入专家约束的示例,首先我们定义一个类似奖励函数的专家约束:

python
import torch
from copy import deepcopy
from typing import Dict

# Whether to normalize the computed reward values (default: False)
normalize = False
# Weight applied to the computed reward; this can be adjusted here or within the function below
weight = 1.0

# Configuring matching_nodes can help assign rules to specified matchers (optional)
matching_nodes = ["temperature", "action", "next_temperature"]

# The function name should be defined as get_reward
def get_reward(data: Dict[str, torch.Tensor], graph) -> torch.Tensor:
    # Create a copy of the original data
    noise_data = deepcopy(data)
    # Add random noise to the 'action' node of the original data
    noise_data["action"] += torch.randn_like(noise_data["action"]) * 0.1

    # Compute the output of the 'next_temperature' node using the noisy data
    node_name = "next_temperature"
    if graph.get_node(node_name).node_type == 'network':
        # Call the graph to compute the output of the network node
        node_output = graph.compute_node(node_name, noise_data).mode
    else:
        # Call the graph to compute the output of the function node
        node_output = graph.compute_node(node_name, current_batch)

    # Compute the correlation between the changes in the 'action' node and the 'next_temperature' node
    correlation = ((noise_data["action"] - data["action"]) * (node_output - data[node_name]))

    # If a positive correlation exists, assign a reward of -0.2; otherwise, assign a reward of 0
    reward = torch.where(
        correlation > 0,
        -0.2 * torch.ones_like(correlation[..., :1]),
        torch.zeros_like(correlation[..., :1])
    )

    return reward

需要注意,在使用专家约束函数对数据进行处理时,通常会将多个数据按批量(batch)组织起来进行一次性运算处理。这种方式可以提高代码的运行效率。因此,在编写奖励函数时,需要注意保证函数能够处理与输入张量形状相对应的多维数据。此外,在计算专家约束函数输出时,我们通常会关注最后一维的特征维度。

为方便处理,专家函数的计算维度通常都设在了最后一维。因此,在使用数据时需要使用切片([..., n:m ])的方式获取数据的最后一维的特征,并对特征进行计算。而对应返回的reward应该是一个对应的Pytorch Tensor,batch维度保持和输入数据一致, 最后一维特征的维度应该是1。

通过-mrf参数引入专家约束函数进行环境训练的命令:

bash
python train.py \
    -df test_data.npz \
    -cf test.yaml \
    -mrf data/test_rule.py \
    -rf test_reward.py \
    -vm once \
    -pm once \
    --run_id once