見出し画像

Gym Retro入門 / AtariラッパーとRetroラッパー

1. 環境ラッパー

強化学習のエージェントは環境と対話します。エージェントはenv.step()で「行動」を渡し、「次の状態」「報酬」「エピソード完了」「情報」を取得します。

state, reward, done, info = env.step(action)

「環境ラッパー」は、この処理をカスタマイズします。環境を環境ラッパーでラップすると、環境に新しい機能が追加されます。

2. Atariラッパー

「Atariラッパー」は、Atari環境用の「環境ラッパー」です。DQNの論文で紹介されている各種手法が提供されています。OpenAI Baselinesのリポジトリの「atari_wrapper.py」に含まれています。

◎No-Operationラッパー

NoopResetEnv(env, noop_max=30)

環境リセット後、0〜30ステップ(ランダム)の間、何もしない行動(行動=0)を実施します。ゲーム開始の初期状態にばらつきを与え、特定の開始状態に特化して学習することを防ぎます。

◎FireResetラッパー

FireResetEnv(env)

環境リセット時にFireを実施します。Atari環境はFireでゲーム開始しますが、それを覚えるまで学習開始しないので、強制的に開始させます。

◎EpisodicLifeラッパー

EpisodicLifeEnv(env)

Atariゲームにはライフが複数あり、ライフが0になるとエピソード完了となります。複数回の失敗を待つのは面倒なので、ライフが1減ったらエピソード完了とします。ただし、1回失敗しただけでゲームリセットしてしまうと、初期状態ばかり学習することになってしまいます。そこで、ライフ0になった時だけゲームリセットするようにします。

◎MaxAndSkipラッパー

MaxAndSkipEnv(env)

Atariゲームは60Hzでゲームが進行しますが、この速さで動かすと速いので、4フレームごとに行動を選択し、4フレーム連続で同じ行動を採るようにします。

◎ClipRewardラッパー

ClipRewardEnv(env)

各ステップで得られる報酬を-1、0、1のいずれかに固定します。これによって、環境ごとの報酬の大きさの違いをなくし、複数の環境を同じモデルで実行できるようになります。

◎WrapFrameラッパー

WarpFrame(env, width=84, height=84, grayscale=True, dict_space_key=None)

画面イメージを84x84のグレースケールに変換します。

◎FrameStackラッパー

FrameStack(env, k)

最近4フレーム分の画面イメージを、環境の状態として利用します。

◎ScaledFloatFrameラッパー

ScaledFloatFrame(env)

環境の状態を255.0で割ることで正規化します。

◎Atari環境の生成

# Atari環境の生成
def make_atari(env_id, max_episode_steps=None):
   env = gym.make(env_id)
   assert 'NoFrameskip' in env.spec.id
   env = NoopResetEnv(env, noop_max=30)
   env = MaxAndSkipEnv(env, skip=4)
   if max_episode_steps is not None:
       env = TimeLimit(env, max_episode_steps=max_episode_steps)
   return env

Atari環境を生成するメソッドです。引数は環境ID、最大ステップ数になります。

◎DeepMindスタイルのラッパーの追加

# DeepMindスタイルのラッパー
def wrap_deepmind(env, episode_life=True, clip_rewards=True, frame_stack=False, scale=False):
   if episode_life:
       env = EpisodicLifeEnv(env)
   if 'FIRE' in env.unwrapped.get_action_meanings():
       env = FireResetEnv(env)
   env = WarpFrame(env)
   if scale:
       env = ScaledFloatFrame(env)
   if clip_rewards:
       env = ClipRewardEnv(env)
   if frame_stack:
       env = FrameStack(env, 4)
   return env

DeepMindスタイルのラッパーを追加するメソッドです。引数は環境、EpisodicLifeラッパー、RewardClippingラッパー、FrameStackラッパー、ScaledFloadFrameラッパーの有効・無効になります。

3. Retroラッパー

「Retroラッパー」は、Retro環境用の「環境ラッパー」です。「Open Retro Contest」で考え出された各種手法が提供されています。OpenAI Baselinesのリポジトリの「retro_wrapper.py」に含まれています。

◎StochasticFrameSkipラッパー

StochasticFrameSkip(env, n, stickprob)

