Korzystanie z zaszyfrowanych modeli w usłudze Windows ML

Istnieje kilka metod statycznych, które można zastosować w klasie LearningModel, aby załadować modele uczenia maszynowego, takie jak ładowanie modelu z pliku w aplikacji, z pliku na dysku lub ładowanie modelu ze strumienia.

Ładowanie z metody strumieniowej umożliwia lepszą kontrolę nad modelem. W takim przypadku można wybrać model zaszyfrowany na dysku i odszyfrować go tylko w pamięci przed wywołaniem jednej z metod LoadFromStream.

Z tego samouczka dowiesz się, jak zintegrować zaszyfrowany model uczenia maszynowego z aplikacją uczenia maszynowego systemu Windows (C#).

Interfejsy API uczenia maszynowego systemu Windows nie zapewniają usługi szyfrowania uczenia maszynowego i nie będą ponosić odpowiedzialności za żadne szkody ani utratę jakiegokolwiek rodzaju.

Pobierz model ONNX

W tym samouczku użyjesz modelu SqueezeNet w formacie ONNX, aby wykonać szyfrowanie, odszyfrowywanie i załadowanie z strumienia danych.

Pobierz lub sklonuj przykładową aplikację Do wykrywania obiektów SqueezeNet z usługi GitHub, aby pobrać model SqueezeNet.onnx.

Określanie wymaganych deklaracji i zmiennych

  1. Skopiuj poniższe deklaracje using, aby uzyskać dostęp do wszystkich potrzebnych interfejsów 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;

Zdefiniujesz dwie specjalne zmienne dla klucza i wektor inicjowania.

Klucz jest zmienną klasy CryptographicKey, która reprezentuje symetryczną (lub asymetryczną) parę kluczy. Będziesz potrzebować obiektu z tej klasy, ponieważ użyjesz metody do utworzenia AsymmetricKeyAlgorithmProvider lub zaimportowania kluczy.

Wektor inicjowania jest zmienną klasy IBuffer, która reprezentuje przywołyną tablicę bajtów używanych przez interfejsy odczytu i zapisu strumienia bajtów.

Zarówno zmienne klasowe CryptographicKey, jak i IBuffer są używane do szyfrowania i deszyfrowania strumienia.

  1. Dodaj następujące deklaracje zmiennych i klasę MainPage po instrukcjach using wewnątrz przestrzeni nazw kryptograficznych:
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();
        }
    }
}

Szyfrowanie modelu

Interfejsy API systemu Windows udostępniają bogaty zestaw funkcji i możliwości, które mogą zwiększyć funkcjonalność zestawu interfejsów API uczenia maszynowego systemu Windows. W tym miejscu użyjesz usługi szyfrowania i odszyfrowywania udostępnionej w interfejsie API systemu Windows w celu utworzenia strumienia w pamięci i użyjesz interfejsów API uczenia maszynowego systemu Windows do załadowania modelu z tego strumienia.

Możesz użyć dowolnej usługi szyfrowania do szyfrowania modelu uczenia maszynowego zgodnie z wygodą. W tym samouczku użyjemy metody szyfrowania — SymmetricAlgorithmNames - .AesCbcPkcs7.

Klasa SymmetricAlgorithmNames ułatwia pobieranie algorytmów kluczy symetrycznych w celu zastosowania szyfrowania klucza symetrycznego w modelu. Ten typ szyfrowania wymaga, aby ten sam klucz używany do szyfrowania był również używany do odszyfrowywania.

SymmetricKeyAlgorithmProvider Korzystając z klasy, możesz wybrać algorytm i utworzyć klucz. W tym samouczku użyjemy algorytmu .AesCbcPkcs7..

Algorytm AES_CBC_PKCS7 reprezentuje zaawansowany standard szyfrowania (AES) w połączeniu z trybem działania łańcucha bloków szyfrujących i wypełnianiem PKCS#7.

  1. Poniższy kod pokazuje, jak wygenerować klucz i zaszyfrować model.
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;
}

[UWAGA!] Chcesz dowiedzieć się więcej o kluczach kryptograficznych? Zapoznaj się z dokumentacją kluczy kryptograficznych.

Odszyfruj model i załaduj ze strumienia

Przed załadowaniem modelu należy go odszyfrować przy użyciu metody CryptographicEngine.Decrypt. CryptographicEngine.Decrypt to metoda odszyfrowywania zawartości, która została wcześniej zaszyfrowana przy użyciu algorytmu symetrycznego lub asymetrycznego. Podczas wywoływania metody należy podać wcześniej wygenerowany klucz.

Aby uzyskać dostęp do odszyfrowanego modelu, użyjesz InMemoryRandomAccessStream klasy , która zapewnia losowy dostęp do danych w strumieniach wejściowych i wyjściowych przechowywanych w pamięci zamiast na dysku.

W ostatnim kroku utworzysz sesję w celu załadowania modelu ze strumienia przy użyciu metody LearningModel.LoadFromStreamAsync. Tę metodę można wywołać jako zadanie synchroniczne lub asynchroniczne.

Poniższy kod pokazuje, jak odszyfrować model przy użyciu wygenerowanego klucza, zapisać go w strumieniu, a następnie załadować model ze strumienia.

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);
}

Uruchamianie modelu

Skopiuj następującą metodę Run, aby wywołać metody zdefiniowane wcześniej.

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);
}

Podsumowanie

I już! Model został pomyślnie załadowany do aplikacji uczenia maszynowego systemu Windows.

Po załadowaniu modelu możesz kontynuować tworzenie sesji, wiązanie danych wejściowych i wyjściowych modelu oraz ocenę modelu w celu ukończenia aplikacji uczenia maszynowego systemu Windows.

Dodatkowe zasoby

Aby dowiedzieć się więcej o tematach wymienionych w tym samouczku, odwiedź następujące zasoby: