次の方法で共有



JULY 2018

VOLUME 33 NUMBER 7

機械学習 - エッジ上の IoT デバイスを使用した機械学習

によってJames McCaffrey

いないすぎる distant 今後は、使用しているスマート トラフィックの積集合のデザイナーを想像してください。スマートの積集合は、4 つのビデオ_カメラを Raspberry Pi のような小規模の cpu には、things (IoT) デバイスのインターネットに接続していますカメラでは、machine learning (ML) 画像認識モデルを使用して、分析しているを制御する命令がトラフィック信号を送信し、IoT デバイスにビデオ フレームを送信します。小規模の IoT デバイスの 1 つは、Azure Cloud Services、情報のログ記録し、オフライン分析の場所に接続されます。

これは、エッジでの IoT デバイスの ML の例です。Microsoft Azure や、会社のリモート サーバーのようなものにクラウドと場所、クラウドに接続されているものを意味するのに用語の edge デバイスを使用します。この記事では、ML を設計するには、edge で 2 つの方法を後ほどします。具体的には、Microsoft Embedded Learning ライブラリ (ELL) 一連のツールを使用して、edge 上のデバイスに最適化された ML モデルをデプロイする方法とカスタム モデルとデバイスの場合、IO 関数を記述する方法を説明します。カスタム IO アプローチは、執筆時点でこの記事では、IoT デバイスの ML モデルをデプロイする最も一般的な方法では現在、です。ELL アプローチは、将来的なです。

場合でも、作業を行っていない ML を使用した IoT デバイス上で、この記事を読みたい理由には少なくとも 3 つの理由があります。最初に、関連するデザインの原則は、他のソフトウェア開発シナ リオに汎用化します。次に、決してを操作する ML や IoT デバイスと比較的すぐになります。第 3 に、だけかもしれませんここで説明した手法湧く興味深いです。

ML は、IoT edge 上に存在する理由は必要でしょうか。クラウドのすべての処理をだけはなぜですか。エッジでの IoT デバイスを非常に不経済できますが、多くの場合が限定されているメモリの制限機能と制限付きの電源を処理します。多くのシナリオでは、いくつかの欠点が ML クラウドでの処理を実行しようとしています。

待機時間は、多くの場合、大きな問題です。スマート トラフィック積集合の例での複数の秒の端数の遅延に大きな損害をもたらす可能性があります。クラウドで ML を実行しようと他の問題は、信頼性 (ネットワーク接続の切断は通常を予測することは不可能と困難に対処する)、ネットワークの可用性 (たとえば、宇宙船海上必要があります、サテライト場合にのみ接続オーバーヘッドが)、プライバシー/セキュリティ (場合、たとえば、監視している患者を病院にします)。

この記事では、任意の特定の背景またはスキルが設定されますが、一般的なソフトウェア開発経験があることを前提としてに想定していません。デモ (CNTK ライブラリを使用して ML モデルを IoT のコードをシミュレートする C プログラムと Python プログラム ELL モデルを使用してを作成する Python プログラム) この記事で説明されているプログラムは長すぎてここでは、表示しますが、ダウン付随するファイルで利用可能なこと読み込みます。

機械学習モデルとは何ですか。

ML モデルをエッジで IoT デバイスに展開すると、問題を理解するために理解する必要がありますはどのような ML モデル。非常に大まかに言えば、ML モデルは、入力データを受け入れる、予測を行い、出力データを生成するために必要なすべての情報です。抽象で説明しようとするではなく、具体的な例を使用してアイデアを示します。

スクリーン ショットを見て図 1とで図図 2します。2 つの図は、次の 4 つの入力ノード、5 つの処理を非表示層ノード、および出力層の 3 つのノードでニューラル ネットワークを表示します。(6,1、3.1、5.1、1.1) は、入力値と、出力値は (0.0321、0.6458、0.3221)。図 1モデルを開発して学習する方法を示しています。Visual Studio Code を使用しましたが、多くの代替案がないです。

作成して、ニューラル ネットワーク モデルのトレーニング
図 1 を作成して、ニューラル ネットワーク モデルのトレーニング

