見出し画像

Gym Retro入門 / 完了条件と報酬関数

1. 完了条件と報酬関数

Gym Retroの「ソニック・ザ・ヘッジホッグ」の環境を学習の目標にあわせて、「完了条件」と「報酬関数」を変更します。今回はハイスコアではなく、レベルの攻略を目標とします。

Gym Retroの初期設定では次のようになっています。

◎完了条件
・ライフが0になった時

◎報酬関数
・獲得したスコアの値

これを、学習の目標にあわせて次のように変更します。

◎完了条件
・ライフが2になった時
・レベルを攻略した時

◎報酬関数
・右に進捗したX座標の変化量

「右に進捗したX座標の変化量」は、「現在のX座標 - これまでの最大X座標」で、逆進捗のペナルティはなしとします。さらに、学習効率を考えて、最大で1.0になるようスケール調整も行います。

Gym Retroの「完了条件」と「報酬関数」は、「ゲームインテグレーション」の「scenario.json」で指定するのがスマートですが、今回はお手軽に環境ラッパーで設定します。

2. CustomRewardAndDoneラッパー

「完了条件」と「報酬関数」をカスタマイズする環境ラッパーを作成します。

# パラメータ
GOAL_X = 9600
REWARD_SCALE = 0.1

# CustomRewardAndDoneラッパー
class CustomRewardAndDoneEnv(gym.Wrapper):
   # 初期化
   def __init__(self, env):
       super(CustomRewardAndDoneEnv, self).__init__(env)
       self._cur_x = 0
       self._max_x = 0

   # リセット
   def reset(self, **kwargs):
       self._cur_x = 0
       self._max_x = 0
       return self.env.reset(**kwargs)

   # ステップ
   def step(self, action):
       obs, rew, done, info = self.env.step(action)

       # 完了条件のカスタマイズ
       if info['lives'] == 2 or info['x'] > GOAL_X:
           done = True

       # 報酬関数のカスタマイズ
       self._cur_x = info['x']
       rew = max(0, self._cur_x - self._max_x)
       self._max_x = max(self._max_x, self._cur_x)
       rew *= REWARD_SCALE # スケールの調整
       return obs, rew, done, info

Gym Retroのenv.step()の戻り値の「info」には、ゲームインテグレーションの「data.json」で定義したゲーム変数の現在の値が返ってきます。

{'act': 0, 'screen_x': 0, 'zone': 0, 'level_end_bonus': 0, 'screen_y': 768, 'score': 0, 'lives': 3, 'screen_x_end': 9407, 'rings': 0, 'x': 80, 'y': 944}

これを利用して、完了条件と報酬関数をカスタマイズしています。

3. 動作確認

完了条件と報酬関数の動作確認を行うには、「retro-movies」の「human-recorder.py」をカスタマイズして使うと便利です。

(1)先ほど作った「CustomRewardAndDoneEnv」をコードに追加後、環境生成の次の行でそのラッパーを適用。

env = retro.make(game=args.game, state=args.state, use_restricted_actions=retro.Actions.ALL, scenario=args.scenario)
env = CustomRewardAndDoneEnv(env) # ←追加
obs = env.reset()

(2)env.step()の次の行で、報酬とエピソード完了のログを出力
「human-recorder.py」には環境リセットもなかったので、それも追加しています。

obs, rew, done, info = env.step(action)
if rew != 0:
   print('reward:', rew)
if done:
   print('done: True')
   obs = env.reset()
#print(info)

(3)以下のコマンドで実行

$ python human-recorder.py --game=SonicTheHedgehog-Genesis --state=GreenHillZone.Act1

ゲームの実行画面と共に、以下のようなログが表示されます。

reward: 0.5
reward: 0.5
reward: 0.6
reward: 0.6
done: True

「完了条件」と「報酬関数」が正しく設定されているか確認できます。
操作方法は次の通りです。

十字ボタン: 方向キー
スタート: Enter
Bボタン: Xキー


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