LearningModel クラスには、アプリ内のファイルからモデルを読み込む、ディスク上のファイルからモデルを読み込む、ストリームからモデルを読み込むなど、機械学習モデルを読み込むための静的メソッドがいくつかあります。
ストリーム メソッドから読み込むと、モデルをより適切に制御できます。 この場合、LoadFromStream メソッドのいずれかを呼び出す前に、モデルをディスク上で暗号化し、メモリ内でのみ復号化することができます。
このチュートリアルでは、暗号化された機械学習モデルを Windows ML アプリケーション (C#) と統合する方法について説明します。
Windows ML API は機械学習暗号化サービスを提供せず、いかなる損害や損失についても責任を負いません。
ONNX モデルを取得する
このチュートリアルでは、ONNX 形式の SqueezeNet モデルを使用して、ストリームからの暗号化、復号化、読み込みを実行します。
GitHub から SqueezeNet オブジェクト検出サンプル アプリ をダウンロードまたは複製して、SqueezeNet.onnx モデルを取得します。
必要な宣言と変数を指定する
- 次の using ステートメント宣言をコピーして、必要なすべての API にアクセスします。
using System;
using System.Threading.Tasks;
using Windows.AI.MachineLearning;
using Windows.Security.Cryptography;
using Windows.Security.Cryptography.Core;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Controls;
キーと初期化ベクトルに 2 つの特別な変数を定義します。
キーは、対称 (または非対称) キー ペアを表す CryptographicKey クラスの変数です。
AsymmetricKeyAlgorithmProvider
メソッドを使用してキーを作成またはインポートするため、このクラスのオブジェクトが必要です。
初期化ベクトルは IBuffer クラスの変数であり、バイト ストリームの読み取りおよび書き込みインターフェイスで使用されるバイトの参照先配列を表します。
CryptographicKey
クラス変数とIBuffer
クラス変数の両方を使用して、ストリームの暗号化と暗号化解除を行います。
- 暗号化名前空間内の using ステートメントの後に、次の変数宣言と
MainPage
クラスを追加します。
namespace crypto
{
/// <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 CryptographicKey _key;
private IBuffer _initialization_vector;
public MainPage()
{
this.InitializeComponent();
Run();
}
}
}
モデルを暗号化する
Windows API には、Windows ML API セットの機能を強化できる豊富な機能セットが用意されています。 ここでは、Windows API セットで提供される暗号化と復号化サービスを使用してメモリ内のストリームを生成し、Windows ML API を使用してそのストリームからモデルを読み込みます。
任意の暗号化サービスを使用して、利便性に応じて機械学習モデルを暗号化できます。 このチュートリアルでは、暗号化方法 ( SymmetricAlgorithmNames - .AesCbcPkcs7
) を使用します。
SymmetricAlgorithmNames クラスは、モデルに対称キー暗号化を適用する対称キー アルゴリズムを取得するのに役立ちます。 この種類の暗号化では、暗号化に使用されるのと同じキーを暗号化解除にも使用する必要があります。
SymmetricKeyAlgorithmProvider
クラスを使用すると、アルゴリズムを選択してキーを作成できます。 このチュートリアルでは、 .AesCbcPkcs7.
アルゴリズムを使用します。
AES_CBC_PKCS7
アルゴリズムは、高度な暗号化標準 (AES) アルゴリズムを表し、暗号ブロック チェーン モードの操作と PKCS#7 パディングと組み合わせて使用します。
- 次のコードは、キーを生成し、モデルを暗号化する方法を示しています。
async Task<IBuffer> EncryptAsync(StorageFile model_file)
{
// get a buffer for the model file
var file_buffer = await Windows.Storage.FileIO.ReadBufferAsync(model_file);
// set up the encryption algorithm
var algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
uint key_length = 32;
var key_buffer = CryptographicBuffer.GenerateRandom(key_length);
_key = algorithm.CreateSymmetricKey(key_buffer);
_initialization_vector = CryptographicBuffer.GenerateRandom(algorithm.BlockLength);
// perform the encryption
var encrypted_buffer = CryptographicEngine.Encrypt(_key, file_buffer, _initialization_vector);
return encrypted_buffer;
}
注 暗号化キーの詳細については、以下をご覧ください。 暗号化キーのドキュメントを確認してください。
モデルの暗号化を解除し、ストリームから読み込む
モデルを読み込む前に、 CryptographicEngine.Decrypt メソッドを使用して復号化する必要があります。
CryptographicEngine.Decrypt
は、対称アルゴリズムまたは非対称アルゴリズムを使用して以前に暗号化されたコンテンツを復号化するメソッドです。 メソッドを呼び出すときは、以前に生成されたキーを指定する必要があります。
復号化されたモデルにアクセスするには、 InMemoryRandomAccessStream
クラスを使用します。このクラスを使用すると、ディスクではなくメモリに格納されている入力ストリームと出力ストリーム内のデータにランダムにアクセスできます。
最後の手順として、 LearningModel.LoadFromStreamAsync
メソッドを使用して、ストリームからモデルを読み込むセッションを作成します。 このメソッドは、同期タスクまたは非同期タスクとして呼び出すことができます。
次のコードは、生成されたキーを使用してモデルを復号化し、ストリームに書き込み、ストリームからモデルを読み込む方法を示しています。
async Task DecryptAndRunAsync(IBuffer encryptyed_buffer)
{
// decrypt the buffer
var decrypted_buffer = CryptographicEngine.Decrypt(_key, encryptyed_buffer, _initialization_vector);
// write it to a stream
var decrypted_stream = new InMemoryRandomAccessStream();
await decrypted_stream.WriteAsync(decrypted_buffer);
// load the model from the stream
var model = await LearningModel.LoadFromStreamAsync(RandomAccessStreamReference.CreateFromStream(decrypted_stream));
// create a session
var session = new LearningModelSession(model);
}
モデルを実行する
次の Run メソッドをコピーして、前に定義したメソッドを呼び出します。
async Task Run()
{
// get the model file
var model_file = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/SqueezeNet.onnx"));
// encrypt the model file.
var encryptyed_buffer = await EncryptAsync(model_file);
// decrypt the model file and load it
await DecryptAndRunAsync(encryptyed_buffer);
}
概要
これで終了です。 モデルが Windows ML アプリに正常に読み込まれました。
モデルを読み込んだ後は、セッションの作成、モデルの入力と出力のバインド、モデルの評価を続行して Windows ML アプリを完成させることができます。
その他のリソース
このチュートリアルで説明されているトピックの詳細については、次のリソースを参照してください。