ニューラル ネットワークの入出力メカニズム
図 2 ニューラル ネットワークの入出力メカニズム

この例では、(リーフのような構造) がくの長さと幅、花弁の長さと幅を表す入力の値を使用して、あやめの種を予測する必要があります。花の 3 つの可能な指定がある: setosa、versicolor、virginica します。出力値を確率 (合計すると 1.0 メモ) として解釈できるため、0.6458、2 番目の値は最大であるために、モデルの予測は versicolor の 2 番目の指定。

図 2各行の重みを接続するには、2 つのノードを表します。重みは、数値定数だけです。インデックスを作成、上から下、ノードが始まる場合、input [0] と hidden [0] から、重みが 0.2680 と、出力 [0] に非表示の [4] から重量は 0.9381 です。

各非表示と出力のノードには、ノードを指す小さい矢印があります。これらは、バイアスと呼ばれます。Hidden [0] のバイアスが 0.1164 と output [0] のバイアスが-0.0466 します。

数値入力を受け入れるだけ数値出力が生成されますので、複雑な数学関数と、ニューラル ネットワークの考えることができます。IoT デバイスで ML モデルでは、出力を計算する方法を理解する必要があります。ニューラル ネットワークの図 2、隠しノードの値を計算するのには、まずします。各隠しノードの値は、入力と、関連付けられている重みとバイアスの製品の合計に適用されるハイパーボリック タンジェント (tanh) 関数。Hidden [0] の計算は次のとおりです。

hidden[0] = tanh((6.1 * 0.2680) + (3.1 * 0.3954) +
                 (5.1 * -0.5503) + (1.1 * -0.3220) + 0.1164)
          = tanh(-0.1838)
          = -0.1817

同様に、隠しノード [1] から [4] が計算されます。この tanh 関数は隠し層の活性化関数と呼ばれます。ロジスティック シグモイドや正規化線形単体など、別の隠しノードの値となる、使用できるその他のアクティブ化関数があります。

隠しノードの値が計算された後、次の手順では、予備出力ノード値を計算します。予備出力ノード値は、隠しノードと関連付けられている出力を非表示には、重みとバイアスの製品の合計だけです。つまり、非表示のノードがアクティブ化関数を使用せずに、として同じ計算が使用されます。出力 [0] の暫定値、計算は次のとおりです。

o_pre[0] = (-0.1817 * 0.7552) + (-0.0824 * -0.7297) +
           (-0.1190 * -0.6733) + (-0.9287 * 0.9367) +
           (-0.9081 * 0.9381) + (-0.0466)
         = -1.7654

出力ノード [1] と [2] の値は、同じ方法で計算されます。出力ノードの暫定値を計算した後、最終的な出力ノード値は、ソフトマックス活性化関数を使用して確率に変換できます。Softmax 関数は最適な例について説明します。最終的な出力値の計算は次のとおりです。

sum = exp(o_pre[0]) + exp(o_pre[1]) + exp(o_pre[2])
    = 0.1711 + 3.4391 + 1.7153
    = 5.3255
output[0] = exp(o_pre[0]) / sum
          = 0.1711 / 5.3255 = 0.0321
output[1] = exp(o_pre[1]) / sum
          = 3.4391 / 5.3255 = 0.6458
output[2] = exp(o_pre[2]) / sum
          = 1.7153 / 5.3255 = 0.3221

非表示のノードと同様、identity 関数など、別の出力ノードの活性化関数があります。

要約するは、ML モデルは、入力データを受け入れるし、出力予測の生成に必要なすべての情報です。ニューラル ネットワークの場合は、重みとバイアスの値、入力と出力のある非表示のノードの数と非表示と出力層ノードで使用する活性化関数の型のこの情報で構成されます。

OK は、重みの値とバイアスに由来でしょうか。これらはしているモデルのトレーニングによって決まります。トレーニングは、一連の既知の入力値とわかっていますが、出力の値を修正し、計算した出力値の差を最小限に抑えるし、わかっていますが、出力値を修正するには、バックプロパゲーションなどの最適化アルゴリズムを適用するデータを使用しています。

