Google AutoML Tables の機械学習を使ってカード利用明細から家計簿の勘定科目を予測する(4)Docker 環境で予測

教師付きの機械学習サービスである Google AutoML Tables を使って、クレジットカードの利用明細(CSVファイル)から家計簿の勘定科目を予測してみます。第4回目の本記事では、モデルをエクスポートしてAutoML Tables 以外の環境で予測する方法を見ていきます。

【目次】

[1]はじめに


AutoML Tables で作成した機械学習モデルを使った予測方法として、大きく以下の2つ
  • AutoML Tables が提供(管理)する実行環境で予測
    • バッチ予測
    • オンライン予測
  • AutoML Tables 以外の環境で予測
    • 機械学習モデルをエクスポートして、外部のDocker環境で予測する
があります。

前者の「AutoML Tables が提供(管理)する実行環境で予測」については前の記事で概観しました。この方法は有償サービスではありますが、面倒な環境構築などは不要といったメリットがあります。

これに対して、後者の「AutoML Tables 以外の環境で予測」は、AutoML Tables で作成した機械学習モデルをエクスポートして、AutoML Tables 環境以外でモデルを利用する方法です。この方法は、自前で予測環境の構築が必要になりますが、目的や予算に応じた予測環境が作れます。また、エクスポートしたモデルは他のツールでも再利用できます。

特に、今回の題材のような超個人的(極めてプライベート)な用途には、予測処理に費用がかかると辛いし、せっかく作った機械学習モデルなので、自分のPC環境で費用を気にせず(無料で)気軽に利用したいです。

そこで、本記事では、作成済みの機械学習モデルをエクスポートして、自分のPC環境で予測する方法を見ていきます。

[2]エクスポートして予測する基本的な流れ

(1)概要

AutoML Tables で作成した機械学習モデルは Cloud Storage にエクスポートできます。また、エクスポートしたモデルを利用して予測処理ができる AutoML Tables モデルサーバー(Dockerコンテナ)も提供されています。これらを組み合わせると、AutoML Tables 環境以外でも予測処理ができます。

本記事では、上記ドキュメントに沿って、モデルをエクスポートし、自分のPC上にDocker環境を構築して予測できるようにします。

大まかな手順は以下の通りです。
  1. AutoML Tables の機械学習モデルを Cloud Storage にエクスポートします。
  2. AutoML Tables モデルサーバ(Dockerコンテナ)を実行する環境を準備します。
  3. エクスポートしたモデルをダウンロード後、AutoML tables モデルサーバにマウントして実行します。
    • または、新たにモデルを組み込んだDockerコンテナを作成して実行します。
  4. AutoML tables モデルサーバに対して予測リクエストを送信して予測結果を得ます。

AutoML tables モデルサーバでエクスポートしたモデルを実行する流れ

なお、本記事では、ローカル実行環境として、Windows 10 上の Vagrant + Ubuntu 20.04 LTS 環境を利用します。

(2)【参考】Google Cloud Runで動かす場合

本記事はエクスポートしたモデルを自分のPC上で動かす方法を見ていきますが、AutoML Tables モデルサーバ(Docker コンテナ)を実行できる環境であれば何でもよくて、ローカル環境に限ったものではありません。

例えば、以下のようにGCP上の Cloud Run で動かす方法もあります。

[3]モデルのエクスポート

(1)エクスポート手順

エクスポートは、データセット画面の「テストと使用」タブから行う方法に加えて、モデル一覧画面の該当のモデルの右端にあるメニューから行う方法もあります。

ここではデータセット画面からエクスポートする手順をメモしておきます。

AutoML Tables モデルのエクスポート画面

<エクスポート手順>
  1. 「テストと使用」タブ画面下の「モデルエクスポート」をクリックします。
  2. 「コンテナ」をクリックします。
  3. 右側にエクスポートのダイアログが表示されますので、ここでエクスポート先のクラウドストレージのフォルダを指定します。
    • 「BROWSE」ボタンをクリックすると「フォルダの選択」ダイアログに切り替わりますので、エクスポートしたモデルを格納したいCloud Storageのフォルダを指定して「SELECT」で決定します。
  4. フォルダを指定すると「エクスポート」ボタンが有効化されますので、「エクスポート」をクリックします。
    • エクスポートは非同期処理で実行されます。エクスポート処理が完了するとメールで通知してくれます。
  5. エクスポートが完了すると、gsutilを利用してダウンロードするためのコマンドサンプルが表示されますので、必要に応じてコピーしておきます。
    • 但し、現時点?では、このコマンドをそのまま実行すとエラーになりますのでご注意ください。詳細については「エクスポートしたモデルのダウンロード」の項を参照して下さい。
  6. 「完了」をクリックして画面を閉じます。

