最近何かと耳にするようになってきた「ONNX」。
Webの記事とかで見るんだけど「DeepLearningとかで使われてるアレでしょ?」「そもそもどう読むか分からない」という人のためにONNXがどういったものなのか、Windows Machine Learningとどう関係してくるのかを3分で分かるくらいの分量でまとめようと思います。
さくっと結論から見たい方はこちらから
つまりWindows10上でWindowsMLを使って機械学習するにはどうすればいいの?
想定読者
DeepLearning界隈の動向を追っているような方々は対象にしていません。
もともとこの記事を書こうと思ったきっかけが、Hololens界隈でWindows Machine Learningが話題になっているけどONNXに関する情報が少ないなーと思ったことです。
なので、日頃からDeepLearningに触れているわけではなく、特にHololensとかUWP界隈にいる人達向けの解説となります。
ONNXとは?
ONNXはOpen Neural Network eXchangeの略で、DeepLearningモデルを様々なフレームワーク間で交換するためのフォーマットです。
これを使えばあるDeepLearningフレームワークで学習させたモデルを他のフレームワークでも利用することができます。DeepLearningフレームワーク戦国時代には嬉しい仕組みです。
ちなみにONNXは「オニキス」と発音します。
ONNXフォーマットの対応状況
こちらが2018年4月の段階での各種DeepLearningフレームワークのONNXフォーマットの対応状況です。
ONNXフォーマットを扱う上で注意しなくてはならない点が2つあります。
注意1:各フレームワーク間でのExport/Import
図の中にいろいろ見知らぬフレームワークの名前がありますが、大切なのは全てのフレームワークで相互変換が可能なわけではないということです。
図を見ても分かる通り、各フレームワークでExport/Importの対応状況に差があり、例えばChainerで学習させたモデルをPyTorchに持ち込むということはできません。
注意2:各フレームワークのパーツレベルでの対応
またもうひとつ注意しなくてはならないのが、各フレームワークが一部のDeepLearnigモデルのパーツ(関数)のExport/Importに対応していないということです。
少しややこしい話になりますが、ONNXの仕様上は存在しているがフレームワーク側でまだ対応できていないといったパーツが存在します。
特定のフレームワークのモデルをONNXフォーマットでExport/Importする場合、モデルのパーツ全てがそのフレームワークで対応している必要があります。
PyTrochを例に出すと、こちらのページにあるパーツがPyTorchが対応しているパーツですが、この中にLSTMといったパーツは存在しておらずこれを含むモデルはONNXフォーマットでExportすることができません。
そのため、フレームワークがONNXフォーマットに対応しているからといって全てのモデルをExport/Importできるわけではないということに注意してください。
(余談: ONNX公式の仕様にはLSTMといったパーツも含まれているため、いずれ対応されると思います。)
Windows Machine Learningとは
Windows Machine Learning(Windows ML)はWindows10デバイス上で機械学習を行うためのAPIを提供するプラットフォームです。
これを使えば、Windows10上での機械学習のコードをC#を使ってさくっと書くことができるようになります。
重要なのはONNXフォーマットのモデルを読み込んで推論(予測)を行う機能が用意されていることです。
winmltoolsを使えばCoreMLなどのモデルも取り込める
winmltoolsはMicrosoftが公式で出しているWindows ML向けのtoolで、これを使えばCoreMLやScikit-learnといった機械学習フレームワークのモデルをWindows MLが読み込めるONNXフォーマットに変換して保存することができます。
(CoreMLはDeepLearningフレームワークの1種です)
# coremltoolsはCoreMLモデルを扱うtool
from coremltools.models.utils import load_spec
from winmltools import convert_coreml
from winmltools.utils import save_model, save_text
# CoreMLモデルのロード
model_coreml = load_spec("MobileNet.mlmodel")
# CoreMLモデルをONNXモデルに変換
model_onnx = convert_coreml(model_coreml, name="mobilenet")
# モデルをONNXフォーマットのバイナリモデルとテキストで保存する
save_model(model_onnx, "Mobilenet.onnx")
save_text(model_onnx, "Mobilenet.txt")
つまりWindows10上でWindowsMLを使って機械学習するにはどうすればいいの?
結局のところ、機械学習モデルをONNXフォーマットで用意できれば後はWindows MLで読み込んでAPIを使って推論を行えます。
そのため機械学習モデルを
- Windows ML上で学習
- 各種DeepLearningライブラリでモデルを学習させONNXフォーマットでExport
- 公開されている機械学習モデルをwinmltoolsで変換したり、各種フレームワークでExport
といった手段で用意することが考えられます。
2や3で各フレームワークで学習済みのモデルをExportする際には、こちらで書いたように各フレームワークがそのモデルの全てのパーツに対してExportに対応しているかどうかが鍵になります。どんなモデルでもONNXフォーマットに変換できるわけではありません。
3. に関してはModel Zooといって学習済みモデルを公開する場所がいくつかあり、そこから良さそうなモデルを探してきてwinmltoolsで変換するのが良いでしょう。
- ONNX Models: ONNXの学習済みモデルを配布している
- Core ML Store: CoreMLの学習済みモデルを配布している
おまけ
3のパターンとして、CoreMLの学習済みモデルが公開されているMobileNetを使ってリアルタイムに画像認識を行うアプリを作ったので参考までにどうぞ
https://github.com/ymym3412/WindowsML-CoreML-MobileNet-demo
やり方やコードはこちらの記事のものをほぼ流用させて頂きました。ありがとうございました。
Custom Vision Serviceから出力したモデルを使ってWindowsML上で物体認識をする(その1 AIモデルの作成と出力)
参考文献
ONNX公式
Github: ONNX/ONNX
Windows Machine Learning
Github: Microsoft/Windows-Machine-Learning
Custom Vision Serviceから出力したモデルを使ってWindowsML上で物体認識をする(その1 AIモデルの作成と出力)
HoloLensでWindowsMLを試してみる(サンプル実行編)