TensorBoardをGoogle App Engineで使えるようにしてみた

## 概要

TensorBoardはCloud Storageにある学習結果ファイルを参照できるっぽいのだけれど、ローカルからCloud Storageにアクセスするのに環境構築や権限設定が面倒だったので、App Engineに環境を作ってTensorBoardにアクセスできるようにした。

といいますか、公式がそういう便利なのを用意してくれてたので、ありがたく利用させてもらいます。

GoogleCloudPlatform/appengine-tensorboard
https://github.com/GoogleCloudPlatform/appengine-tensorboard

>Google App Engineを使用すると、小さなコストで認証を使用して永続的なTensorboardサーバを簡単に取得できます。

>さらに、Tensorboardサーバーを起動するときにGCSから大量のデータを取得する場合は、GCSとGAE間のデータ出力に料金を払わないため、実際には永続的なGAEサーバーの料金が少なくなることがあります。

(Google翻訳)

仕組み的にはoauth2_proxyでユーザー認証の上、デプロイ時に設定したCloud Storageの指定バケットをlog_dirとして参照できるみたいです。


## 手順

### プロジェクトファイルのダウンロード

```sh
> git clone https://github.com/GoogleCloudPlatform/appengine-tensorboard.git
> cd appengine-tensorboard
```

### OAuth2の設定

ここではGCPの認証を利用します。

GCP管理コンソールの[APIとサービス]にある[認証情報]を開く。

[認証情報を作成]ボタンから[OAuthクライアントIDの作成]をクリック
<img width="576" alt="スクリーンショット 2018-08-13 18.35.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/48549/3c2d1470-6384-35f9-a50a-1a655d05b564.png">


以下の内容を選択・入力して[作成]ボタンをクリック

- アプリケーションの種類: ウェブアプリケーション
- 名前: 適当に
- 承認済みのJavaScriptを生成: 空でOK
- 承認済みのリダイレクトURI: あとから設定するので空でおｋ
<img width="636" alt="スクリーンショット 2018-08-13 18.36.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/48549/db1936f7-55da-ce8c-ca94-bf9fef37c9b9.png">

これで、OAuth2認証用のクライアントIDとクライアントシークレットが発行されます。
<img width="511" alt="認証情報.png" src="https://qiita-image-store.s3.amazonaws.com/0/48549/bff12f78-18ed-fd91-4b08-22838771fc06.png">


OAuth2　Proxyの設定を行います。

```sh
> cp example_oauth2_proxy.cfg oauth2_proxy.cfg
> vi oauth2_proxy.cfg
```

```txt:oauth2_proxy.cfg
-client_id = "my-client-id"
-client_secret = "myclientsecret"
+client_id = "GCP認証情報のクライアントID"
+client_secret = "GCP認証情報のクライアントシークレット"
```

App Engineの設定を行います。

```sh
> cp example-app.yaml app.yaml
> vi app.yaml
```

もし既存のGCPプロジェクトにデプロイする場合、```service``` 指定しないと、```default``` にデプロイされてしまうので、ご注意ください。

```yaml:app.yaml
runtime: custom
env: flex
+service: サービス名
threadsafe: true
resources:
  memory_gb: 32
  cpu: 8
automatic_scaling:
  max_num_instances: 1
env_variables:
- EVENT_FILE_PATH: gs://ml-workshop/output/mnist_hptuning10
+ EVENT_FILE_PATH: gs://任意のバケット/output/TensorFlowの結果フォルダ
  RELOAD_INTERVAL: 600
- GCS_PROXY_CONFIG: gs://ml-workshop/oauth2_proxy.cfg
+ GCS_PROXY_CONFIG: gs://任意のバケット/oauth2_proxy.cfg
  RELOAD_INTERVAL: 600
```

### App Engineへデプロイ

oauth2_proxy.cfgをCloud Storageへコピーします。

バケットがなかったら作成しておきましょう。

```sh
> gsutil cp oauth2_proxy.cfg gs://任意のバケット/oauth2_proxy.cfg
```

TensorFlowの結果についてもCloud Storageへコピーしておきましょう。

```sh
> gsutil cp -r TensorFlowの結果フォルダ  gs://任意のバケット/output/
```

では、App Engineへデプロイします。
GoogleさんがDockerイメージを用意してくれているので、それをデプロイする感じです。

```sh
> gcloud app deploy app.yaml --image-url=gcr.io/google-samples/appengine-tensorboard:latest

(略)
Deployed service [サービス名] to [https://サービス名-dot-プロジェクトID.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s サービス名

To view your application in the web browser run:
```

これでURLがきまりましたので、先程作成した、認証情報の[承認済みのリダイレクトURI]に設定しておきましょう。



### アクセスしてみる。

では、App Engineにデプロイできたので、URLへアクセスしてみましょう。

```sh
> open https://サービス名-dot-プロジェクトID.appspot.com
```

認証しろと表示されます。
<img width="1008" alt="Sign_In.png" src="https://qiita-image-store.s3.amazonaws.com/0/48549/d7d06c4c-a71d-22c2-45cb-53b73999b8f2.png">


この辺は通常のOAuth2の認証ですね。
<img width="521" alt="ログイン_-_Google_アカウント-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/48549/abbf935f-25a3-06c9-bf75-a984d6cb46ab.png">


で、認証したら無事にTensorBoardが表示されました。
<img width="1093" alt="TensorBoard-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/48549/13507634-4de5-e0a8-c19e-53fc8a120742.png">


やったぜ。


注意点としては、Dockerイメージが用意されていますが、TensorFlowのバージョンが古め(0.8.0)なところでしょうか。


## 参考

GoogleCloudPlatform/appengine-tensorboard
https://github.com/GoogleCloudPlatform/appengine-tensorboard