使用机器学习工作室(经典)和 PowerShell 从一个试验创建多个 Web 服务终结点Create multiple web service endpoints from one experiment with ML Studio (classic) and PowerShell

适用于: yes机器学习工作室(经典) noAzure 机器学习APPLIES TO: yesMachine Learning Studio (classic) noAzure Machine Learning

这是一个常见的机器学习问题:你需要创建具有相同训练工作流并使用相同算法的多个模型,Here's a common machine learning problem: You want to create many models that have the same training workflow and use the same algorithm. 但是需要它们使用不同的训练数据集作为输入。But you want them to have different training datasets as input. 本文演示如何仅使用单个试验在 Azure 机器学习工作室(经典)中大规模地执行此操作。This article shows you how to do this at scale in Azure Machine Learning Studio (classic) using just a single experiment.

例如,假设用户拥有全球自行车租赁特许经营业务。For example, let's say you own a global bike rental franchise business. 想要生成回归模型以预测基于历史数据的租赁需求。You want to build a regression model to predict the rental demand based on historic data. 你在全世界有 1,000 个租赁位置,并为每个位置收集了一个数据集。You have 1,000 rental locations across the world and you've collected a dataset for each location. 它们包括特定于每个位置的重要功能,例如日期、时间、天气、交通。They include important features such as date, time, weather, and traffic that are specific to each location.

只要使用所有位置间全部数据集的合并版本,就可以训练模型。You could train your model once using a merged version of all the datasets across all locations. 但是,每个位置的环境都是唯一的。But, each of your locations has a unique environment. 因此,更好的方法是使用每个位置的数据集单独训练回归模型。So a better approach would be to train your regression model separately using the dataset for each location. 这样一来,每个训练的模型都可以考虑不同的存储大小、体积、地理位置、人口数量、自行车友好型交通环境等。That way, each trained model could take into account the different store sizes, volume, geography, population, bike-friendly traffic environment, and more.

这可能是最好的方法,但你不想在 Azure 机器学习工作室(经典)中创建 1,000 个训练实验,每个实验代表一个唯一位置。That may be the best approach, but you don't want to create 1,000 training experiments in Azure Machine Learning Studio (classic) with each one representing a unique location. 除了是项艰巨的任务,它看起来效率也低,因为每个实验都具有全部相同的组件(除了训练数据集)。Besides being an overwhelming task, it also seems inefficient since each experiment would have all the same components except for the training dataset.

幸运的是,可以使用 Azure 机器学习工作室(经典)重新训练 API 并使用 Azure 机器学习工作室(经典)PowerShell 自动完成任务以实现此目的。Fortunately, you can accomplish this by using the Azure Machine Learning Studio (classic) retraining API and automating the task with Azure Machine Learning Studio (classic) PowerShell.

备注

若要使示例运行更快,请将位置数从 1,000 减少到 10。To make your sample run faster, reduce the number of locations from 1,000 to 10. 但是相同原则和过程可应用于 1,000 个位置。But the same principles and procedures apply to 1,000 locations. 但是,如果确实需要根据 1,000 个数据集进行训练,则可能需要并行运行以下 PowerShell 脚本。However, if you do want to train from 1,000 datasets you might want to run the following PowerShell scripts in parallel. 本文不讨论如何执行此操作,但可在 Internet 上找到 PowerShell 多线程的示例。How to do that is beyond the scope of this article, but you can find examples of PowerShell multi-threading on the Internet.

设置训练实验Set up the training experiment

请使用 Cortana Intelligence 库中的示例训练实验Use the example training experiment that's in the Cortana Intelligence Gallery. Azure 机器学习工作室(经典)工作区中打开此实验。Open this experiment in your Azure Machine Learning Studio (classic) workspace.

备注