ML モデルを単純な Bayes、デシジョン ツリーなどの他の多くの種類がありますが、一般的な原則は同じです。Microsoft CNTK や Google の Keras/TensorFlow などのニューラル ネットワーク コード ライブラリを使用する場合、ML モデルをトレーニングするプログラムがそのモデルをディスクに保存されます。たとえば、CNTK の Keras のコードでは次のようになります。

mp = ".\\Models\\iris_nn.model"
model.save(mp, format=C.ModelFormat.CNTKv2)  # CNTK
model.save(".\\Models\\iris_model.h5")  # Keras

また、ML ライブラリには、保存済みのモデルを読み込む関数があります。以下に例を示します。

mp = ".\\Models\\iris_nn.model"
model = C.ops.functions.Function.load(mp)  # CNTK
model = load_model(".\\Models\\iris_model.h5")  # Keras

最もニューラル ネットワーク ライブラリでは、モデルの重みとバイアス値だけを (モデル全体) ではなくファイルを保存する方法が必要です。

標準 ML モデルを IoT デバイスに展開します。

内のイメージ図 1 ML モデルをトレーニングの外観の例を示しています。エディターと CNTK v2.4 ライブラリには、Python 言語 API インターフェイスとして Visual Studio Code を使用します。数日や数週間の労力がかかるトレーニング済みの ML モデルを作成して、通常、多くの処理能力とメモリが必要です。そのため、モデルのトレーニングは通常、1 つまたは複数の gpu を搭載した多くの場合、強力なマシンで実行します。さらに、ニューラル ネットワークの複雑さとサイズの増加、重みの数とバイアスが飛躍的に向上し、ので、保存したモデルのファイル サイズも大きくなりますが大幅にします。

たとえば、4-5-3、前のセクションで説明されているあやめのモデルのみを持つ (4 * 5) + 5 + (5 * 3) + 3 = 43 の重みし、バイアスします。何百万ものピクセルの入力値と、何百もの隠し処理ノードのイメージ分類モデルは、数百万個、または数十億もの重みとバイアスの数百を持つことができます。43 のすべての重みの値とバイアスのあやめの使用例に示すような通知図 1:

[[ 0.2680 -0.3782 -0.3828  0.1143  0.1269]
 [ 0.3954 -0.4367 -0.4332  0.3880  0.3814]
 [-0.5503  0.6453  0.6394 -0.6454 -0.6300]
 [-0.322   0.4035  0.4163 -0.3074 -0.3112]]
 [ 0.1164 -0.1567 -0.1604  0.0810  0.0822]
[[ 0.7552 -0.0001 -0.7706]
 [-0.7297 -0.2048  0.9301]
 [-0.6733 -0.2512  0.9167]
 [ 0.9367 -0.4276 -0.5134]
 [ 0.9381 -0.3728 -0.5667]]
 [-0.0466  0.4528 -0.4062]

そのため、トレーニング済みの ML モデルがあるとします。モデルを小さな、脆弱な場合は、IoT デバイスに展開するには。最も単純なソリューションでは、IoT デバイス上にモデルのトレーニングに使用した同じニューラル ネットワーク ライブラリのソフトウェアをインストールします。IoT デバイスに保存したトレーニング済みモデル ファイルをコピーすると、モデルを読み込むし、予測を行うコードを記述できます。簡単です。

残念ながら、このアプローチは、IoT デバイスが非常に強力な比較的まれな状況でのみ動作は、デスクトップ PC やラップトップの線に沿ってなど。また、CNTK や TensorFlow の Keras/などのニューラル ネットワーク ライブラリが迅速かつ効率的に、モデルのトレーニングに設計されていますが、一般に必ずしも本来の最適なパフォーマンスのトレーニング済みモデルでの入出力を実行するときに。つまり、エッジで IoT デバイスにトレーニングされた ML モデルを展開するための簡単な解決策は、ほとんど不可能です。

カスタム コードのソリューション

私の経験と仕事仲間との会話に基づき、エッジで IoT デバイスにトレーニングされた ML モデルをデプロイする最も一般的な方法は、デバイスのカスタムの C/C++ コードを記述するは。考え方は、[C/C++] は、IoT デバイスで使用可能なほとんどの状況と、C と C++ は、通常、高速かつコンパクトなことです。デモ プログラム図 3概念を示します。

