在高層RLlib提供了Trainer類,他keep一個policy用于和環境互動。通過trainer接口,policy可以訓練,儲存,或者用于動作的計算。在多智能體訓練中,trainer同時管理多個政策的查詢和優化。
你能使用下述指令訓練一個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的一部分。
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中可視化
例子:課程學習
來看使用上述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接口。
例子
>>> 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例子