tanaka's Programming Memo

プログラミングについてのメモ。

Unityの公式サンプルml-agentsでAIを試す

Unityで機械学習を利用できるようにするUnity公式のml-agentsWindows7で動かすまでのメモです。

(2017/11/11 トレーニングの自動終了について追記)

f:id:am1tanaka:20171108132119p:plain

ざっくりと概要

ml-agentsUnity Machine Learning Agentsを略した名前です。「Unityの機械学習エージェント」ということですね。

機械学習には様々なものがありますが、このプロジェクトでは機械学習の代表格であるTensorFlow(テンソル・フロー)というオープンソースを利用します。ゲーム専用ではなく、デファクトスタンダードなAIシステムを採用しているのは大きな利点だと思います。TensorFlowは手書き文字や写真に写っているものを推定するなど様々な用途に使われていて、応用範囲がとても広いです。以前から使ってみたいと思っていましたが、よいきっかけになりました。

今回のプロジェクトの利用の流れは大体以下の感じです。

  1. [Unity] Unityで機械学習で使うための実行ファイルをビルド
  2. [Python+Unity] Unityでビルドした実行ファイルをPythonから呼び出して、TensorFlowで学習
  3. [Python] 学習結果を.bytesファイルに保存
  4. [Unity] Unityのアセットに.bytesファイルを含める
  5. [Unity] 学習結果を組み込んだ実行ファイルをUnityでビルドして、単体アプリの完成

機械学習には、「学習する段階」「学習成果を使って実行する段階」の2段階があります。機械学習を行うTensorFlowはPythonで動くソフトウェアですので、学習する段階はUnityとPythonを連携させて行います。学習結果はデータファイルに出力されます。それをUnityに含めてビルドすれば、機械学習で作成したAIに状況を判断させることができます。こうやって作成した「学習成果を使って実行する」アプリにはTensorFlowは不要なので、単体で配布することができます。

現在のml-agentsはβ版で、ビルドができるのは[Windows, mac, Linuxスタンドアロン実行形式][iOS][Android]の3種類とありました。

ふとした疑問

  • 単体アプリになったあとは学習しないのだろうか?
    • それなりに効果のある学習をするには1万回とかの試行が必要なので、人間が遊ぶ回数では学習させても効果はなさそう
    • プレイヤーの操作を記録しておいて、別途学習させる、ということになるのかな?

前提

  • Windows7 64-bit版
  • Unity 2017.1以降
  • Anaconda(Python)のインストールに管理者権限が必要

インストール

ml-agents/installation.md at master · Unity-Technologies/ml-agents · GitHubの流れに沿って作業を進めます。大まかには以下のとおりです。

  1. Anaconda 64-bit版のインストール(これでPythonも入る)
  2. ml-agentsリポジトリーの入手
  3. Pythonの仮想環境の作成
  4. ml-agentsのSetupを実行

ではインストールをはじめましょう。

Anaconda 64-bit版のインストール

TensorFlowを動かすのに必要なので、Anacondaというデータサイエンス向けの機能が沢山用意されているPythonパッケージをインストールします。このパッケージはPythonを含むので、同時にPythonのインストールも完了することになります。

(Anacondaについての詳細はこちら)

Downloads | Anacondaを開いて、利用するPythonのバージョンの[64-Bit Graphical Installer]をクリックしてダウンロードします。

f:id:am1tanaka:20171108144633p:plain

ダウンロードが完了したら、実行して、設定はそのままでインストールを完了させます。完了したら[Next]を押して、以下のチェックは不要なので外して、[Finish]をクリックして完了です。

f:id:am1tanaka:20171108154706p:plain

ml-agentsリポジトリーの入手

Unity公式が提供している[ml-agents]リポジトリーを入手します。GitHubリポジトリーなのでクローンするのが本道な気もしますが、今回はシンプルにZIPをダウンロードして使います。

