Morikatron Engineer Blog

モリカトロン開発者ブログ

MacでUnity ML-Agents(v1.0)の環境構築

こんにちは、モリカトロンのAIエンジニアの本間です。

Unity ML-Agentsがついに1.0メジャーアップデートされましたね! という事で、この記事では環境構築した後にサンプルプロジェクトで学習します。


Unity ML-Agentsとは

f:id:morika-homma:20200505133012p:plain

Unity ML-Agentsは、Unityで強化学習をするための学習環境フレームワークです。 フレームワーク内部でUnityとPython間の通信をして、pythonでニューラルネットワークを学習します。 これを使うことで、Pythonを触らずにUnityゲーム内のキャラクターを学習させる事が可能です。 今回は開発環境を構築した後にPythonを触らずにサンプルプロジェクトで学習を回してみましょう。

検証環境

  • 機種名 : iMac (21.5-inch, 2017)
    • CPU:2.3GHz デュアルコア Core i5
    • メモリ:16GB
    • グラフィックス:Intel Iris Plus Graphics 640 1536MB
  • OS : MacOS Catalina 10.15.2
  • Unity : 2019.3.12f1
  • Python : 3.6.5
  • ML-Agents : release_1

(必要なら)Unityをインストールする

Unityのインストール方法はアップデートにより変更される事があり、加えて手順が多く、意外と説明が大変です。 (公式のドキュメントもバージョンアップに追いついていなかったりします)
そんなこともあり何か分かりやすい記事や動画が無いか調べたところ、【ゲームの作り方!】というYoutubeチャンネルさんの動画が分かりやすかったため、そちらの動画をご紹介します
動画を参考にUnityインストールを完了しましょう。
(分かりやすい動画、ありがとうございます!)

本記事では【2019.3.12f1】をインストールして進めていきます。
なお今回はMacで動かすため、Unityインストール時には【Mac Build Support】オプションにチェックしておくと後々便利です。


(必要なら)Pythonをインストールする

以下で、pyenvというPythonバージョン管理ツールを利用してPythonをインストールしていきます。 pyenvは複数のPythonバージョンを管理するときに便利なツールですが必須ではありません、pyenvの代わりにanacondaやminicondaを使っても良いですし、Dockerでも構築出来ます。Pythonのインストールは色々なやり方があるので、好きな方法でインストールしましょう。
ここではpyenvを使う方法を紹介します。

(必要なら)Homebrewインストール

まずはmacOS用パッケージマネージャーであるHomebrewをインストールします。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

(必要なら)pyenvインストール

Homebrewのインストールが無事に完了できたら
Pythonの仮想環境ツールであるpyenvをインストールしていきます。

brew install pyenv

続いて、pyenvを利用するための環境変数を設定していきます。

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile

(必要なら)やっとpythonインストール

pyenvの準備が整ったので、pythonをインストールします。
今回はpython3.6.5をインストールします。

pyenv install 3.6.5

# pythonのバージョンを切り替え
pyenv global 3.6.5


Unity ML-Agentsをダウンロード&セットアップする

適当なフォルダに Github からリポジトリをクローンして pip install するだけでセットアップ完了です。カンタン!

# 作業ディレクトリを作成
mkdir mla_test
# 作業ディレクトリへ移動
cd mla_test

# ml-agentsリポジトリからrelease_1ブランチをクローン
git clone --branch release_1 https://github.com/Unity-Technologies/ml-agents.git

# 各種パッケージをインストール
pip install mlagents


サンプルプロジェクトを動かす

1.Unity Hubを開き、【リストに追加】をクリックし 【mla_test > ml-agents > Project】を選択します。

f:id:morika-homma:20200410111338p:plain

2.Unity Hubにプロジェクトが追加されたら、【Unityバージョン】を選択します。
今回は【2019.3.12f1】を選択し、プロジェクトを開きます。 その際「プロジェクトをアップグレードしますか?」と聞かれるので、【確認】を選択します。 【確認】クリック後に以下のようなウィンドウが出てきた場合、【Yes】をクリックします。 プロジェクトを開くとエラーが出るかもしれませんが、気にせず続行して下さい。

f:id:morika-homma:20200506171901p:plain

3.プロジェクトが開いたら、 上部ツールバーから【ウインドウ > Package Manager】をクリックしてPackage Managerウィンドウを開きます。

4.開いたウィンドウの左上にある【+】タブをクリックし、【Add package from disk...】をクリックして、先ほどダウンロードしたml-agentsのパッケージを選択します。
今回は【mla_test/ml-agents/com.unity.ml-agents/package.json】を指定しましょう。

f:id:morika-homma:20200410111509p:plain

