Ray RLlib 提供了靈活的模型自定義和組態機制,以滿足不同強化學習任務的需求。開發者可以根據實際情況調整模型架構、組態訓練引數、選擇合適的探索策略,以及有效利用計算資源。理解 RLlib 的模型架構、前處理器、Q 值和動作分佈的取得方式,對於構建高效的強化學習模型至關重要。此外,RLlib 提供了豐富的組態選項,涵蓋訓練、環境、rollout workers 等方面,可以根據需求微調訓練過程。對於多代理環境,RLlib 提供了 MultiAgentEnv 和 ExternalEnv 等工具,方便定義和訓練多代理強化學習模型。
強化學習模型的自定義與組態
在前面的章節中,我們探討了使用Ray RLlib進行強化學習(RL)的基本原理和實踐方法。現在,我們將進一步討論如何自定義和組態RLlib模型,以滿足特定的實驗需求。
強化學習模型的架構
首先,讓我們回顧一下RLlib中模型的架構。以DQN模型為例,其輸出代表了狀態-動作對的Q值。模型的架構如下所示:
Model: "model"
________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
================================================================================
observations (InputLayer) [(None, 25)] 0
________________________________________________________________________________
fc_1 (Dense) (None, 256) 6656 observations[0][0]
________________________________________________________________________________
fc_out (Dense) (None, 256) 65792 fc_1[0][0]
________________________________________________________________________________
value_out (Dense) (None, 1) 257 fc_1[0][0]
================================================================================
Total params: 72,705
Trainable params: 72,705
Non-trainable params: 0
________________________________________________________________________________
內容解密:
此模型的架構包含一個輸入層、兩個密集層(Dense layers)和一個輸出層。輸入層接收觀察值,形狀為(None, 25),表示輸入資料的形狀是未知的,但每個樣本有25個特徵。第一個密集層(fc_1)有256個單元,使用ReLU啟用函式。第二個密集層(fc_out)同樣有256個單元。最後,輸出層(value_out)預測一個單一值,即Q值。
自定義模型
RLlib允許使用者自定義模型,以適應複雜的環境。例如,如果環境的觀察空間很大,您可能需要一個更大的模型來捕捉這種複雜性。然而,這需要深入瞭解底層的神經網路框架,例如TensorFlow。
from ray.rllib.models.preprocessors import get_preprocessor
env = GymEnvironment()
obs_space = env.observation_space
preprocessor = get_preprocessor(obs_space)(obs_space)
observations = env.reset()
transformed = preprocessor.transform(observations).reshape(1, -1)
model_output, _ = model({"obs": transformed})
內容解密:
這段程式碼展示瞭如何使用get_preprocessor來存取策略所使用的前處理器,並將原始觀察值轉換為模型可接受的格式。首先,我們建立了一個GymEnvironment例項,並取得其觀察空間。然後,我們使用get_preprocessor獲得前處理器,並將原始觀察值轉換為適合模型的格式。最後,我們將轉換後的觀察值輸入模型,獲得模型的輸出。
取得Q值和動作分佈
獲得模型輸出後,我們可以存取Q值和動作分佈:
q_values = model.get_q_value_distributions(model_output)
print(q_values)
action_distribution = policy.dist_class(model_output, model)
sample = action_distribution.sample()
print(sample)
內容解密:
這段程式碼展示瞭如何從模型輸出中取得Q值和動作分佈。首先,我們呼叫get_q_value_distributions方法獲得Q值。然後,我們使用策略的dist_class屬性建立一個動作分佈例項,並從中取樣一個動作。
組態RLlib實驗
現在,讓我們討論如何組態和執行RLlib實驗。RLlib提供了豐富的組態選項,以滿足不同的實驗需求。
組態類別
RLlib的組態選項分為以下類別:
training():組態訓練相關的選項。environment():組態環境相關的選項。rollouts():組態rollout workers的行為。exploration():組態探索策略。resources():組態計算資源。offline_data():組態離線資料訓練。multi_agent():組態多代理訓練。
這些類別涵蓋了RLlib實驗的大部分組態需求。透過鏈式呼叫這些方法,我們可以輕鬆地組態和執行RLlib實驗。
組態強化學習訓練的高階選項
一旦確定使用某種強化學習演算法並希望進一步最佳化其效能時,演算法特定的組態在訓練過程中變得尤為重要。在實際操作中,RLlib 提供了良好的預設值讓使用者能夠順利開始。
資源組態
無論是在本地端還是在叢集上使用 Ray RLlib,都可以指定用於訓練程式的資源。以下是一些重要的選項。以 DQN 演算法為例,但這些選項同樣適用於其他 RLlib 演算法:
from ray.rllib.algorithms.dqn import DQNConfig
config = DQNConfig().resources(
num_gpus=1,
num_cpus_per_worker=2,
num_gpus_per_worker=0,
)
內容解密:
num_gpus=1:指定用於訓練的 GPU 數量。這個值也可以是小數,例如,若在 DQN 中使用四個 rollout workers (num_rollout_workers=4),可以設定num_gpus=0.25將所有四個 workers 放在同一個 GPU 上,以利用潛在的加速效果。num_cpus_per_worker=2:設定每個 rollout worker 使用的 CPU 數量。num_gpus_per_worker=0:設定每個 worker 使用的 GPU 數量。
Rollout Worker 組態
RLlib 允許使用者組態如何計算 rollout 以及如何分配它們:
from ray.rllib.algorithms.dqn import DQNConfig
config = DQNConfig().rollouts(
num_rollout_workers=4,
num_envs_per_worker=1,
create_env_on_local_worker=True,
)
內容解密:
num_rollout_workers=4:指定使用的 Ray workers 數量。num_envs_per_worker=1:指定每個 worker 評估的環境數量。這允許將環境評估進行「批次」處理,特別是在模型評估需要較長時間時,可以加速訓練。create_env_on_local_worker=True:當num_rollout_workers > 0時,本地 worker 不需要環境。設定此選項為 True 可以在本地 worker 上建立環境。
環境組態
from ray.rllib.algorithms.dqn import DQNConfig
config = DQNConfig().environment(
env="CartPole-v1",
env_config={"my_config": "value"},
observation_space=None,
action_space=None,
render_env=True,
)
內容解密:
env="CartPole-v1":指定用於訓練的環境,可以是已知的 Gym 環境或自定義環境的類別名稱。env_config={"my_config": "value"}:可選地為環境指定組態字典,這些組態將傳遞給環境建構函式。observation_space=None和action_space=None:可以指定環境的觀測空間和動作空間,如果未指定,將從環境中推斷。render_env=True:允許渲染環境,需要實作環境的 render 方法。
與 RLlib 環境協作
RLlib 支援多種環境,包括 Gym 環境、VectorEnv、MultiAgentEnv 和 ExternalEnv。其中,MultiAgentEnv 允許訓練具有多個代理的模型,而 ExternalEnv 可以用於連線外部模擬器到 RLlib。
MultiAgentEnv
允許多個代理與環境互動,需要定義代理之間的介面和互動邏輯。
ExternalEnv
提供了一個簡單的客戶端-伺服器架構,用於與外部模擬器進行通訊,支援透過 REST API 進行通訊。
多代理環境下的強化學習:以Ray RLlib為例
在強化學習(RL)領域中,多代理環境(Multi-Agent Environment)是一個重要的研究方向。Ray RLlib是一個強大的強化學習框架,它提供了對多代理環境的原生支援。在本篇文章中,我們將探討如何在Ray RLlib中定義和訓練多代理環境。
多代理環境的基本概念
在多代理環境中,我們有多個代理(Agent)在同一環境中互動。每個代理都有自己的觀察(Observation)、動作(Action)和獎勵(Reward)。與單代理環境不同,多代理環境需要考慮多個代理之間的互動和協調。
定義多代理環境
在Ray RLlib中,定義多代理環境需要繼承MultiAgentEnv類別。以下是一個簡單的例子,定義了一個具有兩個代理的多代理迷宮環境:
from ray.rllib.env.multi_agent_env import MultiAgentEnv
from gym.spaces import Discrete
class MultiAgentMaze(MultiAgentEnv):
def __init__(self, *args, **kwargs):
self.action_space = Discrete(4)
self.observation_space = Discrete(5*5)
self.agents = {1: (4, 0), 2: (0, 4)}
self.goal = (4, 4)
self.info = {1: {'obs': self.agents[1]}, 2: {'obs': self.agents[2]}}
def reset(self):
self.agents = {1: (4, 0), 2: (0, 4)}
return {1: self.get_observation(1), 2: self.get_observation(2)}
def get_observation(self, agent_id):
seeker = self.agents[agent_id]
return 5 * seeker[0] + seeker[1]
def get_reward(self, agent_id):
return 1 if self.agents[agent_id] == self.goal else 0
def is_done(self, agent_id):
return self.agents[agent_id] == self.goal
def step(self, action):
agent_ids = action.keys()
for agent_id in agent_ids:
seeker = self.agents[agent_id]
if action[agent_id] == 0: # move down
seeker = (min(seeker[0] + 1, 4), seeker[1])
elif action[agent_id] == 1: # move left
seeker = (seeker[0], max(seeker[1] - 1, 0))
elif action[agent_id] == 2: # move up
seeker = (max(seeker[0] - 1, 0), seeker[1])
elif action[agent_id] == 3: # move right
seeker = (seeker[0], min(seeker[1] + 1, 4))
else:
raise ValueError("Invalid action")
self.agents[agent_id] = seeker
observations = {i: self.get_observation(i) for i in agent_ids}
rewards = {i: self.get_reward(i) for i in agent_ids}
done = {i: self.is_done(i) for i in agent_ids}
done["__all__"] = all(done.values())
return observations, rewards, done, self.info
程式碼解密:
此程式碼定義了一個多代理迷宮環境,具有兩個代理。reset方法重置環境,step方法根據代理的動作更新環境狀態。get_observation、get_reward和is_done方法分別傳回代理的觀察、獎勵和完成狀態。
多代理環境的訓練
在定義好多代理環境後,我們可以使用Ray RLlib的訓練API來訓練代理。具體的訓練過程取決於所選擇的強化學習演算法和超引數。
# 以下是一個簡單的訓練範例
from ray import tune
from ray.rllib.agents.ppo import PPOTrainer
config = {
"env": MultiAgentMaze,
"num_gpus": 0,
"num_workers": 1,
"framework": "tf"
}
tune.run(PPOTrainer, config=config)
程式碼解密:
此程式碼使用Ray RLlib的PPO演算法訓練多代理迷宮環境。config字典定義了訓練組態,包括環境、GPU數量、worker數量和框架。