Руководство по Развертывание модели классификации изображений в Экземплярах контейнеров AzureTutorial: Deploy an image classification model in Azure Container Instances

Это руководство представляет собой вторую часть серии, состоящей из двух частей.This tutorial is part two of a two-part tutorial series. В предыдущем руководстве вы обучили модели машинного обучения и затем зарегистрировали модель в рабочей области в облаке.In the previous tutorial, you trained machine learning models and then registered a model in your workspace on the cloud.

Теперь вы готовы развернуть модель как веб-службу в Экземплярах контейнеров Azure.Now you're ready to deploy the model as a web service in Azure Container Instances. Веб-служба — это образ. В данном случае образ Docker.A web service is an image, in this case a Docker image. Он инкапсулирует логику оценки и саму модель.It encapsulates the scoring logic and the model itself.

В этой части вы будете использовать Службу машинного обучения Azure, чтобы научиться выполнять следующие задачи:In this part of the tutorial, you use Azure Machine Learning service for the following tasks:

  • настройка тестовой среды;Set up your testing environment.
  • извлечение модели из рабочей области;Retrieve the model from your workspace.
  • локальное тестирование модели;Test the model locally.
  • развертывание модели в Экземплярах контейнеров;Deploy the model to Container Instances.
  • тестирование развернутой модели.Test the deployed model.

Экземпляры контейнеров — это идеальное решение для тестирования и понимания рабочего процесса.Container Instances is a great solution for testing and understanding the workflow. Для масштабируемых рабочих развертываний рекомендуется использовать Службу Azure Kubernetes.For scalable production deployments, consider using Azure Kubernetes Service. Дополнительные сведения см. в статье Развертывание моделей с помощью Службы машинного обучения Azure.For more information, see how to deploy and where.

Примечание

Код в этой статье протестирован с помощью пакета SDK для Машинного обучения Azure версии 1.0.41.Code in this article was tested with Azure Machine Learning SDK version 1.0.41.

Предварительные требованияPrerequisites

Перейдите к разделу о настройке среды разработки, чтобы ознакомиться с шагами записной книжки.Skip to Set the development environment to read through the notebook steps.

Чтобы запустить записную книжку, выполните обучение модели, как описано в статье Руководство (часть 1). Обучение модели классификации изображений с помощью Службы машинного обучения Azure.To run the notebook, first complete the model training in Tutorial (part 1): Train an image classification model with Azure Machine Learning service. Затем запустите записную книжку tutorials/img-classification-part2-deploy.ipynb, используя тот же сервер записных книжек.Then run the tutorials/img-classification-part2-deploy.ipynb notebook using the same notebook server.

Настройка средыSet up the environment

Начните с создания тестовой среды.Start by setting up a testing environment.

Импорт пакетовImport packages

Импортируйте пакеты Python, необходимые для этого руководства.Import the Python packages needed for this tutorial:

%matplotlib inline
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
 
import azureml
from azureml.core import Workspace, Run

# display the core SDK version number
print("Azure ML SDK Version: ", azureml.core.VERSION)

Извлечение моделиRetrieve the model

В предыдущем руководстве вы зарегистрировали модель в рабочей области.You registered a model in your workspace in the previous tutorial. Теперь загрузите эту рабочую область и скачайте модель в локальный каталог.Now load this workspace and download the model to your local directory:

from azureml.core import Workspace
from azureml.core.model import Model
import os
ws = Workspace.from_config()
model = Model(ws, 'sklearn_mnist')

model.download(target_dir=os.getcwd(), exist_ok=True)

# verify the downloaded model file
file_path = os.path.join(os.getcwd(), "sklearn_mnist_model.pkl")

os.stat(file_path)

Локальное тестирование моделиTest the model locally

Перед развертыванием убедитесь, что модель работает локально, выполнив следующие действия:Before you deploy, make sure your model is working locally:

  • загрузку тестовых данных;Load test data.
  • прогнозирование тестовых данных;Predict test data.
  • изучение матрицы неточностей.Examine the confusion matrix.

Загрузка тестовых данныхLoad test data

Загрузите тестовые данные из каталога ./data/ , созданного в обучающем руководстве:Load the test data from the ./data/ directory created during the training tutorial:

from utils import load_data
import os

data_folder = os.path.join(os.getcwd(), 'data')
# note we also shrink the intensity values (X) from 0-255 to 0-1. This helps the neural network converge faster
X_test = load_data(os.path.join(data_folder, 'test-images.gz'), False) / 255.0
y_test = load_data(os.path.join(
    data_folder, 'test-labels.gz'), True).reshape(-1)