以上で設定は完了です、試しにサンプルシーンを動かしてみましょう。
Unityエディタのプロジェクトウィンドウにて、
【Assets/ML-Agents/Examples/PushBlock/Scenes/PushBlock】をダブルクリックで開きます。
Unityエディタの中央上部にあるプレイボタンをクリックし、動作確認をしてみます。

f:id:morika-homma:20200408172725g:plain

サンプルシーンには最初から学習済みのモデルが設定されており、 実行してみるとイイ感じに白いブロックを緑エリアのゴールまで押していくのが確認出来るかと思います


サンプルプロジェクトで学習する

学習済みモデルの設定を外す

1.ゲームを実行中の場合、再度プレイボタンをクリックして実行を中止して下さい。

2.Unityエディタのヒエラルキーウィンドウの【Area】の右にある【>】をクリックして、元となるプレハブを開きます。

f:id:morika-homma:20200410112048p:plain

3.【Agent】オブジェクトの【Behavior Parameters】の【モデル】項目をクリックし、削除キーを押しましょう。この操作により学習済みモデルの設定が外れ、勝手に動かなくなりました。

f:id:morika-homma:20200410111715p:plain

4.ヒエラルキーウィンドウの左上にある【<】をクリックすることで、プレハブ編集を終了します。この作業を行う事で、プレハブを参照している全てのエリアオブジェクトの設定が一斉に変更されます。

f:id:morika-homma:20200410111740p:plain

これで全エージェントが動かなくなったはずです。試しに実行して確認してみましょう。

いざ学習

現在、Unity ML-Agentsを使って学習する方法は3つあります。

  1. mlagents-learn

  2. Unity ML-Agents Gym Wrapper

  3. Unity ML-Agents Python Low Level API

今回は一番簡単に学習出来るmlagents-learnを使ってみます。

非常に簡単なので、2ステップで終わります。

1.mlagents-learnコマンドで学習パラメータファイルと識別IDを指定して、実行します。

# ディレクトリ移動
cd ml-agents

# 学習コマンド実行
# 学習パラメータファイル=config/trainer_config.yaml, 識別ID=firstRun
mlagents-learn config/trainer_config.yaml --run-id=firstRun

問題なく実行出来た場合、以下のようなUnityロゴが表示されます。
なおmlagents-learnコマンドの詳細はml-agents/docs/Training-ML-Agents.mdにあります。

                ▄▄▄▓▓▓▓
           ▓▓▓▓▓▓█▓▓▓▓▓
      ,▄▄▄▀▀▀'  ,▓▓▓▀▓▓▄                           ▓▓▓  ▓▓▌
    ▄▓▓▓▀'      ▄▓▓▀  ▓▓▓      ▄▄     ▄▄ ,▄▄ ▄▄▄▄   ,▄▄ ▄▓▓▌▄ ▄▄▄    ,▄▄
  ▄▓▓▓▀        ▄▓▓▀   ▐▓▓▌     ▓▓▌   ▐▓▓ ▐▓▓▓▀▀▀▓▓▌ ▓▓▓ ▀▓▓▌▀ ^▓▓▌  ╒▓▓▌