(2)エクスポートしたモデルのディレクトリ階層

エクスポート処理が完了すると、出力先に指定した Cloud Storage のフォルダの下に「model-export」というフォルダができていると思います。このフォルダは以下の階層になっています。

+ Cloud Storage のエクスポート先フォルダ
  + model-export
    + tbl
      + tf_saved_model-<model-name>-<export-timestamp>

ここで、「tf_saved_model-<model-name>-<export-timestamp>」がエクスポートしたモデルのディレクトリになっています。このディレクトリ名に含まれるタイムスタンプ(export-timespamp)部分は「YYYY-MM-DDThh:mm:ss.xxxxxxZ」の形をしているので、全て合わせるとかなり長いパスになっています。。。

(3)【参考】モデルの保存形式

モデルのエクスポート画面に「モデルを TensorFlow パッケージとしてエクスポートします。」と書いてありましたので、エクスポートしたデータの形式を調べてみました。

といっても、この部分については全くの素人なので自信はありませんが、SavedModel 形式のように思えます。

実際に試してはいませんが、このドキュメントを見ると、エクスポートしたモデルを利用して、いろいろな展開ができそうです(TFLite、TensorFlow.js, TensorFlow Serving など)。

[4]ローカル実行環境の準備

AutoML Tables のドキュメントに書かれているモデルサーバ(Dockerコンテナ)を、自前PCで実行するための環境を作ります。

(1)Vagrant+Ubuntu 20.04 LTS 環境の構築

Docker コンテナを実行する方法は色々考えられますが、本記事では、以前の記事に書いた Windows 10 上の Vagrant+Ubuntsu 20.04 LTS 環境を利用して試しました。

本記事では、この記事で作成した Ubuntu 20.04 LTS のBOXから作った仮想マシン上にDockerコンテナの実行環境を作ります。
(仮想マシンの作り方は、上記記事の「[6]BOXから新しい仮想マシンを作ってテストする」と同じ手順ですが、メモリ量などのパラメータは環境に合わせて調整します。)

ところで、予測だけなら、わざわざデスクトップ環境を用意する必要はありません。

ただ、上記デスクトップ環境には LibreOffice(Calc)などのスプレッドシートや curl 等のツールがセットアップ済みですし、プログラミング環境も簡単にセットアップできますので、今回の一連の記事に書いている作業を行うにあたっては、デスクトップ環境がとても重宝しました。

(2)Dockerのインストール

Docker は今回の記事の主題ではありませんので、Ubuntu 環境への簡単なインストール手順と動作確認のみにとどめます。

Ubuntu環境へのDockerのインストール手順の詳細については、以下の公式ドキュメントを参照して下さい。

ここでは、リポジトリを利用した Docker エンジンのインストール手順(コマンド)を抜粋します。

sudo apt-get update

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io

上記手順が完了したら、以下のコマンドを実行して Docker が正しくインストールされているか確認します。

sudo docker run hello-world

実行すると、メッセージがいっぱい出ると思いますが、中ほどに「Hello from Docker!」と表示されていれば Docker のインストールはうまくいっていると思います。

また、以下のコマンドを実行すると、hello-world というイメージが表示されると思います。
sudo docker images

[5]AutoML Tables モデルサーバの準備と起動

Docker コンテナの実行環境が用意できましたので、Cloud Storage にエクスポートした機械学習モデルをダウンロードして、AutoML Tables モデルサーバを起動します。

(1)Cloud SDK のインストール

Cloud Storage にエクスポートしたモデルをダウンロードする方法はいくつかあいますが、ここではツール(gsutil)を利用します。gsutil を利用するために、Google Cloud SDK をインストールします(gsutil は Cloud SDK に含まれています)。

Cloud SDKは、Ubuntu 環境のターミナルを開いて以下のコマンドを実行するだけで簡単にインストールできます。(以下は、上記ドキュメントからの抜粋です。)

# Add the Cloud SDK distribution URI as a package source
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list

# Import the Google Cloud public key
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -

# Update the package list and install the Cloud SDK
sudo apt-get update && sudo apt-get install google-cloud-sdk

インストールが完了したら、以下のコマンドを実行して初期化を行います。(モデルをエクスポートしたGoogleアカウントとプロジェクトを設定しておくと便利です。)

gcloud init

これで gsutil コマンドが利用できるようになりました。

(2)エクスポートしたモデルのダウンロード

gsutil コマンドを使ってエクスポートしたモデルをダウンロードします。gsutil コマンドの利用例などについては、以下の記事も参考にしてください。