Прогнозирование тестовых данныхPredict test data

Чтобы получить прогнозы, введите тестовый набор данных в модель:To get predictions, feed the test dataset to the model:

import pickle
from sklearn.externals import joblib

clf = joblib.load(os.path.join(os.getcwd(), 'sklearn_mnist_model.pkl'))
y_hat = clf.predict(X_test)

Изучение матрицы неточностейExamine the confusion matrix

Создайте матрицу неточностей, чтобы увидеть количество правильно классифицированных выборок из тестового набора.Generate a confusion matrix to see how many samples from the test set are classified correctly. Обратите внимание на неправильно классифицированное значение неверных прогнозов:Notice the misclassified value for the incorrect predictions:

from sklearn.metrics import confusion_matrix

conf_mx = confusion_matrix(y_test, y_hat)
print(conf_mx)
print('Overall accuracy:', np.average(y_hat == y_test))

Отображается следующая матрица неточностей:The output shows the confusion matrix:

[[ 960    0    1    2    1    5    6    3    1    1]
 [   0 1112    3    1    0    1    5    1   12    0]
 [   9    8  920   20   10    4   10   11   37    3]
 [   4    0   17  921    2   21    4   12   20    9]
 [   1    2    5    3  915    0   10    2    6   38]
 [  10    2    0   41   10  770   17    7   28    7]
 [   9    3    7    2    6   20  907    1    3    0]
 [   2    7   22    5    8    1    1  950    5   27]
 [  10   15    5   21   15   27    7   11  851   12]
 [   7    8    2   13   32   13    0   24   12  898]]
Overall accuracy: 0.9204

Используйте matplotlib для отображения матрицы неточностей в виде графа.Use matplotlib to display the confusion matrix as a graph. В этом графе ось X показывает фактические значения, а ось Y — прогнозируемые значения.In this graph, the x-axis shows the actual values, and the y-axis shows the predicted values. Цвет в каждой сетке показывает частоту ошибок.The color in each grid shows the error rate. Чем светлее цвет, тем выше частота ошибок.The lighter the color, the higher the error rate is. Например, многие цифры 5 неправильно классифицированы как 3.For example, many 5's are misclassified as 3's. Поэтому вы видите яркую сетку в расположении (5,3).So you see a bright grid at (5,3):

# normalize the diagonal cells so that they don't overpower the rest of the cells when visualized
row_sums = conf_mx.sum(axis=1, keepdims=True)
norm_conf_mx = conf_mx / row_sums
np.fill_diagonal(norm_conf_mx, 0)

fig = plt.figure(figsize=(8, 5))
ax = fig.add_subplot(111)
cax = ax.matshow(norm_conf_mx, cmap=plt.cm.bone)
ticks = np.arange(0, 10, 1)
ax.set_xticks(ticks)
ax.set_yticks(ticks)
ax.set_xticklabels(ticks)
ax.set_yticklabels(ticks)
fig.colorbar(cax)
plt.ylabel('true labels', fontsize=14)
plt.xlabel('predicted values', fontsize=14)
plt.savefig('conf.png')
plt.show()

Диаграмма, где отображается матрица неточностей

Развертывание в виде веб-службыDeploy as a web service

Если после тестирования модели вы получили устраивающие вас результаты, разверните модель в виде веб-службы, размещенной в Экземплярах контейнеров.After you tested the model and you're satisfied with the results, deploy the model as a web service hosted in Container Instances.

Чтобы создать правильную среду для Экземпляров контейнеров, предоставьте следующие компоненты:To build the correct environment for Container Instances, provide the following components:

  • сценарий оценки, чтобы показать, как использовать модель;A scoring script to show how to use the model.
  • файл среды, чтобы показать, какие пакеты должны быть установлены;An environment file to show what packages need to be installed.
  • файл конфигурации для создания экземпляра контейнера;A configuration file to build the container instance.
  • обученная ранее модель.The model you trained previously.

Создание сценария оценкиCreate scoring script

Создайте сценарий оценки, называемый score.py.Create the scoring script, called score.py. Он нужен в вызове веб-службы, чтобы показать, как использовать модель.The web service call uses this script to show how to use the model.

