在高层RLlib提供了Trainer类,他keep一个policy用于和环境交互。通过trainer接口,policy可以训练,保存,或者用于动作的计算。在多智能体训练中,trainer同时管理多个策略的查询和优化。
![ad4ef1803cc42ca89a17ed99e956997c.png](https://img-blog.csdnimg.cn/img_convert/ad4ef1803cc42ca89a17ed99e956997c.png)
你能使用下述命令训练一个DQN:
rllib train --run DQN --env CartPole-v0
结果会默认保存到子目录~/ray_results。这个子目录包含文件
params.json(用于保存超参数),
{
"env": "CartPole-v0"
}
文件result.json(包含了每个episode的训练数据)
{"episode_reward_max": 49.0, "episode_reward_min": 8.0, "episode_reward_mean": 20.74736842105263, "episode_len_mean": 20.74736842105263, "episodes_this_iter": 190, "policy_reward_mean": {}, "custom_metrics": {}, "sampler_perf": {"mean_env_wait_ms": 0.06072526728229897, "mean_processing_ms": 0.15717214266133053, "mean_inference_ms": 0.7396685669186922}, "off_policy_estimator": {}, "info": {"num_steps_trained": 3968, "num_steps_sampled": 4000, "sample_time_ms": 2006.434, "load_time_ms": 46.28, "grad_time_ms": 1630.859, "update_time_ms": 476.545, "learner": {"default_policy": {"cur_kl_coeff": 0.20000000298023224, "cur_lr": 4.999999873689376e-05, "total_loss": 64.50533294677734, "policy_loss": -0.03904179856181145, "vf_loss": 64.53799438476562, "vf_explained_var": 0.042524512857198715, "kl": 0.03189465031027794, "entropy": 0.6628726124763489, "entropy_coeff": 0.0}}}, "timesteps_this_iter": 4000, "done": false, "timesteps_total": 4000, "episodes_total": 190, "training_iteration": 1, "experiment_id": "78133ebfb69b4d1590b42716371ad75d", "date": "2019-08-24_15-16-13", "timestamp": 1566630973, "time_this_iter_s": 4.203403949737549, "time_total_s": 4.203403949737549, "pid": 3569, "hostname": "yang-XPS-15-9570", "node_ip": "183.173.87.224", "config": {"monitor": false, "log_level": "INFO", "callbacks": {"on_episode_start": null, "on_episode_step": null, "on_episode_end": null, "on_sample_end": null, "on_train_result": null, "on_postprocess_traj": null}, "ignore_worker_failures": false, "log_sys_usage": true, "model": {"conv_filters": null, "conv_activation": "relu", "fcnet_activation": "tanh", "fcnet_hiddens": [256, 256], "free_log_std": false, "no_final_linear": false, "vf_share_layers": true, "use_lstm": false, "max_seq_len": 20, "lstm_cell_size": 256, "lstm_use_prev_action_reward": false, "state_shape": null, "framestack": true, "dim": 84, "grayscale": false, "zero_mean": true, "custom_preprocessor": null, "custom_model": null, "custom_options": {}}, "optimizer": {}, "gamma": 0.99, "horizon": null, "soft_horizon": false, "env_config": {}, "env": "CartPole-v0", "clip_rewards": null, "clip_actions": true, "preprocessor_pref": "deepmind", "lr": 5e-05, "evaluation_interval": null, "evaluation_num_episodes": 10, "evaluation_config": {}, "num_workers": 2, "num_gpus": 0, "num_cpus_per_worker": 1, "num_gpus_per_worker": 0, "custom_resources_per_worker": {}, "num_cpus_for_driver": 1, "num_envs_per_worker": 1, "sample_batch_size": 200, "train_batch_size": 4000, "batch_mode": "truncate_episodes", "sample_async": false, "observation_filter": "NoFilter", "synchronize_filters": true, "tf_session_args": {"intra_op_parallelism_threads": 2, "inter_op_parallelism_threads": 2, "gpu_options": {"allow_growth": true}, "log_device_placement": false, "device_count": {"CPU": 1}, "allow_soft_placement": true}, "local_tf_session_args": {"intra_op_parallelism_threads": 8, "inter_op_parallelism_threads": 8}, "compress_observations": false, "collect_metrics_timeout": 180, "metrics_smoothing_episodes": 100, "remote_worker_envs": false, "remote_env_batch_wait_ms": 0, "min_iter_time_s": 0, "timesteps_per_iteration": 0, "seed": null, "input": "sampler", "input_evaluation": ["is", "wis"], "postprocess_inputs": false, "shuffle_buffer_size": 0, "output": null, "output_compress_columns": ["obs", "new_obs"], "output_max_file_size": 67108864, "multiagent": {"policies": {}, "policy_mapping_fn": null, "policies_to_train": null}, "use_gae": true, "lambda": 1.0, "kl_coeff": 0.2, "sgd_minibatch_size": 128, "shuffle_sequences": true, "num_sgd_iter": 30, "lr_schedule": null, "vf_share_layers": false, "vf_loss_coeff": 1.0, "entropy_coeff": 0.0, "entropy_coeff_schedule": null, "clip_param": 0.3, "vf_clip_param": 10.0, "grad_clip": null, "kl_target": 0.01, "simple_optimizer": false}, "time_since_restore": 4.203403949737549, "timesteps_since_restore": 4000, "iterations_since_restore": 1, "num_healthy_workers": 2, "trial_id": "09c8ad76"}
以及一个用于可视化训练过程的TensorBoard文件。
rllib train命令有许多选项,可自行查看
rllib train --help
最重要的选项是使用--env选择环境(任何gym的环境以及用户自定义gym环境),以及使用--run选择算法(可用选项包括SAC,PPO,PG,A2C,A3C,IMPALA,ES,DDPG,DQN,MARWIL,APEX,APEX_DDPG)。
评估训练策略
为了保存checkpoints,当运行rilib train时设置--checkpoint-freq(两次保存之间的训练迭代次数)
评估以前训练得到的DQN策略:
rllib rollout
~/ray_results/default/DQN_CartPole-vo_0upjmdgr0/checkpoint_1/checkpoint-1
--run DQN --env CartPole-vo --steps 10000
rollout.py将从位于~/ray_results/default/DQN_CartPole-vo_0upjmdgr0/checkpoint_1/checkpoint-1的策略重建DQN网络并渲染。
配置
指定参数
除了一堆common超参,每个算法都有特定的超参数,可以通过--config来设置。
如下我们指定A2C使用8个worker,
rllib train --env=PongDeterministic-v4 --run=A2C --config '{"num_workers": 8}'
指定资源
对大多数算法,可通过设置num_workers来指定并行程度。gpu资源可通过num_gpus选项设置。同样分配到worker的资源可通过num_cpus_per_worker,num_gpus_per_worker和custom_resources_per_worker来设置。GPU的数量可以是小数以分配GPU的一部分。
![9785fc882339099f1edcba04ee609a11.png](https://img-blog.csdnimg.cn/img_convert/9785fc882339099f1edcba04ee609a11.png)
Common参数
COMMON_CONFIG = {
# === 用于调试 ===
# 是否向log文件夹写入episode状态和视频
"monitor": False,
# 为agnet和workers设置ray.rllib.*的log等级
# 应该为DEBUG,INFO,WARN,ERROR其中之一。 DEBUG 等级将会
# 定期打印内部数据流的相关信息 (这也是INFO等级在一开始会打印的).
"log_level": "INFO",
# 训练不同阶段的回调函数。这些函数将会把单一的info作为参数,对于episode回调,我们可更新
# episode对象的自定义度量字典,进而将自定义的度量指标能够附加在episode上,你还能改变回
# 调中传入的批处理数据
"callbacks": {
"on_episode_start": None, # arg: {"env": .., "episode": ...}
"on_episode_step": None, # arg: {"env": .., "episode": ...}
"on_episode_end": None, # arg: {"env": .., "episode": ...}
"on_sample_end": None, # arg: {"samples": .., "worker": ...}
"on_train_result": None, # arg: {"trainer": ..., "result": ...}
"on_postprocess_traj": None, # arg: {
# "agent_id": ..., "episode": ...,
# "pre_batch": (before processing),
# "post_batch": (after processing),
# "all_pre_batches": (other agent ids),
# }
},
# 如果一个worker失败,是否继续
"ignore_worker_failures": False,
# log系统资源利情况
"log_sys_usage": True,
# 开启TF eager
"eager": False,
# === 策略 ===
# 传入模型的参数,model/catalog.py中说明了全部参数
"model": MODEL_DEFAULTS,
# 传入优化器的参数. 随优化器而边
"optimizer": {},
# === 环境 ===
# MDP折扣因子
"gamma": 0.99,
# 一个episode的最大步数。默认为gym环境的env.spec.max_episode_steps。
"horizon": None,
# 计算reward但是当步数达到horizon的时候不reset环境,这使得我们可以做value estimation
# 而且可以将RNN状态在多个episode之间扩展。这个参数当horizon不为无穷时才有用。
"soft_horizon": False,
# 在episode结束的时候不设置done. 注意如果soft_horizon=True,你还是要设置done的,除非
# 你的环境可以持续运行而不用重设
"no_done_at_end": False,
# 传给env creator的参数
"env_config": {},
# 环境的名字
"env": None,
# 是否在后处理时进行reward截断,设置为None则只对Atari环境做reward clip
"clip_rewards": None,
# 是否将动作截断在定义的动作空间高低区间上
"clip_actions": True,
# 是否默认使用rllib或者deepmind的预处理
"preprocessor_pref": "deepmind",
# 默认的学习率
"lr": 0.0001,
# === 评估 ===
# 每 `evaluation_interval` 个训练迭代次数进行评估。
# 评估的信息包含在“evaluation”度量键中
# 当前评估不支持并行
# Apex的度量只对其中一个worker进行。
"evaluation_interval": None,
# 每次评估运行的episode数量
"evaluation_num_episodes": 10,
# 要传给评估worker的其他参数
# 典型的用法是传入用于评估的env creator的参数
# 以及通过计算确定性动作关闭探索
# TODO(kismuz): implement determ. actions and include relevant keys hints
"evaluation_config": {},
# === 资源 ===
# 用于并行的actor个数
"num_workers": 2,
# 分配给训练过程的GPU资源. 不是所有算法都能利用GPU的,可以是小数(如0.3)
"num_gpus": 0,
# 分配给每个worker的CPU数量
"num_cpus_per_worker": 1,
# 分配给每个worker的GPU数量
"num_gpus_per_worker": 0,
# 分配给每个worker的自定义资源
"custom_resources_per_worker": {},
# 分配给trainer的CPU数量。注意:只有大那该在Tune中运行时才有效
"num_cpus_for_driver": 1,
# === 内存配额 ===
# 可通过设置这些配额来告诉ray为你的训练保留这些内存,这保证了顺利的运行,
# 代价是如果你的工作负荷超过配额就会失败
# 为训练进程保留的堆内存(0代表无限)
# 这可以很大如果你用大的batch,replay buffer等
"memory": 0,
# 为训练进程保留的对象存储空间. Being large
# 足够容纳几份模型权重的拷贝即可
# 默认开启,因为模型一般都很小.
"object_store_memory": 0,
# 为每个worker保留的堆内存
# 一般来说小一点就好,除非你的环境很占内存
"memory_per_worker": 0,
# 为每个worker保留的对象存储空间
# 大到一次容纳几个sample batch就足够
# 默认开启,因为一般超不过200M
"object_store_memory_per_worker": 0,
# === 执行 ===
# 每个worker的环境数量
"num_envs_per_worker": 1,
# 默认sample batch大小. 这样大小的batch不断从workers收集
# 直到满足train_batch_size,如果一个worker用多个环境
# 需要乘一个num_envs_per_worker
"sample_batch_size": 200,
# 用于训练的batch size, 应该 >= sample_batch_size.
# Samples batches将会级联成这个大小用于训练
"train_batch_size": 200,
# 是否展开 "complete_episodes" or "truncate_episodes"
"batch_mode": "truncate_episodes",
# 使用后台线程用于采样 (因为不同步,轻微off-policy, 不建议打开
# 除非你的环境要求)
"sample_async": False,
# 逐元素的observation过滤器, "NoFilter" 或者 "MeanStdFilter"
"observation_filter": "NoFilter",
# 是否同步remote过滤器的数据.
"synchronize_filters": True,
# 默认配置单进程tf op
"tf_session_args": {
# note: overriden by `local_tf_session_args`
"intra_op_parallelism_threads": 2,
"inter_op_parallelism_threads": 2,
"gpu_options": {
"allow_growth": True,
},
"log_device_placement": False,
"device_count": {
"CPU": 1
},
"allow_soft_placement": True, # required by PPO multi-gpu
},
# 过载local worker的tf session参数
"local_tf_session_args": {
# 默认允许更高程度的并行,但是有限制
# 因为那会造成多个并发dirver的冲突
"intra_op_parallelism_threads": 8,
"inter_op_parallelism_threads": 8,
},
# 是否用LZ4压缩单个observation
"compress_observations": False,
# 等待metric batches的最大时间(s). 没有按时返回的数据将在下一轮迭代中收集
"collect_metrics_timeout": 180,
# 在这样数量的episode下做度量平滑
"metrics_smoothing_episodes": 100,
# 如果num_envs_per_worker > 1, 是否在remote进程中创建这些env而不是在worker中
# 这增加了通信开支, 但如果你的环境用很多时间step/reset(如星际争霸),这就很合理
# 谨慎使用,overheads很重要
"remote_worker_envs": False,
# 和环境交互获取batch时remote worker的等待时间
# 0 (当至少一个环境准备好后继续) 是一个合理的选择,
# 但最优值需要测量环境的step/reset,以及model推断时间获得
"remote_env_batch_wait_ms": 0,
# 每次迭代的最少时间
"min_iter_time_s": 0,
# 每次train call最小的环境的步数
# 这个值不影响训练效果,只影响每次迭代的长度
"timesteps_per_iteration": 0,
# 这个参数和 worker_index, 用来设置每个worker的随机种子
# 这样相同的配置下就会有相同的结果
# 这使得实验可以复现
"seed": None,
# === 离线数据集 ===
# 用于指定如何产生经验:
# - "sampler": 通过在线仿真产生经验 (默认)
# - 一个局部路径或者全局文件表达形式 (如, "/tmp/*.json")
# - 文件路径或url的列表 (如, ["/tmp/1.json", "s3://bucket/2.json"])
# - 一个使用字符串为键和采样概率为值的字典 (如,
# {"sampler": 0.4, "/tmp/*.json": 0.4, "s3://bucket/expert.json": 0.2}).
# - 一个返回rllib.offline.InputReader的函数
"input": "sampler",
# 用于指定如何评估当前策略. 仅当读取离线经验时有效
# 可用选项:
# - "wis": 加权重要性采样估计.
# - "is": 重要性采样估计.
# - "simulation": 后台运行环境,但仅用于评估不用于学习
"input_evaluation": ["is", "wis"],
# 是否在离线输入的轨迹片段上运行后处理trajectory()
# 注意后处理将用当前策略而不是行为策略,对于on-policy算法这是不行的
"postprocess_inputs": False,
# 如果设置为正数, 将会通过一个这样数量batch的滑窗buffer将输入batch打乱
# 如果输入数据顺序不够随机,就使用这个选项
# 直到这个buffer填满,才会进行输入
"shuffle_buffer_size": 0,
# 指定经验保存的地方:
# - None: 不保存任何经验
# - "logdir":保存在agent的log目录下
# - 或者自定义任何路径/url (如, "s3://bucket/")
# - 一个返回rllib.offline.OutputWriter的函数
"output": None,
# 指定压缩为LZ4的sample batch columns
"output_compress_columns": ["obs", "new_obs"],
# 最大输出文件大小
"output_max_file_size": 64 * 1024 * 1024,
# === 多智能体 ===
"multiagent": {
# 从策略id到元祖 (policy_cls, obs_space,
# act_space, config)的映射. See rollout_worker.py for more info.
"policies": {},
# 从agent id到policy id
"policy_mapping_fn": None,
# 有选择的选择要训练的策略
"policies_to_train": None,
},
}
Tuned例子
rllib train -f /path/to/tuned/example.yaml
Python API
python api提供了必要的灵活性,他可以用来自定义环境,预处理器,以及模型。
基本例子
import
注意:建议使用Tune运行rllib trainer,这样可以使得实验管理更简单,并且可以可视化训练过程。 只需要在实验config中设置"run": ALG_NAME, "env": ENV_NAME
所有RLlib trainer都和Tune API兼容,如下的代码展示了一个简单的ppo超参数sweep。
import ray
from ray import tune
ray.init()
tune.run(
"PPO",
stop={"episode_reward_mean": 200},
config={
"env": "CartPole-v0",
"num_gpus": 0,
"num_workers": 1,
"lr": tune.grid_search([0.01, 0.001, 0.0001]),
"eager": False,
},
)
Tune将会并行的在集群上训练.
== Status ==
Using FIFO scheduling algorithm.
Resources requested: 2/12 CPUs, 0/1 GPUs
Memory usage on this node: 5.1/33.3 GB
Result logdir: /home/yang/ray_results/PPO
Number of trials: 3 ({'TERMINATED': 2, 'RUNNING': 1})
RUNNING trials:
- PPO_CartPole-v0_1_lr=0.001: RUNNING, [2 CPUs, 0 GPUs], [pid=4478], 173 s, 39 iter, 156000 ts, 194 rew
TERMINATED trials:
- PPO_CartPole-v0_0_lr=0.01: TERMINATED, [2 CPUs, 0 GPUs], [pid=4482], 120 s, 24 iter, 96000 ts, 200 rew
- PPO_CartPole-v0_2_lr=0.0001: TERMINATED, [2 CPUs, 0 GPUs], [pid=4476], 70 s, 13 iter, 52000 ts, 200 rew
自定义训练工作流
默认的,Tune会在每一次迭代调用trainer上的train()并且报告新的训练结果。但有时我们需要自定义训练流。Tune也支持自定义训练函数,主要有两个API,一个python类API,一个python函数API。对更加细化的训练控制,就可以直接用RLlib的底层API(如policy,optimizer,evaluator等)来写。
"""Example of a custom training workflow. Run this for a demo.
This example shows:
- using Tune trainable functions to implement custom training workflows
You can visualize experiment results in ~/ray_results using TensorBoard.
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import ray
from ray import tune
from ray.rllib.agents.ppo import PPOTrainer
def my_train_fn(config, reporter):
# Train for 100 iterations with high LR
agent1 = PPOTrainer(env="CartPole-v0", config=config)
for _ in range(10):
result = agent1.train()
result["phase"] = 1
reporter(**result)
phase1_time = result["timesteps_total"]
state = agent1.save()
agent1.stop()
# Train for 100 iterations with low LR
config["lr"] = 0.0001
agent2 = PPOTrainer(env="CartPole-v0", config=config)
agent2.restore(state)
for _ in range(10):
result = agent2.train()
result["phase"] = 2
result["timesteps_total"] += phase1_time # keep time moving forward
reporter(**result)
agent2.stop()
if __name__ == "__main__":
ray.init()
config = {
"lr": 0.01,
"num_workers": 0,
}
resources = PPOTrainer.default_resource_request(config).to_json()
tune.run(my_train_fn, resources_per_trial=resources, config=config)
获取Policy状态
我们一般需要获取trainer的内部状态,如需要设置或获取内部权重。在RLlib中,trainer的state是在rollout workers之间复制存在的。你可以在调用train()方法的中间通过调用trainer.workers.foreach_worker()或者trainer.workers.foreach_worker_with_index()来获取和更新这些状态。这些方法的参数是一个用于worker的lambda函数,这个函数可以返回值,最后将以列表的形式返回。
也可以不用拿每个worker的状态而只获取其中一个主要的copy,trainer.get_policy()或者trainer.workers.local_worker()。
# 获取本地policy权重
trainer.get_policy().get_weights()
# 同上
trainer.workers.local_worker().policy_map["default_policy"].get_weights()
# 获取每个worker的权重,包括remote的replicas
trainer.workers.foreach_worker(lambda ev: ev.get_policy().get_weights())
# 同上
trainer.workers.foreach_worker_with_index(lambda ev, i: ev.get_policy().get_weights())
全局统筹
有时需要协调不同进程中的代码,比如我们有时需要维持一个变量的全局平均,或者集中控制一个policy的超参数。Ray通过named actor这个东西来实现。举个例子,比如我们现在需要维持一个全局计数器,这个计数器通过环境递增,并定期从驱动程序中读取。
from ray.experimental import named_actors
@ray.remote
class Counter:
def __init__(self):
self.count = 0
def inc(self, n):
self.count += n
def get(self):
return self.count
# on the driver
counter = Counter.remote()
named_actors.register_actor("global_counter", counter)
print(ray.get(counter.get.remote())) # get the latest count
# in your envs
counter = named_actors.get_actor("global_counter")
counter.inc.remote(1) # async call to increment the global count
Ray的actor有着很强的灵活性,它能够实现如ps和allreduce这样的通信模式。
回调和自定义度量
可以自定义用于policy evaluation过程的回调函数。这些回调函数将当前episode的状态的字典作为参数。自定义的状态量可以存储在info["episode"].user_data字典中,自定义的整数度量可以存储在info["episode"].custom_metrics字典中。这些自定义的度量将会作为训练结果的一部分。下列代码从环境中log了自定义的度量。
def on_episode_start(info):
print(info.keys()) # -> "env", 'episode"
episode = info["episode"]
print("episode {} started".format(episode.episode_id))
episode.user_data["pole_angles"] = []
def on_episode_step(info):
episode = info["episode"]
pole_angle = abs(episode.last_observation_for()[2])
episode.user_data["pole_angles"].append(pole_angle)
def on_episode_end(info):
episode = info["episode"]
pole_angle = np.mean(episode.user_data["pole_angles"])
print("episode {} ended with length {} and pole angles {}".format(
episode.episode_id, episode.length, pole_angle))
episode.custom_metrics["pole_angle"] = pole_angle
def on_train_result(info):
print("trainer.train() result: {} -> {} episodes".format(
info["trainer"].__name__, info["result"]["episodes_this_iter"]))
ray.init()
analysis = tune.run(
"PG",
config={
"env": "CartPole-v0",
"callbacks": {
"on_episode_start": tune.function(on_episode_start),
"on_episode_step": tune.function(on_episode_step),
"on_episode_end": tune.function(on_episode_end),
"on_train_result": tune.function(on_train_result),
},
},
)
自定义的度量同样可以在tensorboard中可视化
![2478146decc0627154c96a7a49c41242.png](https://img-blog.csdnimg.cn/img_convert/2478146decc0627154c96a7a49c41242.png)
例子:课程学习
来看使用上述API实现课程学习的两种方式。在课程学习中,agent的任务随着学习过程不断调整,假设我们的环境类中有set_phase()方法,其可以随时间调节任务难度。
方法一:使用Trainer API在train()之间更新环境,以下例子展示了trainer在Tune函数中的运行。
import ray
from ray import tune
from ray.rllib.agents.ppo import PPOTrainer
def train(config, reporter):
trainer = PPOTrainer(config=config, env=YourEnv)
while True:
result = trainer.train()
reporter(**result)
if result["episode_reward_mean"] > 200:
phase = 2
elif result["episode_reward_mean"] > 100:
phase = 1
else:
phase = 0
trainer.workers.foreach_worker(
lambda ev: ev.foreach_env(
lambda env: env.set_phase(phase)))
ray.init()
tune.run(
train,
config={
"num_gpus": 0,
"num_workers": 2,
},
resources_per_trial={
"cpu": 1,
"gpu": lambda spec: spec.config.num_gpus,
"extra_cpu": lambda spec: spec.config.num_workers,
},
)
方法二,使用回调函数
import ray
from ray import tune
def on_train_result(info):
result = info["result"]
if result["episode_reward_mean"] > 200:
phase = 2
elif result["episode_reward_mean"] > 100:
phase = 1
else:
phase = 0
trainer = info["trainer"]
trainer.workers.foreach_worker(
lambda ev: ev.foreach_env(
lambda env: env.set_phase(phase)))
ray.init()
tune.run(
"PPO",
config={
"env": YourEnv,
"callbacks": {
"on_train_result": tune.function(on_train_result),
},
},
)
调试
Gym Monitor
rllib train --env=PongDeterministic-v4
--run=A2C --config '{"num_workers": 2, "monitor": true}'
# videos will be saved in the ~/ray_results/<experiment> dir, for example
openaigym.video.0.31401.video000000.meta.json
openaigym.video.0.31401.video000000.mp4
openaigym.video.0.31403.video000000.meta.json
openaigym.video.0.31403.video000000.mp4
Tensorflow eager
使用build_tf_policy构建的策略可以通过设置"eager": True或者使用rllib train --eager使用eager模式运行。
Eager模式更方便调试,因为可以使用print来打印出tensor的值。
Episode Traces
可通过数据输出API保存episode信息用于调试,如下代码会将episode信息存入/tmp/debug
rllib train --run=PPO --env=CartPole-v0
--config='{"output": "/tmp/debug", "output_compress_columns": []}'
# episode traces will be saved in /tmp/debug, for example
output-2019-02-23_12-02-03_worker-2_0.json
output-2019-02-23_12-02-04_worker-1_0.json
Log verbosity
可以通过"log_level"控制训练log记录等级。 有INFO DEBUG WARN ERROR几种选择,
rllib train --env=PongDeterministic-v4
--run=A2C --config '{"num_workers": 2, "log_level": "DEBUG"}'
REST API
在有些情况下(如与一个外部simulator或者生产环境交互时),不适合用RLlib包裹这个simulator,而要通过RLlib的外部agent接口。
![f9ed0e2d2f6e8f40d55584a2a596891b.png](https://img-blog.csdnimg.cn/img_convert/f9ed0e2d2f6e8f40d55584a2a596891b.png)
![03ffbfef4d4207004e3c720b6888a517.png](https://img-blog.csdnimg.cn/img_convert/03ffbfef4d4207004e3c720b6888a517.png)
例子
>>> class CartpoleServing(ExternalEnv):
def __init__(self):
ExternalEnv.__init__(
self, spaces.Discrete(2),
spaces.Box(
low=-10,
high=10,
shape=(4,),
dtype=np.float32))
def run(self):
server = PolicyServer(self, "localhost", 8900)
server.serve_forever()
>>> register_env("srv", lambda _: CartpoleServing())
>>> pg = PGTrainer(env="srv", config={"num_workers": 0})
>>> while True:
pg.train()
>>> client = PolicyClient("localhost:8900")
>>> eps_id = client.start_episode()
>>> action = client.get_action(eps_id, obs)
>>> ...
>>> client.log_returns(eps_id, reward)
>>> ...
>>> client.log_returns(eps_id, reward)
完整client例子
完整server例子