OpenAI Gym の Atari Environment の命名規則と罠について

# TL; DR
- OpenAI Gym の Atari 環境を使うときは、 `{}NoFrameskip-v4` という名前になっている環境を使おう
    - 環境側でのフレームスキップなし
    - ALE側での `repeat_action_probability` なし

# OpenAI Gym の Atari 環境について

## はじめに

この記事は、OpenAI Gym 0.10.5 版 (2018/04/05 リリース；https://github.com/openai/gym/releases/tag/v0.10.5) についてとなります。それ以外におけるバージョンでは何も確認をしていませんので、ご注意ください。

```bash
$ pip freeze | grep gym
gym==0.10.5
```

## 環境の一覧

参考：[python - List all environment id in openai gym - Stack Overflow](https://stackoverflow.com/questions/48980368/list-all-environment-id-in-openai-gym/48989130#48989130 "python - List all environment id in openai gym - Stack Overflow")

現在 Gym に登録されている環境の一覧は次のコードで一覧を全出力できます：

```python
from gym import envs
    all_envs = envs.registry.all()
    env_ids = [env_spec.id for env_spec in all_envs]
    for env_id in env_ids:
        print(env_id)
```

## 命名規則

今 (2018/05/14) の所、OpenAI Gym の Atari においては、各ゲームごとに次の環境が確認できます ( `{}` に入るのがゲーム名です)：

- {}-v0
- {}-v4
- {}Deterministic-v0
- {}Deterministic-v4
- {}NoFrameskip-v0
- {}NoFrameskip-v4
- {}-ram-v0
- {}-ram-v4
- {}-ramDeterministic-v0
- {}-ramDeterministic-v4
- {}-ramNoFrameskip-v0
- {}-ramNoFrameskip-v4

例えば、Pong なら次のとおりです：

- Pong-v0
- Pong-v4
- PongDeterministic-v0
- PongDeterministic-v4
- PongNoFrameskip-v0
- PongNoFrameskip-v4
- Pong-ram-v0
- Pong-ram-v4
- Pong-ramDeterministic-v0
- Pong-ramDeterministic-v4
- Pong-ramNoFrameskip-v0
- Pong-ramNoFrameskip-v4

それぞれについている suffix の意味を調べようと思います。
OpenAI Gym のソースコードを追うと、意味がわかります：

- https://github.com/openai/gym/blob/v0.10.5/gym/envs/__init__.py#L424
- https://github.com/openai/gym/blob/v0.10.5/gym/envs/atari/atari_env.py#L19

それぞれの suffix は部分的に意味をもった組み合わせになっているため、上述のコードからひとつひとつ解説していきます。

### v0 / v4

v0 と v4 の違いは、 `repeat_action_probability` の違いです。

- v0: `repeat_action_probability = 0.25`
    - つまり、ALE側で「どんな行動を入力されようが、0.25 の確率で一つ前の行動を繰り返す」設定です
- v4: `repeat_action_probability = 0.0`
    - つまり、ALE側で行動の繰り返しが発生する確率はゼロです

(対応箇所：https://github.com/openai/gym/blob/v0.10.5/gym/envs/__init__.py#L454、https://github.com/openai/gym/blob/v0.10.5/gym/envs/atari/atari_env.py#L40)

`repeat_action_probability` とは、 [ここ](https://github.com/openai/gym/blob/v0.10.5/gym/envs/atari/atari_env.py#L40) で使われている変数であり、詳しい説明が次の Isuue に上がっています：
[AtariEnv is doubly nondeterminstic due to ALEInterface's repeat_action_probability setting · Issue #349 · openai/gym](https://github.com/openai/gym/issues/349 "AtariEnv is doubly nondeterminstic due to ALEInterface's repeat_action_probability setting · Issue #349 · openai/gym")

この Issue によると、

- `repeat_action_probability` は ALE側での行動繰り返しの設定である
- これを明示的にゼロに設定しないと意図したような動作になっていない

ことがわかります。
以上から、特に理由がない限りは v4 を使ったほうが良いことがわかります。

### ram / <無印>

環境名に `ram` がついていると、画面のピクセル出力ではなく、内部RAMの状態を観測値として得る設定になります。

- ram: 内部RAMの状態を観測値 `observation` として返答する
- <無印>: 画面のピクセル出力を観測値 `observation` として返答する

(対応箇所：https://github.com/openai/gym/blob/v0.10.5/gym/envs/__init__.py#L444、https://github.com/openai/gym/blob/v0.10.5/gym/envs/atari/atari_env.py#L90)

研究等で使われるのは内部RAM状態ではなく画面のピクセル出力であることが多いので、
特に理由がない限りは、<無印> を使ったほうが良いことがわかります。

### Deterministic / <無印> / NoFrameskip

環境名に `Deterministic` がついていると、frameskip の値が固定されます。

- Deteministic: 必ず4回 [^1] 連続で行動を繰り返す
    - この繰り返しは ALE 側ではなく、それをラップしている Gym 側であることに注意
    - 環境 (env) の `step` を呼ぶと、内部で自動的に4回連続で同じ行動を繰り返す
    - 貰える報酬はその4回の累計になる
- <無印>: 2, 3, 4 のうち毎回ランダムに選ばれた回数連続で行動を繰り返す
    - この繰り返しは ALE 側ではなく、それをラップしている Gym 側であることに注意
    - 環境 (env) の `step` を呼ぶと、内部で自動的にn回連続で同じ行動を繰り返す
        - その n は 2, 3, 4 からランダムに選ばれる
    - 貰える報酬はそのn回の累計になる
- NoFrameskip: 行動の繰り返しなし

(対応箇所：https://github.com/openai/gym/blob/v0.10.5/gym/envs/__init__.py#L467、https://github.com/openai/gym/blob/v0.10.5/gym/envs/atari/atari_env.py#L70)

NoFrameskip であれば、Deterministic も <無印> も env の `step` を呼ぶ側から (乱数を除けば) 同等の再現が可能です。
特に <無印> は取扱が面倒であるため、あまり使う機会はないと思います。

Deterministic にせよ <無印> にせよ、結局はALE側ではなくラップしている Gym 側での制御であるため、内部で繰り返し処理をすることによる速度面での向上もそこまで期待できないでしょう。(Gym 内での制御であるということは、Python から出られていない)

環境側で勝手に行動が繰り返されると誤解の温床になりそうであるため、繰り返しをしたいときは自分で明示的にエージェントに命令する NoFrameskip を使っておくのが安全だと思います。


# 参考資料
- [python - List all environment id in openai gym - Stack Overflow](https://stackoverflow.com/questions/48980368/list-all-environment-id-in-openai-gym/48989130#48989130 "python - List all environment id in openai gym - Stack Overflow")
- [AtariEnv is doubly nondeterminstic due to ALEInterface's repeat_action_probability setting · Issue #349 · openai/gym](https://github.com/openai/gym/issues/349 "AtariEnv is doubly nondeterminstic due to ALEInterface's repeat_action_probability setting · Issue #349 · openai/gym")

[^1]: space_invaders に限っては3回繰り返しのようです (https://github.com/openai/gym/blob/v0.10.5/gym/envs/__init__.py#L468)