为了遵循此示例,可能需要使用标准工作区而不是免费工作区。In order to follow along with this example, you may want to use a standard workspace rather than a free workspace. 请为每个客户创建一个终结点(总共 10 个终结点),这需要一个标准工作区,因为免费工作区中最多只能有 3 个终结点。You create one endpoint for each customer - for a total of 10 endpoints - and that requires a standard workspace since a free workspace is limited to 3 endpoints.

实验使用导入数据模块以从 Azure 存储帐户中导入训练数据集 customer001.csvThe experiment uses an Import Data module to import the training dataset customer001.csv from an Azure storage account. 假设已从所有自行车租赁位置中收集了训练数据集,并将其存储在相同的 Blob 存储位置中,文件名范围为 rentalloc001.csvrentalloc10.csvLet's assume you have collected training datasets from all bike rental locations and stored them in the same blob storage location with file names ranging from rentalloc001.csv to rentalloc10.csv.

读取器模块从 Azure blob 导入数据

请注意,Web 服务输出模块已添加到训练模型模块。Note that a Web Service Output module has been added to the Train Model module. 如果此实验部署为 Web 服务,那么与此输出关联的终结点以 .ilearner 文件的格式返回训练的模板。When this experiment is deployed as a web service, the endpoint associated with that output returns the trained model in the format of an .ilearner file.

另请注意,所设置的 Web 服务参数可定义“导入数据”模块使用的 URL。Also note that you set up a web service parameter that defines the URL that the Import Data module uses. 这样即可使用参数来指定单个训练数据集,以便训练每个位置的模型。This allows you to use the parameter to specify individual training datasets to train the model for each location. 也可通过其他方式来这样做。There are other ways you could have done this. 可将 SQL 查询与 Web 服务参数结合使用,从 Azure SQL 数据库中的数据库获取数据。You can use a SQL query with a web service parameter to get data from a database in Azure SQL Database. 也可使用“Web 服务输入”模块将数据集传递到 Web 服务。Or you can use a Web Service Input module to pass in a dataset to the web service.

训练的模型模块将输出到 Web 服务输出模块

现在,请使用默认值 rental001.csv 作为训练数据集来运行此训练实验。Now, let's run this training experiment using the default value rental001.csv as the training dataset. 如果查看评估模块的输出(单击输出并选择“可视化”),则可以看到获得了不错的性能,即 AUC = 0.91。If you view the output of the Evaluate module (click the output and select Visualize), you can see you get a decent performance of AUC = 0.91. 此时,你已准备好部署超出此训练实验的 Web 服务。At this point, you're ready to deploy a web service out of this training experiment.

部署训练和评分 Web 服务Deploy the training and scoring web services

要部署训练 Web 服务,可单击实验画布下的“设置 Web 服务”按钮,并选择“部署 Web 服务”。To deploy the training web service, click the Set Up Web Service button below the experiment canvas and select Deploy Web Service. 调用此 Web 服务“自行车租赁训练”。Call this web service "Bike Rental Training".

现在需要部署评分 Web 服务。Now you need to deploy the scoring web service. 若要执行此操作,可单击画布下的“设置 Web 服务”,然后选择“预测 Web 服务”。To do this, click Set Up Web Service below the canvas and select Predictive Web Service. 这会创建评分实验。This creates a scoring experiment. 需要进行一些细微调整,使之可以作为 Web 服务使用。You need to make a few minor adjustments to make it work as a web service. 请从输入数据中删除标签列“cnt”,使输出只能是实例 ID 和相应的预测值。Remove the label column "cnt" from the input data and limit the output to only the instance id and the corresponding predicted value.

若要保存该工作,可以打开已准备好的库中的预测实验To save yourself that work, you can open the predictive experiment in the Gallery that has already been prepared.

要部署 Web 服务,请运行预测实验,并单击画布下的“部署 Web 服务”按钮。To deploy the web service, run the predictive experiment, then click the Deploy Web Service button below the canvas. 将评分 Web 服务命名为“自行车租赁评分”。Name the scoring web service "Bike Rental Scoring".