В сценарий оценки необходимо включить две обязательные функции:Include these two required functions in the scoring script:

  • Функция init(), которая обычно загружает модель в глобальный объект.The init() function, which typically loads the model into a global object. Эта функция выполняется только один раз при запуске контейнера Docker.This function is run only once when the Docker container is started.

  • Функция run(input_data) использует модель для прогнозирования значения на основе входных данных.The run(input_data) function uses the model to predict a value based on the input data. Входные и выходные данные для запуска обычно используют JSON для сериализации и десериализации, но поддерживаются и другие форматы.Inputs and outputs to the run typically use JSON for serialization and de-serialization, but other formats are supported.

%%writefile score.py
import json
import numpy as np
import os
import pickle
from sklearn.externals import joblib
from sklearn.linear_model import LogisticRegression

from azureml.core.model import Model

def init():
    global model
    # retrieve the path to the model file using the model name
    model_path = Model.get_model_path('sklearn_mnist')
    model = joblib.load(model_path)

def run(raw_data):
    data = np.array(json.loads(raw_data)['data'])
    # make prediction
    y_hat = model.predict(data)
    # you can return any data type as long as it is JSON-serializable
    return y_hat.tolist()

Создание файла средыCreate environment file

Создайте файл среды myenv.yml, который указывает все зависимости пакетов для этого сценария.Next create an environment file, called myenv.yml, that specifies all of the script's package dependencies. Этот файл гарантирует, что все эти зависимости устанавливаются в образ Docker.This file is used to make sure that all of those dependencies are installed in the Docker image. Для этой модели требуется scikit-learn и azureml-sdk.This model needs scikit-learn and azureml-sdk:

from azureml.core.conda_dependencies import CondaDependencies

myenv = CondaDependencies()
myenv.add_conda_package("scikit-learn")

with open("myenv.yml", "w") as f:
    f.write(myenv.serialize_to_string())

Проверьте содержимое файла myenv.yml.Review the content of the myenv.yml file:

with open("myenv.yml", "r") as f:
    print(f.read())

Создание файла конфигурацииCreate a configuration file

Создайте файл конфигурации развертывания.Create a deployment configuration file. Укажите необходимое для контейнера службы "Экземпляры контейнеров" количество ЦП и объем ОЗУ в гигабайтах.Specify the number of CPUs and gigabytes of RAM needed for your Container Instances container. Хотя это зависит от модели, для многих моделей по умолчанию обычно бывает достаточно одного ядра и 1 ГБ ОЗУ.Although it depends on your model, the default of one core and 1 gigabyte of RAM is sufficient for many models. Если в дальнейшем вам потребуется больше ресурсов, создайте образ еще раз и повторно разверните службу.If you need more later, you have to re-create the image and redeploy the service.

from azureml.core.webservice import AciWebservice

aciconfig = AciWebservice.deploy_configuration(cpu_cores=1,
                                               memory_gb=1,
                                               tags={"data": "MNIST",
                                                     "method": "sklearn"},
                                               description='Predict MNIST with sklearn')

Развертывание в Экземплярах контейнеровDeploy in Container Instances

Примерное время завершения развертывания — около 7–8 минут.The estimated time to finish deployment is about seven to eight minutes.

Настройте изображение и разверните его.Configure the image and deploy. Следующий код выполняет указанные далее действия.The following code goes through these steps:

  1. Создание образа с использованием таких файлов:Build an image by using these files:
    • файл оценки (score.py);The scoring file, score.py.
    • файл среды (myenv.yml);The environment file, myenv.yml.
    • файл модели.The model file.
  2. Регистрация образа в рабочей области.Register the image under the workspace.
  3. Отправка образа в контейнер службы "Экземпляры контейнеров".Send the image to the Container Instances container.
  4. Запуск контейнера в Экземплярах контейнеров с помощью образа.Start up a container in Container Instances by using the image.
  5. Получение конечной точки HTTP веб-службы.Get the web service HTTP endpoint.
%%time
from azureml.core.webservice import Webservice
from azureml.core.image import ContainerImage

# configure the image
image_config = ContainerImage.image_configuration(execution_script="score.py", 
                                                  runtime="python", 
                                                  conda_file="myenv.yml")

service = Webservice.deploy_from_model(workspace=ws,
                                       name='sklearn-mnist-svc',
                                       deployment_config=aciconfig,
                                       models=[model],
                                       image_config=image_config)

service.wait_for_deployment(show_output=True)

Получите конечную точку HTTP веб-службы оценки, которая принимает вызовы клиента REST.Get the scoring web service's HTTP endpoint, which accepts REST client calls. К этой конечной точке можно предоставить совместный доступ всем, кто хочет протестировать веб-службу или интегрировать ее в приложение.You can share this endpoint with anyone who wants to test the web service or integrate it into an application:

print(service.scoring_uri)

Тестирование развернутой службыTest the deployed service

Ранее вы оценили все тестовые данные с помощью локальной версии модели.Earlier, you scored all the test data with the local version of the model. Теперь можно проверить развернутую модель, используя случайную выборку из 30 изображений в тестовых данных.Now you can test the deployed model with a random sample of 30 images from the test data.

Следующий код выполняет указанные далее действия.The following code goes through these steps:

  1. Отправка данных в виде массива JSON в веб-службу, размещенную в Экземплярах контейнеров.Send the data as a JSON array to the web service hosted in Container Instances.

  2. Использование API run пакета SDK для вызова службы.Use the SDK's run API to invoke the service. Вы также можете выполнять необработанные вызовы с помощью любого средства HTTP, например curl.You can also make raw calls by using any HTTP tool such as curl.

  3. Вывод возвращенных прогнозов и отображение их вместе с входными изображениями.Print the returned predictions and plot them along with the input images. Красный шрифт и обратное изображение (белое на черном фоне) используются для выделения неправильно классифицированных изображений.Red font and inverse image, white on black, is used to highlight the misclassified samples.

Так как модель характеризуется высокой точностью, перед отображением неправильно классифицированной выборки может потребоваться несколько раз запустить следующий код.Because the model accuracy is high, you might have to run the following code a few times before you can see a misclassified sample:

import json

# find 30 random samples from test set
n = 30
sample_indices = np.random.permutation(X_test.shape[0])[0:n]

test_samples = json.dumps({"data": X_test[sample_indices].tolist()})
test_samples = bytes(test_samples, encoding='utf8')

# predict using the deployed model
result = service.run(input_data=test_samples)

# compare actual value vs. the predicted values:
i = 0
plt.figure(figsize=(20, 1))

for s in sample_indices:
    plt.subplot(1, n, i + 1)
    plt.axhline('')
    plt.axvline('')

    # use different color for misclassified sample
    font_color = 'red' if y_test[s] != result[i] else 'black'
    clr_map = plt.cm.gray if y_test[s] != result[i] else plt.cm.Greys

    plt.text(x=10, y=-10, s=result[i], fontsize=18, color=font_color)
    plt.imshow(X_test[s].reshape(28, 28), cmap=clr_map)

    i = i + 1
plt.show()

Это результат одной случайной выборки тестовых изображений:This result is from one random sample of test images:

Рисунок, показывающий результаты

Для проверки веб-службы можно также отправить необработанный HTTP-запрос.You can also send a raw HTTP request to test the web service:

import requests

# send a random row from the test set to score
random_index = np.random.randint(0, len(X_test)-1)
input_data = "{\"data\": [" + str(list(X_test[random_index])) + "]}"

headers = {'Content-Type': 'application/json'}

# for AKS deployment you'd need to the service key in the header as well
# api_key = service.get_key()
# headers = {'Content-Type':'application/json',  'Authorization':('Bearer '+ api_key)}

resp = requests.post(service.scoring_uri, input_data, headers=headers)

print("POST to url", service.scoring_uri)
#print("input data:", input_data)
print("label:", y_test[random_index])
print("prediction:", resp.text)

Очистка ресурсовClean up resources

Чтобы сохранить группу ресурсов и рабочую область для других руководств и исследований, удалите только развертывание службы "Экземпляры контейнеров" с помощью этого вызова API:To keep the resource group and workspace for other tutorials and exploration, you can delete only the Container Instances deployment by using this API call:

service.delete()

Важно!

Созданные ресурсы могут использоваться в качестве необходимых компонентов для других руководств и статей с практическими рекомендациями по Службе машинного обучения Azure.The resources you created can be used as prerequisites to other Azure Machine Learning service tutorials and how-to articles.

Если вы не планируете использовать созданные ресурсы, удалите их, чтобы с вас не взималась плата.If you don't plan to use the resources you created, delete them, so you don't incur any charges:

  1. На портале Azure выберите Группы ресурсов в левой части окна.In the Azure portal, select Resource groups on the far left.

    Удаление ресурсов на портале Azure

  2. В списке выберите созданную группу ресурсов.From the list, select the resource group you created.

  3. Выберите Удалить группу ресурсов.Select Delete resource group.

  4. Введите имя группы ресурсов.Enter the resource group name. Теперь щелкните Удалить.Then select Delete.

Дополнительная информацияNext steps