GitHub - Unity-Technologies/ml-agents: Unity Machine Learning Agents を開きます。右の方の[Clone or download]ボタンをクリックして、[Download ZIP]をクリックします(cloneの方がいい人はクローンしてください)。

f:id:am1tanaka:20171108151201p:plain

[ドキュメント]フォルダー下の[Unity Projects]フォルダー内など、Unityからアクセス可能な場所にZIPファイルを展開します。

展開したフォルダー内のunity-environmentフォルダーにUnityのプロジェクト、pythonフォルダーにPython関連のファイルが入っています。ここからは、このフォルダー内にインストールをしていきます。

Pythonの仮想環境の作成

Pythonは、プロジェクトごとに個別に環境を持たせることができます。通常のPython3ではvenvで行いますが、Anacondaはcondaで同様のことを行います。

(余談:Pythonは特別な環境設定をせずに、複数の異なるバージョンや32-bit版、64-bit版のものをインストールしても問題ありません。プロジェクトごとに、[venv]や[conda]で必要なバージョンの仮想環境を作成して使うことができます。進んでます)

Anacondaのプロンプトを起動します。

[スタート]メニューから[すべてのプログラム]>[Anaconda3 (64-bit)]>[Anaconda Prompt]を起動します。

f:id:am1tanaka:20171108161557p:plain

Anaconda版のPythonが利用できるコマンドプロンプトが開きます。この後の作業で、文字コードUTF-8じゃないとエラーが出る部分があるので、以下を実行して、コマンドプロンプト文字コードUTF-8に切り替えておきます。

chcp 65001

追記2017/12/8 以下のような The system cannot write to the specified device. エラーが発生した場合

コマンドラインのフォントがUTF-8の日本語に対応していないと以下のようなエラーが発生します。

f:id:am1tanaka:20171208164136p:plain

その場合、以下のように対処します。

  • エラーが発生したコマンドプロンプトを閉じます
  • 改めて、[スタート]メニューから[すべてのプログラム]>[Anaconda3 (64-bit)]>[Anaconda Prompt]を起動します
  • タイトル部分を右クリックして、プロパティを選択します

f:id:am1tanaka:20171208164519p:plain

  • フォントタブを選択して、フォントをMS ゴシックに変更して、[OK]をクリックします

f:id:am1tanaka:20171208164603p:plain

以上で、改めてchcp 65001を実行すれば切り替わります。

続き

cdコマンドでml-agents-masterフォルダーを開きます。エクスプローラーでml-agents-masterフォルダーを開いてから、上のアドレスバーをクリックしてパスをコピーします。

f:id:am1tanaka:20171108161904p:plain

コマンドプロンプトcdと入力して、右クリックして[貼り付け]を選べば楽です。

f:id:am1tanaka:20171108161957p:plain

以下を実行して、Anacondaの環境下にml-agents用の環境を作って、Python3.6.3が使えるようにします。Pythonのバージョンはその時々に応じて変更して構いません。

conda create -n ml-agents python=3.6.3

[Proceed]の問いが表示されたら[Enter]キーを押してインストールを開始します。

f:id:am1tanaka:20171108162522p:plain

ml-agentsのSetupの実行

残りのインストールは、パッケージに含まれるSetup.pyで行えます。これはml-agents環境にインストールしたいので、環境を切り替えます。

activate ml-agents

これで、コマンドラインの行頭が(ml-agents)に変わります。この後のインストールは、全てこの環境内に行われます。

cd python
pip install .

しばらく待って、コマンドラインが表示されたらインストール完了です。この後もコマンドプロンプトは利用しますので、閉じないでおいてください。

f:id:am1tanaka:20171108164918p:plain

ml-agentsのボールのサンプルのセットアップ

Unityで機械学習をさせるための準備をします。ボールのバランスを取るサンプルを使います。ここからはml-agents/Getting-Started-with-Balance-Ball.md at master · Unity-Technologies/ml-agents · GitHubに従って作業をします。

  • Unity2017.1以降のバージョンを起動
  • [OPEN]を選択
  • 先にダウンロードした[ml-agents-master]フォルダー内の[unity-environment]フォルダーを選択して開く
  • 以下のような警告が表示されたら、構わず[Continue]して読み込む