使用 PowerShell 创建 10 个完全相同的 Web 服务终结点Create 10 identical web service endpoints with PowerShell

此 Web 服务附带了一个默认终结点。This web service comes with a default endpoint. 但是,你不会对此默认终结点感兴趣,因为它不能进行更新。But you're not as interested in the default endpoint since it can't be updated. 需要执行的操作是创建 10 个其他终结点,每个位置一个。What you need to do is to create 10 additional endpoints, one for each location. 可以使用 PowerShell 执行此操作。You can do this with PowerShell.

首先,请设置 PowerShell 环境:First, you set up the PowerShell environment:

Import-Module .\AzureMLPS.dll
# Assume the default configuration file exists and is properly set to point to the valid Workspace.
$scoringSvc = Get-AmlWebService | where Name -eq 'Bike Rental Scoring'
$trainingSvc = Get-AmlWebService | where Name -eq 'Bike Rental Training'

然后,运行以下 PowerShell 命令:Then, run the following PowerShell command:

# Create 10 endpoints on the scoring web service.
For ($i = 1; $i -le 10; $i++){
    $seq = $i.ToString().PadLeft(3, '0');
    $endpointName = 'rentalloc' + $seq;
    Write-Host ('adding endpoint ' + $endpointName + '...')
    Add-AmlWebServiceEndpoint -WebServiceId $scoringSvc.Id -EndpointName $endpointName -Description $endpointName     
}

现在已创建 10 个终结点,所有终结点都包含在 customer001.csv 上训练的同一已训练模型。Now you created 10 endpoints and they all contain the same trained model trained on customer001.csv. 可以在 Azure 门户中查看它们。You can view them in the Azure portal.

在门户中查看已训练模型的列表

更新终结点以通过 PowerShell 使用单独的训练数据集Update the endpoints to use separate training datasets using PowerShell

下一步是使用在每个客户单独数据上唯一训练的模型来更新终结点。The next step is to update the endpoints with models uniquely trained on each customer's individual data. 但是,首先需要从自行车租赁训练 Web 服务中生成这些模型。But first you need to produce these models from the Bike Rental Training web service. 让我们回到自行车租赁训练 Web 服务。Let's go back to the Bike Rental Training web service. 需要使用 10 个不同的训练数据集调用其 BES 终结点 10 次,以便生成 10 个不同的模型。You need to call its BES endpoint 10 times with 10 different training datasets in order to produce 10 different models. 请使用 InovkeAmlWebServiceBESEndpoint PowerShell cmdlet 来执行此操作。Use the InovkeAmlWebServiceBESEndpoint PowerShell cmdlet to do this.

还需要将 Blob 存储帐户的凭据提供到 $configContent 中。You will also need to provide credentials for your blob storage account into $configContent. 也即提供到 AccountNameAccountKeyRelativeLocation 字段中。Namely, at the fields AccountName, AccountKey, and RelativeLocation. AccountName 可以是帐户名称的一个,如 Azure 门户(“存储”选项卡)中所示。The AccountName can be one of your account names, as seen in the Azure portal (Storage tab). 单击存储帐户之后,可通过按底部的“管理访问键”按钮和复制“主访问键”来查找其 AccountKeyOnce you click on a storage account, its AccountKey can be found by pressing the Manage Access Keys button at the bottom and copying the Primary Access Key. RelativeLocation是相对于存储(其中存储了新模型)的路径。The RelativeLocation is the path relative to your storage where a new model will be stored. 例如,以下脚本中的 hai/retrain/bike_rental/ 路径指向名为 hai 的容器,/retrain/bike_rental/ 是子文件夹。For instance, the path hai/retrain/bike_rental/ in the following script points to a container named hai, and /retrain/bike_rental/ are subfolders. 目前,不能通过门户 UI 创建子文件夹,但是有几个 Azure 存储资源管理器可允许这样做。Currently, you cannot create subfolders through the portal UI, but there are several Azure Storage Explorers that allow you to do so. 建议在存储中创建新的容器以存储新的训练模型(.iLearner 文件),如下所示:在存储页中,单击底部的“添加”按钮并将其命名为 retrainIt is recommended that you create a new container in your storage to store the new trained models (.iLearner files) as follows: from your storage page, click the Add button at the bottom and name it retrain. 总之,对以下脚本进行的必要更改包括 AccountNameAccountKeyRelativeLocation (:"retrain/model' + $seq + '.ilearner")。In summary, the necessary changes to the following script pertain to AccountName, AccountKey, and RelativeLocation (:"retrain/model' + $seq + '.ilearner").

