LoginSignup
6
8

More than 5 years have passed since last update.

Google Cloud Machine Learning EngineでUnity ML-Agentsを動かす

Last updated at Posted at 2018-08-06

本記事のUnity ML-Agentsバージョンは0.4.0となります。
バージョン0.5.0がリリースされましたが、一部コマンドやディレクトリ構成に変更があったため、バージョン0.5.0の場合、動作しない可能性があります。
絶賛記事更新作業中です(2018/09/13)

概要

Unity ML-Agents(以下 ML-Agents)をクラウド上で動作させるのに適切な環境を探しています。
そのなかで、Google Cloud Machine Learning Engine(以下 Cloud ML)上で動作するものなのか、検証してみました。

ML-AgentsはTensorflowを利用した強化学習ができるライブラリです。
なので、Tensorflowなどの機械学習実行エンジンであるCloud MLで動かないわけがない。(はず)

Google Cloud Machine Learning Engineとは

Google Cloud Machine Learning Engine は”エンジン”であって開発環境ではない ~制約に気を付けよう~
https://www.gixo.jp/blog/10960/

ML Engine を一言で説明するなら「機械学習を実行するためのクラウドサービス」です。そのため、DataRobotなどの他のクラウドサービスのようにサービス上で開発は行えません。

Unity ML-Agents

Unity Machine Learning Agentsベータ版
https://unity3d.com/jp/machine-learning

Unity ML-Agentsは、新世代のロボット、ゲームをはじめさまざまな分野において、迅速かつ効率的に新しいAIアルゴリズムの開発を行い、テストする柔軟な方法を提供します。

手順

前提条件

Cloud MLやUnity、ML-Agentsの環境構築が済んでいる前提です。
まだ環境がないという方は下記をご参考ください。

MacでCloud Machine Learning Engineを利用してみる
https://qiita.com/kai_kou/items/0952c9b28efe19f2f680

Macでhomebrewを使ってUnityをインストールする(Unity Hub、日本語化対応)
https://qiita.com/kai_kou/items/445e614fb71f2204e033

MacでUnity ML-Agentsの環境を構築する
https://qiita.com/kai_kou/items/6478fa686ce1af5939d8

Unityでアプリをビルドする

ML-Agentsでは実際にUnityアプリを動作させつつ強化学習がすすみます。
MacであればMac用、WindowsであればWindows用にアプリをビルドするわけですが、今回はCloud ML上で動作させる必要があるので、Linux用のビルドとなります。

アプリはML-Agentsに含まれる[3DBall]アプリを利用します。
手順は下記記事のDockerに関する手順以外をすすめてビルドします。

MacでUnity ML-AgentsをDockerで動作させる
https://qiita.com/kai_kou/items/df3f3518a5a27b66f617

unity-volume フォルダに以下ファイルとフォルダが用意できたと思います。

> ll ml-agents/unity-volume/
3DBall.x86_64
3DBall_Data

Cloud ML上で実行するための準備

Cloud MLで実行するための下準備です。

変数設定

Cloud Storageのバケット名やCloud MLを利用するリージョンなどを変数に設定します。
BUCKET_NAMEJOB_NAMEは任意で指定してください。

fish
> set -x BUCKET_NAME 任意のバケット名
> set -x REGION us-central1
> set -x JOB_NAME gcp_ml_cloud_run_01
bash
> export BUCKET_NAME=任意のバケット名
> export REGION=us-central1
> export JOB_NAME=gcp_ml_cloud_run_01

ハイパーパラメータの指定

今回は動作確認が目的となりますので、学習のステップを少なくします。
ML-Agentsライブラリにtrainer_config.yamlというハイパーパラメータを指定するYAMLがあるので、そちらでmax_stepsの指定をして5,000ステップ実行して終了するようにします。

> cd 任意のディレクトリ/ml-agents

> vi python/trainer_config.yaml

Ball3DBrain:
    normalize: true
    batch_size: 64
    buffer_size: 12000
    summary_freq: 1000
    time_horizon: 1000
    lambd: 0.99
    gamma: 0.995
    beta: 0.001
+   max_steps: 5000

アプリとハイパーパラメータファイルのアップロード

Cloud MLでは学習に利用するファイルなどをCloud Storageに置いて利用することになります。
今回はUnityアプリのファイル・フォルダとハイパーパラメータ設定ファイルをCloud Storageにコピーしておきます。
また、Linux用ビルドはDataフォルダがないとアプリが起動しません。
フォルダのままだと取り回しが面倒なので、ZIPファイルに圧縮しておきます。

> cd 任意のディレクトリ/ml-agents

# Dataフォルダの圧縮
> zip -r 3DBall_Data.zip unity-volume/3DBall_Data/

# Cloud Storageのバケットにコピー

# Unityアプリファイル
> gsutil cp unity-volume/3DBall.x86_64 gs://$BUCKET_NAME/data/3DBall.x86_64

> gsutil cp unity-volume/3DBall_Data.zip gs://$BUCKET_NAME/data/3DBall_Data.zip

# ハイパーパラメータ設定ファイル
> gsutil cp python/trainer_config.yaml gs://$BUCKET_NAME/data/trainer_config.yaml

