<jupyter_start><jupyter_text>创建实时推理服务

在训练了预测模型之后，可以将其部署为实时服务，客户端可以使用该服务从新数据中获取预测。  连接到工作区

首先，请连接到你的工作区。

> **备注**：如果尚未与 Azure 订阅建立经过身份验证的会话，则系统将提示你通过执行以下操作进行身份验证：单击链接，输入验证码，然后登录到 Azure。<jupyter_code>import azureml.core
from azureml.core import Workspace

# Load the workspace from the saved config file
ws = Workspace.from_config()
print('Ready to use Azure ML {} to work with {}'.format(azureml.core.VERSION, ws.name))<jupyter_output><empty_output><jupyter_text>训练和注册模型

现在我们来训练并注册模型。<jupyter_code>from azureml.core import Experiment
from azureml.core import Model
import pandas as pd
import numpy as np
import joblib
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_curve

# Create an Azure ML experiment in your workspace
experiment = Experiment(workspace=ws, name="mslearn-train-diabetes")
run = experiment.start_logging()
print("Starting experiment:", experiment.name)

# load the diabetes dataset
print("Loading Data...")
diabetes = pd.read_csv('data/diabetes.csv')

# Separate features and labels
X, y = diabetes[['Pregnancies','PlasmaGlucose','DiastolicBloodPressure','TricepsThickness','SerumInsulin','BMI','DiabetesPedigree','Age']].values, diabetes['Diabetic'].values

# Split data into training set and test set
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30, random_state=0)

# Train a decision tree model
print('Training a decision tree model')
model = DecisionTreeClassifier().fit(X_train, y_train)

# calculate accuracy
y_hat = model.predict(X_test)
acc = np.average(y_hat == y_test)
print('Accuracy:', acc)
run.log('Accuracy', np.float(acc))

# calculate AUC
y_scores = model.predict_proba(X_test)
auc = roc_auc_score(y_test,y_scores[:,1])
print('AUC: ' + str(auc))
run.log('AUC', np.float(auc))

# Save the trained model
model_file = 'diabetes_model.pkl'
joblib.dump(value=model, filename=model_file)
run.upload_file(name = 'outputs/' + model_file, path_or_stream = './' + model_file)

# Complete the run
run.complete()

# Register the model
run.register_model(model_path='outputs/diabetes_model.pkl', model_name='diabetes_model',
                   tags={'Training context':'Inline Training'},
                   properties={'AUC': run.get_metrics()['AUC'], 'Accuracy': run.get_metrics()['Accuracy']})

print('Model trained and registered.')<jupyter_output><empty_output><jupyter_text>将模型部署为 Web 服务

你已经训练并注册了一个机器学习模型，该模型可以根据患者患上糖尿病的可能性对他们进行分类。此模型可在生产环境中使用，例如医生的手术室（在此场景中，只有被认为有风险的患者需要进行糖尿病临床测试）。为了支持此场景，你需要将模型部署为 Web 服务。

首先，让我们确定你在工作区中注册了哪些模型。<jupyter_code>from azureml.core import Model

for model in Model.list(ws):
    print(model.name, 'version:', model.version)
    for tag_name in model.tags:
        tag = model.tags[tag_name]
        print ('\t',tag_name, ':', tag)
    for prop_name in model.properties:
        prop = model.properties[prop_name]
        print ('\t',prop_name, ':', prop)
    print('\n')<jupyter_output><empty_output><jupyter_text>现在我们来获取要部署的模型。默认情况下，如果我们指定模型名称，将返回最新版本。<jupyter_code>model = ws.models['diabetes_model']
print(model.name, 'version', model.version)<jupyter_output><empty_output><jupyter_text>我们将创建一个 Web 服务来托管此模型，这将需要一些代码和配置文件；因此，我们先为它们创建一个文件夹。<jupyter_code>import os

# Create a folder for the deployment files
deployment_folder = './diabetes_service'
os.makedirs(deployment_folder, exist_ok=True)
print(deployment_folder, 'folder created.')

# Set path for scoring script
script_file = 'score_diabetes.py'
script_path = os.path.join(deployment_folder,script_file)<jupyter_output><empty_output><jupyter_text>我们在其中部署模型的 Web 服务将需要一些 Python 代码来加载输入数据、从工作区获取模型以及生成和返回预测。我们将此代码保存在将部署到 Web 服务的入口脚本（通常称为评分脚本）中。

脚本由两个函数组成：

- **init**：在初始化服务时调用该函数，通常用于加载模型。注意，评分脚本使用“**AZUREML_MODEL_DIR**”环境变量来确定存储模型的文件夹。
- **run**：每次客户端应用程序提交新数据时都会调用此函数，通常用于从模型推断预测。<jupyter_code>%%writefile $script_path
import json
import joblib
import numpy as np
import os

# Called when the service is loaded
def init():
    global model
    # Get the path to the deployed model file and load it
    model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'diabetes_model.pkl')
    model = joblib.load(model_path)

# Called when a request is received
def run(raw_data):
    # Get the input data as a numpy array
    data = np.array(json.loads(raw_data)['data'])
    # Get a prediction from the model
    predictions = model.predict(data)
    # Get the corresponding classname for each prediction (0 or 1)
    classnames = ['not-diabetic', 'diabetic']
    predicted_classes = []
    for prediction in predictions:
        predicted_classes.append(classnames[prediction])
    # Return the predictions as JSON
    return json.dumps(predicted_classes)<jupyter_output><empty_output><jupyter_text>该 Web 服务将托管在容器中，该容器在进行初始化时需要安装任何所需的 Python 依赖项。在本例中，评分代码需要“**scikit-learn**”和评分 Web 服务使用的一些特定于 Azure 机器学习的包，因此我们将创建一个包含这些内容的环境。然后，我们将把该环境和评分脚本一起添加到“推理配置”中，并为容器定义**“部署配置**”，环境和脚本将驻留在容器中。