# Invoke the retraining API 10 times
# This is the default (and the only) endpoint on the training web service
$trainingSvcEp = (Get-AmlWebServiceEndpoint -WebServiceId $trainingSvc.Id)[0];
$submitJobRequestUrl = $trainingSvcEp.ApiLocation + '/jobs?api-version=2.0';
$apiKey = $trainingSvcEp.PrimaryKey;
For ($i = 1; $i -le 10; $i++){
    $seq = $i.ToString().PadLeft(3, '0');
    $inputFileName = 'https://bostonmtc.blob.core.chinacloudapi.cn/hai/retrain/bike_rental/BikeRental' + $seq + '.csv';
    $configContent = '{ "GlobalParameters": { "URI": "' + $inputFileName + '" }, "Outputs": { "output1": { "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=<myaccount>;AccountKey=<mykey>", "RelativeLocation": "hai/retrain/bike_rental/model' + $seq + '.ilearner" } } }';
    Write-Host ('training regression model on ' + $inputFileName + ' for rental location ' + $seq + '...');
    Invoke-AmlWebServiceBESEndpoint -JobConfigString $configContent -SubmitJobRequestUrl $submitJobRequestUrl -ApiKey $apiKey
}

备注

BES 终结点是此操作唯一支持的模式。The BES endpoint is the only supported mode for this operation. RRS 不能用于生成训练模型。RRS cannot be used for producing trained models.

如上所示,与其构造 10 个不同的 BES 作业配置 json 文件,不如动态创建配置字符串,As you can see above, instead of constructing 10 different BES job configuration json files, you dynamically create the config string instead. 然后将其馈送到 InvokeAmlWebServceBESEndpoint cmdlet 的 jobConfigString 参数。Then feed it to the jobConfigString parameter of the InvokeAmlWebServceBESEndpoint cmdlet. 确实无需在磁盘上保留副本。There's really no need to keep a copy on disk.

如果一切顺利,一段时间后应该能在 Azure 存储帐户中看到 10 个 .iLearner 文件(从 model001.ilearnermodel010.ilearner)。If everything goes well, after a while you should see 10 .iLearner files, from model001.ilearner to model010.ilearner, in your Azure storage account. 现在已准备好使用 Patch-AmlWebServiceEndpoint PowerShell cmdlet 通过这些模型更新 10 个评分 Web 服务终结点。Now you're ready to update the 10 scoring web service endpoints with these models using the Patch-AmlWebServiceEndpoint PowerShell cmdlet. 再次提醒,只能修补之前以编程方式创建的非默认终结点。Remember again that you can only patch the non-default endpoints you programmatically created earlier.

# Patch the 10 endpoints with respective .ilearner models
$baseLoc = 'http://bostonmtc.blob.core.chinacloudapi.cn/'
$sasToken = '<my_blob_sas_token>'
For ($i = 1; $i -le 10; $i++){
    $seq = $i.ToString().PadLeft(3, '0');
    $endpointName = 'rentalloc' + $seq;
    $relativeLoc = 'hai/retrain/bike_rental/model' + $seq + '.ilearner';
    Write-Host ('Patching endpoint ' + $endpointName + '...');
    Patch-AmlWebServiceEndpoint -WebServiceId $scoringSvc.Id -EndpointName $endpointName -ResourceName 'Bike Rental [trained model]' -BaseLocation $baseLoc -RelativeLocation $relativeLoc -SasBlobToken $sasToken
}

