引入专家约束 ====================== 引入专家约束可以为模型的训练和推断提供专业领域知识支持,避免从数据中学习到的环境模型违背约束的知识,减少任务难度,并提高环境模型预测精度。 在冰箱温度控制任务中,存在一个专家先验,即冰箱功率增大会导致冰箱温度下降的负相关关系。将这个负相关关系作为一个专家约束,对模型的训练和推断可以提供专业领域知识的支持, 有效地避免了从数据中学习到的环境模型与约束知识违背的情况。在模型中引入这个约束可以降低任务难度并提高预测精度,在实践中具有很高的应用价值。 REVIVE SDK支持以函数的形式引入专家约束。构建的方式类似于 :doc:`奖励函数<./reward_function_cn>`,约束函数根据环境转移是否违背约束来给予一个奖励。 下面是一个为冰箱示例引入专家约束的示例,首先我们定义一个类似奖励函数的专家约束: .. code:: python import torch from copy import deepcopy from typing import Dict # 是否对计算出奖励值进行归一化处理,默认False normalize = False # 计算出的奖励值的权重,可以修改进行调节,也可以直接在下面的函数中进行调节 weight = 1.0 # 配置matching_nodes可以帮助将规则放入指定的匹配器,也可以不配置 matching_nodes = ["temperature", "action", "next_temperature"] # 函数名应该定义为get_reward def get_reward(data : Dict[str, torch.Tensor], graph) -> torch.Tensor: # 拷贝一份原始数据 noise_data = deepcopy(data) # 对原始数据的action节点加一个随机噪音 noise_data["action"] += torch.randn_like(noise_data["action"]) * 0.1 # 使用加噪之后的数据计算next_temperature节点的输出 node_name = "next_temperature" if graph.get_node(node_name).node_type == 'network': # 调用graph计算网络节点输出 node_output = graph.compute_node(node_name, noise_data).mode else: # 调用graph计算函数节点输出 node_output = graph.compute_node(node_name, current_batch) # 计算action节点的变化和next_temperature节点变化的相关性 correlation = ((noise_data["action"] - data["action"]) * (node_output-data[node_name])) # 如果存在正相关,则给出-0.2的奖励值,否则输出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参数引入专家约束函数进行环境训练的命令** :: 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 可以运行的示例请参考冰箱案例中的README文件。