IoT デバイスでのカスタムの C/C++ IO コードのシミュレーション
IoT デバイスでのカスタムの C/C++ IO コードの図 3 のシミュレーション

デモ プログラムは、ターゲット デバイスで実行可能ファイルにファイル test.c をコンパイルする gcc C と C++ ツールを使用して起動します。ここでは、ターゲット デバイスがデスクトップ PC だけが、ほぼすべての種類と CPU の IoT デバイスの C と C++ コンパイラがあります。実行すると、重みの値とバイアスあやめの花の例でし (6.1、3.1、5.1、1.1) の入力値を使用してと計算出力値 (0.0321、0.6458、0.3221) を表示しますのデモ プログラムを表示します。比較すると図 3図 12出力が同じで (丸め誤差) の対象、入力、重みとバイアスを確認します。   

デモ プログラム test.c では、ニューラル ネットワークの入出力のプロセスのみを実装します。各レイヤー、非表示の値と出力層ノード、ノードの数と、重みとバイアスの値を保持する構造体のデータ構造の設定、プログラムの起動します。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>  // Has tanh()
typedef struct {
  int ni, nh, no;
  float *h_nodes, *o_nodes;  // No i_nodes
  float **ih_wts, **ho_wts;
  float *h_biases, *o_biases;
} nn_t;

プログラムでは、次の関数を定義します。

construct(): initialize the struct
free(): deallocate memory when done
set_weights(): assign values to weights and biases
softmax(): the softmax function
predict(): implements the NN IO mechanism
show_weights(): a display helper

デモ プログラムの main 関数内のコードの主要な行のようになります。

nn_t net;  // Neural net struct
construct(&net, 4, 5, 3);  // Instantiate the NN
float wts[43] = {  // specify the weights and biases
  0.2680, -0.3782, -0.3828, 0.1143, 0.1269,
. . .
 -0.0466, 0.4528, -0.4062 };
set_weights(&net, wts);  // Copy values into NN
float inpts[4] = { 6.1, 3.1, 5.1, 1.1 };  // Inputs
int shownodes = 0;  // Don’t show
float* probs = predict(net, inpts, shownodes);

ある単純なニューラル ネットワークの ML モデルのしくみについて詳しく説明がわかっている場合、IO プロセスは魔法でがポイントです。基本的な IO を非常に簡単に実装できます。

カスタムの C/C++ IO 関数を使用して主な利点は、概念わかりやすくするためです。また、非常に低いレベル (実際には 1 つのレベルの抽象化アセンブリ言語) でコーディングを行っているため、生成された実行可能コード通常は非常に小さく、高速な実行です。さらに、IO コードに対するフル コントロールがあるために、パフォーマンスが向上するか、メモリ フット プリントを削減するすべての種類のテクニックを使用できます。たとえば、プログラム test.c float 型を使用して、問題のシナリオに応じて必要しますが、ありますカスタムの 16 ビットの固定小数点データ型を使用すること。

カスタム C/C++ IO アプローチを使用しての主な欠点は、手法、複雑になるトレーニング済みの ML モデルが増えるとますます困難になります。ライセンス認証では tanh とソフトマックス ニューラル ネットワークを 1 つの非表示層、IO 関数は非常に簡単に実装できるなど、もちろん、さまざまな要因によって、開発作業の 1 週間に約 1 日を取得します。いくつかの隠れ層でのディープ ニューラル ネットワークに対処する少し簡単: 1 週間におそらくまたは 2 つの作業です。畳み込みニューラル ネットワーク (CNN) または long の IO の機能を実装するには、短期的なメモリ (LSTM) 再帰型ニューラル ネットワークは非常に困難とは通常 4 週間よりも多くの開発作業が必要です。

IoT デバイスが増えるの使用、としてがあること、IO CNTK や TensorFlow の Keras/などの異なるニューラル ネットワーク ライブラリによって作成された ML モデルを実装するオープン ソース C と C++ のライブラリを作成するための取り組み気がします。または、十分な需要がある場合のニューラル ネットワーク ライブラリの開発者が IoT デバイス自体の C/C++ IO Api を作成可能性があります。このようなライブラリがある場合、IoT デバイスのカスタムの IO の書き込みは比較的単純ななります。