f:id:am1tanaka:20171108165723p:plain

  • [Project]ビューから[ML-Agents]>[Examples]>[3DBall]フォルダーを開いて、[Scene]シーンをダブルクリックして開く

これで、ご存知の以下のシーンが開きます。

f:id:am1tanaka:20171108165956p:plain

  • [Edit]メニューから[Project Settings]>[Player]を開く
  • [Inspector]ビューで以下を設定
    • [Resolution and Presentation]欄の[Run In Background]にチェックが入っていることを確認
    • 同様に[Display Resolution Dialog]が[Disable]になっていることを確認
  • [Hierarchy]ビューから[Ball3DAcademy]オブジェクトを開いて、[Ball3DBrain]を選択

f:id:am1tanaka:20171108170135p:plain

  • [Inspector]ビューで[Brain Type]を[External]に変更

f:id:am1tanaka:20171108170214p:plain

  • [Ctrl]+[S]キーを押して、シーンを保存する
  • [File]メニューから[Build Settings]を選択
  • ビルドターゲットとして、とりあえず[PC, Mac & Linux Standalone]を選択
    • ライブラリ的には、[iOS]と[Android]も対応しているようですが、試してません
    • ログが必要なら[Development Build]にチェック(どっちでもいいです)
  • [Build]をクリック
    • フォルダーを[ml-agents-master]まで戻してから、[python]フォルダーをダブルクリックして開く
    • ファイル名を3DBallとして、[保存]ボタンをクリック

f:id:am1tanaka:20171108170708p:plain

以上でビルドが完了したら、学習用の実行ファイル3DBallの出来上がりです。

トレーニングする

トレーニングはJupyter(ジュピター)を使って行うと楽です。すでにインストール済みなのでコマンドラインから以下で起動します。

jupyter notebook

これで呼び出したパスが参照できます。pythonフォルダーにいた場合、以下のような具合です。

f:id:am1tanaka:20171108173907p:plain

動作確認と環境設定の確認用の[Basics.ipynb]というファイルと、PPOで学習させる[PPO.ipynb]の2つがJupyterのノートブックです。Basicsは飛ばして、早速学習させましょう。

[PPO.ipynb]をクリックして開きます。

f:id:am1tanaka:20171108174312p:plain

ノートブックでは、説明を読んだり、実行するプログラムをステップごとに実行していくことができます。(1)が実行対象で、ここではプロジェクト名である「Unity ML Agents」と、この学習のアルゴリズムは「Proximal Policy Optimization(PPO)」と呼ばれるもので、詳細はhereで読んでくれ、というようなコメントになっています。

(2)の[Run]ボタンで、現在選択されているセルが実行されますが、実行する前に1つだけ環境設定が必要です。下にスクロールさせて、4つ目のセルを表示します。env_nameから始まる行を探して、environmentを消して、実行ファイル名である3DBallに書き換えてください。

f:id:am1tanaka:20171108174807p:plain

これで準備完了です。最初の「Unity ML Agents]のセルをクリックして青枠で囲まれたら、[Run]ボタンを押して実行します。自動的に次のセルがアクティブになりますので、また[Run]を押して実行します。「Export the trained Tensorflow graph]のセルになるまで[Run]をしてください。

f:id:am1tanaka:20171108175000p:plain

しばらく待っていると、以下のような小さいウィンドウが表示されて、先にビルドした[3DBall]が起動して学習を始めます。。

f:id:am1tanaka:20171108224222p:plain

更に待つと、Mean Reward: 10.82324のようなメッセージが表示されはじめます。

f:id:am1tanaka:20171108175119p:plain

何回目かにSaved Modelと表示されたら、その前のMean Rewordの数値を確認してください。それが成功率です。75を越えるぐらいでしたらかなり頭が良くなっていますので、学習を終了させましょう。