ところで、エクスポートが完了したとき、エクスポート画面に「モデルをエクスポートした後、このコマンドを使用してご自身のコンピュータにパッケージをコピーできます:」として、(現時点では)以下のような gsutil ツールのコマンド例が表示されていたと思います。

gsutil cp -r gs://選択したパス//* ./download_dir

今回はこの gsutil のコマンド例に従ってダウンロードしてみます。

しかし、これをそのまま実行すると以下のエラーになってダウンロードに失敗します。
CommandException: No URLs matched: gs://xxxxx//*

そこで正しくコマンドを実行するために、以下の2点の作業を行います。
  • //* のようにスラッシュが2つあるところを、/* とスラッシュを1つにします。
  • ダウンロード先のディレクトリを作成します(未作成の場合)。
    • この例の場合は、mkdir download_dir などで作成しておきます。
    • なお、download_dir は任意の名前で問題ありません。

これを行った後、以下のコマンドを実行すると、download_dir 以下にモデルがダウンロードされると思います。
gsutil cp -r gs://選択したパス/* ./download_dir

そしてダウンロードが終了すると、download_dir の下に以下のようなフォルダ階層ができていると思います。
+ download_dir
  + model-export
    + tbl
      + tf_saved_model-<model-name>-<export-timestamp>

この「tf_saved_model-<model-name>-<export-timestamp>」がモデルのディレクトリです。

(3)AutoML Tables モデルサーバのダウンロード

予め AutoML Tables モデルサーバーの Docker イメージをダウンロードしておくために、以下の pull コマンドを実行します。

sudo docker pull gcr.io/cloud-automl-tables-public/model_server

ダウンロード後に docker images コマンドを実行すると、「gcr.io/cloud-automl-tables-public/model_server」の行が表示されると思います。

(4)AutoML Tables モデルサーバの起動

エクスポートした機械学習モデルのディレクトリをマウントして AutoML Tables モデルサーバ(Dockerコンテナ)を起動します。

ところで、エクスポートしたモデルのディレクトリ名(tf_saved_model-<model-name>-<export-timestamp>)のタイムスタンプの形式は「YYYY-MM-DDThh:mm:ss.xxxxxxZ」です。

docker run の -v オプションでマウントしようとすると、タイムスタンプ部分に含まれるコロン(:)が邪魔をして失敗します。(実行すると、「docker: Error response from daemon: invalid volume specification: …」というエラーになると思います。)

このため、Google のドキュメントでは、モデルのディレクトリ名を変更して起動する手順が示されています。

本記事では、モデルのディレクトリを、新たなディレクトリに名前を変えてコピーして起動する手順を書きます。

+ download_dir
  + model-export
    + tbl
      + tf_saved_model-<model-name>-<export-timestamp> <=モデル
+ my_model
  + export_model  <= モデルの名前を変えてコピー(移動)したもの

ここでは、新しいディレクトリ(my_model)を作り、その下にモデルのディレクトリ名を変えて(export_model)コピーする例を書きます。
mkdir  my_model
cp -r download_dir/model-export/tbl/モデルのディレクトリ名  my_model/export_model

なお、新しいディレクトリ名は何でも構いません。また、コピーでなく移動でも問題ありません。

以上で準備が整いましたので、以下のように docker run で実行します。
sudo docker run -v `pwd`/my_model/export_model:/models/default/0000001 -p 8080:8080 -it gcr.io/cloud-automl-tables-public/model_server

起動すると、ポート8080でリッスンしてます。

(参考)エクスポートしたディレクトリ名を変更しないで実行する方法

先の例は、docker run の -v オプションがコロンを含むディレクトリ名を扱えないために、モデルのディレクトリ名を変更しましたが、--mount オプションを利用すればこの問題を回避できます。

以下は、--mountオプションを利用した実行例です。
sudo docker run --mount type=bind,source=`pwd`/download_dir/model-export/tbl/tf_saved_モデル名_xxxxxxxxxxxxxx-xxxx-xx-xxTxx:xx:xx.xxxxxxZ,target=/models/default/0000001 -p 8080:8080 -it gcr.io/cloud-automl-tables-public/model_server

(5)【参考】新たにDockerイメージを作成して実行

ここでは、AutoML Tables モデルサーバのDockerイメージに、エクスポートしたモデルを追加して新しい自分用の Docker イメージを作って実行する方法を書きます。

モデルをマウントする方法で試した結果、予測がいい感じに仕上がっていたら、そしてその後も継続して利用するなら、この方法がよいかもしれません。

