見出し画像

PettingZoo 入門 (2) - API

「PettingZoo」のAPIについてまとめました。

・Python 3.8.12
・PettingZoo 1.20.1

前回

1. 学習環境の初期化

「PettingZoo」の使い方は、「OpenAI Gym」 と似ています。学習環境の初期化方法は、次のとおりです。

from pettingzoo.butterfly import pistonball_v6
env = pistonball_v6.env()

引数で各種設定を行うことができます。

cooperative_pong.env(
    ball_speed=18, 
    left_paddle_speed=25,
    right_paddle_speed=25, 
    is_cake_paddle=True, 
    max_cycles=900, 
    bounce_randomness=False)

2. 学習環境との対話

学習環境は、「OpenAI Gym」と同様のインターフェイスを介して対話することができます。

env.reset()
for agent in env.agent_iter():
    observation, reward, done, info = env.last()
    action = policy(observation, agent)
    env.step(action)

主なメソッドは、次のとおりです。

◎ agent_iter(max_iter=2**63)
現在のエージェントを生成するIteratorを返す。全エージェントがエピソード完了した時、またはmax_iter(ステップが実行された) 時に終了。

◎ last(observe=True)
現在行動可能なエージェントの観察、報酬、エピソード完了、情報を返す。報酬はエージェントが最後に行動してから受け取った累積報酬。observeにFalseに設定した場合、観察は計算されずNoneを返す。1つのエージェントが終了しても、学習環境が終了したことにはならないことに注意。

◎ reset()
学習環境をリセット。

◎ step(action)
学習環境内のエージェント行動を1ステップ実行し、次のエージェントに制御を切り替える。

3. Additional Environment API

「PettingZoo」はゲームを「AEC」(Agent Environment Cycle)としてモデル化しており、マルチエージェントRLが考えるあらゆるゲームをサポートすることを可能にします。そのため「PettingZoo」には、おそらく必要ないけれども、必要な時にはとても重要な役割を果たす、低レベルな関数や属性が含まれています。

◎ agents
現在のエージェント名のリスト。通常は整数。学習の進行に応じて変更される可能性がある (エージェントを追加および削除する場合ある)。

◎ num_agents
エージェント名のリストの長さ。

◎ agent_selection
現在選択されているエージェントに対応する環境の属性。

◎ observation_space(agent)
任意のエージェントの状態空間。値の変更は禁止。

◎ action_space(agent)
任意のエージェントの行動空間。値の変更は禁止。

◎ dones
現在のエージェントのエピソード完了の辞書。last()はこの属性にアクセス。