学習実行ファイルの準備

ML-Agentsに含まれているpython/learn.pyが学習を開始するためのファイルになりますが、これをCloud MLで動作できるように以下の準備をします。

  • Pythonのパッケージ化
  • Cloud Storage連携実装追加
Pythonのパッケージ化

Cloud MLにPythonでパッケージ化されたファイルをアップして実行するので、その準備をします。

# Pythonフォルダのsetup.pyがCloud MLで動作するようにファイルを追加
> touch python/MANIFEST.in
> vi python/MANIFEST.in
+include requirements.txt

# learn.py実行用のパッケージ作成
> mkdir python/tasks
> touch python/tasks/__init__.py
> cp python/learn.py python/tasks/learn.py
learn.pyのカスタマイズ

learn.pyにCloud Storageからファイルを取得、学習結果をCloud Storageへ保存する実装を追加します。
今回、ファイル名を固定していますが、とりあえず動作検証のためなので、あしからず。
Cloud Storageからのファイル取得・アップにgsutilコマンドを利用していますが、ここはPythonで実装してもOKです。
手抜きできるところは徹底的に^^

> vi python/tasks/learn.py
python/tasks/learn.py
    # import追加
    import shlex
    import subprocess
    import zipfile    
    # import追加ここまで

    ()

    # General parameters
    ()
    fast_simulation = not bool(options['--slow'])
    no_graphics = options['--no-graphics']

    # ここから追加
    # Stackdriver Loggingでログ確認できるようにする
    logging.basicConfig(level=logging.INFO)

    # Cloud Storageのパス指定
    trainer_config_file = 'gs://任意のバケット名/data/trainer_config.yaml'
    app_file = 'gs://任意のバケット名/data/3DBall.x86_64'
    app_data_file = 'gs://任意のバケット名/data/3DBall_Data.zip'

    # 実行環境のに保存する際のパスを指定
    file_name = env_path.strip().replace('.x86_64', '')
    cwd = os.getcwd() + '/'
    app_data_local_dir = os.path.join(cwd, file_name + '_Data')
    app_local_file = os.path.join(cwd, file_name + '.x86_64')
    app_data_local_file = app_data_local_dir + '.zip'

    # Cloud Storageからコピー、Cloud ML環境だとgsutilが利用できて楽
    logger.info(subprocess.call(['gsutil', 'cp', trainer_config_file, cwd]))
    logger.info(subprocess.call(['gsutil', 'cp', app_file, cwd]))
    logger.info(subprocess.call(['gsutil', 'cp', app_data_file, cwd]))

    # Unityアプリ動作用にDataファイルを展開する
    with zipfile.ZipFile(app_data_local_file) as existing_zip:
        existing_zip.extractall(cwd)

    # Unityアプリが実行できるように権限を付与する
    logger.info(subprocess.call(shlex.split('chmod u+x ' + app_local_file)))
    # ここまで追加

    ()

    tc.start_learning()

    # ここから追加
    # モデルファイルをCloud Storageへアップ
    # TODO: 圧縮する
    models_local_path = './models/{run_id}'.format(run_id=run_id)
    models_storage_path = 'gs://任意のバケット名/{run_id}/models'.format(run_id=run_id)
    logger.info(subprocess.call(['gsutil', 'cp', '-r', models_local_path, models_storage_path]))
    # ここまで追加
パッケージ作成

Cloud MLの操作に利用するgcloudコマンドにはパッケージを自動作成する機能もありますが、ここでは手動でパッケージングします。

> cd python
> python setup.py sdist
()
Writing unityagents-0.4.0/setup.cfg
Creating tar archive
removing 'unityagents-0.4.0' (and everything under it)

> ll dist
total 96
-rw-r--r--  1 user  users    45K  8  6 11:14 unityagents-0.4.0.tar.gz

Cloud MLで実行してみる

さて、下準備が完了しましたので、Cloud MLへジョブ登録して学習を実行してみましょう。

パラメータ指定に--がありますが、これ以降のパラメータが--module-nameで指定したlearn.pyにパラメータとして渡されるので、取ってはいけません。(1敗)

> cd 任意のディレクトリ/ml-agents
> gcloud ml-engine jobs submit training $JOB_NAME \
    --python-version=3.5 \
    --runtime-version 1.8 \
    --module-name tasks.learn \
    --packages python/dist/unityagents-0.4.0.tar.gz \
    --region $REGION \
    --staging-bucket gs://$BUCKET_NAME \
    -- \
    3DBall \
    --run-id $JOB_NAME \
    --train

Job [gcp_ml_cloud_run_01] submitted successfully.
Your job is still active. You may view the status of your job with the command

  $ gcloud ml-engine jobs describe gcp_ml_cloud_run_01

or continue streaming the logs with the command

  $ gcloud ml-engine jobs stream-logs gcp_ml_cloud_run_01
jobId: gcp_ml_cloud_run_01
state: QUEUED


Updates are available for some Cloud SDK components.  To install them,
please run:
  $ gcloud components update

はい。

ジョブが登録されたか確認しましょう。