Microsoft Embedded ラーニング ライブラリ

Microsoft Embedded Learning ライブラリ (ELL) は、edge (microsoft.github.io/ELL) でデバイスに IoT の ML モデルをデプロイするために必要な開発作業を容易にするためのもので、野心的のオープン ソース プロジェクトです。左側にある ELL の基本的な考え方を示します図 4します。

概要と詳細な ELL ワークフロー プロセス
4 の概要と詳細な ELL ワークフロー プロセスを図します。

つまり、ELL システムは、CNTK やニューラル ネットワークの exchange (ONNX) などのサポートされているモデル形式などのサポートされているライブラリによって作成された ML モデルを受け入れます。ELL システムでは、入力の ML モデルを使用し、.ell ファイルとして、中間のモデルを生成します。ELL システムは中間 .ell モデル ファイルを使用して、サポートされているターゲット デバイスに何らかのコードを生成します。別の言い方を行うには、ある種の ML モデルのクロス コンパイラとして ELL に考えることができます。

右側にある ELL の動作の詳細な説明が表示される図 4あやめの花のモデルの例を使用します。作成し、独自のバイナリ形式である iris_cntk.model をという名前の予測モデルを保存する iris_nn.py をという名前の Python プログラムを記述、ML 開発者と、プロセスが開始されます。このプロセスを示した図 1します。

ELL コマンド ライン ツールの cntk_import.py は、JSON 形式で格納されている中間 iris_cntk.ell ファイルを作成し、使用されます。次に、ELL コマンド ライン ツールの wrap.py は、C/C++ ソース コード ファイルのディレクトリ host\build の生成に使用されます。"Host"より一般的なシナリオには、\pi3\build ようになりますので、現在のコンピューターから設定を実行することを意味に注意してください。Cmake.exe C と C++ のコンパイラ ビルド ツールは、元の ML モデル iris_cntk という名前のロジックを含む実行可能ファイルのコードの Python モジュールを生成に使用されます。ターゲットは、C と C++ 実行可能ファイルまたは c# の実行可能ファイルまたはターゲットの IoT デバイスに最適です。

ように、iris_cntk Python モジュールをターゲット デバイス (デスクトップ PC) にで Python プログラム (use_iris_ell_model.py) でインポートし、できる図 5します。入力値 (6.1、3.1、5.1、1.1) と、ELL システム モデルによって生成された出力値 (0.0321、0.6457、0.3221) は、モデルの開発時に生成された値と同じでことに注意してください (図 1) によって生成された値と、カスタムの C/C++ IO 関数 (図 3)。

ELL モデルを使用して、IoT デバイスのシミュレーションELL モデルを使用して、IoT デバイス上の図 5 シミュレーション

前のコマンド プロンプトに、先頭"(py36)"図 5 Conda 環境を使用します。 Python バージョン 3.6、ELL デモ コーディング時にこれが必要と呼ばれる特殊な Python 設定で操作を示します。

プログラム use_iris_ell_model.py のコードに示した図 6します。ELL が他のパッケージ/モジュールと同様に使用できる Python モジュール/パッケージを生成したことがポイントです。

Python プログラム ELL モデルを使用して、図 6

# use_iris_ell_model.py
# Python 3.6
import numpy as np
import tutorial_helpers   # used to find package
import iris_cntk as m     # the ELL module/package
print("\nBegin use ELL model demo \n")
unknown = np.array([[6.1, 3.1, 5.1, 1.1]],
  dtype=np.float32)