決定論的環境は多くの場合、確率的な「スティッキーフレームスキップ」を使用する必要があります。標準の「フレームスキップ」と同様に、「スティッキーフレームスキップ」は4フレームに1行動を適用します。ただし、行動ごとに、確率0:25で1フレーム遅延させ、代わりにそのフレームに前の行動を適用します。

◎PartialFrameStackラッパー

PartialFrameStack(env, k, channel=1)

フレームの任意の1チャンネルのみスタックするFrameStackラッパーです。

◎Downsampleラッパー

Downsample(env, ratio)

画像のダウンサンプリングを行います。

◎Rgb2grayラッパー

Rgb2gray(env)

グレースケールに変換します。

◎MovieRecordラッパー

MovieRecord(env, savedir, k)

kエピソード毎にムービー(*.bk2)を保存します。ムービーは「インテグレーションUI」やPythonコードで再生できます。

◎AppendTimeoutラッパー

AppendTimeout(env)

タイムアウトを追加します。

◎StartDoingRandomActionsラッパー

StartDoingRandomActionsWrapper(env, max_random_steps, on_startup=True, every_episode=False)

環境リセット後、0〜30ステップ(ランダム)の間、ランダム行動を実施します。

◎Retro環境の生成

def make_retro(*, game, state=None, max_episode_steps=4500, **kwargs):
   import retro
   if state is None:
       state = retro.State.DEFAULT
   env = retro.make(game, state, **kwargs)
   env = StochasticFrameSkip(env, n=4, stickprob=0.25)
   if max_episode_steps is not None:
       env = TimeLimit(env, max_episode_steps=max_episode_steps)
   return env

Retro環境を生成するメソッドです。引数はRetro環境ID、Retro状態、最大エピソード数、追加引数になります。

◎DeepMindスタイルのラッパーの追加

# DeepMindスタイルのラッパーの追加
def wrap_deepmind_retro(env, scale=True, frame_stack=4):
   env = WarpFrame(env)
   env = ClipRewardEnv(env)
   if frame_stack > 1:
       env = FrameStack(env, frame_stack)
   if scale:
       env = ScaledFloatFrame(env)
   return env

DeepMindスタイルのラッパーを追加するメソッドです。引数は環境、ScaledFloatFrameラッパー、FrameStackラッパーの有効・無効になります。

◎SonicDiscretizerラッパー

SonicDiscretizer(env)

ソニック・ザ・ヘッジホッグの行動空間をMultiBinary(12)からDiscrete(7)に変換します。GymRetroでは必須のラッパーになります。

◎RewardScalerラッパー

RewardScaler(env, scale=0.01)

報酬を0.01倍にスケーリングします。これは非常に重要でパフォーマンスに大きく影響します。

◎AllowBacktrackingラッパー

AllowBacktracking(env)

ΔXではなく、Δmax(X)を報酬として使用します。この方法では、レベルで正面(右)に進む方法がない場合、エージェントが後方に探索することを推奨しません。

4. Commonラッパー

「Commonラッパー」は、OpenAI Baselinesで提供されている「環境ラッパー」です。OpenAI Baselinesのリポジトリの「wrappers.py」に含まれています。

◎TimeLimitラッパー

TimeLimit(env, max_episode_steps=None)

1エピソードの最大ステップ数を指定します。

◎ClipActionsWrapperラッパー

ClipActionsWrapper(env, action)

行動空間のlowとhighで行動をクリッピングします。

5. ラッパーの利用例

ラッパーの利用例のコードは、次のようになります。

import retro
import os
from baselines.common.retro_wrappers import *

# 環境の生成
env = retro.make(game='SonicTheHedgehog-Genesis')

# 10エピソード毎にビデオを保存
os.makedirs('./movie', exist_ok=True)
env = MovieRecord(env, './movie', k=10)

# フレームスキップおよびスティッキー行動
env = StochasticFrameSkip(env, n=4, stickprob=0.25)

# RGB画像をグレースケールおよびスケーリング
env = WarpFrame(env, width=112, height=128, grayscale=True)

state = env.reset()
while True:
   # 環境の描画
   env.render()

   # 行動の取得
   action = env.action_space.sample()

   # 1ステップの実行
   state, reward, done, info = env.step(action)

   # エピソードの完了時
   if done:
       state = env.reset()
env.close()


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