这应以相当快的速度运行。This should run fairly quickly. 执行完以后,将会成功创建 10 个预测性的 Web 服务终结点。When the execution finishes, you'll have successfully created 10 predictive web service endpoints. 每个终结点都会包含一个针对数据集特别训练过的模型(该数据集特定于租赁位置),全都来自单个训练实验。Each one will contain a trained model uniquely trained on the dataset specific to a rental location, all from a single training experiment. 若要验证这一点,可以使用 InvokeAmlWebServiceRRSEndpoint cmdlet 尝试调用这些终结点,为其提供相同的输入数据。To verify this, you can try calling these endpoints using the InvokeAmlWebServiceRRSEndpoint cmdlet, providing them with the same input data. 预期会看到不同的预测结果,因为这些模型是使用不同的训练集训练的。You should expect to see different prediction results since the models are trained with different training sets.

完整的 PowerShell 脚本Full PowerShell script

下面是完整源代码的列表:Here's the listing of the full source code:

Import-Module .\AzureMLPS.dll
# Assume the default configuration file exists and properly set to point to the valid workspace.
$scoringSvc = Get-AmlWebService | where Name -eq 'Bike Rental Scoring'
$trainingSvc = Get-AmlWebService | where Name -eq 'Bike Rental Training'

# Create 10 endpoints on the scoring web service
For ($i = 1; $i -le 10; $i++){
    $seq = $i.ToString().PadLeft(3, '0');
    $endpointName = 'rentalloc' + $seq;
    Write-Host ('adding endpoint ' + $endpontName + '...')
    Add-AmlWebServiceEndpoint -WebServiceId $scoringSvc.Id -EndpointName $endpointName -Description $endpointName     
}

# Invoke the retraining API 10 times to produce 10 regression models in .ilearner format
$trainingSvcEp = (Get-AmlWebServiceEndpoint -WebServiceId $trainingSvc.Id)[0];
$submitJobRequestUrl = $trainingSvcEp.ApiLocation + '/jobs?api-version=2.0';
$apiKey = $trainingSvcEp.PrimaryKey;
For ($i = 1; $i -le 10; $i++){
    $seq = $i.ToString().PadLeft(3, '0');
    $inputFileName = 'https://bostonmtc.blob.core.chinacloudapi.cn/hai/retrain/bike_rental/BikeRental' + $seq + '.csv';
    $configContent = '{ "GlobalParameters": { "URI": "' + $inputFileName + '" }, "Outputs": { "output1": { "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=<myaccount>;AccountKey=<mykey>", "RelativeLocation": "hai/retrain/bike_rental/model' + $seq + '.ilearner" } } }';
    Write-Host ('training regression model on ' + $inputFileName + ' for rental location ' + $seq + '...');
    Invoke-AmlWebServiceBESEndpoint -JobConfigString $configContent -SubmitJobRequestUrl $submitJobRequestUrl -ApiKey $apiKey
}

# Patch the 10 endpoints with respective .ilearner models
$baseLoc = 'http://bostonmtc.blob.core.chinacloudapi.cn/'
$sasToken = '?test'
For ($i = 1; $i -le 10; $i++){
    $seq = $i.ToString().PadLeft(3, '0');
    $endpointName = 'rentalloc' + $seq;
    $relativeLoc = 'hai/retrain/bike_rental/model' + $seq + '.ilearner';
    Write-Host ('Patching endpoint ' + $endpointName + '...');
    Patch-AmlWebServiceEndpoint -WebServiceId $scoringSvc.Id -EndpointName $endpointName -ResourceName 'Bike Rental [trained model]' -BaseLocation $baseLoc -RelativeLocation $relativeLoc -SasBlobToken $sasToken
}