▄▓▓▓▓▓▄▄▄▄▄▄▄▄▓▓▓      ▓▀      ▓▓▌   ▐▓▓ ▐▓▓    ▓▓▓ ▓▓▓  ▓▓▌   ▐▓▓▄ ▓▓▌
▀▓▓▓▓▀▀▀▀▀▀▀▀▀▀▓▓▄     ▓▓      ▓▓▌   ▐▓▓ ▐▓▓    ▓▓▓ ▓▓▓  ▓▓▌    ▐▓▓▐▓▓
  ^█▓▓▓        ▀▓▓▄   ▐▓▓▌     ▓▓▓▓▄▓▓▓▓ ▐▓▓    ▓▓▓ ▓▓▓  ▓▓▓▄    ▓▓▓▓`
    '▀▓▓▓▄      ^▓▓▓  ▓▓▓       └▀▀▀▀ ▀▀ ^▀▀    `▀▀ `▀▀   '▀▀    ▐▓▓▌
       ▀▀▀▀▓▄▄▄   ▓▓▓▓▓▓,                                      ▓▓▓▓▀
           `▀█▓▓▓▓▓▓▓▓▓▌
                ¬`▀▀▀█▓

2.Unityエディタの中央上部にあるプレイボタンをクリックし、学習を開始します。

この2ステップで学習が始まります。
エージェントが目まぐるしく動き、PCのファンの回転数が上がります。


学習環境情報

f:id:morika-homma:20200505114932g:plain
デバッグ画面

いま学習させている環境がどういうものか、簡単に調べてみましたので、以下に説明します。

エージェントが観測する情報:

  • 前方7方向のレイキャスト
  • 前方7方向のレイキャスト(頭上から)

2つのレイキャストは白いキューブ・ゴール・壁の3種類のオブジェクトを区別して衝突検知します。

エージェントが行う行動:

  • 何もしない
  • 前方移動
  • 後方移動
  • 右旋回
  • 左旋回
  • 左スライド
  • 右スライド

エージェントが環境から受け取る報酬:

  • 白いキューブがゴールに到着した:5.0
  • ステップ毎 :-0.0000005 (= -1 / MaxStep)

エージェントからレイキャスト(レイを飛ばす)事で白いキューブを観測してるようです。 同じ高さと頭上の2箇所からレイキャストする事で、同じ高さのレイキャストは白いキューブを、頭上のレイキャストは壁を、それぞれ独立して観測する事が出来そうです。

並列学習:

以下のように複数の学習エリアを作る事で、一度に複数のエージェントを動かして並列学習出来ます。

f:id:morika-homma:20200507124634g:plain

学習のためのハイパーパラメータ:

mlagents-learnコマンド実行時にパラメータファイルを指定する事で、学習のための様々なパラメータを設定出来ます。
今回の学習では「ml-agents/config/trainer_config.yaml」ファイルをパラメータファイルとして指定しました。

パラメータファイルでは以下のように記述されており、max_steps:2,000,000stepまで学習するかctrl+cキーを押すことで、学習を終了します。

PushBlock:
    max_steps: 2.0e6
…

ちなみに著者のiMacでは学習終了まで27分程度かかりました。


学習経過を観察する

学習の様子

0 step~
学習を開始したばかりの頃は、なかなか白いキューブを動かそうとしません。

f:id:morika-homma:20200504163242g:plain

120000 step~
白いキューブをとにかく動かし続け、左右上下の壁にぶつけ回すようになりました。

f:id:morika-homma:20200504163418g:plain

NGシーン(1800000 step~)
白いキューブを左上の隅に押し込んで詰んでしまいました。
壁にぶつけ回す作戦が裏目に出た瞬間ですね、とても良いです。
PC画面を眺めてニヤニヤしていました、お茶目でかわいいですね。

f:id:morika-homma:20200505150908g:plain

1920000 step~
白いキューブを(さっきよりも若干)効率良く動かし続け、左右上下の壁にぶつけ回すようになりました。

f:id:morika-homma:20200504163509g:plain

学習値の可視化

# 新たにコンソールウィンドウを開きます
# ひらけコンソール!

# mlagentsディレクトリに移動
# cd mla_test/ml-agents

# tensorboardを起動
tensorboard --logdir=summaries/ --port=6006

tensorboardを起動後、ブラウザで http://localhost:6006/ を開きます。
するとtensorboardウェブページが表示され、学習の値を見ることが出来ます。
学習を開始すると「ml-agents/summaries/」ディレクトリ内に学習経過ファイルが作成され、 tensorboardでこのファイルを参照することでブラウザから学習値を見る事が出来ます。 この機能は学習中でも学習後でも使うことが出来ます。

累積報酬

f:id:morika-homma:20200504173411p:plain

1エピソードの平均ステップ数

f:id:morika-homma:20200504173437p:plain

累積報酬を見ると200kステップの段階である程度ゴール出来るようになってるようです。 1エピソードの平均ステップ数を見ても、200kステップ辺りでゴールするまでの時間もガクッと下がってるようです。 最終的には累積報酬が4.942になっているところを見ると、学習は順調に進んだように見えます。 実際の学習時間は27分程度でしたが、累積報酬のカーブを考えると半分の時間で終わらせても実質問題無さそうな事が分かりました。


学習したモデルをゲームで使用する

学習済みのニューラルネットワークファイル(.nn)は、Unityゲーム内で推論モジュールとして使用出来ます。 以下では、今回学習したモデルをUnityゲームで使用する手順を説明します。

1.学習したモデルは、「ml-agents/models/firstRun/PushBlock.nn」に出力されます。このファイルをUnityプロジェクトのAssetsにドラッグ&ドロップする事で、Untiyプロジェクトに取り込まれます。

2.取り込まれたファイルを、ヒエラルキーから「Arena/Agent/Behavior Parameters/モデル」にドラッグ&ドロップします。

3.プレイボタンをクリックします。

以上で学習したモデルをUnityゲームで使用することが出来ます。


最後に

今回は一番簡単に出来るmlagents-learnコマンドを使用して学習してみました。次の記事では二番目に簡単なUnity ML-Agents Gym Wrapperを使用して学習してみたいと思います。

最後まで読んでいただきありがとうございました。