> gcloud ml-engine jobs describe $JOB_NAME

createTime: '2018-08-06T02:20:53Z'
etag: sm-_r3BqJBo=
jobId: gcp_ml_cloud_run_01
startTime: '2018-08-06T02:21:24Z'
state: RUNNING
trainingInput:
  args:
  - 3DBall
  - --run-id
  - gcp_ml_cloud_run_01
  - --train
  packageUris:
  - gs://任意のバケット名/gcp_ml_cloud_run_01/xxxx/unityagents-0.4.0.tar.gz
  pythonModule: tasks.learn
  pythonVersion: '3.5'
  region: us-central1
  runtimeVersion: '1.8'
trainingOutput:
  consumedMLUnits: 0.01

ジョブ実行されたかログを見てみましょう。

> gcloud ml-engine jobs stream-logs $JOB_NAME

()
INFO    2018-08-06 11:22:50 +0900       master-replica-0                List of nodes to export :
INFO    2018-08-06 11:22:50 +0900       master-replica-0                        action
INFO    2018-08-06 11:22:50 +0900       master-replica-0                        value_estimate
INFO    2018-08-06 11:22:50 +0900       master-replica-0                        action_probs
INFO    2018-08-06 11:22:51 +0900       master-replica-0                Restoring parameters from ./models/gcp_ml_cloud_run_01/model-5001.cptk
INFO    2018-08-06 11:22:51 +0900       master-replica-0                Froze 16 variables.
()
INFO    2018-08-06 11:22:54 +0900       master-replica-0                Module completed; cleaning up.
INFO    2018-08-06 11:22:54 +0900       master-replica-0                Clean up finished.
INFO    2018-08-06 11:22:54 +0900       master-replica-0                Task completed successfully.
INFO    2018-08-06 11:27:32 +0900       service         Job completed successfully.

はい。

これで、ML-AgentsがCloud ML上で実行されて、modelsフォルダに結果ファイルが出力されているはずです。
learn.pymodelsフォルダをCloud Storageにコピーしてるので、フォルダをローカルにコピーして、Unityアプリにbytesファイルを組み込んで動作させることができます。

> gsutil ls gs://任意のバケット名/$JOB_NAME/models

gs://任意のバケット名/gcp_ml_cloud_run_01/models/3DBall_gcp_ml_cloud_run_01.bytes
gs://任意のバケット名/gcp_ml_cloud_run_01/models/checkpoint
gs://任意のバケット名/gcp_ml_cloud_run_01/models/model-5001.cptk.data-00000-of-00001
gs://任意のバケット名/gcp_ml_cloud_run_01/models/model-5001.cptk.index
gs://任意のバケット名/gcp_ml_cloud_run_01/models/model-5001.cptk.meta
gs://任意のバケット名/gcp_ml_cloud_run_01/models/raw_graph_def.pb

tensorboardでも結果が確認できます。

> gsutil cp -r gs://任意のバケット名/$JOB_NAME/models ローカルの任意のフォルダ/
> tensorboard --logdir=ローカルの任意のフォルダ/models

実行できることが確認できました。やったぜ^^

あとは、learn.pyをもう少し実用的に改修したり、Cloud Pub/Subや、Cloud Functionsなどを利用すれば、Cloud StorageにUnityアプリをアップすれば、自動的に強化学習が実行される素敵環境が構築できそうです^^

参考

Google Cloud Machine Learning Engine は”エンジン”であって開発環境ではない ~制約に気を付けよう~
https://www.gixo.jp/blog/10960/

Unity Machine Learning Agentsベータ版
https://unity3d.com/jp/machine-learning

MacでCloud Machine Learning Engineを利用してみる
https://qiita.com/kai_kou/items/0952c9b28efe19f2f680

Macでhomebrewを使ってUnityをインストールする(Unity Hub、日本語化対応)
https://qiita.com/kai_kou/items/445e614fb71f2204e033

MacでUnity ML-Agentsの環境を構築する
https://qiita.com/kai_kou/items/6478fa686ce1af5939d8

MacでUnity ML-AgentsをDockerで動作させる
https://qiita.com/kai_kou/items/df3f3518a5a27b66f617

トレーニング アプリケーションのパッケージング
https://cloud.google.com/ml-engine/docs/tensorflow/packaging-trainer?hl=ja

【mac】zipファイル操作コマンド
https://qiita.com/griffin3104/items/948e38aab62bbb0d0610

Linuxの権限確認と変更(超初心者向け)
https://qiita.com/shisama/items/5f4c4fa768642aad9e06

17.5.1. subprocess モジュールを使う
https://docs.python.jp/3/library/subprocess.html

CloudMLからgoogle cloud storageのファイルにアクセスする
https://qiita.com/mikebird28/items/543581ef04476a76d3e0

Google Cloud ML Engine 上でPythonを実行する時のコツ
https://rooter.jp/ml/google-cloud-ml-engine-python-tips/

Pythonでzipファイルを圧縮・解凍するzipfile
https://note.nkmk.me/python-zipfile/

gsutilコマンド全部試したので解説する(part1)
https://www.apps-gcp.com/gsutil-command-explanation-part1/

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8