TensorFlow モデルを作る
#
はじめにBigQuery ML は インポートした TensorFlow モデルでの予測 ができます。 BigQuery ML で使える TensorFlow モデルを作るために色々なドキュメントを往復したので、まとめておきます。 BigQuery ML を使って TensorFlow モデルを管理できれば、データソースとの転送を省略したり、 モデルや実行環境の管理を BigQuery と Cloud Storage に任せたりできます。
また SavedModel 形式は、予測に限らず数式を入れたりできるので、brainfuck が実装できるか遊んでみました(敗北)。
#
モデルの作り方TensorFlow モデルをインポートする CREATE MODEL ステートメント にあるように、BigQuery ML で使える TensorFlow モデルは SavedModel として保存されている必要があります。 SavedModel を実際に作っていきましょう。
#
SavedModel を作る#
シンプルな SavedModel を作るtf.saved_model.save の例から始めましょう。
例では tf.TensorSpec は shape=None
と定義されていますが、BigQuery ML から使う場合は必須のようですので、
shape=1
とします。
#
作った SavedModel を BigQuery にインポートするTensorFlow モデルのインポート を参考にモデルをインポートします。 Cloud Storage にある SavedModel を参照できるので、予め転送しておきましょう。 クエリ 1 つでインポートできるのでとてもお手軽です。
#
インポートしたモデルを使うインポートした TensorFlow モデルでの予測 を参考にモデルで予測します。
実行結果。
行 | output_0 | x |
---|---|---|
0 | 3.0 | 1 |
1 | 5.0 | 2 |
2 | 7.0 | 3 |
3 | 9.0 | 4 |
4 | 11.0 | 5 |
5 | 13.0 | 6 |
6 | 15.0 | 7 |
7 | 17.0 | 8 |
8 | 19.0 | 9 |
9 | 21.0 | 10 |
無事に実行できました。
#
サポートされている型サポートされている入力 にありますが、再掲します。
TensorFlow 型 | BigQuery ML type |
---|---|
tf.int8, tf.int16, tf.int32, tf.int64, tf.uint8, tf.uint16, tf.uint32, tf.uint64 | INT64 |
tf.float16, tf.float32, tf.float64, tf.bfloat16 | FLOAT64 |
tf.bool | BOOL |
tf.string | STRING |
2020 年 2 月 12 日現在、対応している入出力型は限定的なため、BigQuery のデータ型とモデル作成時の型の自由度の差異に注意しましょう。
#
tf.estimator を使った SavedModel の作り方予測に使用する SavedModel のエクスポート を参考に、情報を補足します。
#
tf.estimator.BoostedTreesClassifier の SavedModel を作るBoosted trees using Estimators を参考に作ります。
#
データのロード#
入力値の作成#
tf.estimator の作成#
SavedModel の作成トレーニング中にサービスグラフを作成する にある json_serving_input_fn を使って、export すると BigQuery ML から理想的な形で呼び出すことができます。
#
ここが厄介TensorFlow 1.x は tf.placeholder が使えるので上のコードが動作します。 TensorFlow 2.x は tf.placeholder が使えないため、以下の serving_input_fn で Proto Buffers を経由して頑張る必要がありそうです。予め Proto Buffers に変換したテーブルを用意するのが解になってしまいます。他には tensorflow/tensorflow/core/example の .proto を JavaScript にコンパイルして UDF を作成すると回避できる可能性があります。
#
作った SavedModel を BigQuery にインポートする#
インポートしたモデルを使う実行結果。
行 | all_class_ids | all_classes | class_ids | classes | logistic | logits | probabilities | age | fare |
---|---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 0.001847356558 | -6.292150497 | 0.9981526732 | 10 | 0 |
1 | 1 | 0.001847356558 | |||||||
2 | 0 | 0 | 1 | 1 | 0.9975745082 | 6.019282341 | 0.00242551649 | 80 | 30 |
1 | 1 | 0.9975745082 |
動いてそうです。
#
Brainfuck を実装する#
UnliftableError に敗北実装してみたのですが、循環参照が計算グラフに変換できなさそうなエラーと遭遇して断念しました。
#
先行研究EsotericTensorFlow で、Brainfuck の実装が行われています。 しかし、Brainfuck のソースコードを渡して計算モデルを作成するもので、計算モデルにソースコードを渡して実行するインタプリタではなさそうです。 そのため、私は TensorFlow の計算モデルのチューリング完全性を証明することはできませんでした。
#
おわりにBigQuery ML で使える TensorFlow の SavedModel を作って動作確認しました。 チューリング完全性の証明には至りませんでしたが、BigQuery ML でテンソルグラフ計算や、 BigQuery ML 未リリースの BoostedTreesClassifier を実現できました。 BigQuery ML を使えれば、データとモデルが近い位置におけるメリットと、クエリ拡張性が出るため活用できると良いですね。