[3DBall]の[x]ボタンをクリックして閉じてください。

f:id:am1tanaka:20171108175331p:plain

JupyterにJSONDecodeErrorなどが表示されますが大丈夫です。

f:id:am1tanaka:20171108175519p:plain

Mean Rewardの値は、時々低い値になる場合があります。そのままですと、かなり頭が悪いAIになります。学習を継続させれば改善しますので、改善したい場合は[3DBall]を閉じずに待ってください。再び、Mean Rewardが表示されるようになり、また何回目かでSaved Modelが表示されます。納得がいく値が出るまで待ってください。

納得のいく数字がでて実行ファイルを停止したら、Jupyterに切り替えてExport the trained Tensorflow graphの下のセルを[Run]して実行します。

f:id:am1tanaka:20171108175706p:plain

このように表示されたら、学習した人工知能のデータが保存されます。

なお、手動で停止しなくても、max_stepsで定義されているステップ数を実行したら自動的に学習は終了して、.bytesファイルが保存されます。デフォルトでは5e5が代入されていますが、これは5*105乗で、50万ステップを表しています。1e5ぐらいにしておくと、10万回で自動的に終了して保存されます(2017/11/11追記)

トレーニング結果をUnityに組み込む

プラグインのインポート

TensorFlowの学習成果をUnityに組み込んで、単独のアプリとして動くようにしましょう。TensorflowのデータをUnityで扱えるようにするためのプラグインが必要なので、Unityのプロジェクトにインポートします。

  • https://s3.amazonaws.com/unity-agents/TFSharpPlugin.unitypackage からTF#をダウンロード
  • ダウンロードが完了したら、ダブルクリックするか、Unityの[Project]ビューにドラッグ&ドロップしてインポートする
  • [Edit]メニューから[Project Settings]>[Player]を選択
  • [Inspector]ビューの[Other Settings]欄で以下を設定
    • [Scripting Runtime Version]を[Experimental(.Net 4.6 Equivalent)]にする
    • Scripting Defined Symbols欄にENABLE_TENSORFLOWを入力

f:id:am1tanaka:20171108180751p:plain

以上ができたら、[File]>[Save Scene]、[File]>[Save Project]をしてから、Unityを一度閉じて、起動し直します。これで、TensorFlowのデータを組み込むためのInternal Brain Typeが使えるようになります。

学習データを組み込む

学習データを組み込んで、Unityで結果を見ましょう。

  • Unityを起動して、[unity-environment]プロジェクトを開く
  • [Project]ビューから[ML-Agents]>[Examples]>[3DBall]>[TFModels]フォルダーを開く
  • 予め入っている[3DBall]ファイルは不要なので削除する

f:id:am1tanaka:20171108185534p:plain

  • [Explorer]などで、[ml-agents-master]フォルダー>[python]>[models]>[ppo]フォルダーを開く

f:id:am1tanaka:20171108185317p:plain

  • フォルダー内の[3DBall.bytes]をドラッグして、Unityの[Project]ビューの[ML-Agents]>[Examples]>[3DBall]>[TFModels]フォルダーにドロップ
  • [Hierarchy]ビューから[Ball3DAcademy]オブジェクトを開いて、子供の[Ball3DBrain]を選択
  • [Inspector]ビューの[Brain Type]欄を[Internal]に変更
  • [Project]ビューの[ML-Agents]>[Examples]>[3DBall]>[TFModels]フォルダーから[3DBall]をドラッグして、[Inspector]ビューの[Graph Model]欄の[Missing]となっているところにドラッグ&ドロップ

f:id:am1tanaka:20171108181213p:plain

以下は恐らく最初から設定済みですが、念のため確認しておいてください。

  • [Graph Placeholders]欄を開いて、[Size]が1か確認
  • [epsilon]欄の[Value Type]を[floating point]にして、[Min Value]と[Max Value]をどちらも0にする
    • 上記2つの設定は、3DBallがContinuous controlで制御する設定なので、TensorFlowモデルがノイズパラメーターを必要としているので設定しています。Discrete Controlだった場合はepsilonは不要です

