1.RLlibとは
RLlib は、Ray 上に構築された業界グレードの強化学習 (RL) ライブラリです。RLlib は、さまざまな産業および研究アプリケーションに適した、拡張性の高い統合 API を提供します。
次に、Anaconda で Ray RLlib 環境を作成します。
conda create -n RayRLlib python=3.7
conda activate RayRLlib
conda install pytorch==1.12.1 torchvision==0.13.1 torchaudio==0.12.1 cudatoolkit=11.3 -c pytorch
pip install tensorflow -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install tensorflow-probability -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install ipykernel -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pyarrow
pip install gputil
pip install "ray[rllib]" -i https://pypi.tuna.tsinghua.edu.cn/simple
インタプリタとして上記の RayLib を選択し、ジム環境とレイ ライブラリをインポートします。PPO アルゴリズムを使用して、ジム環境をカスタマイズします。
import gymnasium as gym
from ray.rllib.algorithms.ppo import PPOConfig
2. ジムに似た小規模なゲーム クラスを定義する
SimpleCorridor というカスタム ジム環境が定義されています。この環境では、エージェントは廊下の出口に到達するために右に移動することを学習する必要があります。エージェントは出口に到達するために廊下を移動する必要があります。S はスタート地点、G はゴールを表し、コリドーの長さは設定可能です。エージェントが選択できるアクションは 0 (左) と 1 (右) です。観測値は、現在位置のインデックスを表す浮動小数点数です。目標位置に到達しない限り、各ステップの報酬値は -0.1 になります (報酬値 +1.0)。
和文訳版:
エージェントが出口に到達するために右に移動することを学ばなければならない廊下。
---------------------
| S | 1 | 2 | 3 | G | S=開始; G=ゴール; 廊下の長さ=5
----------
選択できるアクションは次のとおりです。 0=左; 1=right
観測値は、現在のフィールド インデックスを示す浮動小数点です。たとえば、
開始位置の場合は 0.0、開始位置の隣のフィールドの場合は 1.0 などです。
報酬は、ゴール (+1.0) に到達する場合を除き、すべてのステップで -0.1 です。
クラスは次のように定義されます
# Define your problem using python and Farama-Foundation's gymnasium API:
class SimpleCorridor(gym.Env):
def __init__(self, config):
# 初始化环境,包括设置结束位置、当前位置、动作空间(两个离散动作:左和右)和观察空间。
self.end_pos = config["corridor_length"]
self.cur_pos = 0
self.action_space = gym.spaces.Discrete(2) # left and right
self.observation_space = gym.spaces.Box(0.0, self.end_pos, shape=(1,))
def reset(self, *, seed=None, options=None):
# 重置环境,将当前位置设为0,并返回初始观察值。
"""Resets the episode.
Returns:
Initial observation of the new episode and an info dict.
"""
self.cur_pos = 0
# Return initial observation.
return [self.cur_pos], {}
def step(self, action):
# 根据给定的动作在环境中执行一步操作。根据动作和当前位置更新智能体位置。
# 当到达走廊末端(目标)时,设置terminated标志。
# 当目标达成时,奖励为+1.0,否则为-0.1。
# 返回新的观察值、奖励、terminated标志、truncated标志和信息字典。
"""Takes a single step in the episode given `action`.
Returns:
New observation, reward, terminated-flag, truncated-flag, info-dict (empty).
"""
# Walk left.
if action == 0 and self.cur_pos > 0:
self.cur_pos -= 1
# Walk right.
elif action == 1:
self.cur_pos += 1
# Set `terminated` flag when end of corridor (goal) reached.
terminated = self.cur_pos >= self.end_pos
truncated = False
# +1 when goal reached, otherwise -1.
reward = 1.0 if terminated else -0.1
return [self.cur_pos], reward, terminated, truncated, {}
3. PPOベースの強化学習トレーニング
次のコードは、Ray RLlib を通じて PPOConfig オブジェクトを作成し、SimpleCorridor 環境を使用します。環境構成を設定し、コリドーの長さを 28 に設定します。num_rollout_workers を 10 に設定して、環境探索を並列化します。構成を通じて PPO アルゴリズム オブジェクトを構築します。
config = (
PPOConfig().environment(
# Env class to use (here: our gym.Env sub-class from above).
env=SimpleCorridor,
# Config dict to be passed to our custom env's constructor.
# Use corridor with 20 fields (including S and G).
env_config={"corridor_length": 28},
)
# Parallelize environment rollouts.
.rollouts(num_rollout_workers=10)
)
# Construct the actual (PPO) algorithm object from the config.
algo = config.build()
# 循环训练PPO算法20次迭代,输出每次迭代的平均奖励。
for i in range(20):
results = algo.train()
print(f"Iter: {i}; avg. reward={results['episode_reward_mean']}")
強化学習トレーニングは、10 個の並列ロールアウト ワーカーと 20 回のトレーニング反復を使用して、上記のコードを通じて実行されます。
トレーニング中の平均報酬出力は次のとおりです。
(RolloutWorker pid=334231) /home/yaoyao/anaconda3/envs/RayRLlib/lib/python3.7/site-packages/gymnasium/spaces/box.py:227: UserWarning: WARN: Casting input x to numpy array.
...
Iter: 0; avg. reward=-24.700000000000117
Iter: 1; avg. reward=-29.840909090909282
...
Iter: 18; avg. reward=-1.7286713286713296
Iter: 19; avg. reward=-1.7269503546099298
4. モデルを検証する
コリドー環境で完全なエピソードを実行します。最初の観測から開始して、アルゴリズムを使用してアクションを計算し、そのアクションを環境に適用して、新しい観測、報酬、終了フラグ、切り捨てフラグを取得します。報酬を蓄積し、ループの最後に合計報酬を出力します。
# 在训练完成后,使用训练好的算法在新的走廊环境(长度为10)中进行推理
env = SimpleCorridor({"corridor_length": 10})
# 首先初始化环境并获得初始观察值。
terminated = truncated = False
total_reward = 0.0
# 玩1个回合
while not terminated and not truncated:
# Compute a single action, given the current observation
# from the environment.
action = algo.compute_single_action(obs)
# Apply the computed action in the environment.
obs, reward, terminated, truncated, info = env.step(action)
# Sum up rewards for reporting purposes.
total_reward += reward
# 结果输出
print(f"Played 1 episode; total-reward={total_reward}")
トレーニング後に得られたモデルは指定された環境で検証され、最終的な報酬は +0.1 となり、当初の -24 と比較して大幅な改善が見られます。
Played 1 episode; total-reward=0.10000000000000009
この場合、廊下の長さは 10 であるため、エージェントは最適な戦略 (常に右に歩く) を採用し、得られる最大の報酬は次のようになります。
エージェントが PPO アルゴリズムを通じて最適な戦略を学習したことがわかります。