官方教程:https://revive.cn/help/polixir-revive-sdk/index.html
面临的挑战
强化学习自主试错学习的方式,减少了对人力的依赖,也因此被Deepmind认为是通向「通用人工智能」的关键技术。在游戏规则完全清晰的虚拟环境中,借助强大的算力,可以取得现实世界一天、游戏世界数十年的加速效果,于是强化学习在短时间内通过海量试错学习,可获得超越人类的决策能力。以AlphaGo为例,它在围棋环境中通过强化学习在短短数月内自我对弈了超过三千万局,倘若以业余棋手平均一小时一局计算,人类习得这样的决策能力至少需要4000年!
可以想象,对于实际业务问题,如果人们也能刻画出清晰完整的游戏规则,那么强化学习就可以轻松找出最优业务决策,成为人们有力的帮手,解放人类在细碎决策上的繁琐劳动,转而在顶层设计上充分发挥人类的优势——想象力与创造力。但事实上,我们面对的大多数实际问题都缺乏清晰完整的规则,并非理想的「游戏环境」。更残酷的是,如果让强化学习在现实世界中训练试错,会给人们带来巨大的代价,乃至发生生命危险!
因此,离开了虚拟的游戏世界,强化学习显得不再智能,不仅学习速度极慢,而且还会因为在学习过程中会尝试大量的错误行为造成不可挽回的损失。
在AlphaGo的光环下,今天的强化学习已成为人工智能领域的高光方向。然而学术界的进展与业界的期望尚不匹配。如果说今天有一项算法创新可以将强化学习所需的数亿次探索交互降低两个数量级,这在学术界一定是重磅新闻。然而,数百万次的探索在产业界仍然距离广泛应用遥遥无期。
现实是在尝试应用强化学习技术时,往往遇到缺乏「游戏环境」的挑战,在淘宝搜索排序任务上,没有明确的规则可以描述用户的行为,因此难以构造强化学习训练的「游戏环境」。如果可以从离线数据中还原出「游戏环境」,强化学习便可发挥优势,那就能解决问题了。
Revive简介
2019年6月,在南京大学人工智能创新研究院与投资人的共同支持下,俞扬教授和秦熔均师徒二人开始组建南栖仙策团队,推动技术的深度应用和普及。南栖仙策一边将环境学习技术应用在更多的场景中,一边带回场景落地的经验和挑战,不断完善技术。经过不断的迭代,南栖仙策将核心技术与应用经验沉淀,打造基于环境学习的通用智能决策工具「仙启」。2021年12月24日,南栖仙策「仙启」正式版面世了。通过与数十家各类行业领域的公司合作打磨,「仙启」已经实现了在能源、制造、物流、营销跨行业多业务场景的应用,获得产业和企业侧的高度认可。「AI决策●强化学习落地挑战赛」与「仙启」同步发布。详情参见博客:赛题分析:AI决策•强化学习落地挑战赛——学习指定平等的促销策略
「仙启」为工业业务场景提供辅助决策工具,与业务实际决策环进行解耦,可由企业根据自身情况灵活部署。同时,「仙启」直接基于业务场景的历史数据进行学习,不借助其他商业软件,部署周期短,也为企业带来了极低的使用门槛。这里调用的算法之一就是Revive。
Revive 用于构建仅基于离线数据的智能决策系统。离线强化学习,即在不与环境进一步交互的情况下从固定数据集中学习的任务,构成了 Revive 的核心。它有望将历史数据集转变为强大的决策引擎。离线强化学习方法探索了从现有数据中提取具有最大效用的策略的可能性,从而使许多关键决策领域的策略优化过程自动化,从机械系统的优化控制,提高能源部门的能源效率,到更广泛的影响促进科学研究。
其中Revive的训练包含两个阶段:
Venv 训练:通过模拟状态转换(也称为策略)和离线数据中的智能体行为来训练虚拟环境和智能体策略。
策略训练:将其中一个智能体视为活动智能体,将另一个视为其环境。通过强化学习训练活动智能体,推导出更好的目标策略。
目前Revive已推出0.6.0。
安装
需要:
- Linux x86_64
- Python : v3.6.0+ / v3.7.0+ / v3.8.0+
- CUDA Toolkit
在Linux端执行命令:
git clone https://agit.ai/Polixir/revive
cd revive
pip install -e .
申请许可证:
REVIVE 库由 polixir 开发。官方对REVIVE中少数拥有自主知识产权的算法模块进行了加密保护。可以申请许可证以使用完整的算法包功能。
我们进入Revive库中的License文件夹,然后在此位置执行命令:
python get_machine_info.py
这里会获取机器信息生成一个machine_info.json文件。
把这个文件上传官网https://www.revive.cn/(点击SDK按钮 –> SDK License申请),为机器申请许可证,然后得到一个License.lic文件。我们需要设置其环境变量:
vim ~/.bashrc
然后在最后添加以下内容:
export PYARMOR_LICENSE = /license_save_dir/license.lic
重新加载设置:
source ~/.bashrc
运行测试用例
Revive提供了测试用例供我们运行,运行用到的数据文件就放在data文件夹中,执行命令:
# Training models and strategies with default parameters.
python train.py -df test.npz -cf test.yaml -rf test_reward.py -vm once -pm once --run_id test
# Training networks and parameters using hyperparametric search mode.
python train.py -df test.npz -cf test.yaml -rf test_reward.py -vm tune -pm tune --run_id test
# Use config.json to modify hyperparameters for training.
python train.py -df test.npz -cf test.yaml -rf test_reward.py -rcf config.json --run_id test
REVIVE 会自动创建一个日志文件夹logs/test
来记录训练结果和日志。训练结束后,结果会以 env.pkl和 policy.pkl的形式存放在日志文件中。
数据准备
数据至少包含以下两个文件:
- 描述数据之间关系的.yaml文件。
- 存储数字的.npz文件。
yaml文件编写
这个文件用来定义数据之间的关系。首先你应当有一个详细的决策流程。这个文件中内容分为三个部分:graph,columns,expert_function。
metadata:
graph:
action:
- obs
next_obs:
- obs
- action
columns:
- obs_1:
type : continuous
dim : obs
min : 0
max : 1
- obs_2:
type : discrete
dim : obs
max : 15
min : 0
num : 16
- action1:
type : category
dim : action
values : [0, 1, 2]
...
expert_functions:
next_obs:
'node_function' : 'dynamics.transition'
graph定义了每个动作输出和状态输入之间的关系,这里定义了两个神经网络,一个输入是obs,输出action。一个输入为obs和action,输出为next_obs。
columns定义了每个动作输出和状态输入中包含哪些变量,这里给obs定义了两个变量,分别为连续变量obs_1,离散变量obs_2。给action定义了一个category变量action1,只能取整数的有限子集。数值的定义支持continuous,discrete,category三个属性。
expert_functions指的是专家函数,构建虚拟环境时,专家知识十分有用,如果我们知道某个输出节点的计算方法,就可以定义这个函数,必要时可以取代神经网络。其中next_obs就是我们需要求得的节点,dynamics.transition就是对应的函数名。这个函数应当放在data文件夹下的dynamics文件中,函数示例如下:
import torch
from typing import Dict
def transition(data: Dict[str, torch.Tensor]) -> torch.Tensor:
obs = data["obs"]
return obs + 1
构建数组数据
数据文件的储存格式是.npz或.h5文件。而且必须是一个字典,以数据的名称为键,以ndarray格式的数据为值,值必须是二维的ndarray。同时键的名称应当与.yaml文件中的名称匹配。
import numpy as np
from revive.utils.common_utils import save_h5
data = { "obs": obs_array, "act": act_array}
np.savez_compressed("data.npz", **data)
save_h5("data.h5", data)
定义奖励函数
奖励函数定义了优化目标。奖励函数的输入是单步决策流的数据,奖励值对应于奖励函数的输出。您应该在 python 源文件中提供奖励函数,并且 get_reward 函数在内部定义为接口。
模板奖励函数如下。
import torch
from typing import Dict
def get_reward(data : Dict[str, torch.Tensor]) -> torch.Tensor:
return data['next_obs'][..., 0] - data['obs'][..., 0]
开始训练
当准备好yaml文件,数据文件以及奖励函数之后,就可以开始训练虚拟环境以及策略了。训练运行的是train.py文件,同时配置适当的参数:
命令格式例子:
python train.py -df test_data.npz -cf test.yaml -rf test_reward.py --run_id test
Revive支持三种训练模式:
- once:默认参数。
- tune:通过参数搜索进行训练,会消耗大量计算资源,同时效果得到一定的改进。
- None:不训练虚拟环境和策略,用于已存在现成的虚拟环境下的策略训练。
参数设置的指令如下:
- -df:用于训练虚拟环境的训练数据集的文件名,以
.npz
或.h5
结尾。 - -vf:验证数据集的文件名。(可选)
- -cf:数据描述文件,以
.yaml
. - -rf:奖励函数文件,以.py结尾
- -tpn:决策代理的名称。必须是图中定义的节点;如果未指定,则默认使用具有第一个拓扑顺序的节点作为决策代理。
- -vm:虚拟环境训练的模式,包括:
once
,tune
,None
. - -pm:策略训练的模式,包括:
once
,tune
,None
. - –run_id:本次训练的名称。REVIVE 将以该名称在logs下创建日志目录。如果未提供,REVIVE 将自动生成一个随机 ID。
- -rcf:一个可以覆盖默认超参数和超参数搜索空间的json文件。(可选)
训练完成后,结果会以env.pkl和policy.pkl的形式保存。训练过程中可以打开tensorboard来查看训练进程。
使用策略
策略文件的文件名为policy.pkl,我们可以使用它得到输出的动作:
import os
import pickle
import numpy as np
# Get model path
policy_model_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),"models","policy.pkl")
# Load policy model
policy_model = pickle.load(open(policy_model_path, 'rb'), encoding='utf-8')
# Generate fake state data
state = {"obs":np.random.rand(2,15)}
# Inference with policy model
action = policy_model.infer(state)
print("Model input state:", state)
print("Model output action:", action)
后记
- 如果我们只需要Revive帮助我们创建虚拟环境而不需要训练策略,那么我们可以不用提供奖励函数,这样Revive训练过后不会产生policy.pkl,只会产生env.pkl。然后我们可以通过stable-baseline3等强化学习包来对其进行训练即可。
- 有专家函数的情况下,可以得到准确的值,就不需要训练神经网络拟合了。
- 更多的Revive KPI请参考https://revive.cn/help/polixir-revive-sdk/revive_server.html。