超参数的设置对强化学习算法的训练效果起着非常重要的作用,如果超参数没有调整好,可能非常好的网络结构和强化学习算法也发挥不出优势。超参数的调整是一项非常困难又略带玄学的工作,好在ray的tune能自动帮我们进行超参数的调整,找到最优的超参数。 下面我们通过例子来看一下tune的使用。 在开始使用之前,需要通过
pip install ray[tune]
命令来安装tune。 代码中有部分注释,请仔细阅读。
# -*- coding: utf-8 -*-
import ray
from ray import tune
import time
ray.shutdown()
ray.init(ignore_reinit_error=True)
#如果想使用pytorch框架,添加 'framework':'torch',
#num_workers指在多少个cpu核心上采集数据,如果不知道自己的机器有多少核心,通过下面的命令查看
#ray.available_resources()['CPU']
#ray.available_resources()['GPU']
#注意:如果有24个核心,num_workers只能最大写到23,因为trainer占用一个核心,rolloutworker最多只能有23个,rolloutworker代表采集数据的worker,例如蒙特卡洛采样函数
#通过我观察,num_workers并不是越大越快,其实不加num_workers参数,ray会自动分配,速度相比最大的核心数反而要快
#num_gpus对于单卡机器,可以设为分数,如0.5,代表当前的trainer占用一半的gpu资源,后面会看一下什么是trainer
config = {
'env': 'CartPole-v1',
'num_workers':23,
'num_gpus':1,
}
stop = {
'episode_reward_mean': 500
}
st=time.time()
results = tune.run(
'PPO', # Specify the algorithm to train
config=config,
stop=stop
)
print('elapsed time=',time.time()-st)
ray.shutdown()
运行代码后,在浏览器中访问 http://127.0.0.1:8265/,类似tensorboard的使用,就可以观察训练过程中的资源占用情况。 我们可以看到,有个PPO.train()占用一个核心,这个PPO就代表上面注释中说的trainer,23个rolloutworker,负责与环境交互采集数据。
输出:
elapsed time= 402.83113956451416
同时输出的还有训练过程信息,默认自动保存在 ~/ray_results文件夹下,可以通过命令
tensorboard --logdir=~/ray_results
来打开tensorboard查看,总共有3页的信息显示,非常全面。
到目前为止,还没有涉及到自动调参的过程,下面就来自动调参的例子。 tune中使用Grid Search来调整参数,即tune.grid_search()函数,这个函数从你提供的可选参数列表中找到最优的参数值。我们来看一个例子。
# -*- coding: utf-8 -*-
import ray
from ray import tune
import time
ray.shutdown()
ray.init(ignore_reinit_error=True)
config = {
"env": 'CartPole-v0',
"num_workers": 10,
"framework":"torch",
"num_gpus":1,
#将要调整的参数以tune.grid_search([])的形式表示,tune即可自动在其中选择最优的参数
#具体的参数意义可直接在谷歌搜 参数名 ray 即可
"vf_share_layers": tune.grid_search([True, False]),
"lr": tune.grid_search([1e-4, 1e-5, 1e-6]),
}
results = tune.run(
'PPO',
stop={
'timesteps_total': 100000
},
#verbose=0,
config=config)
# =============================================================================
# config = {
# 'env': 'CartPole-v0',
# 'framework':'torch',
# 'num_workers':23,
# 'num_gpus':1,
# }
# stop = {
# 'episode_reward_mean': 200
# }
# st=time.time()
# results = tune.run(
# 'PPO', # Specify the algorithm to train
# config=config,
# stop=stop
# )
# =============================================================================
#print('elapsed time=',time.time()-st)
ray.shutdown()
输出:
2021-02-16 22:52:24,888 INFO tune.py:448 -- Total run time: 1809.41 seconds (1806.60 seconds for the tuning loop).
如果想要查看results中的内容,可以在当前运行程序的命令行环境中输入
s=results.dataframe()
即像下面这样,然后在spyder的变量管理器中双击变量s,就可以看到s中的内容。这里面包括了几乎所有的训练过程中的信息。
这时候,我们还是打开tensorboard,选择刚才训练的记录,
找到其中需要的指标,就可以观察哪个参数设置是最好的。对于上面那个问题,我们可以看到在lr=0.0001,vf_share_layers=False的时候,episode_reward_mean是最高的。