Google Cloud Machine Learning : 入門編 (1)
Google Cloud Machine Learning がパブリック・ベータになった旨のお知らせを頂きましたのでさっそく試してみました。サービスの概要は以下に記されています :
要約すれば、Google Cloud Machine Learning は GCP (Google Cloud Platform) と統合され、Google Cloud Dataflow、BigQuery、Cloud Storage そして Cloud Datalab のようなクラウド・コンピューティング・ツールと TensorFlow に渡るリッチな環境をスケールして作成可能なフルマネージドサービスになります。
また、新しい特徴として HyperTune があります。これは自動的に予測精度を改善します。モデルのための値を手動で発見する代わりに自動的にハイパーパラメータを調整することにより、より高性能なモデルを構築することを可能にします。
本記事では Getting Started – 入門編として、導入及びシンプルなジョブを投入するまでを簡単にまとめておきます。文章やスナップショットを混えると長く感じますが、実際の作業量は少なく、慣れてしまえば非常に簡単です。
クライアント環境は Ubuntu 14.04 LTS ですが、今回は Chrome から Cloud Shell 経由で接続していますので、他の OS でもおそらく同様に試せるかと思います。
* あくまでベータですので仕様が変更される可能性はありますのでご注意ください。
セットアップする
セットアップは順を追って説明しますが、基本的に以下のドキュメントに従って行えば良いです。作業量も大した量ではありません :
Google Cloud プロジェクトを設定する
まず準備としてプロジェクトを選択または作成して、以下の API を有効にします :
API を有効にするには上の “Gettng Set Up” ページで “Enable the APIs” ボタンをクリックすれば簡単です。
環境をセットアップする
クライアント環境については 1) Cloud Shell 2) Docker コンテナ 3) ローカル Mac/Linux から選択できますが、Docker をインストールしていないのであれば “Cloud Shell” を選択しましょうと指示されていますので、取り敢えず 1) の Cloud Shell で試してみます。
Cloud Shell はどのソフトウェアのインストールも必要なく Cloud ML を最速で試すことができる方法で、すべての変更は Cloud Shell 仮想マシンに隔離されます。それらの変更を失うことなく切断可能、そして後で再接続できます。(Getting Set Up から抜粋)
【手順】
- Cloud Shell を開始し、以下の全てのコマンドを shell 上で実行します。
* Cloud Shell の開始は簡単で、”Google Cloud Platform Console” の最上部の “Google Cloud Shell を有効にする” ボタンをクリックするだけです。
* Debian Jessie の f1-micro インスタンスが起動し、bash が使えますので特に迷うことはないでしょう。 - 必要なツールとその依存をインストールするために以下を実行します :
curl https://storage.googleapis.com/cloud-ml/scripts/setup_cloud_shell.sh | bash
numpy, pandas, scikit-learn のような定番ライブラリとともに tensorflow がインストールされ、およそ 5 分でインストール完了です。tensorflow のバージョンは現時点 (10/16/2016) での最新版 0.11.0 rc0 です。
- 新しくインストールされたツールを PATH に追加とありますが、実際には .bashrc に追記されます :
export PATH=${HOME}/.local/bin:${PATH}
- 以下でインストールされた環境の検証ができます :
curl https://storage.googleapis.com/cloud-ml/scripts/check_environment.py | python
“Success! Your environment is configured correctly.” と表示されれば O.K. です。
Cloud ML プロジェクトを初期化する
Cloud ML サービス・アカウントに Google Cloud プロジェクトのリソースへのアクセスを許可します :
gcloud beta ml init-project
Cloud Storage バケットを設定する
Cloud ML サービスは、モデル訓練とバッチ予測の間、データを読み書きするために Cloud Storage にアクセスする必要があります。
* 以下の例では us-central1 リージョンを使っていますが、Cloud ML ジョブを走らせるのと同じリージョンを使います。
[手順]
- 新しいバケットのために名前を設定します。名前は何でも良いのでしょうけど、ドキュメントでは “プロジェクト名+ml” が例としてあげられています :
PROJECT_ID=$(gcloud config list project --format "value(core.project)") BUCKET_NAME=${PROJECT_ID}-ml
- 新しいバケットを作成します :
gsutil mb -l us-central1 gs://$BUCKET_NAME
Training クイックスタート
セットアップが完了したので、具体的な training を試すことができます。以下のドキュメントに従って試していきます :
ローカルで訓練する
一般的な開発ワークフローとして、最初に(small dataset で)ローカルで実行することが推奨されています。これはコードが正常に動作し、期待する結果を生成することを保証してくれます。
サンプルは例によって MNIST で取り敢えず以下に移動します、コード自体は trainer/task.py で見つかります :
cd ~/google-cloud-ml/samples/mnist/trainable/
訓練を実行する
ローカルで訓練コードを実行してみます、MNIST 訓練データは自動的にダウンロードされます :
# ローカルで訓練 python -m trainer.task
特に問題なく訓練終了です :
$ python -m trainer.task Successfully downloaded train-images-idx3-ubyte.gz 9912422 bytes. Extracting /tmp/tmp7Vv8ZD/train-images-idx3-ubyte.gz Successfully downloaded train-labels-idx1-ubyte.gz 28881 bytes. Extracting /tmp/tmp7Vv8ZD/train-labels-idx1-ubyte.gz Successfully downloaded t10k-images-idx3-ubyte.gz 1648877 bytes. Extracting /tmp/tmp7Vv8ZD/t10k-images-idx3-ubyte.gz Successfully downloaded t10k-labels-idx1-ubyte.gz 4542 bytes. Extracting /tmp/tmp7Vv8ZD/t10k-labels-idx1-ubyte.gz Step 0: loss = 2.31 (0.112 sec) Step 100: loss = 2.18 (0.005 sec) Step 200: loss = 1.92 (0.004 sec) Step 300: loss = 1.59 (0.005 sec) Step 400: loss = 1.33 (0.005 sec) Step 500: loss = 0.88 (0.004 sec) Step 600: loss = 0.76 (0.005 sec) Step 700: loss = 0.72 (0.005 sec) Step 800: loss = 0.75 (0.005 sec) Step 900: loss = 0.46 (0.004 sec) Training Data Eval: Num examples: 55000 Num correct: 46859 Precision @ 1: 0.8520 Validation Data Eval: Num examples: 5000 Num correct: 4324 Precision @ 1: 0.8648 Test Data Eval: Num examples: 10000 Num correct: 8635 Precision @ 1: 0.8635 Step 1000: loss = 0.54 (0.038 sec) Step 1100: loss = 0.44 (0.235 sec) Step 1200: loss = 0.42 (0.005 sec) Step 1300: loss = 0.41 (0.005 sec) Step 1400: loss = 0.41 (0.005 sec) Step 1500: loss = 0.46 (0.005 sec) Step 1600: loss = 0.63 (0.005 sec) Step 1700: loss = 0.34 (0.004 sec) Step 1800: loss = 0.43 (0.006 sec) Step 1900: loss = 0.34 (0.004 sec) Training Data Eval: Num examples: 55000 Num correct: 49038 Precision @ 1: 0.8916 Validation Data Eval: Num examples: 5000 Num correct: 4517 Precision @ 1: 0.9034 Test Data Eval: Num examples: 10000 Num correct: 8989 Precision @ 1: 0.8989
TensorBoard も利用可能です :
tensorboard --logdir=data/ --port=8080
クラウド上で訓練する : シングル・ワーカー
ここからが本番です。コードの検証ができたら、次のステップは(full dataset を使って)Cloud ML API に訓練ジョブをサブミットすることによりモデルを訓練することです。
ここでは、ローカルで試したものと同じ訓練コードを使用します :
cd ~/google-cloud-ml/samples/mnist/trainable/
訓練ジョブを submit する
訓練ジョブのために名前を選択します、 e.g. “mnist_yourusername”。
名前は英文字で始まり、英数字と underscore を含めることができます。
JOB_NAME=<your job name>
念のため、以前の実行出力をクリアしておきます :
PROJECT_ID=`gcloud config list project --format "value(core.project)"` TRAIN_BUCKET=gs://${PROJECT_ID}-ml TRAIN_PATH=${TRAIN_BUCKET}/${JOB_NAME} # ex) gs://classcat-tensorflow-ml/mnist_classcat gsutil rm -rf ${TRAIN_PATH}
訓練ジョブを submit するためには、以下を実行します :
gcloud beta ml jobs submit training ${JOB_NAME} \ --package-path=trainer \ --module-name=trainer.task \ --staging-bucket="${TRAIN_BUCKET}" \ --region=us-central1 \ -- \ --train_dir="${TRAIN_PATH}/train"
以下は submit 直後の出力例です :
createTime: '2016-10-16T08:45:11Z' jobId: mnist_classcat state: QUEUED trainingInput: args: - --train_dir=gs://classcat-tensorflow-ml/mnist_classcat/train packageUris: - gs://classcat-tensorflow-ml/cloudmldist/1476607509/trainer-0.0.0.tar.gz pythonModule: trainer.task region: us-central1
ジョブのステータスの確認もできます、以下はまだ準備中ですね :
$ gcloud beta ml jobs describe --project ${PROJECT_ID} ${JOB_NAME} createTime: '2016-10-16T08:45:11Z' jobId: mnist_classcat state: PREPARING trainingInput: args: - --train_dir=gs://classcat-tensorflow-ml/mnist_classcat/train packageUris: - gs://classcat-tensorflow-ml/cloudmldist/1476607509/trainer-0.0.0.tar.gz pythonModule: trainer.task region: us-central1
そして実行中 :
$ gcloud beta ml jobs describe --project ${PROJECT_ID} ${JOB_NAME} createTime: '2016-10-16T08:45:11Z' jobId: mnist_classcat startTime: '2016-10-16T08:48:12Z' state: RUNNING trainingInput: args: - --train_dir=gs://classcat-tensorflow-ml/mnist_classcat/train packageUris: - gs://classcat-tensorflow-ml/cloudmldist/1476607509/trainer-0.0.0.tar.gz pythonModule: trainer.task region: us-central1
成功しました! :
$ gcloud beta ml jobs describe --project ${PROJECT_ID} $ {JOB_NAME} createTime: '2016-10-16T08:45:11Z' endTime: '2016-10-16T08:52:48Z' jobId: mnist_classcat startTime: '2016-10-16T08:48:12Z' state: SUCCEEDED trainingInput: args: - --train_dir=gs://classcat-tensorflow-ml/mnist_classcat/train packageUris: - gs://classcat-tensorflow-ml/cloudmldist/1476607509/trainer-0.0.0.tar.gz pythonModule: trainer.task region: us-central1
管理コンソールからも確認できます :
出力を inspect する
クラウド訓練では、出力は Google Cloud Storage に生成されます。
この例では、出力は ${TRAIN_PATH}/train にセーブされ、以下のようにリスティングできます :
$ echo $TRAIN_PATH gs://classcat-tensorflow-ml/mnist_classcat $ gsutil ls ${TRAIN_PATH}/train gs://classcat-tensorflow-ml/mnist_classcat/train/ gs://classcat-tensorflow-ml/mnist_classcat/train/checkpoint gs://classcat-tensorflow-ml/mnist_classcat/train/checkpoint-1999 gs://classcat-tensorflow-ml/mnist_classcat/train/checkpoint-1999.meta gs://classcat-tensorflow-ml/mnist_classcat/train/checkpoint-999 gs://classcat-tensorflow-ml/mnist_classcat/train/checkpoint-999.meta gs://classcat-tensorflow-ml/mnist_classcat/train/events.out.tfevents.1476607903.master-9a8c-0-n6vcy
Stackdriver logging を inspect する
Cloud ML は訓練ジョブを実行する時、全ての stdout/stderr ストリームを捕捉してロギングします。これらのログは Stackdriver logging に保存され、実行中及び実行後に見ることができます。
ログを見る一番簡単な方法は管理コンソールから “ログを表示” をクリックすることです :
* master-replica-0 は master 視点からジョブ実行の概要を与えてくれます。
alternative として、コマンドラインからもログが取得できます。
以下は、master-replica-0 タスクのための全てのログを取得します :
gcloud beta logging read --project ${PROJECT_ID} --format=json \ "labels.\"ml.googleapis.com/task_name\"=\"master-replica-0\" AND \ labels.\"ml.googleapis.com/job_id\"=\"${JOB_NAME}\""
実行結果です :
$ gcloud beta logging read --project ${PROJECT_ID} --for mat=json "labels.\"ml.googleapis.com/task_name\"=\"master-replica-0\" AND \ labels.\"ml.googleapis.com/job_id\"=\"${JOB_NAME}\"" | head -40 [ { "insertId": "chs2jrg2q03vhr", "jsonPayload": { "created": 1476607935.08323, "levelname": "INFO", "lineno": 690, "message": "Task completed successfully.", "pathname": "/runcloudml.py" }, "labels": { "compute.googleapis.com/resource_id": "6857495858232852682", "compute.googleapis.com/resource_name": "master-9a8c-0-n6vcy", "compute.googleapis.com/resource_type": "instance", "ml.googleapis.com/job_id": "mnist_classcat", "ml.googleapis.com/job_id/log_area": "root", "ml.googleapis.com/task_name": "master-replica-0", "ml.googleapis.com/trial_id": "" }, "logName": "projects/classcat-tensorflow/logs/master-replica-0", "resource": { "labels": { "job_id": "mnist_classcat", "task_name": "master-replica-0" }, "type": "ml_job" }, "severity": "INFO", "timestamp": "2016-10-16T08:52:15.083230972Z" }, { "insertId": "chs2jrg2q03vhp", "jsonPayload": { "created": 1476607935.08276, "levelname": "INFO", "lineno": 688, "message": "Clean up finished.", "pathname": "/runcloudml.py" }, "labels": { ...
要約ログを inspect する
もちろん TensorBoard も利用可能で –logdir=${TRAIN_PATH}/train を引数にすれば良いです。
具体的には、例えば :
tensorboard --logdir=gs://classcat-tensorflow-ml/mnist_classcat/train --port=8080
区切りが良いので、入門編 (1) はここまでとします。
入門編 (2) では分散や hyperparameter 調整が主題になります。
以上