ここでは、 先の例で利用した my_modelの下のモデルディレクトリ(export_model)をパッケージしたDockerコンテナを作成する簡単な例を書きます。

まず、my_model ディレクトリの下に、以下の内容のDockerfileを作成します。
FROM gcr.io/cloud-automl-tables-public/model_server

ADD export_model /models/default/0000001

ちなみに、このDockerfileの内容は以下を参考にさせていただきました。

また、この方法ではコロンの問題はありませんので、エクスポートしたままのタイムスタンプを含むディレクトリ名でも利用できます。(リネームするより、リネームしないほうがモデルの出所が分かりやすいかもしれません。)

さて、Dockerfileが準備できたら、Dockerイメージをビルドします。ここではイメージ名を mymodel とします。(何でも構いません。)

my_model ディレクトリをカレントディレクトリにして、以下のコマンドを実行します。
sudo docker build . -t mymodel

ビルドが成功すると、docker images コマンドで mymodelが表示されると思います。

下記の docker run コマンドでサーバを起動します。(ポート8080でリッスンしてます。)
sudo docker run -p 8080:8080 -it mymodel

以上、ざっと Dockerコンテナで実行する方法を書きました。本格的に利用するなら、バージョンなどの管理面からもこちらの方法がよいと思いつつ、ちょっと試すだけなら少々大げさな気もします。なお、Cloud Run で実行する方法も、モデルをパッケージしたDockerイメージを作って実行します。

[6]予測

AutoML Tables モデルサーバが起動したら、予測を行うことができます。

(1)基本的な使い方

AutoML Tables モデルサーバを起動すると、「http://localhost:8080/predict」に対して予測リクエストを送信することができます。

予測リクエストのデータは、以下のJSON形式で指定します。
{
  "instances": [
    {
      "column_name_1": value,
      "column_name_2": value,
      …
    },
    …
  ]
}

ここで、column_name_X は、特徴量の名前で、それに対する値を指定します。特徴量のデータ型に対する値(value部分)の表現方法については以下のドキュメントを参考にしてください。

ところで、AutoML Tables モデルサーバは、AutoML Tables のオンライン予測と違って複数の予測データを一括して送信できます。また、バッチ予測のような非同期処理ではなく、同期処理です。このため、パフォーマンスを考慮する必要がある場合は、1回のリクエストに予測データをどのくらい含めるかの検討が必要になるかもしれません。(レイテンシとスループットの関係についてはドキュメントを参照して下さい。)

続いて、マルチカラム分類の場合の予測結果は、以下のJSON形式で返却されます。
{
  "predictions": [
    {
      "scores": [
        value_1,
        value_2,
        value_3,
      …
      ],
      "classes": [
        "category_value_1",
        "category_value_2",
        "category_value_3",
      …
      ]
    },
      …
  ]
}

ここで、classesはターゲットの全てのカテゴリ値のリストになっており、scoresは、カテゴリ値に対する確率スコアがそれぞれ設定されます。

(2)curl を利用した実行例

curl コマンドを利用して予測を行ってみます。

まず、以下のリクエストデータを作成して、request.json として保存します。
{
  "instances": [
    {
      "date": "2021/07/01",
      "description": "スーパーマーケット名",
      "amount": 562
    }
  ]
}

これを以下のように curl でリクエストします。この例では結果を response.json に保存します。
curl -X POST --data @request.json http://localhost:8080/predict  > response.json

以下は、response.json の内容を整形した結果です。
{
  "predictions": [
    {
      "scores": [
        4.234746953102331e-8,
        0.1305987685918808,
       …
      ],
      "classes": [
        "食費",
        "費用:医療費",
       …
      ]
    }
  ]
}

リクエスト用のJSONファイルを作るのはテキストエディタで作成できますが、結果を見るときは、JSONファイルのプリティプリントツールを利用しないと少々厳しいかもしれません。(最も簡単な整形表示方法は、response.json をFirefoxなどのブラウザにドラッグして表示することかも。)

[7]引き続き…

本記事では、AutoML Tables で作成した機械学習モデルをエクスポートして、自前PCで予測する方法を見てきました。

この方法は、AutoML Tables のバッチ予測やオンライン予測と違って、お手軽さはありませんが、無料で思う存分予測ができます(笑)。

さて、ここまで AutoML Tables の利用方法を中心に見てきましたので、次回の記事では、実験したことについて簡単にまとめたいと思います。

コメント

このブログの人気の投稿

VirtualBoxのスナップショット機能

Google Document AIで画像から表形式データを抽出する(Vision API OCRとの違い)

Ubuntu/Colab環境でPDFファイルのページを画像化する(pdf2image、pdftoppm、pdftocairo)