はじめに
前回はCNTKでirisの推論モデルを作成し、ONNX形式で出力しました。MarkLogic10はCNTKとONNXに対応しており、ONNXに対応するフレームワークで作成したモデルを読み込めます。
今回はオリジナルのCNTKで作成したモデルをMarkLogicのCNTKで読み込み、推論してみます。
環境
環境 | バージョン |
---|---|
CentOS | 7.6 |
MarkLogic | 10.0-1 |
ONNXモデルをDBにロードする
使用するONNXモデルをMarkLogicにロードします。ロードはMarkLogicのロードツールMLCPを使用します。
MLCPの実行例は以下の通りです。ポイントはバイナリ形式でロードする点です。
$ mlcp.sh import \
-host [MarkLogicサーバ] \
-port [XDBCサーバのポート] \
-username [ユーザ名] \
-password [パスワード] \
-input_file_type documents \
-document_type binary \
-input_file_path [ONNXモデルのファイルパス] \
-output_uri_replace "[ONNXモデルのファイルパス], '[MarkLogic上のロード先URI]'"
ONNXモデルで推論してみる
ロードしたONNXモデルを使って、MarkLogic上でirisの推論を行います。irisデータセットは以前の投稿に記載したものです。言語はXQueryです。
なお、ソースコードは以下に公開しています。
https://github.com/t2hk/marklogic_cntk_onnx
ONNXモデルの読み込み
以下のようにMarkLogic上のONNXモデルを読み込みます。バイナリとして読み込むことがポイントです。
(:ONNXモデルの読み込む。:)
let $doc := fn:doc("[ONNXモデルのURI]")/binary()
let $model := cntk:function($doc, cntk:gpu(0), "onnx")
入出力データの変数定義
モデルの入力データ、出力データの変数定義を行います。モデル定義から読み込めます。
(:モデルの入出力形式を取得する。:)
let $input_variable := cntk:function-arguments($model)
let $output_variable := cntk:function-output($model)
入力データを用意する
テストデータ(irisの特徴量)からモデルの入力データを作成します。入力データは、モデルの入力定義であるcntk:input-variableと、入力データであるcntk:valueを組み合わせたJson形式の配列でなければなりません。
let $test := json:to-array(($sepal_length, $sepal_width, $petal_length, $petal_width))
let $input_value := cntk:batch(cntk:variable-shape($input_variable), $test)
let $input_pair := json:to-array(($input_variable, $input_value))
推論する
推論はcntk:evaluate関数を使います。
推論結果はcntk:value形式であるため、cntk:value-to-array関数を使ってJSON配列に変換します。
(:ONNXモデルを使用して推論する。:)
let $output_value := cntk:evaluate($model, $input_pair, $output_variable)
(:結果を出力する。:)
let $infer_result := cntk:value-to-array($output_variable, $output_value)
return fn:index-of($infer_result[1], fn:max($infer_result[1]))
上記の変数$infer_resultは、irisの種類に応じた確率値となります。この中で最大値のクラスのラベルを推論結果として返却しています。
[[-3.597829, 1.868926, 1.515098]]]
おしまい
MarkLogic10がCNTKを搭載したことによりDB上での機械学習モデルの構築が実現しましたが、XQueryでネットワークを構築するのは大変な点が多いです。
また、CNTKは本家が開発を中止しており情報も少ないこともあり、TensorflowやChainerなど使い慣れたフレームワークを使いたくなります。
ONNXを使用することで、使い慣れた環境で構築したモデルをMarkLogic上で動かせるようになります。