np.set_printoptions(precision=4, suppress=True)
print("Input to ELL model: ")
print(unknown)
predicted = m.predict(unknown)
print("\nPrediction probabilities: ")
print(predicted)
print("\nEnd ELL demo \n"

ELL システム、開発のごく初期の段階でまだが、私の経験に基づいて、システムを試す準備が限定された実稼働の開発シナ リオの十分な安定性。

ELL、プロセスの図に、反応を期待どおり図 4とその説明については、何かなどの「これはすごい手順の多くは、!」 少なくとも、私の反応でした。最終的には、IoT デバイスの行に配置するためのモデルを生成するポイントに発展 ELL システムは期待される結果します。

source_model = ".\\iris_cntk.model"
target_model = ".\\iris_cortex_m4.model"
ell_generate(source_model, target_model)

ここでは、ある場合は、ELL を確認するいくつかの手順を使用します。さいわい、この記事の多くの基になる ELL Web サイトから ELL チュートリアルが非常に良好です。ELL を使用するデスクトップ コンピューターで、ELL をインストールする必要があります、C/C++ ソース コードのビルドの構成に指摘する必要があります: ELL (まだ) 用の .msi インストーラーはありません。

わかりません ELL の優れた機能は、バック グラウンドでいくつかの非常に高度な最適化が実行されます。たとえば、ELL チームは sparsification と排除手法、1 ビットの数値演算と浮動小数点数値演算を置き換えるなど、大規模な ML モデルを圧縮する方法について説明しました。また、ELL チームはより優れた意思決定ツリーと k DNF 分類子を含む、ニューラル ネットワークの代わりに使用できるアルゴリズムで探しています。

ELL Web サイトのチュートリアルの内容はかなり良いが少し長は多くの手順が関係するため。自分で簡単にプロセスをスケッチの感覚を取得できるようには ELL のインストールと似ています。私のコマンドが構文的に正しいいないことに注意してください。これらは、非常明瞭を保持する単純化されています。

ELL システムをインストールするようになります。

x> (install several tools such as cmake and BLAS)
> git clone https://github.com/Microsoft/ELL.git
> cd ELL
> nuget.exe restore external/packages.config -PackagesDirectory external
> md build
> cd build
> cmake -G "Visual Studio 15 2017 Win64" ..
> cmake --build . --config Release
> cmake --build . --target _ELL_python --config Release

つまりを始める前にインストールされている多数のツールがありますし、ELL のソース コードを GitHub からプルし、ELL 実行可能なツールと cmake を使用して Python バインディングを構築します。

ELL モデルを作成するようになります。

> python cntk_import.py iris_cntk.model
> python wrap.py iris_nn_cntk.ell --language python --target host
> cd host
> md build
> cd build
> cmake -G "Visual Studio 15 2017 Win64" .. && cmake --build . --config release

つまり、ELL ツール cntk_import.py を使用して、CNTK モデル ファイルから .ell ファイルを作成します。Wrap.py を使用して、特定のターゲット IoT デバイスに固有の C と C++ の多くを生成します。Cmake を使用して、元トレーニングされた ML モデルの動作をカプセル化する実行可能ファイルを生成します。

まとめ

要約するは、機械学習モデルは、入力を受け取り、予測を生成するソフトウェア システムに必要なすべての情報です。多くの場合、エッジでの IoT デバイスには、非常に高速で信頼性の高いパフォーマンスが必要とするため、デバイス上で直接 ML の予測を計算するために必要な場合があります。ただし、IoT デバイスは多くの場合、小規模であり、弱いためデバイスに強力なデスクトップ コンピューターで開発されたモデルを単にコピーすることはできません。標準的なアプローチは、カスタムの C/C++ コードを記述するが、このアプローチは、複雑な ML モデルに合わせて拡張されません。新たなアプローチは、ML クロス コンパイラ、Microsoft Embedded ラーニング ライブラリなどの使用です。

完全に成熟した、リリースされた、ときに ELL システムは今日よりも大幅に簡単に edge 上の IoT デバイスの複雑な ML モデルを開発することをおそらく。


Dr.James McCaffrey は、ワシントン州レドモンドの Microsoft Research に勤務しています。これまでに、Internet Explorer、Bing などの複数のマイクロソフト製品にも携わってきました。Dr.McCaffrey の連絡先は jammc@microsoft.com (英語のみ) です。

この記事のレビューに協力してくれたマイクロソフト技術スタッフの Byron Changuion、Chuck Jacobs、Chris Lee、Ricky Loynd


この記事について MSDN マガジン フォーラムで議論する