概要
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://cloudpack.media/42306
Macでhomebrewを使ってUnityをインストールする(Unity Hub、日本語化対応)
https://cloudpack.media/42142
MacでUnity ML-Agentsの環境を構築する
https://cloudpack.media/42164
Unityでアプリをビルドする
ML-Agentsでは実際にUnityアプリを動作させつつ強化学習がすすみます。
MacであればMac用、WindowsであればWindows用にアプリをビルドするわけですが、今回はCloud ML上で動作させる必要があるので、Linux用のビルドとなります。
アプリはML-Agentsに含まれる[3DBall]アプリを利用します。
手順は下記記事のDockerに関する手順以外をすすめてビルドします。
MacでUnity ML-AgentsをDockerで動作させる
https://cloudpack.media/42285
unity-volume
フォルダに以下ファイルとフォルダが用意できたと思います。
> ll ml-agents/unity-volume/ 3DBall.x86_64 3DBall_Data
Cloud ML上で実行するための準備
Cloud MLで実行するための下準備です。
変数設定
Cloud Storageのバケット名やCloud MLを利用するリージョンなどを変数に設定します。BUCKET_NAME
とJOB_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.py
でmodels
フォルダを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://cloudpack.media/42306
Macでhomebrewを使ってUnityをインストールする(Unity Hub、日本語化対応)
https://cloudpack.media/42142
MacでUnity ML-Agentsの環境を構築する
https://cloudpack.media/42164
MacでUnity ML-AgentsをDockerで動作させる
https://cloudpack.media/422854
トレーニング アプリケーションのパッケージング
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/