OpenAI Retro Contestの「Gym Retro Integration」でソニック・ザ・ヘッジホッグをプレイする

つい先日、OpenAIが主催するOpenAI Retro Contestが終了したようです。このコンテストでは"Sonic The Hedgehog"を題材に、ゲームをプレイするエージェントを作成しその性能を競うものでした。コンテストの結果は実際にプレイ動画とともにleaderboardから見ることができるのですが、上位陣のエージェントのプレイを眺めていると、深層強化学習の進歩をひしひしと感じます。中でも1位の"Dharmaraja"というアリババのチームは途中でオブジェクトの隙間に入り込むバグを発見して大きくスコアを伸ばしていたようです。この先機械がゲームをプレイする未来を考えると、実用的には機械がテストプレイをしたり、非実用的にはTASを自動で作成したりと、色々と夢が広がるものでした。

さて、私もちょっと強化学習を勉強してみようと思ってOpenAI Retro Contestのドキュメントを眺めていたのですが、その中で実際にゲーム画面を見ながら開発ができるよう、ゲームの状態を確認したり操作を行うGym Retro Integrationというユーザインターフェイスが開発されていたので、ちょっと試してみました。それほどハマるポイントがあるわけではないのですが、色々とやることがあって若干ややこしいので、利用するまでの手順を書いておきます。

環境

Gym Retro Integrationの準備

1. retoレポジトリをgit cloneする

2018/06/27現在はdevelopブランチからコンパイルする必要がありますので、ソースコードをcloneしてきてdevelopブランチをチェックアウトします。

$ git clone https://github.com/openai/retro/
$ git checkout develop

2. Gym Retro Integrationをコンパイルする

ここからはdevelopブランチのREADME.mdに記載されている通りにコマンドを実行します。

openai/retro at develop

$ brew install pkg-config capnp lua@5.1 qt5
$ cmake . -DCMAKE_PREFIX_PATH=/usr/local/opt/qt -DBUILD_UI=ON -UPYLIB_DIRECTORY
$ make -j$(sysctl hw.ncpu | cut -d: -f2)

なお、fish shellの場合は$()が利用できません。ここではマシンのCPUコア数を指定しているだけなので、make -j4といった形で実行します。

これが終われば、retroディレクトリにGym Retro Integration.appが作成されていますので、ダブルクリックまたはopen "Gym Retro Integration.app"で実行します。

プレイするROMの準備("Sonic The Hedgehog"の場合)

プレイする環境は準備ができたので、次にプレイするソフトウェアの準備をします。ここの部分はOpenAI Retro ContestのDetailにも記載されている内容と同様のものです。

OpenAI Retro Contest

1. Steamで購入する

Steamで今回のOpenAI Retro Contestで対象となっている下記のゲームを購入します。SteamではWindows用と表示されていますが、気にせず購入して問題ありません。

ちなみに、2018/06/27現在はサマーセール中ということで、通常は1本498円のところ、66%引きの168円で購入することができました。

2. gym-retroでsteamからROMをダウンロードする

Steamで購入したソフトをダウンロードします。ゲームを遊ぶときのようにSteam.appからダウンロードする方法もあるのですが、openai/retroでは直接ダウンロードするPythonスクリプトが用意されているので、そちらを利用します。

まず、openai/retroをインストールします。上記でソースコードをcloneしているので、そちらを利用しても問題ありません。

$ pip install gym-retro

次にretro.import.sega_classicsを実行します。ここではSteamにログインするときのUsernameとPasswordnほかに、Steam ガードコードと呼ばれるメールで届くワンタイムトークンの入力が求められます。ここでソニックのソフトを購入できていれば、下記のように3つのゲームが無事ダウンロードできます。

$ python -m retro.import.sega_classics
Steam Username: yag_ays
Steam Password (leave blank if cached):
Downloading games...
Installing games...
Importing SonicAndKnuckles3-Genesis
Importing SonicTheHedgehog2-Genesis
Importing SonicTheHedgehog-Genesis
Imported 3 games

さて、肝心のゲームのROMはというと、gym-retroのパッケージのdata/ディレクトリ以下に配置されます。"Sonic The Hedgehog"の場合はSonicTheHedgehog-Genesis/rom.mdがROMに当たります。これをGym Retro Integration.appで開くことになるので、参照しやすいディレクトリにコピーしておくと良いと思います。

なお、これは利用している環境によって場所が異なりますので注意してください。私の場合はpyenvを利用しているので$HOME/.pyenv/versions/3.6.3/envs/main/lib/python3.6/site-packages/retro/dataにありました。この場所を探すときはipythonでgym-retroをインポートしてどこから読み込んでるのかを確認するのが手っ取り早いと思います。

In [1]: import retro

In [2]: retro?
Type:        module
String form: <module 'retro' from '/Users/yag_ays/.pyenv/versions/3.6.3/envs/main/lib/python3.6/site-packages/retro/__init__.py'>
File:        ~/.pyenv/versions/3.6.3/envs/main/lib/python3.6/site-packages/retro/__init__.py
Docstring:   <no docstring>

Gym Retro Integrationを使ってみる

ようやく準備が終わりました。それではGym Retro Integrationを使ってゲームを実行してみます。

まずGym Retro Integration.appを開くと、以下のような画面が表示されます。まだ何も表示されていないサラの状態です。

f:id:yag_ays:20180627224620p:plain

次にゲームのROMを読み込む必要があります。メニューバーの"Game"→"Open"(または"Load Game...")からROMを選択します。ここではSonicTheHedgehog-Genesisrom.mdを指定しました。

f:id:yag_ays:20180627224712p:plain

ようやくゲームが実行できました!!!ゲームが進むにつれて画面右の"Senario Information"ではFrameやTimestepの値がインクリメントされており、状態がきちんと取得できているようでした。実際には各ステージのシナリオ等を読み込む必要があると思いますが、ここでは割愛します。

そしてゲームのプレイですが、矢印キーで操作したりzキーでジャンプできます。操作方法は、メニューバーの"Window"→"Controls.."で確認したり変更することができます。

f:id:yag_ays:20180627225205p:plain

さて、ここまで色々準備してきましたが、まだエージェントを作成する準備が整っただけです。ここからopenai gymを使って様々な強化学習などの手法を用いてエージェントを学習させていく必要があります。そちらはまだ勉強途中ということもありますので、別の機会にアウトプットできればと思います。

参考