dones = {0:[first agent's done state], 1:[second agent's done state] ... n-1:[nth agent's done state]}

◎ infos
現在のエージェントごとの情報の辞書。last()はこの属性にアクセス。

infos = {0:[first agent's info], 1:[second agent's info] ... n-1:[nth agent's info]}

◎ observe(agent)
現在のエージェントの観察の辞書。last()はこの属性にアクセス。

◎ rewards
現在のエージェントの報酬の辞書。最後のステップの後に生成された瞬間的な報酬を取得。last()はこの属性にアクセス。

{0:[first agent's reward], 1:[second agent's reward] ... n-1:[nth agent's reward]}

◎ seed(seed=None)
乱数シードの指定。reset()の前に呼び出す。

◎ render(mode='human')
学習環境からレンダリングされたフレームを表示。

◎ close()
レンダリングウィンドウを閉じる。

4. Optional API Components

基本APIでは必須ありませんが、多くの下流ラッパーやユーティリティは以下の属性やメソッドに依存しており、追加が不可能な特殊な状況を除いて、新しい環境には、追加した方が良いです。

◎ possible_agents
学習環境が生成する全てのエージェントのリスト。観察空間や行動空間のエージェントのリストと同じ。これは、プレイやリセットによって変更することはできない。

◎ max_num_agents
possible_agents リストの長さ。

◎ observation_spaces
各エージェントの観察空間の辞書。これは、プレイやリセットで変更することはできない。

◎ action_spaces
各エージェントの行動空間の辞書。これは、プレイやリセットで変更することはできない。

◎ state()
学習環境の現在の状態についてのグローバルな観測結果を返す。全ての学習環境がこの機能をサポートするわけではない。

◎ state_space
学習環境のグローバル観察空間です。全ての学習環境がこの機能をサポートするわけではない。

5. Notable Idioms

◎ 学習環境全体が終了したかどうかの確認
エージェントが終了すると、エージェントリストから削除されるため、全ての学習環境が終了した時、エージェントリストは空になります。つまり、env.agentsが空な場合、学習環境がdoneされたことを示します。

◎ 学習環境のアンラップ
ラップされた学習環境があり、全てのラッパーレイヤーの下にあるラップされていない学習環境を取得したい場合、 .unwrapped属性を使用することができます。

base_env = prospector_v4.env().unwrapped

◎ エージェント数の変化(死)
エージェントは、学習環境の中で死んだり生成されたりすることがあります。エージェントが死ぬと、dones辞書のそのエントリがTrueに設定され、次の選択されたエージェントとなり(または同じくdonesされた他のエージェントの後に)、それが取る行動はNoneであることが要求されます。この空虚なステップがとられた後、エージェントは、エージェントと他の変更可能な属性から削除されます。エージェント生成は、エージェントと他の変更可能な属性にそれを追加し、ある時点で agent_iter でそれに遷移させるだけで行うことができます。

◎ エージェントとしての学習環境
ある種のケースでは、エージェントと学習環境の行動を分離することが勉強になります。これは、学習環境をエージェントとして扱うことで実現できます。env.agentsで学習環境のアクターをenvと呼び、行動としてNoneを取らせることを推奨します。

◎ 生の学習環境
学習環境はデフォルトで、エラーメッセージを処理し、間違った使い方をした場合の妥当な動作を保証する軽量なラッパーで包まれています。しかし、これらはごくわずかなオーバーヘッドを追加するだけです。もし、これらのない学習環境を作りたいのであれば、各モジュールに含まれる raw_env() コンストラクタを使用することで実現可能です。

env = prospector_v4.raw_env(<environment parameters>)

6. Parallel API

メインAPIに加え、全てのエージェントが同時に行動や観察を行う学習環境のためのSecondary Parallel APIも用意されています。Parallel APIをサポートする学習環境は、<game>.parallel_env()で作成することができます。このAPIは、Partially Observable Stochastic Games (POSG) のパラダイムに基づき、RLLib の MultiAgent 環境仕様に似ていますが、エージェント間で異なる観察・行動空間を許容している点が異なります。

◎ 使用例
環境は、以下のように操作できます。

parallel_env = pistonball_v1.parallel_env()
observations = parallel_env.reset()
max_cycles = 500
for step in range(max_cycles):
    actions = {agent: policy(observations[agent], agent) for agent in parallel_env.agents}
    observations, rewards, dones, infos = parallel_env.step(actions)

◎ Full API
agents, num_agents, possible_agents, max_num_agents, observation_spaces, action_spaces 属性が利用可能で、これらは上記の説明にある通りです。

◎ render(mode='human'), seed(seed=None), close()
上記の説明にあるようなメソッド。

◎ step(actions)
エージェント名をキーにした行動の辞書を受け取る。観察辞書、報酬辞書、エピソード完了辞書、情報辞書を返すが、各辞書はエージェントによってキーが設定される。

◎ reset()
学習環境をリセットし、観察結果の辞書を返す。

7. SuperSuit

「SuperSuit」は、フレームスタッキングや RGB観察をグレイスケールに変更するような、一般的な前処理を行うための素晴らしいラッパーを含んでいます。また、「PettingZoo」に加え、「OpenAI Gym」もサポートしています。

8. Utils

「PettingZoo」には、学習環境との簡単な対話を実装するのに役立つユーティリティがあります。学習環境の開発を容易にするためのユーティリティは、開発者向けドキュメントに記載されています。

◎ Average Total Reward Util
ドキュメントに示されているように、学習環境の平均総報酬は、エピソードの全ステップにわたって全エージェントを合計したものです。
この値は、最も単純なベースラインであるランダムポリシーを確立するために重要です。

from pettingzoo.utils import average_total_reward
from pettingzoo.butterfly import pistonball_v6
env = pistonball_v6.env()
average_total_reward(env, max_episodes=100, max_steps=10000000000)

max_episodes と max_steps の両方が評価の総数を制限する場合 (最初のヒットで評価が停止)

◎ Manual Control
学習環境をマニュアル操作する方法は、次のとおりです。

from pettingzoo.butterfly knights_archers_zombies_v10
knights_archers_zombies_v10.manual_control(<environment parameters>)

◎ Random Demo
学習環境をランダムポリシーで操作する方法は、次のとおりです。

from pettingzoo.utils import random_demo
random_demo(env, render=True, episodes=1)

◎ Playing Alongside Trained Policies
学習環境の一人のエージェントを操作し、他のエージェントを学習済みポリシーで操作する方法は、次のとおりです。

import time
from pettingzoo.butterfly import knights_archers_zombies_v10

env = knights_archers_zombies_v10.env()
env.reset()

manual_policy = knights_archers_zombies_v10.ManualPolicy(env)

for agent in env.agent_iter():
    observation, reward, done, info = env.last()

    if agent == manual_policy.agent:
        action = manual_policy(observation, agent)
    else:
        action = policy(observation, agent)

    env.step(action)

    env.render()
    time.sleep(0.05)

    if done:
        env.reset()

「ManualPolicy」は、いくつかのデフォルト引数を受け付けます。

◎ agent_id
キーボードで操作する学習環境内のエージェントを整数で指定。どのエージェントが利用可能で、そのインデックスは何なのかを問い合わせるには、manual_policy.availabla_agents を使用。

◎ show_obs
現在選択されているエージェントからの観察があれば、それを表示するブール値。

◎ Observation Saving
エージェントが画像で観察を行った場合、その観察結果を画像ファイルに保存することができます。この関数は、学習環境と指定されたエージェントを取り込みます。エージェントが指定されていない場合、その学習環境に対して現在選択されているエージェントが選択されます。all_agents が True で渡された場合、学習環境内の全エージェントの観察が保存されます。デフォルトでは、画像は現在の作業ディレクトリに、学習環境名と一致するフォルダに保存されます。保存される画像は、観察しているエージェントの名前と一致します。save_dir が渡された場合、画像が保存される新しいフォルダが作成されます。この関数は、必要に応じて学習や評価中に呼び出すことができます。そのため、この関数を使用する前に、学習環境をリセットする必要があります。

from pettingzoo.utils import save_observation
from pettingzoo.butterfly import pistonball_v6
env = pistonball_v6.env()
env.reset()
save_observation(env, agent=None, all_agents=False, save_dir=os.getcwd())

9. 参考



この記事が気に入ったらサポートをしてみませんか?