以上できたら実行してください。学習が成功していれば、ボールをなるべく落とさないようにパネルが自動制御されるはずです。以下はRewardが80ぐらいの学習データで動かしたものですが、安定して制御できています。

f:id:am1tanaka:20171108190543g:plain

学習していない状態を確認する

学習を殆どさせていないとどうなるでしょうか。殆ど学習させていないデータを用意したので確認してみましょう。

https://github.com/tanakaedu/unity-ml-agents/raw/master/3DBall.bytes をダウンロードして、[Project]ビューの[TFModels]フォルダーにドラッグ&ドロップします。

f:id:am1tanaka:20171108190805p:plain

[Hierarchy]ビューから[Ball3DAcademy]オブジェクトの子供の[Ball3DBrain]を選択して、[Inspector]ビューの[Graph Model]欄に、[3DBall 1]をドラッグ&ドロップして設定してください。

実行してみてください。全くバランスが取れなくなります。これが初期に近い状態です。この状態から機械学習をさせて、先に確認したような動きに変わったのです。

f:id:am1tanaka:20171108185808g:plain

学習回数について

デフォルトでは5万回学習するごとにSave Modelsが表示されるようになっています。Jupyterの以下のsave_freqが保存するまでの学習回数の設定です。

f:id:am1tanaka:20171108185907p:plain

この値を変更すると、保存タイミングを変更することができるようになります。500回に減らしたのが下手バージョンのデータです。経過を見る限り、今回の内容なら2万回ぐらいで十分に上達するようです。

再学習の手順

学習させたあと、もう一度学習し直そうと最初から[Run]し直しても、[Load the environment]のところでtimeoutが発生して失敗します。

f:id:am1tanaka:20171108191222p:plain

再学習させる場合は、[restart the kernel]アイコンをクリックしてカーネルの再起動をします。

f:id:am1tanaka:20171108191301p:plain

[Restart]をクリックします。

f:id:am1tanaka:20171108191508p:plain

右上に[Restarting kernel]と表示されて、消えるまで待ちます。

f:id:am1tanaka:20171108191528p:plain

f:id:am1tanaka:20171108191533p:plain

これで、一番上から[Run]し直せばtime outせずに学習させられます。

終了方法

色々閉じるので、簡単に手順をまとめておきます。

  • Unityを、[File]>[Save Scene]と[File]>[Save Project]をしてから閉じる
  • Jupyterを開いていたWebブラウザーを閉じる
  • Jupyterを起動した[Anaconda Prompt]で、[Ctrl]+[C]キーを押す
  • Jupyterが停止したら、exitを実行してコマンドプロンプトを閉じる

以上です。

プロジェクトの再起動

設定が完了したプロジェクトを再開する方法です。

  • Unityを起動して、[unity-environment]プロジェクトを開く
  • [スタート]メニューから[すべてのプログラム]>[Anaconda3 (64-bit)]>[Anaconda Prompt]を選択して、コマンドプロンプトを起動
  • 以下を実行して、ml-agentsの環境に切り替え
chcp 65001
activate ml-agents
  • cdコマンドで、[ml-agents-master]フォルダー内の[python]フォルダーに移動
  • 以下でJupyterを起動
jupyter notebook
  • PPO.ipynbをクリックしてノートブックを起動

以上です。

まとめ

長かったですが、以上で機械学習を利用するUnityプロジェクトの環境構築が完了です。TensorFlowを利用した様々な機能を開発するよい土台となりそうです。

次は、このサンプルが何をやっているかの調査をして、把握できたらUnityプロジェクトの[examples]フォルダーに入っている他のサンプル([Basic][GridWorld][Tennis]の3つ)もいじってみたりしつつ、応用範囲を広げて行ければと考えています。

参考URL