Azure Custom Vision Serviceで作成したONNXモデルをWindows 10で実行する

#概要
Azure Custom Vision Serviceは誰でも画像認識のモデルが作成できるお手軽なツールになります。DeepLearningの世界で転移学習にしても自分で実行するのはかなり手間ですが、少ないデータで手間なく画像認識を行うことができるのは大きなメリットではないでしょうか？
作成したモデルに関しては[こちらの記事](https://analyticsai.wordpress.com/2018/06/20/azure-custom-vision-service%e3%81%ae%e5%ae%9f%e7%94%a8%e6%80%a7/)を参照ください

#Azure Custom Vision ServiceからONNXモデルのExport
Cusotom Vision Serviceで作成した[モデル](https://analyticsai.wordpress.com/2018/06/25/azure-custom-vision-service%e3%82%92%e4%bd%9c%e6%88%90%e3%81%97%e3%81%9fonnx%e3%83%a2%e3%83%87%e3%83%ab%e3%81%aewindows10%e3%81%a7%e3%81%ae%e5%ae%9f%e8%a1%8c/)をExportします。肺炎患者のレントゲン写真であり、ウイルス性、細菌性の肺炎の判定を行います。Compactモデルで作成しなければExportできないのでCompactモデルを選択して一度学習させます。

![onn3.png](https://qiita-image-store.s3.amazonaws.com/0/177932/e746cea8-21b3-15a8-bf14-14bffa15e8e6.png)

![onnx2.png](https://qiita-image-store.s3.amazonaws.com/0/177932/591f28bb-755a-3ad5-a4da-fdfcb0fccc5c.png)

Exportをクリックするとダウンロドする形式が選べるので、ONNXを選びダウンロードします。

![onnx1.jpg](https://qiita-image-store.s3.amazonaws.com/0/177932/7d3915c4-9f6f-4ccf-05b9-9f445fcb1979.jpeg)

[Netron](https://github.com/lutzroeder/Netron)でモデルを見ることができます。
![netron.jpg](https://qiita-image-store.s3.amazonaws.com/0/177932/c00fc1ec-1f59-47de-0128-ac95b8b30bbe.jpeg)

normal.onnxとして保存しています。

#ONNXモデルをWindows Machine Learningで実行する簡単な方法
AzureのサンプルにCustom Visionで出力されたONNXモデルを使用するものがあります。
Windows10のビルド1803にまずアップデートする必要があります。その上で、Visual Studio 2017をインストールし、対応するSDKを導入します。[こちら](https://developer.microsoft.com/ja-jp/windows/downloads/windows-10-sdk)を参考にしてください
normal.onnxをVisual StudioのAssetに追加します。その場合、非常に長いクラス名のラッパーコードが生成されますが、使わないので削除します。

````
git clone https://github.com/Azure-Samples/cognitive-services-onnx-customvision-sample
````

上記でサンプルを同期できます。
修正箇所は多くなく、２か所の修正で動作させることができます
MainPage.xaml.csを編集します。

````c#
namespace SampleOnnxEvaluationApp
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        private Stopwatch _stopwatch = new Stopwatch();
        private OnnxModel _model = null;
        private string _ourOnnxFileName = "normal.onnx";<---この部分を出力されたファイル名にする。

`````
それから、CustomVisionはラベル名がONNXモデルに組み込まれているので、ラベルの数を変えるだけになります。

`````c#
 public sealed class OnnxModelOutput
        {
            public IList<string> classLabel { get; set; }
            public IDictionary<string, float> loss { get; set; }
            public OnnxModelOutput()
            {
                this.classLabel = new List<string>();
                int _nLabels = 3;<------この部分を追加する
                // For dictionary(map) fields onnx needs the variable to be pre-allocatd such that the 
                // length is equal to the number of labels defined in the model. The names are not
                // required to match what is in the model.
                this.loss = new Dictionary<string, float>();
                for (int x = 0; x < _nLabels; ++x)<-----ラベル数をセットする
                    this.loss.Add("Label_" + x.ToString(), 0.0f);
            }
`````
以上で修正できました。というかほとんど何もしていない状態です。
上記をビルドして実行すると以下のようになります。

![WindowsML1.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/edcb4196-d2fd-07a7-d932-1e4cfb21dd93.jpeg)

恐らくこれが一番簡単な方法ではないかと考えています。