然后，我们可以基于这些配置将模型部署为服务。

> **详细信息**：有关模型部署的更多详细信息以及目标执行环境选项，请参阅此[文档](https://docs.microsoft.com/azure/machine-learning/how-to-deploy-and-where)。

部署会花费一些时间，因为它首先运行一个进程以创建容器映像，然后会运行一个进程以基于该映像创建 Web 服务。成功完成部署后，你会看到“**正常**”状态。<jupyter_code>from azureml.core import Environment
from azureml.core.model import InferenceConfig
from azureml.core.webservice import AciWebservice

# Configure the scoring environment
service_env = Environment(name='service-env')
python_packages = ['scikit-learn', 'azureml-defaults', 'azure-ml-api-sdk']
for package in python_packages:
    service_env.python.conda_dependencies.add_pip_package(package)
inference_config = InferenceConfig(source_directory=deployment_folder,
                                   entry_script=script_file,
                                   environment=service_env)

# Configure the web service container
deployment_config = AciWebservice.deploy_configuration(cpu_cores=1, memory_gb=1)

# Deploy the model as a service
print('Deploying model...')
service_name = "diabetes-service"
service = Model.deploy(ws, service_name, [model], inference_config, deployment_config, overwrite=True)
service.wait_for_deployment(True)
print(service.state)<jupyter_output><empty_output><jupyter_text>希望部署已成功，然后你就能看到“**正常**”状态。如果未成功，可以使用以下代码来获取服务日志以帮助你解决问题。<jupyter_code>print(service.get_logs())

# If you need to make a change and redeploy, you may need to delete unhealthy service using the following code:
#service.delete()<jupyter_output><empty_output><jupyter_text>在 [Azure 机器学习工作室](https://ml.azure.com)中查看工作区，然后查看“**终结点**”页面，此页面显示工作区中已部署的服务。

还可以通过运行以下代码来检索工作区中 Web 服务的名称：<jupyter_code>for webservice_name in ws.webservices:
    print(webservice_name)<jupyter_output><empty_output><jupyter_text>使用 Web 服务

部署此服务后，现在可以从客户端应用程序使用它。<jupyter_code>import json

x_new = [[2,180,74,24,21,23.9091702,1.488172308,22]]
print ('Patient: {}'.format(x_new[0]))

# Convert the array to a serializable list in a JSON document
input_json = json.dumps({"data": x_new})

# Call the web service, passing the input data (the web service will also accept the data in binary format)
predictions = service.run(input_data = input_json)

# Get the predicted class - it'll be the first (and only) one.
predicted_classes = json.loads(predictions)
print(predicted_classes[0])<jupyter_output><empty_output><jupyter_text>还可以将多位患者的观察结果发送到此服务，并获取针对每位患者的预测。<jupyter_code>import json

# This time our input is an array of two feature arrays
x_new = [[2,180,74,24,21,23.9091702,1.488172308,22],
         [0,148,58,11,179,39.19207553,0.160829008,45]]

# Convert the array or arrays to a serializable list in a JSON document
input_json = json.dumps({"data": x_new})

# Call the web service, passing the input data
predictions = service.run(input_data = input_json)

# Get the predicted classes.
predicted_classes = json.loads(predictions)
   
for i in range(len(x_new)):
    print ("Patient {}".format(x_new[i]), predicted_classes[i] )<jupyter_output><empty_output><jupyter_text>上述代码使用 Azure 机器学习 SDK 连接到容器化 Web 服务，并将其用于根据糖尿病分类模型生成预测。在生产环境中，不使用 Azure 机器学习 SDK 而是仅向 Web 服务发出 HTTP 请求的业务应用程序可能使用模型。

我们来确定这些应用程序必须将其请求提交到的 URL：<jupyter_code>endpoint = service.scoring_uri
print(endpoint)<jupyter_output><empty_output><jupyter_text>你已知道终结点 URI，应用程序现在可以发出 HTTP 请求、发送 JSON 格式的患者数据以及接收预测的类。<jupyter_code>import requests
import json

x_new = [[2,180,74,24,21,23.9091702,1.488172308,22],
         [0,148,58,11,179,39.19207553,0.160829008,45]]

# Convert the array to a serializable list in a JSON document
input_json = json.dumps({"data": x_new})

# Set the content type
headers = { 'Content-Type':'application/json' }

predictions = requests.post(endpoint, input_json, headers = headers)
predicted_classes = json.loads(predictions.json())

for i in range(len(x_new)):
    print ("Patient {}".format(x_new[i]), predicted_classes[i] )<jupyter_output><empty_output><jupyter_text>你已将 Web 服务部署为不需要进行身份验证的 Azure 容器实例 (ACI) 服务。这对于开发和测试是可行的，但是对于生产，应考虑部署到 Azure Kubernetes 服务 (AKS) 群集并启用基于令牌的身份验证。这要求 REST 请求包含一个**授权**标头。

 删除服务

如果你不再需要服务，应将其删除以免产生不必要的费用。<jupyter_code>service.delete()
print ('Service deleted.')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11462320901235919, 'fraction_numerical': 0.018593459477195668, 'mean_word_length': 6.274463007159905, 'pattern_counts': {'":': 3, '<': 57, '<?xml version=': 0, '>': 59, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '431247', 'license': 'MIT', 'n_tokens_mistral': 4050, 'n_tokens_neox': 4112, 'n_words': 644, 'path': '09 - Create a Real-time Inferencing Service.ipynb', 'repo_name': 'MicrosoftLearning/mslearn-dp100.zh-cn', 'size': '9143'}