「QualiArts Advent Calendar 2020」 13日目の記事になります。
昨日の12日目の記事は塩塚くんによる「アセットバリデーション用のBlenderプラグインを作ってみる」です。興味がある方はこちらもどうぞ。
#はじめに
はじめまして、Unityエンジニアの山下といいます。この記事では、テトリスに対し、Unity ML-Agentsを用いて強化学習をしてみたことについて説明します。
テトリスは、皆さんご存知かと思いますが有名な落ち物パズルゲームです。最近、ぷよテトやテトリス99で遊んでいて自分で遊ぶちょうどいいレベルの相手を作れないかと思い、お題に選んでみました。
以下、自作してみたテトリスの画面。
落下、左右への移動、回転、列消し程度は実装してあります。T-SpinやRENの実装は一旦要らないかと思い、実装してありません。
Unity ML-Agentsとは
Unity ML-Agentsとは、Unityが提供している機会学習用のフレームワークです。AIに行動の選択肢と現在の状況、適度な報酬を与えることによって学習を行わせ、自動的に操作を行わせることができるようになります。
詳細な内容はこちらの本が日本語で詳しく書いてあるのですが、ML-Agents v0.4当時のものなので少し古いです。Agentの作り方は今でもあまり変わらないので参考になると思います。
Unity ML-Agents実践ゲームプログラミング
こちらの記事ではRelease10を使用しました。Unity ML-Agents Release10
また、Unityは2018.4.30f1を利用しました。
この他、pythonの実行環境が必要です。python3.7と、pipでmlagentsパッケージをインストールしました。
学習方法の詳細
学習させるに当たって、AIに行わせる操作と、AIに渡す観測情報、報酬を考える必要があります。
まず操作についてですが、基本的なテトリスで行えるアクションは左移動、右移動、下移動、左回転、右回転の5つです。(さらに言うならハードドロップやホールドもありますが今回は省略しています)
移動と回転は別軸として考えても良かったのですが、移動と回転を同時に行わないものとしてアクションは1次元でどれかしか選べないようにしてみました。離散値なのでDiscrete、何もしないを含めて1次元でサイズ6までです。
次に観測ですが、テトリスの盤面情報をAIに簡単に渡そうと思って、Visual Observationを使いました。CameraSensorコンポーネントを利用して、画像情報で現在の盤面を渡しています。Unity ML-Agentsではこの他にVector Observationというのがあって、オブジェクトの位置や、回転、盤面等をベクトル情報として渡すこともできます。
最後に報酬です。Agentクラスを継承したTetorisAgentクラスを作り、そこで上記の操作、観測と共に報酬の実装を行います。
列を消したら+1、ゲームオーバーで-1、そして毎ステップごとに-0.001という設定をしました。ゲームオーバーにならずに、列を消せていれば報酬が増えるはずなので、うまくいけばいい感じに列を消してくれそうです。
実行
上記の設定で5万ステップほど学習させてみました。
ターミナルで以下のコマンドを実行させると
# mlagents-learn config/ppo/tetoris.yaml --run-id=tetris
以下のような画面が出てくるはずなので、この状態でUnityを実行するとUnity側で勝手に学習を進めてくれます。
今回の環境では5万ステップで16分ほどかかりました。