Compare commits

...

99 Commits

Author SHA1 Message Date
Shané Winner
5ec6d8861b Delete auto-ml-dataprep-remote-execution.yml 2019-08-27 11:19:38 -07:00
Shané Winner
ae188f324e Delete auto-ml-dataprep-remote-execution.ipynb 2019-08-27 11:19:27 -07:00
Shané Winner
4c30c2bdb9 Delete auto-ml-dataprep.yml 2019-08-27 11:19:00 -07:00
Shané Winner
b891440e2d Delete auto-ml-dataprep.ipynb 2019-08-27 11:18:50 -07:00
Shané Winner
784827cdd2 Update README.md 2019-08-27 09:23:40 -07:00
vizhur
0957af04ca Merge pull request #545 from Azure/imatiach-msft-patch-1
add dataprep dependency to notebook
2019-08-23 13:14:30 -04:00
Ilya Matiach
a3bdd193d1 add dataprep dependency to notebook
add dataprep dependency to train-explain-model-on-amlcompute-and-deploy.ipynb notebook for azureml-explain-model package
2019-08-23 13:11:36 -04:00
Shané Winner
dff09970ac Update README.md 2019-08-23 08:38:01 -07:00
Shané Winner
abc7d21711 Update README.md 2019-08-23 05:28:45 +00:00
Shané Winner
ec12ef635f Delete azure-ml-datadrift.ipynb 2019-08-21 10:32:40 -07:00
Shané Winner
81b3e6f09f Delete azure-ml-datadrift.yml 2019-08-21 10:32:32 -07:00
Shané Winner
cc167dceda Delete score.py 2019-08-21 10:32:23 -07:00
Shané Winner
bc52a6d8ee Delete datasets-diff.ipynb 2019-08-21 10:31:50 -07:00
Shané Winner
5bbbdbe73c Delete Titanic.csv 2019-08-21 10:31:38 -07:00
Shané Winner
fd4de05ddd Delete train.py 2019-08-21 10:31:26 -07:00
Shané Winner
9eaab2189d Delete datasets-tutorial.ipynb 2019-08-21 10:31:15 -07:00
Shané Winner
12147754b2 Delete datasets-diff.ipynb 2019-08-21 10:31:05 -07:00
Shané Winner
90ef263823 Delete README.md 2019-08-21 10:30:54 -07:00
Shané Winner
143590cfb4 Delete new-york-taxi_scale-out.ipynb 2019-08-21 10:30:39 -07:00
Shané Winner
40379014ad Delete new-york-taxi.ipynb 2019-08-21 10:30:29 -07:00
Shané Winner
f7b0e99fa1 Delete part-00000-34f8a7a7-c3cd-4926-92b2-ba2dcd3f95b7.gz.parquet 2019-08-21 10:30:18 -07:00
Shané Winner
7a7ac48411 Delete part-00000-34f8a7a7-c3cd-4926-92b2-ba2dcd3f95b7.gz.parquet 2019-08-21 10:30:04 -07:00
Shané Winner
50107c5b1e Delete part-00007-0b08e77b-f17a-4c20-972c-aa382e830fca-c000.csv 2019-08-21 10:29:51 -07:00
Shané Winner
e41d7e6819 Delete part-00006-0b08e77b-f17a-4c20-972c-aa382e830fca-c000.csv 2019-08-21 10:29:36 -07:00
Shané Winner
691e038e84 Delete part-00005-0b08e77b-f17a-4c20-972c-aa382e830fca-c000.csv 2019-08-21 10:29:18 -07:00
Shané Winner
426e79d635 Delete part-00004-0b08e77b-f17a-4c20-972c-aa382e830fca-c000.csv 2019-08-21 10:29:02 -07:00
Shané Winner
326677e87f Delete part-00003-0b08e77b-f17a-4c20-972c-aa382e830fca-c000.csv 2019-08-21 10:28:45 -07:00
Shané Winner
44988e30ae Delete part-00002-0b08e77b-f17a-4c20-972c-aa382e830fca-c000.csv 2019-08-21 10:28:31 -07:00
Shané Winner
646ae37384 Delete part-00001-0b08e77b-f17a-4c20-972c-aa382e830fca-c000.csv 2019-08-21 10:28:18 -07:00
Shané Winner
457e29a663 Delete part-00000-0b08e77b-f17a-4c20-972c-aa382e830fca-c000.csv 2019-08-21 10:28:03 -07:00
Shané Winner
2771edfb2c Delete _SUCCESS 2019-08-21 10:27:45 -07:00
Shané Winner
f0001ec322 Delete adls-dpreptestfiles.crt 2019-08-21 10:27:31 -07:00
Shané Winner
d3e02a017d Delete chicago-aldermen-2015.csv 2019-08-21 10:27:05 -07:00
Shané Winner
a0ebed6876 Delete crime-dirty.csv 2019-08-21 10:26:55 -07:00
Shané Winner
dc0ab6db47 Delete crime-spring.csv 2019-08-21 10:26:45 -07:00
Shané Winner
ea7900f82c Delete crime-winter.csv 2019-08-21 10:26:35 -07:00
Shané Winner
0cb3fd180d Delete crime.parquet 2019-08-21 10:26:26 -07:00
Shané Winner
b05c3e46bb Delete crime.txt 2019-08-21 10:26:17 -07:00
Shané Winner
a1b7d298d3 Delete crime.xlsx 2019-08-21 10:25:41 -07:00
Shané Winner
cc5516c3b3 Delete crime_duplicate_headers.csv 2019-08-21 10:25:32 -07:00
Shané Winner
4fb6070b89 Delete crime.zip 2019-08-21 10:25:23 -07:00
Shané Winner
1b926cdf53 Delete crime-full.csv 2019-08-21 10:25:13 -07:00
Shané Winner
72fc00fb65 Delete crime.dprep 2019-08-21 10:24:56 -07:00
Shané Winner
ddc6b57253 Delete ADLSgen2-datapreptest.crt 2019-08-21 10:24:47 -07:00
Shané Winner
e8b3b98338 Delete crime_fixed_width_file.txt 2019-08-21 10:24:38 -07:00
Shané Winner
66325a1405 Delete crime_multiple_separators.csv 2019-08-21 10:24:29 -07:00
Shané Winner
0efbeaf4b8 Delete json.json 2019-08-21 10:24:12 -07:00
Shané Winner
11d487fb28 Merge pull request #542 from Azure/sgilley/update-deploy
change deployment to model-centric approach
2019-08-21 10:22:13 -07:00
Shané Winner
073e319ef9 Delete large_dflow.json 2019-08-21 10:21:41 -07:00
Shané Winner
3ed75f28d1 Delete map_func.py 2019-08-21 10:21:23 -07:00
Shané Winner
bfc0367f54 Delete median_income.csv 2019-08-21 10:21:14 -07:00
Shané Winner
075eeb583f Delete median_income_transformed.csv 2019-08-21 10:21:05 -07:00
Shané Winner
b7531d3b9e Delete parquet.parquet 2019-08-21 10:20:55 -07:00
Shané Winner
41dc3bd1cf Delete secrets.dprep 2019-08-21 10:20:45 -07:00
Shané Winner
b790b385a4 Delete stream-path.csv 2019-08-21 10:20:36 -07:00
Shané Winner
8700328fe9 Delete summarize.ipynb 2019-08-21 10:17:21 -07:00
Shané Winner
adbd2c8200 Delete subsetting-sampling.ipynb 2019-08-21 10:17:12 -07:00
Shané Winner
7d552effb0 Delete split-column-by-example.ipynb 2019-08-21 10:17:01 -07:00
Shané Winner
bc81d2a5a7 Delete semantic-types.ipynb 2019-08-21 10:16:52 -07:00
Shané Winner
7620de2d91 Delete secrets.ipynb 2019-08-21 10:16:42 -07:00
Shané Winner
07a43a0444 Delete replace-fill-error.ipynb 2019-08-21 10:16:33 -07:00
Shané Winner
f4d5874e09 Delete replace-datasource-replace-reference.ipynb 2019-08-21 10:16:23 -07:00
Shané Winner
8a0b4d24bd Delete random-split.ipynb 2019-08-21 10:16:14 -07:00
Shané Winner
636f19be1f Delete quantile-transformation.ipynb 2019-08-21 10:16:04 -07:00
Shané Winner
0fd7f7d9b2 Delete open-save-dataflows.ipynb 2019-08-21 10:15:54 -07:00
Shané Winner
ab6c66534f Delete one-hot-encoder.ipynb 2019-08-21 10:15:45 -07:00
Shané Winner
faccf13759 Delete min-max-scaler.ipynb 2019-08-21 10:15:36 -07:00
Shané Winner
4c6a28e4ed Delete label-encoder.ipynb 2019-08-21 10:15:25 -07:00
Shané Winner
64ad88e2cb Delete join.ipynb 2019-08-21 10:15:17 -07:00
Shané Winner
969ac90d39 Delete impute-missing-values.ipynb 2019-08-21 10:12:12 -07:00
Shané Winner
fb977c1e95 Delete fuzzy-group.ipynb 2019-08-21 10:12:03 -07:00
Shané Winner
d5ba3916f7 Delete filtering.ipynb 2019-08-21 10:11:53 -07:00
Shané Winner
f7f1087337 Delete external-references.ipynb 2019-08-21 10:11:43 -07:00
Shané Winner
47ea2dbc03 Delete derive-column-by-example.ipynb 2019-08-21 10:11:33 -07:00
Shané Winner
bd2cf534e5 Delete datastore.ipynb 2019-08-21 10:11:24 -07:00
Shané Winner
65f1668d69 Delete data-profile.ipynb 2019-08-21 10:11:16 -07:00
Shané Winner
e0fb7df0aa Delete data-ingestion.ipynb 2019-08-21 10:11:06 -07:00
Shané Winner
7047f76299 Delete custom-python-transforms.ipynb 2019-08-21 10:10:56 -07:00
Shané Winner
c39f2d5eb6 Delete column-type-transforms.ipynb 2019-08-21 10:10:45 -07:00
Shané Winner
5fda69a388 Delete column-manipulations.ipynb 2019-08-21 10:10:36 -07:00
Shané Winner
87ce954eef Delete cache.ipynb 2019-08-21 10:10:26 -07:00
Shané Winner
ebbeac413a Delete auto-read-file.ipynb 2019-08-21 10:10:15 -07:00
Shané Winner
a68bbaaab4 Delete assertions.ipynb 2019-08-21 10:10:05 -07:00
Shané Winner
8784dc979f Delete append-columns-and-rows.ipynb 2019-08-21 10:09:55 -07:00
Shané Winner
f8047544fc Delete add-column-using-expression.ipynb 2019-08-21 10:09:44 -07:00
Shané Winner
eeb2a05e4f Delete working-with-file-streams.ipynb 2019-08-21 10:09:33 -07:00
Shané Winner
6db9d7bd8b Delete writing-data.ipynb 2019-08-21 10:09:19 -07:00
Shané Winner
80e2fde734 Delete getting-started.ipynb 2019-08-21 10:09:04 -07:00
Shané Winner
ae4f5d40ee Delete README.md 2019-08-21 10:08:53 -07:00
Shané Winner
5516edadfd Delete README.md 2019-08-21 10:08:13 -07:00
Sheri Gilley
475afbf44b change deployment to model-centric approach 2019-08-21 09:50:49 -05:00
Shané Winner
197eaf1aab Merge pull request #541 from Azure/sdgilley/update-tutorial
Update img-classification-part1-training.ipynb
2019-08-20 15:59:24 -07:00
Sheri Gilley
184680f1d2 Update img-classification-part1-training.ipynb
updated explanation of datastore
2019-08-20 17:52:45 -05:00
Shané Winner
474f58bd0b Merge pull request #540 from trevorbye/master
removing tutorials for single combined tutorial
2019-08-20 15:22:47 -07:00
Trevor Bye
22c8433897 removing tutorials for single combined tutorial 2019-08-20 12:09:21 -07:00
Josée Martens
822cdd0f01 Update issue templates 2019-08-20 08:35:00 -05:00
Josée Martens
6e65d42986 Update issue templates 2019-08-20 08:26:45 -05:00
Harneet Virk
4c0cbac834 Merge pull request #537 from Azure/release_update/Release-141
update samples from Release-141 as a part of 1.0.57 SDK release
2019-08-19 18:32:44 -07:00
vizhur
44a7481ed1 update samples from Release-141 as a part of 1.0.57 SDK release 2019-08-19 23:33:44 +00:00
175 changed files with 7552 additions and 5635 deletions

View File

@@ -1,30 +1,43 @@
--- ---
name: Notebook issue name: Notebook issue
about: Create a report to help us improve about: Describe your notebook issue
title: "[Notebook issue]" title: "[Notebook] DESCRIPTIVE TITLE"
labels: '' labels: notebook
assignees: '' assignees: ''
--- ---
**Describe the bug** ### DESCRIPTION: Describe clearly + concisely
A clear and concise description of what the bug is.
Provide the following if applicable:
+ Your Python & SDK version
+ Python Scripts or the full notebook name
+ Pipeline definition
+ Environment definition
+ Example data
+ Any log files.
+ Run and Workspace Id
**To Reproduce** .
Steps to reproduce the behavior: ### REPRODUCIBLE: Steps
1.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Additional context** .
Add any other context about the problem here. ### EXPECTATION: Clear description
.
### CONFIG/ENVIRONMENT:
```Provide where applicable
## Your Python & SDK version:
## Environment definition:
## Notebook name or Python scripts:
## Run and Workspace Id:
## Pipeline definition:
## Example data:
## Any log files:
```

View File

@@ -1,8 +1,17 @@
---
page_type: sample
languages:
- python
products:
- azure
- azure-machine-learning-service
description: "With Azure Machine Learning service, learn to prep data, train, test, deploy, manage, and track machine learning models in a cloud-based environment."
---
# Azure Machine Learning service example notebooks # Azure Machine Learning service example notebooks
This repository contains example notebooks demonstrating the [Azure Machine Learning](https://azure.microsoft.com/en-us/services/machine-learning-service/) Python SDK which allows you to build, train, deploy and manage machine learning solutions using Azure. The AML SDK allows you the choice of using local or cloud compute resources, while managing and maintaining the complete data science workflow from the cloud. This repository contains example notebooks demonstrating the [Azure Machine Learning](https://azure.microsoft.com/en-us/services/machine-learning-service/) Python SDK which allows you to build, train, deploy and manage machine learning solutions using Azure. The AML SDK allows you the choice of using local or cloud compute resources, while managing and maintaining the complete data science workflow from the cloud.
![Azure ML workflow](https://raw.githubusercontent.com/MicrosoftDocs/azure-docs/master/articles/machine-learning/service/media/overview-what-is-azure-ml/aml.png)
## Quick installation ## Quick installation
```sh ```sh

View File

@@ -103,7 +103,7 @@
"source": [ "source": [
"import azureml.core\n", "import azureml.core\n",
"\n", "\n",
"print(\"This notebook was created using version 1.0.55 of the Azure ML SDK\")\n", "print(\"This notebook was created using version 1.0.57 of the Azure ML SDK\")\n",
"print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")" "print(\"You are currently using version\", azureml.core.VERSION, \"of the Azure ML SDK\")"
] ]
}, },

View File

@@ -1,723 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Track Data Drift between Training and Inference Data in Production \n",
"\n",
"With this notebook, you will learn how to enable the DataDrift service to automatically track and determine whether your inference data is drifting from the data your model was initially trained on. The DataDrift service provides metrics and visualizations to help stakeholders identify which specific features cause the concept drift to occur.\n",
"\n",
"Please email driftfeedback@microsoft.com with any issues. A member from the DataDrift team will respond shortly. \n",
"\n",
"The DataDrift Public Preview API can be found [here](https://docs.microsoft.com/en-us/python/api/azureml-contrib-datadrift/?view=azure-ml-py). "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/contrib/datadrift/azureml-datadrift.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Prerequisites and Setup"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Install the DataDrift package\n",
"\n",
"Install the azureml-contrib-datadrift, azureml-opendatasets and lightgbm packages before running this notebook.\n",
"```\n",
"pip install azureml-contrib-datadrift\n",
"pip install lightgbm\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Import Dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"import os\n",
"import time\n",
"from datetime import datetime, timedelta\n",
"\n",
"import numpy as np\n",
"import pandas as pd\n",
"import requests\n",
"from azureml.contrib.datadrift import DataDriftDetector, AlertConfiguration\n",
"from azureml.opendatasets import NoaaIsdWeather\n",
"from azureml.core import Dataset, Workspace, Run\n",
"from azureml.core.compute import AksCompute, ComputeTarget\n",
"from azureml.core.conda_dependencies import CondaDependencies\n",
"from azureml.core.experiment import Experiment\n",
"from azureml.core.image import ContainerImage\n",
"from azureml.core.model import Model\n",
"from azureml.core.webservice import Webservice, AksWebservice\n",
"from azureml.widgets import RunDetails\n",
"from sklearn.externals import joblib\n",
"from sklearn.model_selection import train_test_split\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Set up Configuraton and Create Azure ML Workspace\n",
"\n",
"If you are using an Azure Machine Learning Notebook VM, you are all set. Otherwise, go through the [configuration notebook](../../../configuration.ipynb) first if you haven't already to establish your connection to the AzureML Workspace."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Please type in your initials/alias. The prefix is prepended to the names of resources created by this notebook. \n",
"prefix = \"dd\"\n",
"\n",
"# NOTE: Please do not change the model_name, as it's required by the score.py file\n",
"model_name = \"driftmodel\"\n",
"image_name = \"{}driftimage\".format(prefix)\n",
"service_name = \"{}driftservice\".format(prefix)\n",
"\n",
"# optionally, set email address to receive an email alert for DataDrift\n",
"email_address = \"\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ws = Workspace.from_config()\n",
"print(ws.name, ws.resource_group, ws.location, ws.subscription_id, sep = '\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Generate Train/Testing Data\n",
"\n",
"For this demo, we will use NOAA weather data from [Azure Open Datasets](https://azure.microsoft.com/services/open-datasets/). You may replace this step with your own dataset. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"usaf_list = ['725724', '722149', '723090', '722159', '723910', '720279',\n",
" '725513', '725254', '726430', '720381', '723074', '726682',\n",
" '725486', '727883', '723177', '722075', '723086', '724053',\n",
" '725070', '722073', '726060', '725224', '725260', '724520',\n",
" '720305', '724020', '726510', '725126', '722523', '703333',\n",
" '722249', '722728', '725483', '722972', '724975', '742079',\n",
" '727468', '722193', '725624', '722030', '726380', '720309',\n",
" '722071', '720326', '725415', '724504', '725665', '725424',\n",
" '725066']\n",
"\n",
"columns = ['usaf', 'wban', 'datetime', 'latitude', 'longitude', 'elevation', 'windAngle', 'windSpeed', 'temperature', 'stationName', 'p_k']\n",
"\n",
"\n",
"def enrich_weather_noaa_data(noaa_df):\n",
" hours_in_day = 23\n",
" week_in_year = 52\n",
" \n",
" noaa_df[\"hour\"] = noaa_df[\"datetime\"].dt.hour\n",
" noaa_df[\"weekofyear\"] = noaa_df[\"datetime\"].dt.week\n",
" \n",
" noaa_df[\"sine_weekofyear\"] = noaa_df['datetime'].transform(lambda x: np.sin((2*np.pi*x.dt.week-1)/week_in_year))\n",
" noaa_df[\"cosine_weekofyear\"] = noaa_df['datetime'].transform(lambda x: np.cos((2*np.pi*x.dt.week-1)/week_in_year))\n",
"\n",
" noaa_df[\"sine_hourofday\"] = noaa_df['datetime'].transform(lambda x: np.sin(2*np.pi*x.dt.hour/hours_in_day))\n",
" noaa_df[\"cosine_hourofday\"] = noaa_df['datetime'].transform(lambda x: np.cos(2*np.pi*x.dt.hour/hours_in_day))\n",
" \n",
" return noaa_df\n",
"\n",
"def add_window_col(input_df):\n",
" shift_interval = pd.Timedelta('-7 days') # your X days interval\n",
" df_shifted = input_df.copy()\n",
" df_shifted['datetime'] = df_shifted['datetime'] - shift_interval\n",
" df_shifted.drop(list(input_df.columns.difference(['datetime', 'usaf', 'wban', 'sine_hourofday', 'temperature'])), axis=1, inplace=True)\n",
"\n",
" # merge, keeping only observations where -1 lag is present\n",
" df2 = pd.merge(input_df,\n",
" df_shifted,\n",
" on=['datetime', 'usaf', 'wban', 'sine_hourofday'],\n",
" how='inner', # use 'left' to keep observations without lags\n",
" suffixes=['', '-7'])\n",
" return df2\n",
"\n",
"def get_noaa_data(start_time, end_time, cols, station_list):\n",
" isd = NoaaIsdWeather(start_time, end_time, cols=cols)\n",
" # Read into Pandas data frame.\n",
" noaa_df = isd.to_pandas_dataframe()\n",
" noaa_df = noaa_df.rename(columns={\"stationName\": \"station_name\"})\n",
" \n",
" df_filtered = noaa_df[noaa_df[\"usaf\"].isin(station_list)]\n",
" df_filtered.reset_index(drop=True)\n",
" \n",
" # Enrich with time features\n",
" df_enriched = enrich_weather_noaa_data(df_filtered)\n",
" \n",
" return df_enriched\n",
"\n",
"def get_featurized_noaa_df(start_time, end_time, cols, station_list):\n",
" df_1 = get_noaa_data(start_time - timedelta(days=7), start_time - timedelta(seconds=1), cols, station_list)\n",
" df_2 = get_noaa_data(start_time, end_time, cols, station_list)\n",
" noaa_df = pd.concat([df_1, df_2])\n",
" \n",
" print(\"Adding window feature\")\n",
" df_window = add_window_col(noaa_df)\n",
" \n",
" cat_columns = df_window.dtypes == object\n",
" cat_columns = cat_columns[cat_columns == True]\n",
" \n",
" print(\"Encoding categorical columns\")\n",
" df_encoded = pd.get_dummies(df_window, columns=cat_columns.keys().tolist())\n",
" \n",
" print(\"Dropping unnecessary columns\")\n",
" df_featurized = df_encoded.drop(['windAngle', 'windSpeed', 'datetime', 'elevation'], axis=1).dropna().drop_duplicates()\n",
" \n",
" return df_featurized"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Train model on Jan 1 - 14, 2009 data\n",
"df = get_featurized_noaa_df(datetime(2009, 1, 1), datetime(2009, 1, 14, 23, 59, 59), columns, usaf_list)\n",
"df.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"label = \"temperature\"\n",
"x_df = df.drop(label, axis=1)\n",
"y_df = df[[label]]\n",
"x_train, x_test, y_train, y_test = train_test_split(df, y_df, test_size=0.2, random_state=223)\n",
"print(x_train.shape, x_test.shape, y_train.shape, y_test.shape)\n",
"\n",
"training_dir = 'outputs/training'\n",
"training_file = \"training.csv\"\n",
"\n",
"# Generate training dataframe to register as Training Dataset\n",
"os.makedirs(training_dir, exist_ok=True)\n",
"training_df = pd.merge(x_train.drop(label, axis=1), y_train, left_index=True, right_index=True)\n",
"training_df.to_csv(training_dir + \"/\" + training_file)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create/Register Training Dataset"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"dataset_name = \"dataset\"\n",
"name_suffix = datetime.utcnow().strftime(\"%Y-%m-%d-%H-%M-%S\")\n",
"snapshot_name = \"snapshot-{}\".format(name_suffix)\n",
"\n",
"dstore = ws.get_default_datastore()\n",
"dstore.upload(training_dir, \"data/training\", show_progress=True)\n",
"dpath = dstore.path(\"data/training/training.csv\")\n",
"trainingDataset = Dataset.auto_read_files(dpath, include_path=True)\n",
"trainingDataset = trainingDataset.register(workspace=ws, name=dataset_name, description=\"dset\", exist_ok=True)\n",
"\n",
"datasets = [(Dataset.Scenario.TRAINING, trainingDataset)]\n",
"print(\"dataset registration done.\\n\")\n",
"datasets"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Train and Save Model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import lightgbm as lgb\n",
"\n",
"train = lgb.Dataset(data=x_train, \n",
" label=y_train)\n",
"\n",
"test = lgb.Dataset(data=x_test, \n",
" label=y_test,\n",
" reference=train)\n",
"\n",
"params = {'learning_rate' : 0.1,\n",
" 'boosting' : 'gbdt',\n",
" 'metric' : 'rmse',\n",
" 'feature_fraction' : 1,\n",
" 'bagging_fraction' : 1,\n",
" 'max_depth': 6,\n",
" 'num_leaves' : 31,\n",
" 'objective' : 'regression',\n",
" 'bagging_freq' : 1,\n",
" \"verbose\": -1,\n",
" 'min_data_per_leaf': 100}\n",
"\n",
"model = lgb.train(params, \n",
" num_boost_round=500,\n",
" train_set=train,\n",
" valid_sets=[train, test],\n",
" verbose_eval=50,\n",
" early_stopping_rounds=25)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model_file = 'outputs/{}.pkl'.format(model_name)\n",
"\n",
"os.makedirs('outputs', exist_ok=True)\n",
"joblib.dump(model, model_file)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Register Model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model = Model.register(model_path=model_file,\n",
" model_name=model_name,\n",
" workspace=ws,\n",
" datasets=datasets)\n",
"\n",
"print(model_name, image_name, service_name, model)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Deploy Model To AKS"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Prepare Environment"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn', 'joblib', 'lightgbm', 'pandas'],\n",
" pip_packages=['azureml-monitoring', 'azureml-sdk[automl]'])\n",
"\n",
"with open(\"myenv.yml\",\"w\") as f:\n",
" f.write(myenv.serialize_to_string())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create Image"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Image creation may take up to 15 minutes.\n",
"\n",
"image_name = image_name + str(model.version)\n",
"\n",
"if not image_name in ws.images:\n",
" # Use the score.py defined in this directory as the execution script\n",
" # NOTE: The Model Data Collector must be enabled in the execution script for DataDrift to run correctly\n",
" image_config = ContainerImage.image_configuration(execution_script=\"score.py\",\n",
" runtime=\"python\",\n",
" conda_file=\"myenv.yml\",\n",
" description=\"Image with weather dataset model\")\n",
" image = ContainerImage.create(name=image_name,\n",
" models=[model],\n",
" image_config=image_config,\n",
" workspace=ws)\n",
"\n",
" image.wait_for_creation(show_output=True)\n",
"else:\n",
" image = ws.images[image_name]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create Compute Target"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"aks_name = 'dd-demo-e2e'\n",
"prov_config = AksCompute.provisioning_configuration()\n",
"\n",
"if not aks_name in ws.compute_targets:\n",
" aks_target = ComputeTarget.create(workspace=ws,\n",
" name=aks_name,\n",
" provisioning_configuration=prov_config)\n",
"\n",
" aks_target.wait_for_completion(show_output=True)\n",
" print(aks_target.provisioning_state)\n",
" print(aks_target.provisioning_errors)\n",
"else:\n",
" aks_target=ws.compute_targets[aks_name]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Deploy Service"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"aks_service_name = service_name\n",
"\n",
"if not aks_service_name in ws.webservices:\n",
" aks_config = AksWebservice.deploy_configuration(collect_model_data=True, enable_app_insights=True)\n",
" aks_service = Webservice.deploy_from_image(workspace=ws,\n",
" name=aks_service_name,\n",
" image=image,\n",
" deployment_config=aks_config,\n",
" deployment_target=aks_target)\n",
" aks_service.wait_for_deployment(show_output=True)\n",
" print(aks_service.state)\n",
"else:\n",
" aks_service = ws.webservices[aks_service_name]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Run DataDrift Analysis"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Send Scoring Data to Service"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Download Scoring Data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Score Model on March 15, 2016 data\n",
"scoring_df = get_noaa_data(datetime(2016, 3, 15) - timedelta(days=7), datetime(2016, 3, 16), columns, usaf_list)\n",
"# Add the window feature column\n",
"scoring_df = add_window_col(scoring_df)\n",
"\n",
"# Drop features not used by the model\n",
"print(\"Dropping unnecessary columns\")\n",
"scoring_df = scoring_df.drop(['windAngle', 'windSpeed', 'datetime', 'elevation'], axis=1).dropna()\n",
"scoring_df.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# One Hot Encode the scoring dataset to match the training dataset schema\n",
"columns_dict = model.datasets[\"training\"][0].get_profile().columns\n",
"extra_cols = ('Path', 'Column1')\n",
"for k in extra_cols:\n",
" columns_dict.pop(k, None)\n",
"training_columns = list(columns_dict.keys())\n",
"\n",
"categorical_columns = scoring_df.dtypes == object\n",
"categorical_columns = categorical_columns[categorical_columns == True]\n",
"\n",
"test_df = pd.get_dummies(scoring_df[categorical_columns.keys().tolist()])\n",
"encoded_df = scoring_df.join(test_df)\n",
"\n",
"# Populate missing OHE columns with 0 values to match traning dataset schema\n",
"difference = list(set(training_columns) - set(encoded_df.columns.tolist()))\n",
"for col in difference:\n",
" encoded_df[col] = 0\n",
"encoded_df.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Serialize dataframe to list of row dictionaries\n",
"encoded_dict = encoded_df.to_dict('records')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Submit Scoring Data to Service"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%time\n",
"\n",
"# retreive the API keys. AML generates two keys.\n",
"key1, key2 = aks_service.get_keys()\n",
"\n",
"total_count = len(scoring_df)\n",
"i = 0\n",
"load = []\n",
"for row in encoded_dict:\n",
" load.append(row)\n",
" i = i + 1\n",
" if i % 100 == 0:\n",
" payload = json.dumps({\"data\": load})\n",
" \n",
" # construct raw HTTP request and send to the service\n",
" payload_binary = bytes(payload,encoding = 'utf8')\n",
" headers = {'Content-Type':'application/json', 'Authorization': 'Bearer ' + key1}\n",
" resp = requests.post(aks_service.scoring_uri, payload_binary, headers=headers)\n",
" \n",
" print(\"prediction:\", resp.content, \"Progress: {}/{}\".format(i, total_count)) \n",
"\n",
" load = []\n",
" time.sleep(3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We need to wait up to 10 minutes for the Model Data Collector to dump the model input and inference data to storage in the Workspace, where it's used by the DataDriftDetector job."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"time.sleep(600)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Configure DataDrift"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"services = [service_name]\n",
"start = datetime.now() - timedelta(days=2)\n",
"end = datetime(year=2020, month=1, day=22, hour=15, minute=16)\n",
"feature_list = ['usaf', 'wban', 'latitude', 'longitude', 'station_name', 'p_k', 'sine_hourofday', 'cosine_hourofday', 'temperature-7']\n",
"alert_config = AlertConfiguration([email_address]) if email_address else None\n",
"\n",
"# there will be an exception indicating using get() method if DataDrift object already exist\n",
"try:\n",
" datadrift = DataDriftDetector.create(ws, model.name, model.version, services, frequency=\"Day\", alert_config=alert_config)\n",
"except KeyError:\n",
" datadrift = DataDriftDetector.get(ws, model.name, model.version)\n",
" \n",
"print(\"Details of DataDrift Object:\\n{}\".format(datadrift))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Run an Adhoc DataDriftDetector Run"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"target_date = datetime.today()\n",
"run = datadrift.run(target_date, services, feature_list=feature_list, create_compute_target=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"exp = Experiment(ws, datadrift._id)\n",
"dd_run = Run(experiment=exp, run_id=run)\n",
"RunDetails(dd_run).show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Get Drift Analysis Results"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"children = list(dd_run.get_children())\n",
"for child in children:\n",
" child.wait_for_completion()\n",
"\n",
"drift_metrics = datadrift.get_output(start_time=start, end_time=end)\n",
"drift_metrics"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Show all drift figures, one per serivice.\n",
"# If setting with_details is False (by default), only drift will be shown; if it's True, all details will be shown.\n",
"\n",
"drift_figures = datadrift.show(with_details=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Enable DataDrift Schedule"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"datadrift.enable_schedule()"
]
}
],
"metadata": {
"authors": [
{
"name": "rafarmah"
}
],
"kernelspec": {
"display_name": "Python 3.6",
"language": "python",
"name": "python36"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -1,8 +0,0 @@
name: azure-ml-datadrift
dependencies:
- pip:
- azureml-sdk
- azureml-contrib-datadrift
- azureml-opendatasets
- lightgbm
- azureml-widgets

View File

@@ -1,58 +0,0 @@
import pickle
import json
import numpy
import azureml.train.automl
from sklearn.externals import joblib
from sklearn.linear_model import Ridge
from azureml.core.model import Model
from azureml.core.run import Run
from azureml.monitoring import ModelDataCollector
import time
import pandas as pd
def init():
global model, inputs_dc, prediction_dc, feature_names, categorical_features
print("Model is initialized" + time.strftime("%H:%M:%S"))
model_path = Model.get_model_path(model_name="driftmodel")
model = joblib.load(model_path)
feature_names = ["usaf", "wban", "latitude", "longitude", "station_name", "p_k",
"sine_weekofyear", "cosine_weekofyear", "sine_hourofday", "cosine_hourofday",
"temperature-7"]
categorical_features = ["usaf", "wban", "p_k", "station_name"]
inputs_dc = ModelDataCollector(model_name="driftmodel",
identifier="inputs",
feature_names=feature_names)
prediction_dc = ModelDataCollector("driftmodel",
identifier="predictions",
feature_names=["temperature"])
def run(raw_data):
global inputs_dc, prediction_dc
try:
data = json.loads(raw_data)["data"]
data = pd.DataFrame(data)
# Remove the categorical features as the model expects OHE values
input_data = data.drop(categorical_features, axis=1)
result = model.predict(input_data)
# Collect the non-OHE dataframe
collected_df = data[feature_names]
inputs_dc.collect(collected_df.values)
prediction_dc.collect(result)
return result.tolist()
except Exception as e:
error = str(e)
print(error + time.strftime("%H:%M:%S"))
return error

View File

@@ -8,7 +8,7 @@ As a pre-requisite, run the [configuration Notebook](../configuration.ipynb) not
* [train-on-local](./training/train-on-local): Learn how to submit a run to local computer and use Azure ML managed run configuration. * [train-on-local](./training/train-on-local): Learn how to submit a run to local computer and use Azure ML managed run configuration.
* [train-on-amlcompute](./training/train-on-amlcompute): Use a 1-n node Azure ML managed compute cluster for remote runs on Azure CPU or GPU infrastructure. * [train-on-amlcompute](./training/train-on-amlcompute): Use a 1-n node Azure ML managed compute cluster for remote runs on Azure CPU or GPU infrastructure.
* [train-on-remote-vm](./training/train-on-remote-vm): Use Data Science Virtual Machine as a target for remote runs. * [train-on-remote-vm](./training/train-on-remote-vm): Use Data Science Virtual Machine as a target for remote runs.
* [logging-api](./training/logging-api): Learn about the details of logging metrics to run history. * [logging-api](./track-and-monitor-experiments/logging-api): Learn about the details of logging metrics to run history.
* [register-model-create-image-deploy-service](./deployment/register-model-create-image-deploy-service): Learn about the details of model management. * [register-model-create-image-deploy-service](./deployment/register-model-create-image-deploy-service): Learn about the details of model management.
* [production-deploy-to-aks](./deployment/production-deploy-to-aks) Deploy a model to production at scale on Azure Kubernetes Service. * [production-deploy-to-aks](./deployment/production-deploy-to-aks) Deploy a model to production at scale on Azure Kubernetes Service.
* [enable-data-collection-for-models-in-aks](./deployment/enable-data-collection-for-models-in-aks) Learn about data collection APIs for deployed model. * [enable-data-collection-for-models-in-aks](./deployment/enable-data-collection-for-models-in-aks) Learn about data collection APIs for deployed model.

View File

@@ -155,11 +155,11 @@ jupyter notebook
- [auto-ml-subsampling-local.ipynb](subsampling/auto-ml-subsampling-local.ipynb) - [auto-ml-subsampling-local.ipynb](subsampling/auto-ml-subsampling-local.ipynb)
- How to enable subsampling - How to enable subsampling
- [auto-ml-dataprep.ipynb](dataprep/auto-ml-dataprep.ipynb) - [auto-ml-dataset.ipynb](dataprep/auto-ml-dataset.ipynb)
- Using DataPrep for reading data - Using Dataset for reading data
- [auto-ml-dataprep-remote-execution.ipynb](dataprep-remote-execution/auto-ml-dataprep-remote-execution.ipynb) - [auto-ml-dataset-remote-execution.ipynb](dataprep-remote-execution/auto-ml-dataset-remote-execution.ipynb)
- Using DataPrep for reading data with remote execution - Using Dataset for reading data with remote execution
- [auto-ml-classification-with-whitelisting.ipynb](classification-with-whitelisting/auto-ml-classification-with-whitelisting.ipynb) - [auto-ml-classification-with-whitelisting.ipynb](classification-with-whitelisting/auto-ml-classification-with-whitelisting.ipynb)
- Dataset: scikit learn's [digit dataset](http://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_digits.html#sklearn.datasets.load_digits) - Dataset: scikit learn's [digit dataset](http://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_digits.html#sklearn.datasets.load_digits)

View File

@@ -13,10 +13,13 @@ dependencies:
- scikit-learn>=0.19.0,<=0.20.3 - scikit-learn>=0.19.0,<=0.20.3
- pandas>=0.22.0,<=0.23.4 - pandas>=0.22.0,<=0.23.4
- py-xgboost<=0.80 - py-xgboost<=0.80
- pyarrow>=0.11.0
- pip: - pip:
# Required packages for AzureML execution, history, and data preparation. # Required packages for AzureML execution, history, and data preparation.
- azureml-sdk[automl,explain] - azureml-defaults
- azureml-train-automl
- azureml-widgets - azureml-widgets
- azureml-explain-model
- pandas_ml - pandas_ml

View File

@@ -14,10 +14,13 @@ dependencies:
- scikit-learn>=0.19.0,<=0.20.3 - scikit-learn>=0.19.0,<=0.20.3
- pandas>=0.22.0,<0.23.0 - pandas>=0.22.0,<0.23.0
- py-xgboost<=0.80 - py-xgboost<=0.80
- pyarrow>=0.11.0
- pip: - pip:
# Required packages for AzureML execution, history, and data preparation. # Required packages for AzureML execution, history, and data preparation.
- azureml-sdk[automl,explain] - azureml-defaults
- azureml-train-automl
- azureml-widgets - azureml-widgets
- azureml-explain-model
- pandas_ml - pandas_ml

View File

@@ -69,22 +69,17 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"import json\n",
"import logging\n", "import logging\n",
"\n", "\n",
"from matplotlib import pyplot as plt\n", "from matplotlib import pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n", "import pandas as pd\n",
"import os\n", "import os\n",
"from sklearn import datasets\n",
"import azureml.dataprep as dprep\n",
"from sklearn.model_selection import train_test_split\n",
"\n", "\n",
"import azureml.core\n", "import azureml.core\n",
"from azureml.core.experiment import Experiment\n", "from azureml.core.experiment import Experiment\n",
"from azureml.core.workspace import Workspace\n", "from azureml.core.workspace import Workspace\n",
"from azureml.train.automl import AutoMLConfig\n", "from azureml.core.dataset import Dataset\n",
"from azureml.train.automl.run import AutoMLRun" "from azureml.train.automl import AutoMLConfig"
] ]
}, },
{ {
@@ -155,11 +150,12 @@
" # Create the cluster.\n", " # Create the cluster.\n",
" compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n", " compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n",
" \n", " \n",
" # Can poll for a minimum number of nodes and for a specific timeout.\n", "print('Checking cluster status...')\n",
" # If no min_node_count is provided, it will use the scale settings for the cluster.\n", "# Can poll for a minimum number of nodes and for a specific timeout.\n",
" compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n", "# If no min_node_count is provided, it will use the scale settings for the cluster.\n",
"compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n",
" \n", " \n",
" # For a more detailed view of current AmlCompute status, use get_status()." "# For a more detailed view of current AmlCompute status, use get_status()."
] ]
}, },
{ {
@@ -200,11 +196,8 @@
"# Set compute target to AmlCompute\n", "# Set compute target to AmlCompute\n",
"conda_run_config.target = compute_target\n", "conda_run_config.target = compute_target\n",
"conda_run_config.environment.docker.enabled = True\n", "conda_run_config.environment.docker.enabled = True\n",
"conda_run_config.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE\n",
"\n", "\n",
"dprep_dependency = 'azureml-dataprep==' + pkg_resources.get_distribution(\"azureml-dataprep\").version\n", "cd = CondaDependencies.create(conda_packages=['numpy','py-xgboost<=0.80'])\n",
"\n",
"cd = CondaDependencies.create(pip_packages=['azureml-sdk[automl]', dprep_dependency], conda_packages=['numpy','py-xgboost<=0.80'])\n",
"conda_run_config.environment.python.conda_dependencies = cd" "conda_run_config.environment.python.conda_dependencies = cd"
] ]
}, },
@@ -224,11 +217,10 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/bankmarketing_train.csv\"\n", "data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/bankmarketing_train.csv\"\n",
"dflow = dprep.read_csv(data, infer_column_types=True)\n", "dataset = Dataset.Tabular.from_delimited_files(data)\n",
"dflow.get_profile()\n", "X_train = dataset.drop_columns(columns=['y'])\n",
"X_train = dflow.drop_columns(columns=['y'])\n", "y_train = dataset.keep_columns(columns=['y'], validate=True)\n",
"y_train = dflow.keep_columns(columns=['y'], validate_column_exists=True)\n", "dataset.take(5).to_pandas_dataframe()"
"dflow.head()"
] ]
}, },
{ {
@@ -406,7 +398,7 @@
"def run(rawdata):\n", "def run(rawdata):\n",
" try:\n", " try:\n",
" data = json.loads(rawdata)['data']\n", " data = json.loads(rawdata)['data']\n",
" data = numpy.array(data)\n", " data = np.array(data)\n",
" result = model.predict(data)\n", " result = model.predict(data)\n",
" except Exception as e:\n", " except Exception as e:\n",
" result = str(e)\n", " result = str(e)\n",
@@ -443,7 +435,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"for p in ['azureml-train-automl', 'azureml-sdk', 'azureml-core']:\n", "for p in ['azureml-train-automl', 'azureml-core']:\n",
" print('{}\\t{}'.format(p, dependencies[p]))" " print('{}\\t{}'.format(p, dependencies[p]))"
] ]
}, },
@@ -453,10 +445,8 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.conda_dependencies import CondaDependencies\n",
"\n",
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn','py-xgboost<=0.80'],\n", "myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn','py-xgboost<=0.80'],\n",
" pip_packages=['azureml-sdk[automl]'])\n", " pip_packages=['azureml-train-automl'])\n",
"\n", "\n",
"conda_env_file_name = 'myenv.yml'\n", "conda_env_file_name = 'myenv.yml'\n",
"myenv.save_to_file('.', conda_env_file_name)" "myenv.save_to_file('.', conda_env_file_name)"
@@ -476,7 +466,7 @@
" content = cefr.read()\n", " content = cefr.read()\n",
"\n", "\n",
"with open(conda_env_file_name, 'w') as cefw:\n", "with open(conda_env_file_name, 'w') as cefw:\n",
" cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-sdk']))\n", " cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-train-automl']))\n",
"\n", "\n",
"# Substitute the actual model id in the script file.\n", "# Substitute the actual model id in the script file.\n",
"\n", "\n",
@@ -618,8 +608,6 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# Load the bank marketing datasets.\n", "# Load the bank marketing datasets.\n",
"from sklearn.datasets import load_diabetes\n",
"from sklearn.model_selection import train_test_split\n",
"from numpy import array" "from numpy import array"
] ]
}, },
@@ -630,11 +618,10 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/bankmarketing_validate.csv\"\n", "data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/bankmarketing_validate.csv\"\n",
"dflow = dprep.read_csv(data, infer_column_types=True)\n", "dataset = Dataset.Tabular.from_delimited_files(data)\n",
"dflow.get_profile()\n", "X_test = dataset.drop_columns(columns=['y'])\n",
"X_test = dflow.drop_columns(columns=['y'])\n", "y_test = dataset.keep_columns(columns=['y'], validate=True)\n",
"y_test = dflow.keep_columns(columns=['y'], validate_column_exists=True)\n", "dataset.take(5).to_pandas_dataframe()"
"dflow.head()"
] ]
}, },
{ {

View File

@@ -2,6 +2,8 @@ name: auto-ml-classification-bank-marketing
dependencies: dependencies:
- pip: - pip:
- azureml-sdk - azureml-sdk
- azureml-defaults
- azureml-explain-model
- azureml-train-automl - azureml-train-automl
- azureml-widgets - azureml-widgets
- matplotlib - matplotlib

View File

@@ -74,14 +74,12 @@
"from matplotlib import pyplot as plt\n", "from matplotlib import pyplot as plt\n",
"import pandas as pd\n", "import pandas as pd\n",
"import os\n", "import os\n",
"from sklearn.model_selection import train_test_split\n",
"import azureml.dataprep as dprep\n",
"\n", "\n",
"import azureml.core\n", "import azureml.core\n",
"from azureml.core.experiment import Experiment\n", "from azureml.core.experiment import Experiment\n",
"from azureml.core.workspace import Workspace\n", "from azureml.core.workspace import Workspace\n",
"from azureml.train.automl import AutoMLConfig\n", "from azureml.core.dataset import Dataset\n",
"from azureml.train.automl.run import AutoMLRun" "from azureml.train.automl import AutoMLConfig"
] ]
}, },
{ {
@@ -152,11 +150,12 @@
" # Create the cluster.\n", " # Create the cluster.\n",
" compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n", " compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n",
" \n", " \n",
" # Can poll for a minimum number of nodes and for a specific timeout.\n", "print('Checking cluster status...')\n",
" # If no min_node_count is provided, it will use the scale settings for the cluster.\n", "# Can poll for a minimum number of nodes and for a specific timeout.\n",
" compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n", "# If no min_node_count is provided, it will use the scale settings for the cluster.\n",
" \n", "compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n",
" # For a more detailed view of current AmlCompute status, use get_status()." "\n",
"# For a more detailed view of current AmlCompute status, use get_status()."
] ]
}, },
{ {
@@ -197,11 +196,8 @@
"# Set compute target to AmlCompute\n", "# Set compute target to AmlCompute\n",
"conda_run_config.target = compute_target\n", "conda_run_config.target = compute_target\n",
"conda_run_config.environment.docker.enabled = True\n", "conda_run_config.environment.docker.enabled = True\n",
"conda_run_config.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE\n",
"\n", "\n",
"dprep_dependency = 'azureml-dataprep==' + pkg_resources.get_distribution(\"azureml-dataprep\").version\n", "cd = CondaDependencies.create(conda_packages=['numpy','py-xgboost<=0.80'])\n",
"\n",
"cd = CondaDependencies.create(pip_packages=['azureml-sdk[automl]', dprep_dependency], conda_packages=['numpy','py-xgboost<=0.80'])\n",
"conda_run_config.environment.python.conda_dependencies = cd" "conda_run_config.environment.python.conda_dependencies = cd"
] ]
}, },
@@ -211,7 +207,7 @@
"source": [ "source": [
"### Load Data\n", "### Load Data\n",
"\n", "\n",
"Here create the script to be run in azure compute for loading the data, load the credit card dataset into cards and store the Class column (y) in the y variable and store the remaining data in the x variable. Next split the data using train_test_split and return X_train and y_train for training the model." "Here create the script to be run in azure compute for loading the data, load the credit card dataset into cards and store the Class column (y) in the y variable and store the remaining data in the x variable. Next split the data using random_split and return X_train and y_train for training the model."
] ]
}, },
{ {
@@ -221,10 +217,9 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/creditcard.csv\"\n", "data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/creditcard.csv\"\n",
"dflow = dprep.read_csv(data, infer_column_types=True)\n", "dataset = Dataset.Tabular.from_delimited_files(data)\n",
"dflow.get_profile()\n", "X = dataset.drop_columns(columns=['Class'])\n",
"X = dflow.drop_columns(columns=['Class'])\n", "y = dataset.keep_columns(columns=['Class'], validate=True)\n",
"y = dflow.keep_columns(columns=['Class'], validate_column_exists=True)\n",
"X_train, X_test = X.random_split(percentage=0.8, seed=223)\n", "X_train, X_test = X.random_split(percentage=0.8, seed=223)\n",
"y_train, y_test = y.random_split(percentage=0.8, seed=223)" "y_train, y_test = y.random_split(percentage=0.8, seed=223)"
] ]
@@ -447,7 +442,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"for p in ['azureml-train-automl', 'azureml-sdk', 'azureml-core']:\n", "for p in ['azureml-train-automl', 'azureml-core']:\n",
" print('{}\\t{}'.format(p, dependencies[p]))" " print('{}\\t{}'.format(p, dependencies[p]))"
] ]
}, },
@@ -458,7 +453,7 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn','py-xgboost<=0.80'],\n", "myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn','py-xgboost<=0.80'],\n",
" pip_packages=['azureml-sdk[automl]'])\n", " pip_packages=['azureml-train-automl'])\n",
"\n", "\n",
"conda_env_file_name = 'myenv.yml'\n", "conda_env_file_name = 'myenv.yml'\n",
"myenv.save_to_file('.', conda_env_file_name)" "myenv.save_to_file('.', conda_env_file_name)"
@@ -478,7 +473,7 @@
" content = cefr.read()\n", " content = cefr.read()\n",
"\n", "\n",
"with open(conda_env_file_name, 'w') as cefw:\n", "with open(conda_env_file_name, 'w') as cefw:\n",
" cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-sdk']))\n", " cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-train-automl']))\n",
"\n", "\n",
"# Substitute the actual model id in the script file.\n", "# Substitute the actual model id in the script file.\n",
"\n", "\n",

View File

@@ -2,6 +2,8 @@ name: auto-ml-classification-credit-card-fraud
dependencies: dependencies:
- pip: - pip:
- azureml-sdk - azureml-sdk
- azureml-defaults
- azureml-explain-model
- azureml-train-automl - azureml-train-automl
- azureml-widgets - azureml-widgets
- matplotlib - matplotlib

View File

@@ -297,7 +297,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"for p in ['azureml-train-automl', 'azureml-sdk', 'azureml-core']:\n", "for p in ['azureml-train-automl', 'azureml-core']:\n",
" print('{}\\t{}'.format(p, dependencies[p]))" " print('{}\\t{}'.format(p, dependencies[p]))"
] ]
}, },
@@ -310,7 +310,7 @@
"from azureml.core.conda_dependencies import CondaDependencies\n", "from azureml.core.conda_dependencies import CondaDependencies\n",
"\n", "\n",
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn','py-xgboost<=0.80'],\n", "myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn','py-xgboost<=0.80'],\n",
" pip_packages=['azureml-sdk[automl]'])\n", " pip_packages=['azureml-train-automl'])\n",
"\n", "\n",
"conda_env_file_name = 'myenv.yml'\n", "conda_env_file_name = 'myenv.yml'\n",
"myenv.save_to_file('.', conda_env_file_name)" "myenv.save_to_file('.', conda_env_file_name)"
@@ -330,7 +330,7 @@
" content = cefr.read()\n", " content = cefr.read()\n",
"\n", "\n",
"with open(conda_env_file_name, 'w') as cefw:\n", "with open(conda_env_file_name, 'w') as cefw:\n",
" cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-sdk']))\n", " cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-train-automl']))\n",
"\n", "\n",
"# Substitute the actual model id in the script file.\n", "# Substitute the actual model id in the script file.\n",
"\n", "\n",

View File

@@ -21,7 +21,7 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"# Automated Machine Learning\n", "# Automated Machine Learning\n",
"_**Prepare Data using `azureml.dataprep` for Remote Execution (AmlCompute)**_\n", "_**Load Data using `TabularDataset` for Remote Execution (AmlCompute)**_\n",
"\n", "\n",
"## Contents\n", "## Contents\n",
"1. [Introduction](#Introduction)\n", "1. [Introduction](#Introduction)\n",
@@ -37,23 +37,20 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Introduction\n", "## Introduction\n",
"In this example we showcase how you can use the `azureml.dataprep` SDK to load and prepare data for AutoML. `azureml.dataprep` can also be used standalone; full documentation can be found [here](https://github.com/Microsoft/PendletonDocs).\n", "In this example we showcase how you can use AzureML Dataset to load data for AutoML.\n",
"\n", "\n",
"Make sure you have executed the [configuration](../../../configuration.ipynb) before running this notebook.\n", "Make sure you have executed the [configuration](../../../configuration.ipynb) before running this notebook.\n",
"\n", "\n",
"In this notebook you will learn how to:\n", "In this notebook you will learn how to:\n",
"1. Define data loading and preparation steps in a `Dataflow` using `azureml.dataprep`.\n", "1. Create a `TabularDataset` pointing to the training data.\n",
"2. Pass the `Dataflow` to AutoML for a local run.\n", "2. Pass the `TabularDataset` to AutoML for a remote run."
"3. Pass the `Dataflow` to AutoML for a remote run."
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Setup\n", "## Setup"
"\n",
"Currently, Data Prep only supports __Ubuntu 16__ and __Red Hat Enterprise Linux 7__. We are working on supporting more linux distros."
] ]
}, },
{ {
@@ -70,15 +67,13 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"import logging\n", "import logging\n",
"import time\n",
"\n", "\n",
"import pandas as pd\n", "import pandas as pd\n",
"\n", "\n",
"import azureml.core\n", "import azureml.core\n",
"from azureml.core.compute import DsvmCompute\n",
"from azureml.core.experiment import Experiment\n", "from azureml.core.experiment import Experiment\n",
"from azureml.core.workspace import Workspace\n", "from azureml.core.workspace import Workspace\n",
"import azureml.dataprep as dprep\n", "from azureml.core.dataset import Dataset\n",
"from azureml.train.automl import AutoMLConfig" "from azureml.train.automl import AutoMLConfig"
] ]
}, },
@@ -89,11 +84,11 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"ws = Workspace.from_config()\n", "ws = Workspace.from_config()\n",
" \n", "\n",
"# choose a name for experiment\n", "# choose a name for experiment\n",
"experiment_name = 'automl-dataprep-remote-dsvm'\n", "experiment_name = 'automl-dataset-remote-bai'\n",
"# project folder\n", "# project folder\n",
"project_folder = './sample_projects/automl-dataprep-remote-dsvm'\n", "project_folder = './sample_projects/automl-dataprep-remote-bai'\n",
" \n", " \n",
"experiment = Experiment(ws, experiment_name)\n", "experiment = Experiment(ws, experiment_name)\n",
" \n", " \n",
@@ -123,35 +118,21 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"# You can use `auto_read_file` which intelligently figures out delimiters and datatypes of a file.\n",
"# The data referenced here was a 1MB simple random sample of the Chicago Crime data into a local temporary directory.\n", "# The data referenced here was a 1MB simple random sample of the Chicago Crime data into a local temporary directory.\n",
"# You can also use `read_csv` and `to_*` transformations to read (with overridable delimiter)\n",
"# and convert column types manually.\n",
"example_data = 'https://dprepdata.blob.core.windows.net/demo/crime0-random.csv'\n", "example_data = 'https://dprepdata.blob.core.windows.net/demo/crime0-random.csv'\n",
"dflow = dprep.read_csv(example_data, infer_column_types=True)\n", "dataset = Dataset.Tabular.from_delimited_files(example_data)\n",
"dflow.get_profile()" "dataset.take(5).to_pandas_dataframe()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# As `Primary Type` is our y data, we need to drop the values those are null in this column.\n",
"dflow = dflow.drop_nulls('Primary Type')\n",
"dflow.head(5)"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Review the Data Preparation Result\n", "### Review the data\n",
"\n", "\n",
"You can peek the result of a Dataflow at any range using `skip(i)` and `head(j)`. Doing so evaluates only `j` records for all the steps in the Dataflow, which makes it fast even against large datasets.\n", "You can peek the result of a `TabularDataset` at any range using `skip(i)` and `take(j).to_pandas_dataframe()`. Doing so evaluates only `j` records, which makes it fast even against large datasets.\n",
"\n", "\n",
"`Dataflow` objects are immutable and are composed of a list of data preparation steps. A `Dataflow` object can be branched at any point for further usage." "`TabularDataset` objects are immutable and are composed of a list of subsetting transformations (optional)."
] ]
}, },
{ {
@@ -160,8 +141,8 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"X = dflow.drop_columns(columns=['Primary Type', 'FBI Code'])\n", "X = dataset.drop_columns(columns=['Primary Type', 'FBI Code'])\n",
"y = dflow.keep_columns(columns=['Primary Type'], validate_column_exists=True)" "y = dataset.keep_columns(columns=['Primary Type'], validate=True)"
] ]
}, },
{ {
@@ -205,7 +186,7 @@
"from azureml.core.compute import ComputeTarget\n", "from azureml.core.compute import ComputeTarget\n",
"\n", "\n",
"# Choose a name for your cluster.\n", "# Choose a name for your cluster.\n",
"amlcompute_cluster_name = \"cpu-cluster\"\n", "amlcompute_cluster_name = \"automlc2\"\n",
"\n", "\n",
"found = False\n", "found = False\n",
"\n", "\n",
@@ -226,11 +207,12 @@
" # Create the cluster.\\n\",\n", " # Create the cluster.\\n\",\n",
" compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n", " compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n",
"\n", "\n",
" # Can poll for a minimum number of nodes and for a specific timeout.\n", "print('Checking cluster status...')\n",
" # If no min_node_count is provided, it will use the scale settings for the cluster.\n", "# Can poll for a minimum number of nodes and for a specific timeout.\n",
" compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n", "# If no min_node_count is provided, it will use the scale settings for the cluster.\n",
"compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n",
"\n", "\n",
" # For a more detailed view of current AmlCompute status, use get_status()." "# For a more detailed view of current AmlCompute status, use get_status()."
] ]
}, },
{ {
@@ -249,11 +231,8 @@
"# Set compute target to AmlCompute\n", "# Set compute target to AmlCompute\n",
"conda_run_config.target = compute_target\n", "conda_run_config.target = compute_target\n",
"conda_run_config.environment.docker.enabled = True\n", "conda_run_config.environment.docker.enabled = True\n",
"conda_run_config.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE\n",
"\n", "\n",
"dprep_dependency = 'azureml-dataprep==' + pkg_resources.get_distribution(\"azureml-dataprep\").version\n", "cd = CondaDependencies.create(conda_packages=['numpy','py-xgboost<=0.80'])\n",
"\n",
"cd = CondaDependencies.create(pip_packages=['azureml-sdk[automl]', dprep_dependency], conda_packages=['numpy','py-xgboost<=0.80'])\n",
"conda_run_config.environment.python.conda_dependencies = cd" "conda_run_config.environment.python.conda_dependencies = cd"
] ]
}, },
@@ -261,9 +240,9 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Pass Data with `Dataflow` Objects\n", "### Pass Data with `TabularDataset` Objects\n",
"\n", "\n",
"The `Dataflow` objects captured above can also be passed to the `submit` method for a remote run. AutoML will serialize the `Dataflow` object and send it to the remote compute target. The `Dataflow` will not be evaluated locally." "The `TabularDataset` objects captured above can also be passed to the `submit` method for a remote run. AutoML will serialize the `TabularDataset` object and send it to the remote compute target. The `TabularDataset` will not be evaluated locally."
] ]
}, },
{ {
@@ -466,8 +445,13 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"dflow_test = dprep.auto_read_file(path='https://dprepdata.blob.core.windows.net/demo/crime0-test.csv').skip(1)\n", "dataset_test = Dataset.Tabular.from_delimited_files(path='https://dprepdata.blob.core.windows.net/demo/crime0-test.csv')\n",
"dflow_test = dflow_test.drop_nulls('Primary Type')" "\n",
"df_test = dataset_test.to_pandas_dataframe()\n",
"df_test = df_test[pd.notnull(df_test['Primary Type'])]\n",
"\n",
"y_test = df_test[['Primary Type']]\n",
"X_test = df_test.drop(['Primary Type', 'FBI Code'], axis=1)"
] ]
}, },
{ {
@@ -486,10 +470,6 @@
"source": [ "source": [
"from pandas_ml import ConfusionMatrix\n", "from pandas_ml import ConfusionMatrix\n",
"\n", "\n",
"y_test = dflow_test.keep_columns(columns=['Primary Type']).to_pandas_dataframe()\n",
"X_test = dflow_test.drop_columns(columns=['Primary Type', 'FBI Code']).to_pandas_dataframe()\n",
"\n",
"\n",
"ypred = fitted_model.predict(X_test)\n", "ypred = fitted_model.predict(X_test)\n",
"\n", "\n",
"cm = ConfusionMatrix(y_test['Primary Type'], ypred)\n", "cm = ConfusionMatrix(y_test['Primary Type'], ypred)\n",

View File

@@ -1,10 +1,10 @@
name: regression-part2-automated-ml name: auto-ml-dataset-remote-execution
dependencies: dependencies:
- pip: - pip:
- azureml-sdk - azureml-sdk
- azureml-defaults
- azureml-explain-model
- azureml-train-automl - azureml-train-automl
- azureml-widgets - azureml-widgets
- azureml-explain-model
- matplotlib - matplotlib
- pandas_ml - pandas_ml
- seaborn

View File

@@ -21,7 +21,7 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"# Automated Machine Learning\n", "# Automated Machine Learning\n",
"_**Prepare Data using `azureml.dataprep` for Local Execution**_\n", "_**Load Data using `TabularDataset` for Local Execution**_\n",
"\n", "\n",
"## Contents\n", "## Contents\n",
"1. [Introduction](#Introduction)\n", "1. [Introduction](#Introduction)\n",
@@ -37,23 +37,20 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Introduction\n", "## Introduction\n",
"In this example we showcase how you can use the `azureml.dataprep` SDK to load and prepare data for AutoML. `azureml.dataprep` can also be used standalone; full documentation can be found [here](https://github.com/Microsoft/PendletonDocs).\n", "In this example we showcase how you can use AzureML Dataset to load data for AutoML.\n",
"\n", "\n",
"Make sure you have executed the [configuration](../../../configuration.ipynb) before running this notebook.\n", "Make sure you have executed the [configuration](../../../configuration.ipynb) before running this notebook.\n",
"\n", "\n",
"In this notebook you will learn how to:\n", "In this notebook you will learn how to:\n",
"1. Define data loading and preparation steps in a `Dataflow` using `azureml.dataprep`.\n", "1. Create a `TabularDataset` pointing to the training data.\n",
"2. Pass the `Dataflow` to AutoML for a local run.\n", "2. Pass the `TabularDataset` to AutoML for a local run."
"3. Pass the `Dataflow` to AutoML for a remote run."
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Setup\n", "## Setup"
"\n",
"Currently, Data Prep only supports __Ubuntu 16__ and __Red Hat Enterprise Linux 7__. We are working on supporting more linux distros."
] ]
}, },
{ {
@@ -76,7 +73,7 @@
"import azureml.core\n", "import azureml.core\n",
"from azureml.core.experiment import Experiment\n", "from azureml.core.experiment import Experiment\n",
"from azureml.core.workspace import Workspace\n", "from azureml.core.workspace import Workspace\n",
"import azureml.dataprep as dprep\n", "from azureml.core.dataset import Dataset\n",
"from azureml.train.automl import AutoMLConfig" "from azureml.train.automl import AutoMLConfig"
] ]
}, },
@@ -89,9 +86,9 @@
"ws = Workspace.from_config()\n", "ws = Workspace.from_config()\n",
" \n", " \n",
"# choose a name for experiment\n", "# choose a name for experiment\n",
"experiment_name = 'automl-dataprep-local'\n", "experiment_name = 'automl-dataset-local'\n",
"# project folder\n", "# project folder\n",
"project_folder = './sample_projects/automl-dataprep-local'\n", "project_folder = './sample_projects/automl-dataset-local'\n",
" \n", " \n",
"experiment = Experiment(ws, experiment_name)\n", "experiment = Experiment(ws, experiment_name)\n",
" \n", " \n",
@@ -121,35 +118,21 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"# You can use `auto_read_file` which intelligently figures out delimiters and datatypes of a file.\n",
"# The data referenced here was a 1MB simple random sample of the Chicago Crime data into a local temporary directory.\n", "# The data referenced here was a 1MB simple random sample of the Chicago Crime data into a local temporary directory.\n",
"# You can also use `read_csv` and `to_*` transformations to read (with overridable delimiter)\n",
"# and convert column types manually.\n",
"example_data = 'https://dprepdata.blob.core.windows.net/demo/crime0-random.csv'\n", "example_data = 'https://dprepdata.blob.core.windows.net/demo/crime0-random.csv'\n",
"dflow = dprep.auto_read_file(example_data).skip(1) # Remove the header row.\n", "dataset = Dataset.Tabular.from_delimited_files(example_data)\n",
"dflow.get_profile()" "dataset.take(5).to_pandas_dataframe()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# As `Primary Type` is our y data, we need to drop the values those are null in this column.\n",
"dflow = dflow.drop_nulls('Primary Type')\n",
"dflow.head(5)"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Review the Data Preparation Result\n", "### Review the data\n",
"\n", "\n",
"You can peek the result of a Dataflow at any range using `skip(i)` and `head(j)`. Doing so evaluates only `j` records for all the steps in the Dataflow, which makes it fast even against large datasets.\n", "You can peek the result of a `TabularDataset` at any range using `skip(i)` and `take(j).to_pandas_dataframe()`. Doing so evaluates only `j` records, which makes it fast even against large datasets.\n",
"\n", "\n",
"`Dataflow` objects are immutable and are composed of a list of data preparation steps. A `Dataflow` object can be branched at any point for further usage." "`TabularDataset` objects are immutable and are composed of a list of subsetting transformations (optional)."
] ]
}, },
{ {
@@ -158,8 +141,8 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"X = dflow.drop_columns(columns=['Primary Type', 'FBI Code'])\n", "X = dataset.drop_columns(columns=['Primary Type', 'FBI Code'])\n",
"y = dflow.keep_columns(columns=['Primary Type'], validate_column_exists=True)" "y = dataset.keep_columns(columns=['Primary Type'], validate=True)"
] ]
}, },
{ {
@@ -190,9 +173,9 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Pass Data with `Dataflow` Objects\n", "### Pass Data with `TabularDataset` Objects\n",
"\n", "\n",
"The `Dataflow` objects captured above can be passed to the `submit` method for a local run. AutoML will retrieve the results from the `Dataflow` for model training." "The `TabularDataset` objects captured above can be passed to the `submit` method for a local run. AutoML will retrieve the results from the `TabularDataset` for model training."
] ]
}, },
{ {
@@ -355,8 +338,13 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"dflow_test = dprep.auto_read_file(path='https://dprepdata.blob.core.windows.net/demo/crime0-test.csv').skip(1)\n", "dataset_test = Dataset.Tabular.from_delimited_files(path='https://dprepdata.blob.core.windows.net/demo/crime0-test.csv')\n",
"dflow_test = dflow_test.drop_nulls('Primary Type')" "\n",
"df_test = dataset_test.to_pandas_dataframe()\n",
"df_test = df_test[pd.notnull(df_test['Primary Type'])]\n",
"\n",
"y_test = df_test[['Primary Type']]\n",
"X_test = df_test.drop(['Primary Type', 'FBI Code'], axis=1)"
] ]
}, },
{ {
@@ -375,9 +363,6 @@
"source": [ "source": [
"from pandas_ml import ConfusionMatrix\n", "from pandas_ml import ConfusionMatrix\n",
"\n", "\n",
"y_test = dflow_test.keep_columns(columns=['Primary Type']).to_pandas_dataframe()\n",
"X_test = dflow_test.drop_columns(columns=['Primary Type', 'FBI Code']).to_pandas_dataframe()\n",
"\n",
"ypred = fitted_model.predict(X_test)\n", "ypred = fitted_model.predict(X_test)\n",
"\n", "\n",
"cm = ConfusionMatrix(y_test['Primary Type'], ypred)\n", "cm = ConfusionMatrix(y_test['Primary Type'], ypred)\n",

View File

@@ -1,4 +1,4 @@
name: auto-ml-dataprep name: auto-ml-dataset
dependencies: dependencies:
- pip: - pip:
- azureml-sdk - azureml-sdk

View File

@@ -231,6 +231,7 @@
"automl_config = AutoMLConfig(task='forecasting',\n", "automl_config = AutoMLConfig(task='forecasting',\n",
" debug_log='automl_nyc_energy_errors.log',\n", " debug_log='automl_nyc_energy_errors.log',\n",
" primary_metric='normalized_root_mean_squared_error',\n", " primary_metric='normalized_root_mean_squared_error',\n",
" blacklist_models = ['ExtremeRandomTrees'],\n",
" iterations=10,\n", " iterations=10,\n",
" iteration_timeout_minutes=5,\n", " iteration_timeout_minutes=5,\n",
" X=X_train,\n", " X=X_train,\n",
@@ -481,7 +482,7 @@
"automl_config_lags = AutoMLConfig(task='forecasting',\n", "automl_config_lags = AutoMLConfig(task='forecasting',\n",
" debug_log='automl_nyc_energy_errors.log',\n", " debug_log='automl_nyc_energy_errors.log',\n",
" primary_metric='normalized_root_mean_squared_error',\n", " primary_metric='normalized_root_mean_squared_error',\n",
" blacklist_models=['ElasticNet'],\n", " blacklist_models=['ElasticNet','ExtremeRandomTrees','GradientBoosting'],\n",
" iterations=10,\n", " iterations=10,\n",
" iteration_timeout_minutes=10,\n", " iteration_timeout_minutes=10,\n",
" X=X_train,\n", " X=X_train,\n",

View File

@@ -244,7 +244,8 @@
"|**X**|Training matrix of features as a pandas DataFrame, shape = [n_training_samples, n_features]|\n", "|**X**|Training matrix of features as a pandas DataFrame, shape = [n_training_samples, n_features]|\n",
"|**y**|Target values as a numpy.ndarray, shape = [n_training_samples, ]|\n", "|**y**|Target values as a numpy.ndarray, shape = [n_training_samples, ]|\n",
"|**n_cross_validations**|Number of cross-validation folds to use for model/pipeline selection|\n", "|**n_cross_validations**|Number of cross-validation folds to use for model/pipeline selection|\n",
"|**enable_ensembling**|Allow AutoML to create ensembles of the best performing models\n", "|**enable_voting_ensemble**|Allow AutoML to create a Voting ensemble of the best performing models\n",
"|**enable_stack_ensemble**|Allow AutoML to create a Stack ensemble of the best performing models\n",
"|**debug_log**|Log file path for writing debugging information\n", "|**debug_log**|Log file path for writing debugging information\n",
"|**path**|Relative path to the project folder. AutoML stores configuration files for the experiment under this folder. You can specify a new empty folder.|\n", "|**path**|Relative path to the project folder. AutoML stores configuration files for the experiment under this folder. You can specify a new empty folder.|\n",
"|**time_column_name**|Name of the datetime column in the input data|\n", "|**time_column_name**|Name of the datetime column in the input data|\n",
@@ -273,7 +274,8 @@
" X=X_train,\n", " X=X_train,\n",
" y=y_train,\n", " y=y_train,\n",
" n_cross_validations=3,\n", " n_cross_validations=3,\n",
" enable_ensembling=False,\n", " enable_voting_ensemble=False,\n",
" enable_stack_ensemble=False,\n",
" path=project_folder,\n", " path=project_folder,\n",
" verbosity=logging.INFO,\n", " verbosity=logging.INFO,\n",
" **time_series_settings)" " **time_series_settings)"
@@ -663,10 +665,10 @@
"conda_env_file_name = 'fcast_env.yml'\n", "conda_env_file_name = 'fcast_env.yml'\n",
"\n", "\n",
"dependencies = ml_run.get_run_sdk_dependencies(iteration = best_iteration)\n", "dependencies = ml_run.get_run_sdk_dependencies(iteration = best_iteration)\n",
"for p in ['azureml-train-automl', 'azureml-sdk', 'azureml-core']:\n", "for p in ['azureml-train-automl', 'azureml-core']:\n",
" print('{}\\t{}'.format(p, dependencies[p]))\n", " print('{}\\t{}'.format(p, dependencies[p]))\n",
"\n", "\n",
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn'], pip_packages=['azureml-sdk[automl]'])\n", "myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn'], pip_packages=['azureml-train-automl'])\n",
"\n", "\n",
"myenv.save_to_file('.', conda_env_file_name)" "myenv.save_to_file('.', conda_env_file_name)"
] ]
@@ -688,7 +690,7 @@
" content = cefr.read()\n", " content = cefr.read()\n",
"\n", "\n",
"with open(conda_env_file_name, 'w') as cefw:\n", "with open(conda_env_file_name, 'w') as cefw:\n",
" cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-sdk']))\n", " cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-train-automl']))\n",
"\n", "\n",
"# Substitute the actual model id in the script file.\n", "# Substitute the actual model id in the script file.\n",
"\n", "\n",

View File

@@ -70,13 +70,12 @@
"import numpy as np\n", "import numpy as np\n",
"import pandas as pd\n", "import pandas as pd\n",
"import os\n", "import os\n",
"from sklearn.model_selection import train_test_split\n",
"import azureml.dataprep as dprep\n",
" \n", " \n",
"\n", "\n",
"import azureml.core\n", "import azureml.core\n",
"from azureml.core.experiment import Experiment\n", "from azureml.core.experiment import Experiment\n",
"from azureml.core.workspace import Workspace\n", "from azureml.core.workspace import Workspace\n",
"from azureml.core.dataset import Dataset\n",
"from azureml.train.automl import AutoMLConfig" "from azureml.train.automl import AutoMLConfig"
] ]
}, },
@@ -147,11 +146,12 @@
" # Create the cluster.\n", " # Create the cluster.\n",
" compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n", " compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n",
" \n", " \n",
" # Can poll for a minimum number of nodes and for a specific timeout.\n", "print('Checking cluster status...')\n",
" # If no min_node_count is provided, it will use the scale settings for the cluster.\n", "# Can poll for a minimum number of nodes and for a specific timeout.\n",
" compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n", "# If no min_node_count is provided, it will use the scale settings for the cluster.\n",
"compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n",
" \n", " \n",
" # For a more detailed view of current AmlCompute status, use get_status()." "# For a more detailed view of current AmlCompute status, use get_status()."
] ]
}, },
{ {
@@ -192,11 +192,8 @@
"# Set compute target to AmlCompute\n", "# Set compute target to AmlCompute\n",
"conda_run_config.target = compute_target\n", "conda_run_config.target = compute_target\n",
"conda_run_config.environment.docker.enabled = True\n", "conda_run_config.environment.docker.enabled = True\n",
"conda_run_config.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE\n",
"\n", "\n",
"dprep_dependency = 'azureml-dataprep==' + pkg_resources.get_distribution(\"azureml-dataprep\").version\n", "cd = CondaDependencies.create(conda_packages=['numpy', 'py-xgboost<=0.80'])\n",
"\n",
"cd = CondaDependencies.create(pip_packages=['azureml-sdk[automl]', dprep_dependency], conda_packages=['numpy'])\n",
"conda_run_config.environment.python.conda_dependencies = cd" "conda_run_config.environment.python.conda_dependencies = cd"
] ]
}, },
@@ -206,7 +203,7 @@
"source": [ "source": [
"### Load Data\n", "### Load Data\n",
"\n", "\n",
"Here create the script to be run in azure compute for loading the data, load the concrete strength dataset into the X and y variables. Next, split the data using train_test_split and return X_train and y_train for training the model. Finally, return X_train and y_train for training the model." "Here create the script to be run in azure compute for loading the data, load the concrete strength dataset into the X and y variables. Next, split the data using random_split and return X_train and y_train for training the model. Finally, return X_train and y_train for training the model."
] ]
}, },
{ {
@@ -216,13 +213,12 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/compresive_strength_concrete.csv\"\n", "data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/compresive_strength_concrete.csv\"\n",
"dflow = dprep.read_csv(data, infer_column_types=True)\n", "dataset = Dataset.Tabular.from_delimited_files(data)\n",
"dflow.get_profile()\n", "X = dataset.drop_columns(columns=['CONCRETE'])\n",
"X = dflow.drop_columns(columns=['CONCRETE'])\n", "y = dataset.keep_columns(columns=['CONCRETE'], validate=True)\n",
"y = dflow.keep_columns(columns=['CONCRETE'], validate_column_exists=True)\n",
"X_train, X_test = X.random_split(percentage=0.8, seed=223)\n", "X_train, X_test = X.random_split(percentage=0.8, seed=223)\n",
"y_train, y_test = y.random_split(percentage=0.8, seed=223) \n", "y_train, y_test = y.random_split(percentage=0.8, seed=223) \n",
"dflow.head()" "dataset.take(5).to_pandas_dataframe()"
] ]
}, },
{ {
@@ -484,7 +480,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"for p in ['azureml-train-automl', 'azureml-sdk', 'azureml-core']:\n", "for p in ['azureml-train-automl', 'azureml-core']:\n",
" print('{}\\t{}'.format(p, dependencies[p]))" " print('{}\\t{}'.format(p, dependencies[p]))"
] ]
}, },
@@ -494,9 +490,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.conda_dependencies import CondaDependencies\n", "myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn','py-xgboost==0.80'], pip_packages=['azureml-train-automl'])\n",
"\n",
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn'], pip_packages=['azureml-sdk[automl]'])\n",
"\n", "\n",
"conda_env_file_name = 'myenv.yml'\n", "conda_env_file_name = 'myenv.yml'\n",
"myenv.save_to_file('.', conda_env_file_name)" "myenv.save_to_file('.', conda_env_file_name)"
@@ -516,7 +510,7 @@
" content = cefr.read()\n", " content = cefr.read()\n",
"\n", "\n",
"with open(conda_env_file_name, 'w') as cefw:\n", "with open(conda_env_file_name, 'w') as cefw:\n",
" cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-sdk']))\n", " cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-train-automl']))\n",
"\n", "\n",
"# Substitute the actual model id in the script file.\n", "# Substitute the actual model id in the script file.\n",
"\n", "\n",

View File

@@ -2,6 +2,8 @@ name: auto-ml-regression-concrete-strength
dependencies: dependencies:
- pip: - pip:
- azureml-sdk - azureml-sdk
- azureml-defaults
- azureml-explain-model
- azureml-train-automl - azureml-train-automl
- azureml-widgets - azureml-widgets
- matplotlib - matplotlib

View File

@@ -70,13 +70,12 @@
"import numpy as np\n", "import numpy as np\n",
"import pandas as pd\n", "import pandas as pd\n",
"import os\n", "import os\n",
"from sklearn.model_selection import train_test_split\n",
"import azureml.dataprep as dprep\n",
" \n", " \n",
"\n", "\n",
"import azureml.core\n", "import azureml.core\n",
"from azureml.core.experiment import Experiment\n", "from azureml.core.experiment import Experiment\n",
"from azureml.core.workspace import Workspace\n", "from azureml.core.workspace import Workspace\n",
"from azureml.core.dataset import Dataset\n",
"from azureml.train.automl import AutoMLConfig" "from azureml.train.automl import AutoMLConfig"
] ]
}, },
@@ -147,11 +146,12 @@
" # Create the cluster.\n", " # Create the cluster.\n",
" compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n", " compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n",
" \n", " \n",
" # Can poll for a minimum number of nodes and for a specific timeout.\n", "print('Checking cluster status...')\n",
" # If no min_node_count is provided, it will use the scale settings for the cluster.\n", "# Can poll for a minimum number of nodes and for a specific timeout.\n",
" compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n", "# If no min_node_count is provided, it will use the scale settings for the cluster.\n",
"compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n",
" \n", " \n",
" # For a more detailed view of current AmlCompute status, use get_status()." "# For a more detailed view of current AmlCompute status, use get_status()."
] ]
}, },
{ {
@@ -192,11 +192,8 @@
"# Set compute target to AmlCompute\n", "# Set compute target to AmlCompute\n",
"conda_run_config.target = compute_target\n", "conda_run_config.target = compute_target\n",
"conda_run_config.environment.docker.enabled = True\n", "conda_run_config.environment.docker.enabled = True\n",
"conda_run_config.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE\n",
"\n", "\n",
"dprep_dependency = 'azureml-dataprep==' + pkg_resources.get_distribution(\"azureml-dataprep\").version\n", "cd = CondaDependencies.create(conda_packages=['numpy', 'py-xgboost<=0.80'])\n",
"\n",
"cd = CondaDependencies.create(pip_packages=['azureml-sdk[automl]', dprep_dependency], conda_packages=['numpy'])\n",
"conda_run_config.environment.python.conda_dependencies = cd" "conda_run_config.environment.python.conda_dependencies = cd"
] ]
}, },
@@ -206,7 +203,7 @@
"source": [ "source": [
"### Load Data\n", "### Load Data\n",
"\n", "\n",
"Here create the script to be run in azure compute for loading the data, load the hardware dataset into the X and y variables. Next split the data using train_test_split and return X_train and y_train for training the model." "Here create the script to be run in azure compute for loading the data, load the hardware dataset into the X and y variables. Next split the data using random_split and return X_train and y_train for training the model."
] ]
}, },
{ {
@@ -216,13 +213,12 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/machineData.csv\"\n", "data = \"https://automlsamplenotebookdata.blob.core.windows.net/automl-sample-notebook-data/machineData.csv\"\n",
"dflow = dprep.read_csv(data, infer_column_types=True)\n", "dataset = Dataset.Tabular.from_delimited_files(data)\n",
"dflow.get_profile()\n", "X = dataset.drop_columns(columns=['ERP'])\n",
"X = dflow.drop_columns(columns=['ERP'])\n", "y = dataset.keep_columns(columns=['ERP'], validate=True)\n",
"y = dflow.keep_columns(columns=['ERP'], validate_column_exists=True)\n",
"X_train, X_test = X.random_split(percentage=0.8, seed=223)\n", "X_train, X_test = X.random_split(percentage=0.8, seed=223)\n",
"y_train, y_test = y.random_split(percentage=0.8, seed=223) \n", "y_train, y_test = y.random_split(percentage=0.8, seed=223)\n",
"dflow.head()" "dataset.take(5).to_pandas_dataframe()"
] ]
}, },
{ {
@@ -502,7 +498,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"for p in ['azureml-train-automl', 'azureml-sdk', 'azureml-core']:\n", "for p in ['azureml-train-automl', 'azureml-core']:\n",
" print('{}\\t{}'.format(p, dependencies[p]))" " print('{}\\t{}'.format(p, dependencies[p]))"
] ]
}, },
@@ -512,7 +508,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn'], pip_packages=['azureml-sdk[automl]'])\n", "myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn','py-xgboost==0.80'], pip_packages=['azureml-train-automl'])\n",
"\n", "\n",
"conda_env_file_name = 'myenv.yml'\n", "conda_env_file_name = 'myenv.yml'\n",
"myenv.save_to_file('.', conda_env_file_name)" "myenv.save_to_file('.', conda_env_file_name)"
@@ -532,7 +528,7 @@
" content = cefr.read()\n", " content = cefr.read()\n",
"\n", "\n",
"with open(conda_env_file_name, 'w') as cefw:\n", "with open(conda_env_file_name, 'w') as cefw:\n",
" cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-sdk']))\n", " cefw.write(content.replace(azureml.core.VERSION, dependencies['azureml-train-automl']))\n",
"\n", "\n",
"# Substitute the actual model id in the script file.\n", "# Substitute the actual model id in the script file.\n",
"\n", "\n",

View File

@@ -2,6 +2,8 @@ name: auto-ml-regression-hardware-performance
dependencies: dependencies:
- pip: - pip:
- azureml-sdk - azureml-sdk
- azureml-defaults
- azureml-explain-model
- azureml-train-automl - azureml-train-automl
- azureml-widgets - azureml-widgets
- matplotlib - matplotlib

View File

@@ -73,10 +73,7 @@
"source": [ "source": [
"import logging\n", "import logging\n",
"import os\n", "import os\n",
"import csv\n",
"\n", "\n",
"from matplotlib import pyplot as plt\n",
"import numpy as np\n",
"import pandas as pd\n", "import pandas as pd\n",
"from sklearn import datasets\n", "from sklearn import datasets\n",
"from sklearn.model_selection import train_test_split\n", "from sklearn.model_selection import train_test_split\n",
@@ -84,8 +81,8 @@
"import azureml.core\n", "import azureml.core\n",
"from azureml.core.experiment import Experiment\n", "from azureml.core.experiment import Experiment\n",
"from azureml.core.workspace import Workspace\n", "from azureml.core.workspace import Workspace\n",
"from azureml.train.automl import AutoMLConfig\n", "from azureml.core.dataset import Dataset\n",
"import azureml.dataprep as dprep" "from azureml.train.automl import AutoMLConfig"
] ]
}, },
{ {
@@ -137,7 +134,7 @@
"from azureml.core.compute import ComputeTarget\n", "from azureml.core.compute import ComputeTarget\n",
"\n", "\n",
"# Choose a name for your cluster.\n", "# Choose a name for your cluster.\n",
"amlcompute_cluster_name = \"cpu-cluster\"\n", "amlcompute_cluster_name = \"automlc2\"\n",
"\n", "\n",
"found = False\n", "found = False\n",
"# Check if this compute target already exists in the workspace.\n", "# Check if this compute target already exists in the workspace.\n",
@@ -156,11 +153,12 @@
" # Create the cluster.\\n\",\n", " # Create the cluster.\\n\",\n",
" compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n", " compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n",
"\n", "\n",
" # Can poll for a minimum number of nodes and for a specific timeout.\n", "print('Checking cluster status...')\n",
" # If no min_node_count is provided, it will use the scale settings for the cluster.\n", "# Can poll for a minimum number of nodes and for a specific timeout.\n",
" compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n", "# If no min_node_count is provided, it will use the scale settings for the cluster.\n",
"compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n",
"\n", "\n",
" # For a more detailed view of current AmlCompute status, use get_status()." "# For a more detailed view of current AmlCompute status, use get_status()."
] ]
}, },
{ {
@@ -236,11 +234,8 @@
"# Set compute target to AmlCompute\n", "# Set compute target to AmlCompute\n",
"conda_run_config.target = compute_target\n", "conda_run_config.target = compute_target\n",
"conda_run_config.environment.docker.enabled = True\n", "conda_run_config.environment.docker.enabled = True\n",
"conda_run_config.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE\n",
"\n", "\n",
"dprep_dependency = 'azureml-dataprep==' + pkg_resources.get_distribution(\"azureml-dataprep\").version\n", "cd = CondaDependencies.create(conda_packages=['numpy','py-xgboost<=0.80'])\n",
"\n",
"cd = CondaDependencies.create(pip_packages=['azureml-sdk[automl]', dprep_dependency], conda_packages=['numpy','py-xgboost<=0.80'])\n",
"conda_run_config.environment.python.conda_dependencies = cd" "conda_run_config.environment.python.conda_dependencies = cd"
] ]
}, },
@@ -248,9 +243,9 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Dprep reference\n", "### Creating a TabularDataset\n",
"\n", "\n",
"Defined X and y as dprep references, which are passed to automated machine learning in the AutoMLConfig." "Defined X and y as `TabularDataset`s, which are passed to automated machine learning in the AutoMLConfig."
] ]
}, },
{ {
@@ -259,8 +254,8 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"X = dprep.read_csv(path=ds.path('irisdata/X_train.csv'), infer_column_types=True)\n", "X = Dataset.Tabular.from_delimited_files(path=ds.path('irisdata/X_train.csv'))\n",
"y = dprep.read_csv(path=ds.path('irisdata/y_train.csv'), infer_column_types=True)" "y = Dataset.Tabular.from_delimited_files(path=ds.path('irisdata/y_train.csv'))"
] ]
}, },
{ {
@@ -498,8 +493,7 @@
" res_path = 'onnx_resource.json'\n", " res_path = 'onnx_resource.json'\n",
" run.download_file(name=constants.MODEL_RESOURCE_PATH_ONNX, output_file_path=res_path)\n", " run.download_file(name=constants.MODEL_RESOURCE_PATH_ONNX, output_file_path=res_path)\n",
" with open(res_path) as f:\n", " with open(res_path) as f:\n",
" onnx_res = json.load(f)\n", " return json.load(f)\n",
" return onnx_res\n",
"\n", "\n",
"if onnxrt_present and python_version_compatible: \n", "if onnxrt_present and python_version_compatible: \n",
" mdl_bytes = onnx_mdl.SerializeToString()\n", " mdl_bytes = onnx_mdl.SerializeToString()\n",

View File

@@ -2,6 +2,8 @@ name: auto-ml-remote-amlcompute-with-onnx
dependencies: dependencies:
- pip: - pip:
- azureml-sdk - azureml-sdk
- azureml-defaults
- azureml-explain-model
- azureml-train-automl - azureml-train-automl
- azureml-widgets - azureml-widgets
- matplotlib - matplotlib

View File

@@ -74,7 +74,6 @@
"source": [ "source": [
"import logging\n", "import logging\n",
"import os\n", "import os\n",
"import csv\n",
"\n", "\n",
"from matplotlib import pyplot as plt\n", "from matplotlib import pyplot as plt\n",
"import numpy as np\n", "import numpy as np\n",
@@ -84,8 +83,8 @@
"import azureml.core\n", "import azureml.core\n",
"from azureml.core.experiment import Experiment\n", "from azureml.core.experiment import Experiment\n",
"from azureml.core.workspace import Workspace\n", "from azureml.core.workspace import Workspace\n",
"from azureml.train.automl import AutoMLConfig\n", "from azureml.core.dataset import Dataset\n",
"import azureml.dataprep as dprep" "from azureml.train.automl import AutoMLConfig"
] ]
}, },
{ {
@@ -137,7 +136,7 @@
"from azureml.core.compute import ComputeTarget\n", "from azureml.core.compute import ComputeTarget\n",
"\n", "\n",
"# Choose a name for your cluster.\n", "# Choose a name for your cluster.\n",
"amlcompute_cluster_name = \"cpu-cluster\"\n", "amlcompute_cluster_name = \"automlc2\"\n",
"\n", "\n",
"found = False\n", "found = False\n",
"# Check if this compute target already exists in the workspace.\n", "# Check if this compute target already exists in the workspace.\n",
@@ -156,11 +155,12 @@
" # Create the cluster.\\n\",\n", " # Create the cluster.\\n\",\n",
" compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n", " compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n",
"\n", "\n",
" # Can poll for a minimum number of nodes and for a specific timeout.\n", "print('Checking cluster status...')\n",
" # If no min_node_count is provided, it will use the scale settings for the cluster.\n", "# Can poll for a minimum number of nodes and for a specific timeout.\n",
" compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n", "# If no min_node_count is provided, it will use the scale settings for the cluster.\n",
"compute_target.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n",
"\n", "\n",
" # For a more detailed view of current AmlCompute status, use get_status()." "# For a more detailed view of current AmlCompute status, use get_status()."
] ]
}, },
{ {
@@ -210,11 +210,8 @@
"# Set compute target to AmlCompute\n", "# Set compute target to AmlCompute\n",
"conda_run_config.target = compute_target\n", "conda_run_config.target = compute_target\n",
"conda_run_config.environment.docker.enabled = True\n", "conda_run_config.environment.docker.enabled = True\n",
"conda_run_config.environment.docker.base_image = azureml.core.runconfig.DEFAULT_CPU_IMAGE\n",
"\n", "\n",
"dprep_dependency = 'azureml-dataprep==' + pkg_resources.get_distribution(\"azureml-dataprep\").version\n", "cd = CondaDependencies.create(conda_packages=['numpy','py-xgboost<=0.80'])\n",
"\n",
"cd = CondaDependencies.create(pip_packages=['azureml-sdk[automl]', dprep_dependency], conda_packages=['numpy','py-xgboost<=0.80'])\n",
"conda_run_config.environment.python.conda_dependencies = cd" "conda_run_config.environment.python.conda_dependencies = cd"
] ]
}, },
@@ -222,9 +219,9 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Dprep reference\n", "### Creating TabularDataset\n",
"\n", "\n",
"Defined X and y as dprep references, which are passed to automated machine learning in the AutoMLConfig." "Defined X and y as `TabularDataset`s, which are passed to Automated ML in the AutoMLConfig. `from_delimited_files` by default sets the `infer_column_types` to true, which will infer the columns type automatically. If you do wish to manually set the column types, you can set the `set_column_types` argument to manually set the type of each columns."
] ]
}, },
{ {
@@ -233,8 +230,8 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"X = dprep.read_csv(path=ds.path('digitsdata/X_train.csv'), infer_column_types=True)\n", "X = Dataset.Tabular.from_delimited_files(path=ds.path('digitsdata/X_train.csv'))\n",
"y = dprep.read_csv(path=ds.path('digitsdata/y_train.csv'), infer_column_types=True)" "y = Dataset.Tabular.from_delimited_files(path=ds.path('digitsdata/y_train.csv'))"
] ]
}, },
{ {

View File

@@ -2,6 +2,8 @@ name: auto-ml-remote-amlcompute
dependencies: dependencies:
- pip: - pip:
- azureml-sdk - azureml-sdk
- azureml-defaults
- azureml-explain-model
- azureml-train-automl - azureml-train-automl
- azureml-widgets - azureml-widgets
- matplotlib - matplotlib

View File

@@ -342,7 +342,6 @@
" n_cross_validations = n_cross_validations, \r\n", " n_cross_validations = n_cross_validations, \r\n",
" preprocess = preprocess,\r\n", " preprocess = preprocess,\r\n",
" verbosity = logging.INFO, \r\n", " verbosity = logging.INFO, \r\n",
" enable_ensembling = False,\r\n",
" X = X_train, \r\n", " X = X_train, \r\n",
" y = y_train, \r\n", " y = y_train, \r\n",
" path = project_folder,\r\n", " path = project_folder,\r\n",

View File

@@ -314,25 +314,18 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Load Training Data Using DataPrep" "## Load Training Data Using Dataset"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Automated ML takes a Dataflow as input.\n", "Automated ML takes a `TabularDataset` as input.\n",
"\n", "\n",
"If you are familiar with Pandas and have done your data preparation work in Pandas already, you can use the `read_pandas_dataframe` method in dprep to convert the DataFrame to a Dataflow.\n", "You are free to use the data preparation libraries/tools of your choice to do the require preparation and once you are done, you can write it to a datastore and create a TabularDataset from it.\n",
"```python\n",
"df = pd.read_csv(...)\n",
"# apply some transforms\n",
"dprep.read_pandas_dataframe(df, temp_folder='/path/accessible/by/both/driver/and/worker')\n",
"```\n",
"\n", "\n",
"If you just need to ingest data without doing any preparation, you can directly use AzureML Data Prep (Data Prep) to do so. The code below demonstrates this scenario. Data Prep also has data preparation capabilities, we have many [sample notebooks](https://github.com/Microsoft/AMLDataPrepDocs) demonstrating the capabilities.\n", "You will get the datastore you registered previously and pass it to Dataset for reading. The data comes from the digits dataset: `sklearn.datasets.load_digits()`. `DataPath` points to a specific location within a datastore. "
"\n",
"You will get the datastore you registered previously and pass it to Data Prep for reading. The data comes from the digits dataset: `sklearn.datasets.load_digits()`. `DataPath` points to a specific location within a datastore. "
] ]
}, },
{ {
@@ -341,21 +334,21 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"import azureml.dataprep as dprep\n", "from azureml.core.dataset import Dataset\n",
"from azureml.data.datapath import DataPath\n", "from azureml.data.datapath import DataPath\n",
"\n", "\n",
"datastore = Datastore.get(workspace = ws, datastore_name = datastore_name)\n", "datastore = Datastore.get(workspace = ws, datastore_name = datastore_name)\n",
"\n", "\n",
"X_train = dprep.read_csv(datastore.path('X.csv'))\n", "X_train = Dataset.Tabular.from_delimited_files(datastore.path('X.csv'))\n",
"y_train = dprep.read_csv(datastore.path('y.csv')).to_long(dprep.ColumnSelector(term='.*', use_regex = True))" "y_train = Dataset.Tabular.from_delimited_files(datastore.path('y.csv'))"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Review the Data Preparation Result\n", "## Review the TabularDataset\n",
"You can peek the result of a Dataflow at any range using `skip(i)` and `head(j)`. Doing so evaluates only j records for all the steps in the Dataflow, which makes it fast even against large datasets." "You can peek the result of a TabularDataset at any range using `skip(i)` and `take(j).to_pandas_dataframe()`. Doing so evaluates only j records for all the steps in the TabularDataset, which makes it fast even against large datasets."
] ]
}, },
{ {
@@ -364,7 +357,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"X_train.get_profile()" "X_train.take(5).to_pandas_dataframe()"
] ]
}, },
{ {
@@ -373,7 +366,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"y_train.get_profile()" "y_train.take(5).to_pandas_dataframe()"
] ]
}, },
{ {

View File

@@ -331,25 +331,18 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Load Training Data Using DataPrep" "## Load Training Data Using Dataset"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Automated ML takes a Dataflow as input.\n", "Automated ML takes a `TabularDataset` as input.\n",
"\n", "\n",
"If you are familiar with Pandas and have done your data preparation work in Pandas already, you can use the `read_pandas_dataframe` method in dprep to convert the DataFrame to a Dataflow.\n", "You are free to use the data preparation libraries/tools of your choice to do the require preparation and once you are done, you can write it to a datastore and create a TabularDataset from it.\n",
"```python\n",
"df = pd.read_csv(...)\n",
"# apply some transforms\n",
"dprep.read_pandas_dataframe(df, temp_folder='/path/accessible/by/both/driver/and/worker')\n",
"```\n",
"\n", "\n",
"If you just need to ingest data without doing any preparation, you can directly use AzureML Data Prep (Data Prep) to do so. The code below demonstrates this scenario. Data Prep also has data preparation capabilities, we have many [sample notebooks](https://github.com/Microsoft/AMLDataPrepDocs) demonstrating the capabilities.\n", "You will get the datastore you registered previously and pass it to Dataset for reading. The data comes from the digits dataset: `sklearn.datasets.load_digits()`. `DataPath` points to a specific location within a datastore. "
"\n",
"You will get the datastore you registered previously and pass it to Data Prep for reading. The data comes from the digits dataset: `sklearn.datasets.load_digits()`. `DataPath` points to a specific location within a datastore. "
] ]
}, },
{ {
@@ -358,21 +351,21 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"import azureml.dataprep as dprep\n", "from azureml.core.dataset import Dataset\n",
"from azureml.data.datapath import DataPath\n", "from azureml.data.datapath import DataPath\n",
"\n", "\n",
"datastore = Datastore.get(workspace = ws, datastore_name = datastore_name)\n", "datastore = Datastore.get(workspace = ws, datastore_name = datastore_name)\n",
"\n", "\n",
"X_train = dprep.read_csv(datastore.path('X.csv'))\n", "X_train = Dataset.Tabular.from_delimited_files(datastore.path('X.csv'))\n",
"y_train = dprep.read_csv(datastore.path('y.csv')).to_long(dprep.ColumnSelector(term='.*', use_regex = True))" "y_train = Dataset.Tabular.from_delimited_files(datastore.path('y.csv'))"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Review the Data Preparation Result\n", "## Review the TabularDataset\n",
"You can peek the result of a Dataflow at any range using skip(i) and head(j). Doing so evaluates only j records for all the steps in the Dataflow, which makes it fast even against large datasets." "You can peek the result of a TabularDataset at any range using `skip(i)` and `take(j).to_pandas_dataframe()`. Doing so evaluates only j records for all the steps in the TabularDataset, which makes it fast even against large datasets."
] ]
}, },
{ {
@@ -381,7 +374,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"X_train.get_profile()" "X_train.take(5).to_pandas_dataframe()"
] ]
}, },
{ {
@@ -390,7 +383,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"y_train.get_profile()" "y_train.take(5).to_pandas_dataframe()"
] ]
}, },
{ {

View File

@@ -115,6 +115,36 @@
" workspace=ws)" " workspace=ws)"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create Environment"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can now create and/or use an Environment object when deploying a Webservice. The Environment can have been previously registered with your Workspace, or it will be registered with it as a part of the Webservice deployment. Only Environments that were created using azureml-defaults version 1.0.48 or later will work with this new handling however.\n",
"\n",
"More information can be found in our [using environments notebook](../training/using-environments/using-environments.ipynb)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core import Environment\n",
"\n",
"env = Environment.from_conda_specification(name='deploytocloudenv', file_path='myenv.yml')\n",
"\n",
"# This is optional at this point\n",
"# env.register(workspace=ws)"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
@@ -153,10 +183,7 @@
"source": [ "source": [
"from azureml.core.model import InferenceConfig\n", "from azureml.core.model import InferenceConfig\n",
"\n", "\n",
"inference_config = InferenceConfig(runtime= \"python\", \n", "inference_config = InferenceConfig(entry_script=\"score.py\", environment=env)"
" entry_script=\"score.py\",\n",
" conda_file=\"myenv.yml\", \n",
" extra_docker_file_steps=\"helloworld.txt\")"
] ]
}, },
{ {

View File

@@ -336,7 +336,7 @@
" num_replicas=1,\n", " num_replicas=1,\n",
" auth_enabled = False)\n", " auth_enabled = False)\n",
"\n", "\n",
"aks_service_name ='my-aks-service'\n", "aks_service_name ='my-aks-service-3'\n",
"\n", "\n",
"aks_service = Webservice.deploy_from_image(workspace = ws,\n", "aks_service = Webservice.deploy_from_image(workspace = ws,\n",
" name = aks_service_name,\n", " name = aks_service_name,\n",

View File

@@ -404,7 +404,7 @@
" num_replicas=1,\n", " num_replicas=1,\n",
" auth_enabled = False)\n", " auth_enabled = False)\n",
"\n", "\n",
"aks_service_name ='my-aks-service'\n", "aks_service_name ='my-aks-service-1'\n",
"\n", "\n",
"aks_service = Webservice.deploy_from_image(workspace = ws,\n", "aks_service = Webservice.deploy_from_image(workspace = ws,\n",
" name = aks_service_name,\n", " name = aks_service_name,\n",

View File

@@ -694,7 +694,7 @@
" num_replicas=1,\n", " num_replicas=1,\n",
" auth_enabled = False)\n", " auth_enabled = False)\n",
"\n", "\n",
"aks_service_name ='my-aks-service'\n", "aks_service_name ='my-aks-service-2'\n",
"\n", "\n",
"aks_service = Webservice.deploy_from_image(workspace = ws,\n", "aks_service = Webservice.deploy_from_image(workspace = ws,\n",
" name = aks_service_name,\n", " name = aks_service_name,\n",

View File

@@ -22,7 +22,7 @@
"If you want to log custom traces, you will follow the standard deplyment process for AKS and you will:\n", "If you want to log custom traces, you will follow the standard deplyment process for AKS and you will:\n",
"1. Update scoring file.\n", "1. Update scoring file.\n",
"2. Update aks configuration.\n", "2. Update aks configuration.\n",
"3. Build new image and deploy it. " "3. Deploy the model with this new configuration. "
] ]
}, },
{ {
@@ -178,7 +178,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"## 6. Create your new Image" "## 6. Create Inference Configuration"
] ]
}, },
{ {
@@ -187,22 +187,11 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.image import ContainerImage\n", "from azureml.core.model import InferenceConfig\n",
"\n", "\n",
"image_config = ContainerImage.image_configuration(execution_script = \"score.py\",\n", "inference_config = InferenceConfig(runtime= \"python\", \n",
" runtime = \"python\",\n", " entry_script=\"score.py\",\n",
" conda_file = \"myenv.yml\",\n", " conda_file=\"myenv.yml\")"
" description = \"Image with ridge regression model\",\n",
" tags = {'area': \"diabetes\", 'type': \"regression\"}\n",
" )\n",
"\n",
"image = ContainerImage.create(name = \"myimage1\",\n",
" # this is the model object\n",
" models = [model],\n",
" image_config = image_config,\n",
" workspace = ws)\n",
"\n",
"image.wait_for_creation(show_output = True)"
] ]
}, },
{ {
@@ -220,7 +209,7 @@
"source": [ "source": [
"from azureml.core.webservice import AciWebservice\n", "from azureml.core.webservice import AciWebservice\n",
"\n", "\n",
"aciconfig = AciWebservice.deploy_configuration(cpu_cores = 1, \n", "aci_deployment_config = AciWebservice.deploy_configuration(cpu_cores = 1, \n",
" memory_gb = 1, \n", " memory_gb = 1, \n",
" tags = {'area': \"diabetes\", 'type': \"regression\"}, \n", " tags = {'area': \"diabetes\", 'type': \"regression\"}, \n",
" description = 'Predict diabetes using regression model',\n", " description = 'Predict diabetes using regression model',\n",
@@ -236,11 +225,7 @@
"from azureml.core.webservice import Webservice\n", "from azureml.core.webservice import Webservice\n",
"\n", "\n",
"aci_service_name = 'my-aci-service-4'\n", "aci_service_name = 'my-aci-service-4'\n",
"print(aci_service_name)\n", "aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aci_deployment_config)\n",
"aci_service = Webservice.deploy_from_image(deployment_config = aciconfig,\n",
" image = image,\n",
" name = aci_service_name,\n",
" workspace = ws)\n",
"aci_service.wait_for_deployment(True)\n", "aci_service.wait_for_deployment(True)\n",
"print(aci_service.state)" "print(aci_service.state)"
] ]
@@ -361,7 +346,7 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"#Set the web service configuration\n", "#Set the web service configuration\n",
"aks_config = AksWebservice.deploy_configuration(enable_app_insights=True)" "aks_deployment_config = AksWebservice.deploy_configuration(enable_app_insights=True)"
] ]
}, },
{ {
@@ -379,12 +364,12 @@
"source": [ "source": [
"if aks_target.provisioning_state== \"Succeeded\": \n", "if aks_target.provisioning_state== \"Succeeded\": \n",
" aks_service_name ='aks-w-dc5'\n", " aks_service_name ='aks-w-dc5'\n",
" aks_service = Webservice.deploy_from_image(workspace = ws, \n", " aks_service = Model.deploy(ws,\n",
" name = aks_service_name,\n", " aks_service_name, \n",
" image = image,\n", " [model], \n",
" deployment_config = aks_config,\n", " inference_config, \n",
" deployment_target = aks_target\n", " aks_deployment_config, \n",
" )\n", " deployment_target = aks_target) \n",
" aks_service.wait_for_deployment(show_output = True)\n", " aks_service.wait_for_deployment(show_output = True)\n",
" print(aks_service.state)\n", " print(aks_service.state)\n",
"else:\n", "else:\n",
@@ -464,7 +449,6 @@
"%%time\n", "%%time\n",
"aks_service.delete()\n", "aks_service.delete()\n",
"aci_service.delete()\n", "aci_service.delete()\n",
"image.delete()\n",
"model.delete()" "model.delete()"
] ]
} }

View File

@@ -243,7 +243,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Create container image\n", "### Setting up inference configuration\n",
"First we create a YAML file that specifies which dependencies we would like to see in our container." "First we create a YAML file that specifies which dependencies we would like to see in our container."
] ]
}, },
@@ -265,7 +265,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Then we have Azure ML create the container. This step will likely take a few minutes." "Then we create the inference configuration."
] ]
}, },
{ {
@@ -274,48 +274,19 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.image import ContainerImage\n", "from azureml.core.model import InferenceConfig\n",
"\n", "\n",
"image_config = ContainerImage.image_configuration(execution_script = \"score.py\",\n", "inference_config = InferenceConfig(runtime= \"python\", \n",
" runtime = \"python\",\n", " entry_script=\"score.py\",\n",
" conda_file = \"myenv.yml\",\n", " conda_file=\"myenv.yml\",\n",
" docker_file = \"Dockerfile\",\n", " extra_docker_file_steps = \"Dockerfile\")"
" description = \"TinyYOLO ONNX Demo\",\n",
" tags = {\"demo\": \"onnx\"}\n",
" )\n",
"\n",
"\n",
"image = ContainerImage.create(name = \"onnxyolo\",\n",
" models = [model],\n",
" image_config = image_config,\n",
" workspace = ws)\n",
"\n",
"image.wait_for_creation(show_output = True)"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"In case you need to debug your code, the next line of code accesses the log file." "### Deploy the model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(image.image_build_log_uri)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We're all set! Let's get our model chugging.\n",
"\n",
"### Deploy the container image"
] ]
}, },
{ {
@@ -336,7 +307,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"The following cell will likely take a few minutes to run as well." "The following cell will take a few minutes to run as the model gets packaged up and deployed to ACI."
] ]
}, },
{ {
@@ -348,14 +319,9 @@
"from azureml.core.webservice import Webservice\n", "from azureml.core.webservice import Webservice\n",
"from random import randint\n", "from random import randint\n",
"\n", "\n",
"aci_service_name = 'onnx-tinyyolo'+str(randint(0,100))\n", "aci_service_name = 'my-aci-service-15ad'\n",
"print(\"Service\", aci_service_name)\n", "print(\"Service\", aci_service_name)\n",
"\n", "aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aciconfig)\n",
"aci_service = Webservice.deploy_from_image(deployment_config = aciconfig,\n",
" image = image,\n",
" name = aci_service_name,\n",
" workspace = ws)\n",
"\n",
"aci_service.wait_for_deployment(True)\n", "aci_service.wait_for_deployment(True)\n",
"print(aci_service.state)" "print(aci_service.state)"
] ]

View File

@@ -54,7 +54,7 @@
"\n", "\n",
"### 3. Download sample data and pre-trained ONNX model from ONNX Model Zoo.\n", "### 3. Download sample data and pre-trained ONNX model from ONNX Model Zoo.\n",
"\n", "\n",
"In the following lines of code, we download [the trained ONNX Emotion FER+ model and corresponding test data](https://github.com/onnx/models/tree/master/emotion_ferplus) and place them in the same folder as this tutorial notebook. For more information about the FER+ dataset, please visit Microsoft Researcher Emad Barsoum's [FER+ source data repository](https://github.com/ebarsoum/FERPlus)." "In the following lines of code, we download [the trained ONNX Emotion FER+ model and corresponding test data](https://github.com/onnx/models/tree/master/vision/body_analysis/emotion_ferplus) and place them in the same folder as this tutorial notebook. For more information about the FER+ dataset, please visit Microsoft Researcher Emad Barsoum's [FER+ source data repository](https://github.com/ebarsoum/FERPlus)."
] ]
}, },
{ {
@@ -176,7 +176,7 @@
"source": [ "source": [
"### ONNX FER+ Model Methodology\n", "### ONNX FER+ Model Methodology\n",
"\n", "\n",
"The image classification model we are using is pre-trained using Microsoft's deep learning cognitive toolkit, [CNTK](https://github.com/Microsoft/CNTK), from the [ONNX model zoo](http://github.com/onnx/models). The model zoo has many other models that can be deployed on cloud providers like AzureML without any additional training. To ensure that our cloud deployed model works, we use testing data from the well-known FER+ data set, provided as part of the [trained Emotion Recognition model](https://github.com/onnx/models/tree/master/emotion_ferplus) in the ONNX model zoo.\n", "The image classification model we are using is pre-trained using Microsoft's deep learning cognitive toolkit, [CNTK](https://github.com/Microsoft/CNTK), from the [ONNX model zoo](http://github.com/onnx/models). The model zoo has many other models that can be deployed on cloud providers like AzureML without any additional training. To ensure that our cloud deployed model works, we use testing data from the well-known FER+ data set, provided as part of the [trained Emotion Recognition model](https://github.com/onnx/models/tree/master/vision/body_analysis/emotion_ferplus) in the ONNX model zoo.\n",
"\n", "\n",
"The original Facial Emotion Recognition (FER) Dataset was released in 2013 by Pierre-Luc Carrier and Aaron Courville as part of a [Kaggle Competition](https://www.kaggle.com/c/challenges-in-representation-learning-facial-expression-recognition-challenge/data), but some of the labels are not entirely appropriate for the expression. In the FER+ Dataset, each photo was evaluated by at least 10 croud sourced reviewers, creating a more accurate basis for ground truth. \n", "The original Facial Emotion Recognition (FER) Dataset was released in 2013 by Pierre-Luc Carrier and Aaron Courville as part of a [Kaggle Competition](https://www.kaggle.com/c/challenges-in-representation-learning-facial-expression-recognition-challenge/data), but some of the labels are not entirely appropriate for the expression. In the FER+ Dataset, each photo was evaluated by at least 10 croud sourced reviewers, creating a more accurate basis for ground truth. \n",
"\n", "\n",
@@ -341,9 +341,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Create the Container Image\n", "### Setup inference configuration"
"\n",
"This step will likely take a few minutes."
] ]
}, },
{ {
@@ -352,48 +350,19 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.image import ContainerImage\n", "from azureml.core.model import InferenceConfig\n",
"\n", "\n",
"image_config = ContainerImage.image_configuration(execution_script = \"score.py\",\n", "inference_config = InferenceConfig(runtime= \"python\", \n",
" runtime = \"python\",\n", " entry_script=\"score.py\",\n",
" conda_file = \"myenv.yml\",\n", " conda_file=\"myenv.yml\",\n",
" docker_file = \"Dockerfile\",\n", " extra_docker_file_steps = \"Dockerfile\")"
" description = \"Emotion ONNX Runtime container\",\n",
" tags = {\"demo\": \"onnx\"})\n",
"\n",
"\n",
"image = ContainerImage.create(name = \"onnximage\",\n",
" # this is the model object\n",
" models = [model],\n",
" image_config = image_config,\n",
" workspace = ws)\n",
"\n",
"image.wait_for_creation(show_output = True)"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"In case you need to debug your code, the next line of code accesses the log file." "### Deploy the model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(image.image_build_log_uri)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We're all done specifying what we want our virtual machine to do. Let's configure and deploy our container image.\n",
"\n",
"### Deploy the container image"
] ]
}, },
{ {
@@ -410,6 +379,13 @@
" description = 'ONNX for emotion recognition model')" " description = 'ONNX for emotion recognition model')"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following cell will likely take a few minutes to run as well."
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
@@ -420,23 +396,11 @@
"\n", "\n",
"aci_service_name = 'onnx-demo-emotion'\n", "aci_service_name = 'onnx-demo-emotion'\n",
"print(\"Service\", aci_service_name)\n", "print(\"Service\", aci_service_name)\n",
"\n", "aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aciconfig)\n",
"aci_service = Webservice.deploy_from_image(deployment_config = aciconfig,\n",
" image = image,\n",
" name = aci_service_name,\n",
" workspace = ws)\n",
"\n",
"aci_service.wait_for_deployment(True)\n", "aci_service.wait_for_deployment(True)\n",
"print(aci_service.state)" "print(aci_service.state)"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following cell will likely take a few minutes to run as well."
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
@@ -470,7 +434,7 @@
"\n", "\n",
"### Useful Helper Functions\n", "### Useful Helper Functions\n",
"\n", "\n",
"We preprocess and postprocess our data (see score.py file) using the helper functions specified in the [ONNX FER+ Model page in the Model Zoo repository](https://github.com/onnx/models/tree/master/emotion_ferplus)." "We preprocess and postprocess our data (see score.py file) using the helper functions specified in the [ONNX FER+ Model page in the Model Zoo repository](https://github.com/onnx/models/tree/master/vision/body_analysis/emotion_ferplus)."
] ]
}, },
{ {

View File

@@ -54,7 +54,7 @@
"\n", "\n",
"### 3. Download sample data and pre-trained ONNX model from ONNX Model Zoo.\n", "### 3. Download sample data and pre-trained ONNX model from ONNX Model Zoo.\n",
"\n", "\n",
"In the following lines of code, we download [the trained ONNX MNIST model and corresponding test data](https://github.com/onnx/models/tree/master/mnist) and place them in the same folder as this tutorial notebook. For more information about the MNIST dataset, please visit [Yan LeCun's website](http://yann.lecun.com/exdb/mnist/)." "In the following lines of code, we download [the trained ONNX MNIST model and corresponding test data](https://github.com/onnx/models/tree/master/vision/classification/mnist) and place them in the same folder as this tutorial notebook. For more information about the MNIST dataset, please visit [Yan LeCun's website](http://yann.lecun.com/exdb/mnist/)."
] ]
}, },
{ {
@@ -187,7 +187,7 @@
"source": [ "source": [
"### ONNX MNIST Model Methodology\n", "### ONNX MNIST Model Methodology\n",
"\n", "\n",
"The image classification model we are using is pre-trained using Microsoft's deep learning cognitive toolkit, [CNTK](https://github.com/Microsoft/CNTK), from the [ONNX model zoo](http://github.com/onnx/models). The model zoo has many other models that can be deployed on cloud providers like AzureML without any additional training. To ensure that our cloud deployed model works, we use testing data from the famous MNIST data set, provided as part of the [trained MNIST model](https://github.com/onnx/models/tree/master/mnist) in the ONNX model zoo.\n", "The image classification model we are using is pre-trained using Microsoft's deep learning cognitive toolkit, [CNTK](https://github.com/Microsoft/CNTK), from the [ONNX model zoo](http://github.com/onnx/models). The model zoo has many other models that can be deployed on cloud providers like AzureML without any additional training. To ensure that our cloud deployed model works, we use testing data from the famous MNIST data set, provided as part of the [trained MNIST model](https://github.com/onnx/models/tree/master/vision/classification/mnist) in the ONNX model zoo.\n",
"\n", "\n",
"***Input: Handwritten Images from MNIST Dataset***\n", "***Input: Handwritten Images from MNIST Dataset***\n",
"\n", "\n",
@@ -325,8 +325,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Create the Container Image\n", "### Create Inference Configuration"
"This step will likely take a few minutes."
] ]
}, },
{ {
@@ -335,48 +334,19 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.image import ContainerImage\n", "from azureml.core.model import InferenceConfig\n",
"\n", "\n",
"image_config = ContainerImage.image_configuration(execution_script = \"score.py\",\n", "inference_config = InferenceConfig(runtime= \"python\", \n",
" runtime = \"python\",\n", " entry_script=\"score.py\",\n",
" conda_file = \"myenv.yml\",\n", " extra_docker_file_steps = \"Dockerfile\",\n",
" docker_file = \"Dockerfile\",\n", " conda_file=\"myenv.yml\")"
" description = \"MNIST ONNX Runtime container\",\n",
" tags = {\"demo\": \"onnx\"}) \n",
"\n",
"\n",
"image = ContainerImage.create(name = \"onnximage\",\n",
" # this is the model object\n",
" models = [model],\n",
" image_config = image_config,\n",
" workspace = ws)\n",
"\n",
"image.wait_for_creation(show_output = True)"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"In case you need to debug your code, the next line of code accesses the log file." "### Deploy the model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(image.image_build_log_uri)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We're all done specifying what we want our virtual machine to do. Let's configure and deploy our container image.\n",
"\n",
"### Deploy the container image"
] ]
}, },
{ {
@@ -397,7 +367,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"The following cell will likely take a few minutes to run as well." "The following cell will likely take a few minutes to run."
] ]
}, },
{ {
@@ -410,12 +380,7 @@
"\n", "\n",
"aci_service_name = 'onnx-demo-mnist'\n", "aci_service_name = 'onnx-demo-mnist'\n",
"print(\"Service\", aci_service_name)\n", "print(\"Service\", aci_service_name)\n",
"\n", "aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aciconfig)\n",
"aci_service = Webservice.deploy_from_image(deployment_config = aciconfig,\n",
" image = image,\n",
" name = aci_service_name,\n",
" workspace = ws)\n",
"\n",
"aci_service.wait_for_deployment(True)\n", "aci_service.wait_for_deployment(True)\n",
"print(aci_service.state)" "print(aci_service.state)"
] ]

View File

@@ -28,7 +28,7 @@
"ONNX is an open format for representing machine learning and deep learning models. ONNX enables open and interoperable AI by enabling data scientists and developers to use the tools of their choice without worrying about lock-in and flexibility to deploy to a variety of platforms. ONNX is developed and supported by a community of partners including Microsoft, Facebook, and Amazon. For more information, explore the [ONNX website](http://onnx.ai).\n", "ONNX is an open format for representing machine learning and deep learning models. ONNX enables open and interoperable AI by enabling data scientists and developers to use the tools of their choice without worrying about lock-in and flexibility to deploy to a variety of platforms. ONNX is developed and supported by a community of partners including Microsoft, Facebook, and Amazon. For more information, explore the [ONNX website](http://onnx.ai).\n",
"\n", "\n",
"## ResNet50 Details\n", "## ResNet50 Details\n",
"ResNet classifies the major object in an input image into a set of 1000 pre-defined classes. For more information about the ResNet50 model and how it was created can be found on the [ONNX Model Zoo github](https://github.com/onnx/models/tree/master/models/image_classification/resnet). " "ResNet classifies the major object in an input image into a set of 1000 pre-defined classes. For more information about the ResNet50 model and how it was created can be found on the [ONNX Model Zoo github](https://github.com/onnx/models/tree/master/vision/classification/resnet). "
] ]
}, },
{ {
@@ -221,7 +221,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Create container image" "### Create inference configuration"
] ]
}, },
{ {
@@ -249,7 +249,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Then we have Azure ML create the container. This step will likely take a few minutes." "Create the inference configuration object"
] ]
}, },
{ {
@@ -258,48 +258,19 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.image import ContainerImage\n", "from azureml.core.model import InferenceConfig\n",
"\n", "\n",
"image_config = ContainerImage.image_configuration(execution_script = \"score.py\",\n", "inference_config = InferenceConfig(runtime= \"python\", \n",
" runtime = \"python\",\n", " entry_script=\"score.py\",\n",
" conda_file = \"myenv.yml\",\n", " conda_file=\"myenv.yml\",\n",
" docker_file = \"Dockerfile\",\n", " extra_docker_file_steps = \"Dockerfile\")"
" description = \"ONNX ResNet50 Demo\",\n",
" tags = {\"demo\": \"onnx\"}\n",
" )\n",
"\n",
"\n",
"image = ContainerImage.create(name = \"onnxresnet50v2\",\n",
" models = [model],\n",
" image_config = image_config,\n",
" workspace = ws)\n",
"\n",
"image.wait_for_creation(show_output = True)"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"In case you need to debug your code, the next line of code accesses the log file." "### Deploy the model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(image.image_build_log_uri)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We're all set! Let's get our model chugging.\n",
"\n",
"### Deploy the container image"
] ]
}, },
{ {
@@ -334,12 +305,7 @@
"\n", "\n",
"aci_service_name = 'onnx-demo-resnet50'+str(randint(0,100))\n", "aci_service_name = 'onnx-demo-resnet50'+str(randint(0,100))\n",
"print(\"Service\", aci_service_name)\n", "print(\"Service\", aci_service_name)\n",
"\n", "aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aciconfig)\n",
"aci_service = Webservice.deploy_from_image(deployment_config = aciconfig,\n",
" image = image,\n",
" name = aci_service_name,\n",
" workspace = ws)\n",
"\n",
"aci_service.wait_for_deployment(True)\n", "aci_service.wait_for_deployment(True)\n",
"print(aci_service.state)" "print(aci_service.state)"
] ]

View File

@@ -28,7 +28,7 @@
"ONNX is an open format for representing machine learning and deep learning models. ONNX enables open and interoperable AI by enabling data scientists and developers to use the tools of their choice without worrying about lock-in and flexibility to deploy to a variety of platforms. ONNX is developed and supported by a community of partners including Microsoft, Facebook, and Amazon. For more information, explore the [ONNX website](http://onnx.ai).\n", "ONNX is an open format for representing machine learning and deep learning models. ONNX enables open and interoperable AI by enabling data scientists and developers to use the tools of their choice without worrying about lock-in and flexibility to deploy to a variety of platforms. ONNX is developed and supported by a community of partners including Microsoft, Facebook, and Amazon. For more information, explore the [ONNX website](http://onnx.ai).\n",
"\n", "\n",
"## MNIST Details\n", "## MNIST Details\n",
"The Modified National Institute of Standards and Technology (MNIST) dataset consists of 70,000 grayscale images. Each image is a handwritten digit of 28x28 pixels, representing numbers from 0 to 9. For more information about the MNIST dataset, please visit [Yan LeCun's website](http://yann.lecun.com/exdb/mnist/). For more information about the MNIST model and how it was created can be found on the [ONNX Model Zoo github](https://github.com/onnx/models/tree/master/mnist). " "The Modified National Institute of Standards and Technology (MNIST) dataset consists of 70,000 grayscale images. Each image is a handwritten digit of 28x28 pixels, representing numbers from 0 to 9. For more information about the MNIST dataset, please visit [Yan LeCun's website](http://yann.lecun.com/exdb/mnist/). For more information about the MNIST model and how it was created can be found on the [ONNX Model Zoo github](https://github.com/onnx/models/tree/master/vision/classification/mnist). "
] ]
}, },
{ {
@@ -401,7 +401,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Create container image\n", "### Create inference configuration\n",
"First we create a YAML file that specifies which dependencies we would like to see in our container." "First we create a YAML file that specifies which dependencies we would like to see in our container."
] ]
}, },
@@ -423,7 +423,7 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"Then we have Azure ML create the container. This step will likely take a few minutes." "Then we setup the inference configuration "
] ]
}, },
{ {
@@ -432,48 +432,19 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.image import ContainerImage\n", "from azureml.core.model import InferenceConfig\n",
"\n", "\n",
"image_config = ContainerImage.image_configuration(execution_script = \"score.py\",\n", "inference_config = InferenceConfig(runtime= \"python\", \n",
" runtime = \"python\",\n", " entry_script=\"score.py\",\n",
" conda_file = \"myenv.yml\",\n", " conda_file=\"myenv.yml\",\n",
" docker_file = \"Dockerfile\",\n", " extra_docker_file_steps = \"Dockerfile\")"
" description = \"MNIST ONNX Demo\",\n",
" tags = {\"demo\": \"onnx\"}\n",
" )\n",
"\n",
"\n",
"image = ContainerImage.create(name = \"onnxmnistdemo\",\n",
" models = [model],\n",
" image_config = image_config,\n",
" workspace = ws)\n",
"\n",
"image.wait_for_creation(show_output = True)"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"In case you need to debug your code, the next line of code accesses the log file." "### Deploy the model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(image.image_build_log_uri)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We're all set! Let's get our model chugging.\n",
"\n",
"### Deploy the container image"
] ]
}, },
{ {
@@ -504,16 +475,12 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.webservice import Webservice\n", "from azureml.core.webservice import Webservice\n",
"from azureml.core.model import Model\n",
"from random import randint\n", "from random import randint\n",
"\n", "\n",
"aci_service_name = 'onnx-demo-mnist'+str(randint(0,100))\n", "aci_service_name = 'onnx-demo-mnist'+str(randint(0,100))\n",
"print(\"Service\", aci_service_name)\n", "print(\"Service\", aci_service_name)\n",
"\n", "aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aciconfig)\n",
"aci_service = Webservice.deploy_from_image(deployment_config = aciconfig,\n",
" image = image,\n",
" name = aci_service_name,\n",
" workspace = ws)\n",
"\n",
"aci_service.wait_for_deployment(True)\n", "aci_service.wait_for_deployment(True)\n",
"print(aci_service.state)" "print(aci_service.state)"
] ]

View File

@@ -34,7 +34,6 @@
"from azureml.core import Workspace\n", "from azureml.core import Workspace\n",
"from azureml.core.compute import AksCompute, ComputeTarget\n", "from azureml.core.compute import AksCompute, ComputeTarget\n",
"from azureml.core.webservice import Webservice, AksWebservice\n", "from azureml.core.webservice import Webservice, AksWebservice\n",
"from azureml.core.image import Image\n",
"from azureml.core.model import Model" "from azureml.core.model import Model"
] ]
}, },
@@ -97,8 +96,51 @@
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"# Create an image\n", "# Create the Environment\n",
"Create an image using the registered model the script that will load and run the model." "Create an environment that the model will be deployed with"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core import Environment\n",
"from azureml.core.conda_dependencies import CondaDependencies \n",
"\n",
"conda_deps = CondaDependencies.create(conda_packages=['numpy','scikit-learn'], pip_packages=['azureml-defaults'])\n",
"myenv = Environment(name='myenv')\n",
"myenv.python.conda_dependencies = conda_deps"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Use a custom Docker image\n",
"\n",
"You can also specify a custom Docker image to be used as base image if you don't want to use the default base image provided by Azure ML. Please make sure the custom Docker image has Ubuntu >= 16.04, Conda >= 4.5.\\* and Python(3.5.\\* or 3.6.\\*).\n",
"\n",
"Only supported with `python` runtime.\n",
"```python\n",
"# use an image available in public Container Registry without authentication\n",
"myenv.docker.base_image = \"mcr.microsoft.com/azureml/o16n-sample-user-base/ubuntu-miniconda\"\n",
"\n",
"# or, use an image available in a private Container Registry\n",
"myenv.docker.base_image = \"myregistry.azurecr.io/mycustomimage:1.0\"\n",
"myenv.docker.base_image_registry.address = \"myregistry.azurecr.io\"\n",
"myenv.docker.base_image_registry.username = \"username\"\n",
"myenv.docker.base_image_registry.password = \"password\"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Write the Entry Script\n",
"Write the script that will be used to predict on your model"
] ]
}, },
{ {
@@ -136,67 +178,23 @@
" return error" " return error"
] ]
}, },
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.conda_dependencies import CondaDependencies \n",
"\n",
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn'])\n",
"\n",
"with open(\"myenv.yml\",\"w\") as f:\n",
" f.write(myenv.serialize_to_string())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.image import ContainerImage\n",
"\n",
"image_config = ContainerImage.image_configuration(execution_script = \"score.py\",\n",
" runtime = \"python\",\n",
" conda_file = \"myenv.yml\",\n",
" description = \"Image with ridge regression model\",\n",
" tags = {'area': \"diabetes\", 'type': \"regression\"}\n",
" )\n",
"\n",
"image = ContainerImage.create(name = \"myimage1\",\n",
" # this is the model object\n",
" models = [model],\n",
" image_config = image_config,\n",
" workspace = ws)\n",
"\n",
"image.wait_for_creation(show_output = True)"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"#### Use a custom Docker image\n", "# Create the InferenceConfig\n",
"Create the inference config that will be used when deploying the model"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.model import InferenceConfig\n",
"\n", "\n",
"You can also specify a custom Docker image to be used as base image if you don't want to use the default base image provided by Azure ML. Please make sure the custom Docker image has Ubuntu >= 16.04, Conda >= 4.5.\\* and Python(3.5.\\* or 3.6.\\*).\n", "inf_config = InferenceConfig(entry_script='score.py', environment=myenv)"
"\n",
"Only Supported for `ContainerImage`(from azureml.core.image) with `python` runtime.\n",
"```python\n",
"# use an image available in public Container Registry without authentication\n",
"image_config.base_image = \"mcr.microsoft.com/azureml/o16n-sample-user-base/ubuntu-miniconda\"\n",
"\n",
"# or, use an image available in a private Container Registry\n",
"image_config.base_image = \"myregistry.azurecr.io/mycustomimage:1.0\"\n",
"image_config.base_image_registry.address = \"myregistry.azurecr.io\"\n",
"image_config.base_image_registry.username = \"username\"\n",
"image_config.base_image_registry.password = \"password\"\n",
"\n",
"# or, use an image built during training.\n",
"image_config.base_image = run.properties[\"AzureML.DerivedImageName\"]\n",
"```\n",
"You can get the address of training image from the properties of a Run object. Only new runs submitted with azureml-sdk>=1.0.22 to AMLCompute targets will have the 'AzureML.DerivedImageName' property. Instructions on how to get a Run can be found in [manage-runs](../../training/manage-runs/manage-runs.ipynb). \n"
] ]
}, },
{ {
@@ -237,23 +235,21 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"'''\n", "# from azureml.core.compute import ComputeTarget, AksCompute\n",
"from azureml.core.compute import ComputeTarget, AksCompute\n",
"\n", "\n",
"# Create the compute configuration and set virtual network information\n", "# # Create the compute configuration and set virtual network information\n",
"config = AksCompute.provisioning_configuration(location=\"eastus2\")\n", "# config = AksCompute.provisioning_configuration(location=\"eastus2\")\n",
"config.vnet_resourcegroup_name = \"mygroup\"\n", "# config.vnet_resourcegroup_name = \"mygroup\"\n",
"config.vnet_name = \"mynetwork\"\n", "# config.vnet_name = \"mynetwork\"\n",
"config.subnet_name = \"default\"\n", "# config.subnet_name = \"default\"\n",
"config.service_cidr = \"10.0.0.0/16\"\n", "# config.service_cidr = \"10.0.0.0/16\"\n",
"config.dns_service_ip = \"10.0.0.10\"\n", "# config.dns_service_ip = \"10.0.0.10\"\n",
"config.docker_bridge_cidr = \"172.17.0.1/16\"\n", "# config.docker_bridge_cidr = \"172.17.0.1/16\"\n",
"\n", "\n",
"# Create the compute target\n", "# # Create the compute target\n",
"aks_target = ComputeTarget.create(workspace = ws,\n", "# aks_target = ComputeTarget.create(workspace = ws,\n",
" name = \"myaks\",\n", "# name = \"myaks\",\n",
" provisioning_configuration = config)\n", "# provisioning_configuration = config)"
"'''"
] ]
}, },
{ {
@@ -300,17 +296,15 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"'''\n", "# # Use the default configuration (can also provide parameters to customize)\n",
"# Use the default configuration (can also provide parameters to customize)\n", "# resource_id = '/subscriptions/92c76a2f-0e1c-4216-b65e-abf7a3f34c1e/resourcegroups/raymondsdk0604/providers/Microsoft.ContainerService/managedClusters/my-aks-0605d37425356b7d01'\n",
"resource_id = '/subscriptions/92c76a2f-0e1c-4216-b65e-abf7a3f34c1e/resourcegroups/raymondsdk0604/providers/Microsoft.ContainerService/managedClusters/my-aks-0605d37425356b7d01'\n",
"\n", "\n",
"create_name='my-existing-aks' \n", "# create_name='my-existing-aks' \n",
"# Create the cluster\n", "# # Create the cluster\n",
"attach_config = AksCompute.attach_configuration(resource_id=resource_id)\n", "# attach_config = AksCompute.attach_configuration(resource_id=resource_id)\n",
"aks_target = ComputeTarget.attach(workspace=ws, name=create_name, attach_configuration=attach_config)\n", "# aks_target = ComputeTarget.attach(workspace=ws, name=create_name, attach_configuration=attach_config)\n",
"# Wait for the operation to complete\n", "# # Wait for the operation to complete\n",
"aks_target.wait_for_completion(True)\n", "# aks_target.wait_for_completion(True)"
"'''"
] ]
}, },
{ {
@@ -326,8 +320,11 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"#Set the web service configuration (using default here)\n", "# Set the web service configuration (using default here)\n",
"aks_config = AksWebservice.deploy_configuration()" "aks_config = AksWebservice.deploy_configuration()\n",
"\n",
"# # Enable token auth and disable (key) auth on the webservice\n",
"# aks_config = AksWebservice.deploy_configuration(token_auth_enabled=True, auth_enabled=False)\n"
] ]
}, },
{ {
@@ -339,11 +336,13 @@
"%%time\n", "%%time\n",
"aks_service_name ='aks-service-1'\n", "aks_service_name ='aks-service-1'\n",
"\n", "\n",
"aks_service = Webservice.deploy_from_image(workspace = ws, \n", "aks_service = Model.deploy(workspace=ws,\n",
" name = aks_service_name,\n", " name=aks_service_name,\n",
" image = image,\n", " models=[model],\n",
" deployment_config = aks_config,\n", " inference_config=inf_config,\n",
" deployment_target = aks_target)\n", " deployment_config=aks_config,\n",
" deployment_target=aks_target)\n",
"\n",
"aks_service.wait_for_deployment(show_output = True)\n", "aks_service.wait_for_deployment(show_output = True)\n",
"print(aks_service.state)" "print(aks_service.state)"
] ]
@@ -390,11 +389,12 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"# retreive the API keys. AML generates two keys.\n", "# # if (key) auth is enabled, retrieve the API keys. AML generates two keys.\n",
"'''\n", "# key1, Key2 = aks_service.get_keys()\n",
"key1, Key2 = aks_service.get_keys()\n", "# print(key1)\n",
"print(key1)\n", "\n",
"'''" "# # if token auth is enabled, retrieve the token.\n",
"# access_token, refresh_after = aks_service.get_token()"
] ]
}, },
{ {
@@ -404,27 +404,28 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"# construct raw HTTP request and send to the service\n", "# construct raw HTTP request and send to the service\n",
"'''\n", "# %%time\n",
"%%time\n",
"\n", "\n",
"import requests\n", "# import requests\n",
"\n", "\n",
"import json\n", "# import json\n",
"\n", "\n",
"test_sample = json.dumps({'data': [\n", "# test_sample = json.dumps({'data': [\n",
" [1,2,3,4,5,6,7,8,9,10], \n", "# [1,2,3,4,5,6,7,8,9,10], \n",
" [10,9,8,7,6,5,4,3,2,1]\n", "# [10,9,8,7,6,5,4,3,2,1]\n",
"]})\n", "# ]})\n",
"test_sample = bytes(test_sample,encoding = 'utf8')\n", "# test_sample = bytes(test_sample,encoding = 'utf8')\n",
"\n", "\n",
"# Don't forget to add key to the HTTP header.\n", "# # If (key) auth is enabled, don't forget to add key to the HTTP header.\n",
"headers = {'Content-Type':'application/json', 'Authorization': 'Bearer ' + key1}\n", "# headers = {'Content-Type':'application/json', 'Authorization': 'Bearer ' + key1}\n",
"\n", "\n",
"resp = requests.post(aks_service.scoring_uri, test_sample, headers=headers)\n", "# # If token auth is enabled, don't forget to add token to the HTTP header.\n",
"# headers = {'Content-Type':'application/json', 'Authorization': 'Bearer ' + access_token}\n",
"\n",
"# resp = requests.post(aks_service.scoring_uri, test_sample, headers=headers)\n",
"\n", "\n",
"\n", "\n",
"print(\"prediction:\", resp.text)\n", "# print(\"prediction:\", resp.text)"
"'''"
] ]
}, },
{ {
@@ -443,7 +444,6 @@
"source": [ "source": [
"%%time\n", "%%time\n",
"aks_service.delete()\n", "aks_service.delete()\n",
"image.delete()\n",
"model.delete()" "model.delete()"
] ]
} }

View File

@@ -0,0 +1,748 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Copyright (c) Microsoft Corporation. All rights reserved.\n",
"\n",
"Licensed under the MIT License."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/explain-model/azure-integration/remote-explanation/explain-model-on-amlcompute.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Train and explain models remotely via Azure Machine Learning Compute\n",
"\n",
"\n",
"_**This notebook showcases how to use the Azure Machine Learning Interpretability SDK to train and explain a regression model remotely on an Azure Machine Leanrning Compute Target (AMLCompute).**_\n",
"\n",
"\n",
"\n",
"\n",
"## Table of Contents\n",
"\n",
"1. [Introduction](#Introduction)\n",
"1. [Setup](#Setup)\n",
" 1. Initialize a Workspace\n",
" 1. Create an Experiment\n",
" 1. Introduction to AmlCompute\n",
" 1. Submit an AmlCompute run in a few different ways\n",
" 1. Option 1: Provision as a run based compute target \n",
" 1. Option 2: Provision as a persistent compute target (Basic)\n",
" 1. Option 3: Provision as a persistent compute target (Advanced)\n",
"1. Additional operations to perform on AmlCompute\n",
"1. [Download model explanations from Azure Machine Learning Run History](#Download)\n",
"1. [Visualize explanations](#Visualize)\n",
"1. [Next steps](#Next)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction\n",
"\n",
"This notebook showcases how to train and explain a regression model remotely via Azure Machine Learning Compute (AMLCompute), and download the calculated explanations locally for visualization.\n",
"It demonstrates the API calls that you need to make to submit a run for training and explaining a model to AMLCompute, download the compute explanations remotely, and visualizing the global and local explanations via a visualization dashboard that provides an interactive way of discovering patterns in model predictions and downloaded explanations.\n",
"\n",
"We will showcase one of the tabular data explainers: TabularExplainer (SHAP).\n",
"\n",
"Problem: Boston Housing Price Prediction with scikit-learn (train a model and run an explainer remotely via AMLCompute, and download and visualize the remotely-calculated explanations.)\n",
"\n",
"| ![explanations-run-history](./img/explanations-run-history.PNG) |\n",
"|:--:|\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup\n",
"If you are using an Azure Machine Learning Notebook VM, you are all set. Otherwise, make sure you go through the [configuration notebook](../../../configuration.ipynb) first if you haven't.\n",
"\n",
"\n",
"You will need to have extensions enabled prior to jupyter kernel starting to see the visualization dashboard.\n",
"```\n",
"(myenv) $ jupyter nbextension install --py --sys-prefix azureml.contrib.explain.model.visualize\n",
"(myenv) $ jupyter nbextension enable --py --sys-prefix azureml.contrib.explain.model.visualize\n",
"```\n",
"Or\n",
"\n",
"```\n",
"(myenv) $ jupyter nbextension install azureml.contrib.explain.model.visualize --user --py\n",
"(myenv) $ jupyter nbextension enable azureml.contrib.explain.model.visualize --user --py\n",
"```\n",
"\n",
"If you are using Jupyter Labs run the following commands instead:\n",
"```\n",
"(myenv) $ jupyter labextension install @jupyter-widgets/jupyterlab-manager\n",
"(myenv) $ jupyter labextension install microsoft-mli-widget\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Check core SDK version number\n",
"import azureml.core\n",
"\n",
"print(\"SDK version:\", azureml.core.VERSION)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Initialize a Workspace\n",
"\n",
"Initialize a workspace object from persisted configuration"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"create workspace"
]
},
"outputs": [],
"source": [
"from azureml.core import Workspace\n",
"\n",
"ws = Workspace.from_config()\n",
"print(ws.name, ws.resource_group, ws.location, ws.subscription_id, sep='\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create An Experiment\n",
"\n",
"**Experiment** is a logical container in an Azure ML Workspace. It hosts run records which can include run metrics and output artifacts from your experiments."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core import Experiment\n",
"experiment_name = 'explainer-remote-run-on-amlcompute'\n",
"experiment = Experiment(workspace=ws, name=experiment_name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction to AmlCompute\n",
"\n",
"Azure Machine Learning Compute is managed compute infrastructure that allows the user to easily create single to multi-node compute of the appropriate VM Family. It is created **within your workspace region** and is a resource that can be used by other users in your workspace. It autoscales by default to the max_nodes, when a job is submitted, and executes in a containerized environment packaging the dependencies as specified by the user. \n",
"\n",
"Since it is managed compute, job scheduling and cluster management are handled internally by Azure Machine Learning service. \n",
"\n",
"For more information on Azure Machine Learning Compute, please read [this article](https://docs.microsoft.com/azure/machine-learning/service/how-to-set-up-training-targets#amlcompute)\n",
"\n",
"If you are an existing BatchAI customer who is migrating to Azure Machine Learning, please read [this article](https://aka.ms/batchai-retirement)\n",
"\n",
"**Note**: As with other Azure services, there are limits on certain resources (for eg. AmlCompute quota) associated with the Azure Machine Learning service. Please read [this article](https://docs.microsoft.com/azure/machine-learning/service/how-to-manage-quotas) on the default limits and how to request more quota.\n",
"\n",
"\n",
"The training script `train_explain.py` is already created for you. Let's have a look."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Submit an AmlCompute run in a few different ways\n",
"\n",
"First lets check which VM families are available in your region. Azure is a regional service and some specialized SKUs (especially GPUs) are only available in certain regions. Since AmlCompute is created in the region of your workspace, we will use the supported_vms () function to see if the VM family we want to use ('STANDARD_D2_V2') is supported.\n",
"\n",
"You can also pass a different region to check availability and then re-create your workspace in that region through the [configuration notebook](../../../configuration.ipynb)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.compute import ComputeTarget, AmlCompute\n",
"\n",
"AmlCompute.supported_vmsizes(workspace=ws)\n",
"# AmlCompute.supported_vmsizes(workspace=ws, location='southcentralus')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create project directory\n",
"\n",
"Create a directory that will contain all the necessary code from your local machine that you will need access to on the remote resource. This includes the training script, and any additional files your training script depends on"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import shutil\n",
"\n",
"project_folder = './explainer-remote-run-on-amlcompute'\n",
"os.makedirs(project_folder, exist_ok=True)\n",
"shutil.copy('train_explain.py', project_folder)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Option 1: Provision as a run based compute target\n",
"\n",
"You can provision AmlCompute as a compute target at run-time. In this case, the compute is auto-created for your run, scales up to max_nodes that you specify, and then **deleted automatically** after the run completes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.runconfig import RunConfiguration\n",
"from azureml.core.conda_dependencies import CondaDependencies\n",
"from azureml.core.runconfig import DEFAULT_CPU_IMAGE\n",
"\n",
"# create a new runconfig object\n",
"run_config = RunConfiguration()\n",
"\n",
"# signal that you want to use AmlCompute to execute script.\n",
"run_config.target = \"amlcompute\"\n",
"\n",
"# AmlCompute will be created in the same region as workspace\n",
"# Set vm size for AmlCompute\n",
"run_config.amlcompute.vm_size = 'STANDARD_D2_V2'\n",
"\n",
"# enable Docker \n",
"run_config.environment.docker.enabled = True\n",
"\n",
"# set Docker base image to the default CPU-based image\n",
"run_config.environment.docker.base_image = DEFAULT_CPU_IMAGE\n",
"\n",
"# use conda_dependencies.yml to create a conda environment in the Docker image for execution\n",
"run_config.environment.python.user_managed_dependencies = False\n",
"\n",
"azureml_pip_packages = [\n",
" 'azureml-defaults', 'azureml-contrib-explain-model', 'azureml-core', 'azureml-telemetry',\n",
" 'azureml-explain-model', 'sklearn-pandas', 'azureml-dataprep'\n",
"]\n",
"\n",
"# specify CondaDependencies obj\n",
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn'],\n",
" pip_packages=azureml_pip_packages)\n",
"\n",
"# Now submit a run on AmlCompute\n",
"from azureml.core.script_run_config import ScriptRunConfig\n",
"\n",
"script_run_config = ScriptRunConfig(source_directory=project_folder,\n",
" script='train_explain.py',\n",
" run_config=run_config)\n",
"\n",
"run = experiment.submit(script_run_config)\n",
"\n",
"# Show run details\n",
"run"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note: if you need to cancel a run, you can follow [these instructions](https://aka.ms/aml-docs-cancel-run)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%time\n",
"# Shows output of the run on stdout.\n",
"run.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Option 2: Provision as a persistent compute target (Basic)\n",
"\n",
"You can provision a persistent AmlCompute resource by simply defining two parameters thanks to smart defaults. By default it autoscales from 0 nodes and provisions dedicated VMs to run your job in a container. This is useful when you want to continously re-use the same target, debug it between jobs or simply share the resource with other users of your workspace.\n",
"\n",
"* `vm_size`: VM family of the nodes provisioned by AmlCompute. Simply choose from the supported_vmsizes() above\n",
"* `max_nodes`: Maximum nodes to autoscale to while running a job on AmlCompute"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.compute import ComputeTarget, AmlCompute\n",
"from azureml.core.compute_target import ComputeTargetException\n",
"\n",
"# Choose a name for your CPU cluster\n",
"cpu_cluster_name = \"cpu-cluster\"\n",
"\n",
"# Verify that cluster does not exist already\n",
"try:\n",
" cpu_cluster = ComputeTarget(workspace=ws, name=cpu_cluster_name)\n",
" print('Found existing cluster, use it.')\n",
"except ComputeTargetException:\n",
" compute_config = AmlCompute.provisioning_configuration(vm_size='STANDARD_D2_V2',\n",
" max_nodes=4)\n",
" cpu_cluster = ComputeTarget.create(ws, cpu_cluster_name, compute_config)\n",
"\n",
"cpu_cluster.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Configure & Run"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.runconfig import RunConfiguration\n",
"from azureml.core.conda_dependencies import CondaDependencies\n",
"\n",
"# create a new RunConfig object\n",
"run_config = RunConfiguration(framework=\"python\")\n",
"\n",
"# Set compute target to AmlCompute target created in previous step\n",
"run_config.target = cpu_cluster.name\n",
"\n",
"# enable Docker \n",
"run_config.environment.docker.enabled = True\n",
"\n",
"azureml_pip_packages = [\n",
" 'azureml-defaults', 'azureml-contrib-explain-model', 'azureml-core', 'azureml-telemetry',\n",
" 'azureml-explain-model', 'azureml-dataprep'\n",
"]\n",
"\n",
"# specify CondaDependencies obj\n",
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn'],\n",
" pip_packages=azureml_pip_packages)\n",
"\n",
"from azureml.core import Run\n",
"from azureml.core import ScriptRunConfig\n",
"\n",
"src = ScriptRunConfig(source_directory=project_folder, \n",
" script='train_explain.py', \n",
" run_config=run_config) \n",
"run = experiment.submit(config=src)\n",
"run"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%time\n",
"# Shows output of the run on stdout.\n",
"run.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run.get_metrics()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Option 3: Provision as a persistent compute target (Advanced)\n",
"\n",
"You can also specify additional properties or change defaults while provisioning AmlCompute using a more advanced configuration. This is useful when you want a dedicated cluster of 4 nodes (for example you can set the min_nodes and max_nodes to 4), or want the compute to be within an existing VNet in your subscription.\n",
"\n",
"In addition to `vm_size` and `max_nodes`, you can specify:\n",
"* `min_nodes`: Minimum nodes (default 0 nodes) to downscale to while running a job on AmlCompute\n",
"* `vm_priority`: Choose between 'dedicated' (default) and 'lowpriority' VMs when provisioning AmlCompute. Low Priority VMs use Azure's excess capacity and are thus cheaper but risk your run being pre-empted\n",
"* `idle_seconds_before_scaledown`: Idle time (default 120 seconds) to wait after run completion before auto-scaling to min_nodes\n",
"* `vnet_resourcegroup_name`: Resource group of the **existing** VNet within which AmlCompute should be provisioned\n",
"* `vnet_name`: Name of VNet\n",
"* `subnet_name`: Name of SubNet within the VNet"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.compute import ComputeTarget, AmlCompute\n",
"from azureml.core.compute_target import ComputeTargetException\n",
"\n",
"# Choose a name for your CPU cluster\n",
"cpu_cluster_name = \"cpu-cluster\"\n",
"\n",
"# Verify that cluster does not exist already\n",
"try:\n",
" cpu_cluster = ComputeTarget(workspace=ws, name=cpu_cluster_name)\n",
" print('Found existing cluster, use it.')\n",
"except ComputeTargetException:\n",
" compute_config = AmlCompute.provisioning_configuration(vm_size='STANDARD_D2_V2',\n",
" vm_priority='lowpriority',\n",
" min_nodes=2,\n",
" max_nodes=4,\n",
" idle_seconds_before_scaledown='300',\n",
" vnet_resourcegroup_name='<my-resource-group>',\n",
" vnet_name='<my-vnet-name>',\n",
" subnet_name='<my-subnet-name>')\n",
" cpu_cluster = ComputeTarget.create(ws, cpu_cluster_name, compute_config)\n",
"\n",
"cpu_cluster.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Configure & Run"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.runconfig import RunConfiguration\n",
"from azureml.core.conda_dependencies import CondaDependencies\n",
"\n",
"# create a new RunConfig object\n",
"run_config = RunConfiguration(framework=\"python\")\n",
"\n",
"# Set compute target to AmlCompute target created in previous step\n",
"run_config.target = cpu_cluster.name\n",
"\n",
"# enable Docker \n",
"run_config.environment.docker.enabled = True\n",
"\n",
"azureml_pip_packages = [\n",
" 'azureml-defaults', 'azureml-contrib-explain-model', 'azureml-core', 'azureml-telemetry',\n",
" 'azureml-explain-model', 'azureml-dataprep'\n",
"]\n",
"\n",
"\n",
"\n",
"# specify CondaDependencies obj\n",
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=['scikit-learn'],\n",
" pip_packages=azureml_pip_packages)\n",
"\n",
"from azureml.core import Run\n",
"from azureml.core import ScriptRunConfig\n",
"\n",
"src = ScriptRunConfig(source_directory=project_folder, \n",
" script='train_explain.py', \n",
" run_config=run_config) \n",
"run = experiment.submit(config=src)\n",
"run"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%time\n",
"# Shows output of the run on stdout.\n",
"run.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run.get_metrics()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.contrib.explain.model.explanation.explanation_client import ExplanationClient\n",
"\n",
"client = ExplanationClient.from_run(run)\n",
"# Get the top k (e.g., 4) most important features with their importance values\n",
"explanation = client.download_model_explanation(top_k=4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Additional operations to perform on AmlCompute\n",
"\n",
"You can perform more operations on AmlCompute such as updating the node counts or deleting the compute. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Get_status () gets the latest status of the AmlCompute target\n",
"cpu_cluster.get_status().serialize()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Update () takes in the min_nodes, max_nodes and idle_seconds_before_scaledown and updates the AmlCompute target\n",
"# cpu_cluster.update(min_nodes=1)\n",
"# cpu_cluster.update(max_nodes=10)\n",
"cpu_cluster.update(idle_seconds_before_scaledown=300)\n",
"# cpu_cluster.update(min_nodes=2, max_nodes=4, idle_seconds_before_scaledown=600)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Delete () is used to deprovision and delete the AmlCompute target. Useful if you want to re-use the compute name \n",
"# 'cpu-cluster' in this case but use a different VM family for instance.\n",
"\n",
"# cpu_cluster.delete()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Download \n",
"1. Download model explanation data."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.contrib.explain.model.explanation.explanation_client import ExplanationClient\n",
"\n",
"# Get model explanation data\n",
"client = ExplanationClient.from_run(run)\n",
"global_explanation = client.download_model_explanation()\n",
"local_importance_values = global_explanation.local_importance_values\n",
"expected_values = global_explanation.expected_values\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Or you can use the saved run.id to retrive the feature importance values\n",
"client = ExplanationClient.from_run_id(ws, experiment_name, run.id)\n",
"global_explanation = client.download_model_explanation()\n",
"local_importance_values = global_explanation.local_importance_values\n",
"expected_values = global_explanation.expected_values"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Get the top k (e.g., 4) most important features with their importance values\n",
"global_explanation_topk = client.download_model_explanation(top_k=4)\n",
"global_importance_values = global_explanation_topk.get_ranked_global_values()\n",
"global_importance_names = global_explanation_topk.get_ranked_global_names()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print('global importance values: {}'.format(global_importance_values))\n",
"print('global importance names: {}'.format(global_importance_names))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2. Download model file."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# retrieve model for visualization and deployment\n",
"from azureml.core.model import Model\n",
"from sklearn.externals import joblib\n",
"original_model = Model(ws, 'original_model')\n",
"model_path = original_model.download(exist_ok=True)\n",
"original_model = joblib.load(model_path)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"3. Download test dataset."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# retrieve x_test for visualization\n",
"from sklearn.externals import joblib\n",
"x_test_path = './x_test_boston_housing.pkl'\n",
"run.download_file('x_test_boston_housing.pkl', output_file_path=x_test_path)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"x_test = joblib.load('x_test_boston_housing.pkl')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Visualize\n",
"Load the visualization dashboard"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.contrib.explain.model.visualize import ExplanationDashboard"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ExplanationDashboard(global_explanation, original_model, x_test)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Next\n",
"Learn about other use cases of the explain package on a:\n",
"1. [Training time: regression problem](../../tabular-data/explain-binary-classification-local.ipynb) \n",
"1. [Training time: binary classification problem](../../tabular-data/explain-binary-classification-local.ipynb)\n",
"1. [Training time: multiclass classification problem](../../tabular-data/explain-multiclass-classification-local.ipynb)\n",
"1. Explain models with engineered features:\n",
" 1. [Simple feature transformations](../../tabular-data/simple-feature-transformations-explain-local.ipynb)\n",
" 1. [Advanced feature transformations](../../tabular-data/advanced-feature-transformations-explain-local.ipynb)\n",
"1. [Save model explanations via Azure Machine Learning Run History](../run-history/save-retrieve-explanations-run-history.ipynb)\n",
"1. Inferencing time: deploy a classification model and explainer:\n",
" 1. [Deploy a locally-trained model and explainer](../scoring-time/train-explain-model-locally-and-deploy.ipynb)\n",
" 1. [Deploy a remotely-trained model and explainer](../scoring-time/train-explain-model-on-amlcompute-and-deploy.ipynb)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"authors": [
{
"name": "mesameki"
}
],
"kernelspec": {
"display_name": "Python 3.6",
"language": "python",
"name": "python36"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,8 @@
name: explain-model-on-amlcompute
dependencies:
- pip:
- azureml-sdk
- azureml-explain-model
- azureml-contrib-explain-model
- sklearn-pandas
- azureml-dataprep

View File

@@ -0,0 +1,63 @@
# Copyright (c) Microsoft. All rights reserved.
# Licensed under the MIT license.
from sklearn import datasets
from sklearn.linear_model import Ridge
from azureml.explain.model.tabular_explainer import TabularExplainer
from azureml.contrib.explain.model.explanation.explanation_client import ExplanationClient
from sklearn.model_selection import train_test_split
from azureml.core.run import Run
from sklearn.externals import joblib
import os
import numpy as np
OUTPUT_DIR = './outputs/'
os.makedirs(OUTPUT_DIR, exist_ok=True)
boston_data = datasets.load_boston()
run = Run.get_context()
client = ExplanationClient.from_run(run)
X_train, X_test, y_train, y_test = train_test_split(boston_data.data,
boston_data.target,
test_size=0.2,
random_state=0)
# write x_test out as a pickle file for later visualization
x_test_pkl = 'x_test.pkl'
with open(x_test_pkl, 'wb') as file:
joblib.dump(value=X_test, filename=os.path.join(OUTPUT_DIR, x_test_pkl))
run.upload_file('x_test_boston_housing.pkl', os.path.join(OUTPUT_DIR, x_test_pkl))
alpha = 0.5
# Use Ridge algorithm to create a regression model
reg = Ridge(alpha)
model = reg.fit(X_train, y_train)
preds = reg.predict(X_test)
run.log('alpha', alpha)
model_file_name = 'ridge_{0:.2f}.pkl'.format(alpha)
# save model in the outputs folder so it automatically get uploaded
with open(model_file_name, 'wb') as file:
joblib.dump(value=reg, filename=os.path.join(OUTPUT_DIR,
model_file_name))
# register the model
run.upload_file('original_model.pkl', os.path.join('./outputs/', model_file_name))
original_model = run.register_model(model_name='original_model', model_path='original_model.pkl')
# Explain predictions on your local machine
tabular_explainer = TabularExplainer(model, X_train, features=boston_data.feature_names)
# Explain overall model predictions (global explanation)
# Passing in test dataset for evaluation examples - note it must be a representative sample of the original data
# x_train can be passed as well, but with more examples explanations it will
# take longer although they may be more accurate
global_explanation = tabular_explainer.explain_global(X_test)
# Uploading model explanation data for storage or visualization in webUX
# The explanation can then be downloaded on any compute
comment = 'Global explanation on regression model trained on boston dataset'
client.upload_model_explanation(global_explanation, comment=comment)

View File

@@ -241,7 +241,7 @@
"\n", "\n",
"azureml_pip_packages = [\n", "azureml_pip_packages = [\n",
" 'azureml-defaults', 'azureml-contrib-explain-model', 'azureml-core', 'azureml-telemetry',\n", " 'azureml-defaults', 'azureml-contrib-explain-model', 'azureml-core', 'azureml-telemetry',\n",
" 'azureml-explain-model'\n", " 'azureml-explain-model', 'azureml-dataprep'\n",
"]\n", "]\n",
" \n", " \n",
"\n", "\n",

View File

@@ -4,5 +4,5 @@ dependencies:
- azureml-sdk - azureml-sdk
- azureml-explain-model - azureml-explain-model
- azureml-contrib-explain-model - azureml-contrib-explain-model
- azureml-dataprep
- sklearn-pandas - sklearn-pandas
- azureml-dataprep

View File

@@ -460,7 +460,7 @@
"source": [ "source": [
"# Submit syntax\n", "# Submit syntax\n",
"# submit(experiment_name, \n", "# submit(experiment_name, \n",
"# pipeline_params=None, \n", "# pipeline_parameters=None, \n",
"# continue_on_step_failure=False, \n", "# continue_on_step_failure=False, \n",
"# regenerate_outputs=False)\n", "# regenerate_outputs=False)\n",
"\n", "\n",

View File

@@ -321,7 +321,11 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {
"tags": [
"hyperdriveconfig-remarks-sample"
]
},
"outputs": [], "outputs": [],
"source": [ "source": [
"hd_config = HyperDriveConfig(estimator=est, \n", "hd_config = HyperDriveConfig(estimator=est, \n",

View File

@@ -299,7 +299,7 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.pipelince.core import PipelineParameter\n", "from azureml.pipeline.core import PipelineParameter\n",
"\n", "\n",
"# Use the default blob storage\n", "# Use the default blob storage\n",
"def_blob_store = Datastore(ws, \"workspaceblobstore\")\n", "def_blob_store = Datastore(ws, \"workspaceblobstore\")\n",

View File

@@ -28,14 +28,14 @@
"metadata": {}, "metadata": {},
"source": [ "source": [
"## Introduction\n", "## Introduction\n",
"In this example we showcase how you can use the `azureml.dataprep` SDK to load and prepare data for AutoML via AML Pipeline. `azureml.dataprep` can also be used standalone; full documentation can be found [here](https://github.com/Microsoft/PendletonDocs).\n", "In this example we showcase how you can use AzureML Dataset to load data for AutoML via AML Pipeline. \n",
"\n", "\n",
"If you are using an Azure Machine Learning Notebook VM, you are all set. Otherwise, make sure you have executed the [configuration](https://aka.ms/pl-config) before running this notebook.\n", "If you are using an Azure Machine Learning Notebook VM, you are all set. Otherwise, make sure you have executed the [configuration](https://aka.ms/pl-config) before running this notebook.\n",
"\n", "\n",
"In this notebook you will learn how to:\n", "In this notebook you will learn how to:\n",
"1. Create an `Experiment` in an existing `Workspace`.\n", "1. Create an `Experiment` in an existing `Workspace`.\n",
"2. Create or Attach existing AmlCompute to a workspace.\n", "2. Create or Attach existing AmlCompute to a workspace.\n",
"3. Define data loading and preparation steps in a `Dataflow` using `azureml.dataprep`.\n", "3. Define data loading in a `TabularDataset`.\n",
"4. Configure AutoML using `AutoMLConfig`.\n", "4. Configure AutoML using `AutoMLConfig`.\n",
"5. Use AutoMLStep\n", "5. Use AutoMLStep\n",
"6. Train the model using AmlCompute\n", "6. Train the model using AmlCompute\n",
@@ -65,7 +65,6 @@
"import pandas as pd\n", "import pandas as pd\n",
"from sklearn import datasets\n", "from sklearn import datasets\n",
"import pkg_resources\n", "import pkg_resources\n",
"import azureml.dataprep as dprep\n",
"\n", "\n",
"import azureml.core\n", "import azureml.core\n",
"from azureml.core.experiment import Experiment\n", "from azureml.core.experiment import Experiment\n",
@@ -73,6 +72,7 @@
"from azureml.train.automl import AutoMLConfig\n", "from azureml.train.automl import AutoMLConfig\n",
"from azureml.core.compute import AmlCompute\n", "from azureml.core.compute import AmlCompute\n",
"from azureml.core.compute import ComputeTarget\n", "from azureml.core.compute import ComputeTarget\n",
"from azureml.core.dataset import Dataset\n",
"from azureml.core.runconfig import RunConfiguration\n", "from azureml.core.runconfig import RunConfiguration\n",
"from azureml.core.conda_dependencies import CondaDependencies\n", "from azureml.core.conda_dependencies import CondaDependencies\n",
"\n", "\n",
@@ -197,13 +197,10 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"# You can use `auto_read_file` which intelligently figures out delimiters and datatypes of a file.\n",
"# The data referenced here was a 1MB simple random sample of the Chicago Crime data into a local temporary directory.\n", "# The data referenced here was a 1MB simple random sample of the Chicago Crime data into a local temporary directory.\n",
"# You can also use `read_csv` and `to_*` transformations to read (with overridable delimiter)\n",
"# and convert column types manually.\n",
"example_data = 'https://dprepdata.blob.core.windows.net/demo/crime0-random.csv'\n", "example_data = 'https://dprepdata.blob.core.windows.net/demo/crime0-random.csv'\n",
"dflow = dprep.auto_read_file(example_data).skip(1) # Remove the header row.\n", "dataset = Dataset.Tabular.from_delimited_files(example_data)\n",
"dflow.get_profile()" "dataset.to_pandas_dataframe().describe()"
] ]
}, },
{ {
@@ -212,20 +209,18 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"# As `Primary Type` is our y data, we need to drop the values those are null in this column.\n", "dataset.take(5).to_pandas_dataframe()"
"dflow = dflow.drop_nulls('Primary Type')\n",
"dflow.head(5)"
] ]
}, },
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
"source": [ "source": [
"### Review the Data Preparation Result\n", "### Review the Dataset Result\n",
"\n", "\n",
"You can peek the result of a Dataflow at any range using `skip(i)` and `head(j)`. Doing so evaluates only `j` records for all the steps in the Dataflow, which makes it fast even against large datasets.\n", "You can peek the result of a TabularDataset at any range using `skip(i)` and `take(j).to_pandas_dataframe()`. Doing so evaluates only `j` records for all the steps in the TabularDataset, which makes it fast even against large datasets.\n",
"\n", "\n",
"`Dataflow` objects are immutable and are composed of a list of data preparation steps. A `Dataflow` object can be branched at any point for further usage." "`TabularDataset` objects are composed of a list of transformation steps (optional)."
] ]
}, },
{ {
@@ -234,8 +229,8 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"X = dflow.drop_columns(columns=['Primary Type', 'FBI Code'])\n", "X = dataset.drop_columns(columns=['Primary Type', 'FBI Code'])\n",
"y = dflow.keep_columns(columns=['Primary Type'], validate_column_exists=True)\n", "y = dataset.keep_columns(columns=['Primary Type'], validate=True)\n",
"print('X and y are ready!')" "print('X and y are ready!')"
] ]
}, },
@@ -441,8 +436,12 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"dflow_test = dprep.auto_read_file(path='https://dprepdata.blob.core.windows.net/demo/crime0-test.csv').skip(1)\n", "dataset = Dataset.Tabular.from_delimited_files(path='https://dprepdata.blob.core.windows.net/demo/crime0-test.csv')\n",
"dflow_test = dflow_test.drop_nulls('Primary Type')" "df_test = dataset_test.to_pandas_dataframe()\n",
"df_test = df_test[pd.notnull(df['Primary Type'])]\n",
"\n",
"y_test = df_test[['Primary Type']]\n",
"X_test = df_test.drop(['Primary Type', 'FBI Code'], axis=1)"
] ]
}, },
{ {
@@ -462,10 +461,6 @@
"source": [ "source": [
"from pandas_ml import ConfusionMatrix\n", "from pandas_ml import ConfusionMatrix\n",
"\n", "\n",
"y_test = dflow_test.keep_columns(columns=['Primary Type']).to_pandas_dataframe()\n",
"X_test = dflow_test.drop_columns(columns=['Primary Type', 'FBI Code']).to_pandas_dataframe()\n",
"\n",
"\n",
"ypred = best_model.predict(X_test)\n", "ypred = best_model.predict(X_test)\n",
"\n", "\n",
"cm = ConfusionMatrix(y_test['Primary Type'], ypred)\n", "cm = ConfusionMatrix(y_test['Primary Type'], ypred)\n",

View File

@@ -1,5 +1,12 @@
{ {
"cells": [ "cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/machine-learning-pipelines/nyc-taxi-data-regression-model-building/nyc-taxi-data-regression-model-building.png)"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
@@ -187,7 +194,19 @@
"metadata": {}, "metadata": {},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.core.compute import AmlCompute\n",
"from azureml.core.compute import ComputeTarget\n",
"\n",
"aml_compute = ws.get_default_compute_target(\"CPU\")\n", "aml_compute = ws.get_default_compute_target(\"CPU\")\n",
"\n",
"if aml_compute is None:\n",
" amlcompute_cluster_name = \"cpu-cluster\"\n",
" provisioning_config = AmlCompute.provisioning_configuration(vm_size = \"STANDARD_D2_V2\",\n",
" max_nodes = 4)\n",
"\n",
" aml_compute = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n",
" aml_compute.wait_for_completion(show_output = True, min_node_count = None, timeout_in_minutes = 20)\n",
"\n",
"aml_compute" "aml_compute"
] ]
}, },
@@ -735,6 +754,8 @@
"outputs": [], "outputs": [],
"source": [ "source": [
"%%writefile $train_model_folder/get_data.py\n", "%%writefile $train_model_folder/get_data.py\n",
"import os\n",
"import pandas as pd\n",
"\n", "\n",
"def get_data():\n", "def get_data():\n",
" print(\"In get_data\")\n", " print(\"In get_data\")\n",

View File

@@ -387,11 +387,15 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {
"tags": [
"pipelineparameterssample"
]
},
"outputs": [], "outputs": [],
"source": [ "source": [
"pipeline = Pipeline(workspace=ws, steps=[batch_score_step])\n", "pipeline = Pipeline(workspace=ws, steps=[batch_score_step])\n",
"pipeline_run = Experiment(ws, 'batch_scoring').submit(pipeline, pipeline_params={\"param_batch_size\": 20})" "pipeline_run = Experiment(ws, 'batch_scoring').submit(pipeline, pipeline_parameters={\"param_batch_size\": 20})"
] ]
}, },
{ {

View File

@@ -384,7 +384,7 @@
"source": [ "source": [
"pipeline = Pipeline(workspace=ws, steps=[stitch_video_step])\n", "pipeline = Pipeline(workspace=ws, steps=[stitch_video_step])\n",
"# submit the pipeline and provide values for the PipelineParameters used in the pipeline\n", "# submit the pipeline and provide values for the PipelineParameters used in the pipeline\n",
"pipeline_run = Experiment(ws, 'style_transfer').submit(pipeline, pipeline_params={\"style\": \"mosaic\", \"nodecount\": 3})" "pipeline_run = Experiment(ws, 'style_transfer').submit(pipeline, pipeline_parameters={\"style\": \"mosaic\", \"nodecount\": 3})"
] ]
}, },
{ {

View File

@@ -26,9 +26,10 @@
"\n", "\n",
" 1. Interactive Login Authentication\n", " 1. Interactive Login Authentication\n",
" 2. Azure CLI Authentication\n", " 2. Azure CLI Authentication\n",
" 3. Service Principal Authentication\n", " 3. Managed Service Identity (MSI) Authentication\n",
" 4. Service Principal Authentication\n",
" \n", " \n",
"The interactive authentication is suitable for local experimentation on your own computer. Azure CLI authentication is suitable if you are already using Azure CLI for managing Azure resources, and want to sign in only once. The Service Principal authentication is suitable for automated workflows, for example as part of Azure Devops build." "The interactive authentication is suitable for local experimentation on your own computer. Azure CLI authentication is suitable if you are already using Azure CLI for managing Azure resources, and want to sign in only once. The MSI and Service Principal authentication are suitable for automated workflows, for example as part of Azure Devops build."
] ]
}, },
{ {
@@ -145,6 +146,43 @@
"print(\"Found workspace {} at location {}\".format(ws.name, ws.location))" "print(\"Found workspace {} at location {}\".format(ws.name, ws.location))"
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### MSI Authentication\n",
"\n",
"__Note__: _MSI authentication is supported only when using SDK from Azure Virtual Machine. The code below will fail on local computer._\n",
"\n",
"When using Azure ML SDK on Azure Virtual Machine (VM), you can use Managed Service Identity (MSI) based authentication. This mode allows the VM connect to the Workspace without storing credentials in the Python code.\n",
"\n",
"As a pre-requisite, enable System-assigned Managed Identity for your VM as described in [this document](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/qs-configure-portal-windows-vm).\n",
"\n",
"Then, assign the VM access to your Workspace. For example from Azure Portal, navigate to your workspace, select __Access Control (IAM)__, __Add Role Assignment__, specify __Virtual Machine__ for __Assign Access To__ dropdown, and select your VM's identity.\n",
"\n",
"![msi assignment](images/msiaccess.PNG)\n",
"\n",
"After completing these steps, you can use authenticate using MsiAuthentication instance."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.authentication import MsiAuthentication\n",
"\n",
"msi_auth = MsiAuthentication()\n",
"\n",
"ws = Workspace(subscription_id=\"my-subscription-id\",\n",
" resource_group=\"my-ml-rg\",\n",
" workspace_name=\"my-ml-workspace\",\n",
" auth=msi_auth)\n",
"\n",
"print(\"Found workspace {} at location {}\".format(ws.name, ws.location))"
]
},
{ {
"cell_type": "markdown", "cell_type": "markdown",
"metadata": {}, "metadata": {},
@@ -238,6 +276,135 @@
"See [Register an application with the Microsoft identity platform](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) quickstart for more details about application registrations. " "See [Register an application with the Microsoft identity platform](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) quickstart for more details about application registrations. "
] ]
}, },
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Using Secrets in Remote Runs\n",
"\n",
"Sometimes, you may have to pass a secret to a remote run, for example username and password to authenticate against external data source.\n",
"\n",
"Azure ML SDK enables this use case through Key Vault associated with your workspace. The workflow for adding a secret is following.\n",
"\n",
"On local computer:\n",
"\n",
" 1. Read in a local secret, for example from environment variable or user input. To keep them secret, do not insert secret values into code as hard-coded strings.\n",
" 2. Obtain a reference to the keyvault\n",
" 3. Add the secret name-value pair in the key vault.\n",
" \n",
"The secret is then available for remote runs as shown further below.\n",
"\n",
"__Note__: The _azureml.core.keyvault.Keyvault_ is different from _azure.keyvault_ library. It is intended as simplified wrapper for setting, getting and listing user secrets in Workspace Key Vault."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os, uuid\n",
"\n",
"local_secret = os.environ.get(\"LOCAL_SECRET\", default = str(uuid.uuid4())) # Use random UUID as a substitute for real secret.\n",
"keyvault = ws.get_default_keyvault()\n",
"keyvault.set_secret(name=\"secret-name\", value = local_secret)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The _set_secret_ method adds a new secret if one doesn't exist, or updates an existing one with new value.\n",
"\n",
"You can list secret names you've added. This method doesn't return the values of the secrets."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"keyvault.list_secrets()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can retrieve the value of the secret, and validate that it matches the original value. \n",
"\n",
"__Note__: This method returns the secret value. Take care not to write the the secret value to output."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"retrieved_secret = keyvault.get_secret(name=\"secret-name\")\n",
"local_secret==retrieved_secret"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In submitted runs on local and remote compute, you can use the get_secret method of Run instance to get the secret value from Key Vault. \n",
"\n",
"The method gives you a simple shortcut: the Run instance is aware of its Workspace and Keyvault, so it can directly obtain the secret without you having to instantiate the Workspace and Keyvault within remote run.\n",
"\n",
"__Note__: This method returns the secret value. Take care not to write the secret to output.\n",
"\n",
"For example, let's create a simple script _get_secret.py_ that gets the secret we set earlier. In an actual appication, you would use the secret, for example to access a database or other password-protected resource."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%writefile get_secret.py\n",
"\n",
"from azureml.core import Run\n",
"\n",
"run = Run.get_context()\n",
"secret_value = run.get_secret(name=\"secret-name\")\n",
"print(\"Got secret value {} , but don't write it out!\".format(len(secret_value) * \"*\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, submit the script as a regular script run, and find the obfuscated secret value in run output. You can use the same approach to other kinds of runs, such as Estimator ones."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core import Experiment, Run\n",
"from azureml.core.script_run_config import ScriptRunConfig\n",
"\n",
"exp = Experiment(workspace = ws, name=\"try-secret\")\n",
"src = ScriptRunConfig(source_directory=\".\", script=\"get_secret.py\")\n",
"\n",
"run = exp.submit(src)\n",
"run.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Furthermore, you can set and get multiple secrets using set_secrets and get_secrets methods."
]
},
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
@@ -267,7 +434,7 @@
"name": "python", "name": "python",
"nbconvert_exporter": "python", "nbconvert_exporter": "python",
"pygments_lexer": "ipython3", "pygments_lexer": "ipython3",
"version": "3.6.4" "version": "3.6.9"
} }
}, },
"nbformat": 4, "nbformat": 4,

View File

@@ -0,0 +1,19 @@
## Follow these sample notebooks to learn:
1. [Logging API](./logging-api/logging-api.ipynb): experiment with various logging functions to create runs and automatically generate graphs.
2. [Manage runs](./manage-runs/manage-runs.ipynb): learn different ways how to start runs and child runs, monitor them, and cancel them.
1. [Tensorboard to monitor runs](./tensorboard/tensorboard.ipynb)
## Use MLflow with Azure Machine Learning service (Preview)
[MLflow](https://mlflow.org/) is an open-source platform for tracking machine learning experiments and managing models. You can use MLflow logging APIs with Azure Machine Learning service: the metrics and artifacts are logged to your Azure ML Workspace.
Try out the sample notebooks:
1. [Use MLflow with Azure Machine Learning for Local Training Run](./train-local/train-local.ipynb)
1. [Use MLflow with Azure Machine Learning for Remote Training Run](./train-remote/train-remote.ipynb)
1. [Deploy Model as Azure Machine Learning Web Service using MLflow](./deploy-model/deploy-model.ipynb)
1. [Train and Deploy PyTorch Image Classifier](./train-deploy-pytorch/train-deploy-pytorch.ipynb)
![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/track-and-monitor-experiments/README.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -0,0 +1,545 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Copyright (c) Microsoft Corporation. All rights reserved.\n",
"\n",
"Licensed under the MIT License."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/track-and-monitor-experiments/logging-api/logging-api.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Logging\n",
"\n",
"_**This notebook showcases various ways to use the Azure Machine Learning service run logging APIs, and view the results in the Azure portal.**_\n",
"\n",
"---\n",
"---\n",
"\n",
"## Table of Contents\n",
"\n",
"1. [Introduction](#Introduction)\n",
"1. [Setup](#Setup)\n",
" 1. Validate Azure ML SDK installation\n",
" 1. Initialize workspace\n",
" 1. Set experiment\n",
"1. [Logging](#Logging)\n",
" 1. Starting a run\n",
" 1. Viewing a run in the portal\n",
" 1. Viewing the experiment in the portal\n",
" 1. Logging metrics\n",
" 1. Logging string metrics\n",
" 1. Logging numeric metrics\n",
" 1. Logging vectors\n",
" 1. Logging tables\n",
" 1. Uploading files\n",
"1. [Analyzing results](#Analyzing-results)\n",
" 1. Tagging a run\n",
"1. [Next steps](#Next-steps)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction\n",
"\n",
"Logging metrics from runs in your experiments allows you to track results from one run to another, determining trends in your outputs and understand how your inputs correspond to your model and script performance. Azure Machine Learning services (AzureML) allows you to track various types of metrics including images and arbitrary files in order to understand, analyze, and audit your experimental progress. \n",
"\n",
"Typically you should log all parameters for your experiment and all numerical and string outputs of your experiment. This will allow you to analyze the performance of your experiments across multiple runs, correlate inputs to outputs, and filter runs based on interesting criteria.\n",
"\n",
"The experiment's Run History report page automatically creates a report that can be customized to show the KPI's, charts, and column sets that are interesting to you. \n",
"\n",
"| ![Run Details](./img/run_details.PNG) | ![Run History](./img/run_history.PNG) |\n",
"|:--:|:--:|\n",
"| *Run Details* | *Run History* |\n",
"\n",
"---\n",
"\n",
"## Setup\n",
"\n",
"If you are using an Azure Machine Learning Notebook VM, you are all set. Otherwise, go through the [configuration](../../../configuration.ipynb) Notebook first if you haven't already to establish your connection to the AzureML Workspace. Also make sure you have tqdm and matplotlib installed in the current kernel.\n",
"\n",
"```\n",
"(myenv) $ conda install -y tqdm matplotlib\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Validate Azure ML SDK installation and get version number for debugging purposes"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"install"
]
},
"outputs": [],
"source": [
"from azureml.core import Experiment, Workspace, Run\n",
"import azureml.core\n",
"import numpy as np\n",
"from tqdm import tqdm\n",
"\n",
"# Check core SDK version number\n",
"\n",
"print(\"This notebook was created using SDK version 1.0.57, you are currently running version\", azureml.core.VERSION)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Initialize workspace\n",
"\n",
"Initialize a workspace object from persisted configuration."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"create workspace"
]
},
"outputs": [],
"source": [
"ws = Workspace.from_config()\n",
"print('Workspace name: ' + ws.name, \n",
" 'Azure region: ' + ws.location, \n",
" 'Subscription id: ' + ws.subscription_id, \n",
" 'Resource group: ' + ws.resource_group, sep='\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Set experiment\n",
"Create a new experiment (or get the one with the specified name). An *experiment* is a container for an arbitrary set of *runs*. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"experiment = Experiment(workspace=ws, name='logging-api-test')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Logging\n",
"In this section we will explore the various logging mechanisms.\n",
"\n",
"### Starting a run\n",
"\n",
"A *run* is a singular experimental trial. In this notebook we will create a run directly on the experiment by calling `run = exp.start_logging()`. If you were experimenting by submitting a script file as an experiment using ``experiment.submit()``, you would call `run = Run.get_context()` in your script to access the run context of your code. In either case, the logging methods on the returned run object work the same.\n",
"\n",
"This cell also stores the run id for use later in this notebook. The run_id is not necessary for logging."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# start logging for the run\n",
"run = experiment.start_logging()\n",
"\n",
"# access the run id for use later\n",
"run_id = run.id\n",
"\n",
"# change the scale factor on different runs to see how you can compare multiple runs\n",
"scale_factor = 2\n",
"\n",
"# change the category on different runs to see how to organize data in reports\n",
"category = 'Red'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Viewing a run in the Portal\n",
"Once a run is started you can see the run in the portal by simply typing ``run``. Clicking on the \"Link to Portal\" link will take you to the Run Details page that shows the metrics you have logged and other run properties. You can refresh this page after each logging statement to see the updated results."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Viewing an experiment in the portal\n",
"You can also view an experiement similarly by typing `experiment`. The portal link will take you to the experiment's Run History page that shows all runs and allows you to analyze trends across multiple runs."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"experiment"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Logging metrics\n",
"Metrics are visible in the run details page in the AzureML portal and also can be analyzed in experiment reports. The run details page looks as below and contains tabs for Details, Outputs, Logs, and Snapshot. \n",
"* The Details page displays attributes about the run, plus logged metrics and images. Metrics that are vectors appear as charts. \n",
"* The Outputs page contains any files, such as models, you uploaded into the \"outputs\" directory from your run into storage. If you place files in the \"outputs\" directory locally, the files are automatically uploaded on your behald when the run is completed.\n",
"* The Logs page allows you to view any log files created by your run. Logging runs created in notebooks typically do not generate log files.\n",
"* The Snapshot page contains a snapshot of the directory specified in the ''start_logging'' statement, plus the notebook at the time of the ''start_logging'' call. This snapshot and notebook can be downloaded from the Run Details page to continue or reproduce an experiment.\n",
"\n",
"### Logging string metrics\n",
"The following cell logs a string metric. A string metric is simply a string value associated with a name. A string metric String metrics are useful for labelling runs and to organize your data. Typically you should log all string parameters as metrics for later analysis - even information such as paths can help to understand how individual experiements perform differently.\n",
"\n",
"String metrics can be used in the following ways:\n",
"* Plot in hitograms\n",
"* Group by indicators for numerical plots\n",
"* Filtering runs\n",
"\n",
"String metrics appear in the **Tracked Metrics** section of the Run Details page and can be added as a column in Run History reports."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# log a string metric\n",
"run.log(name='Category', value=category)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Logging numerical metrics\n",
"The following cell logs some numerical metrics. Numerical metrics can include metrics such as AUC or MSE. You should log any parameter or significant output measure in order to understand trends across multiple experiments. Numerical metrics appear in the **Tracked Metrics** section of the Run Details page, and can be used in charts or KPI's in experiment Run History reports."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# log numerical values\n",
"run.log(name=\"scale factor\", value = scale_factor)\n",
"run.log(name='Magic Number', value=42 * scale_factor)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Logging vectors\n",
"Vectors are good for recording information such as loss curves. You can log a vector by creating a list of numbers, calling ``log_list()`` and supplying a name and the list, or by repeatedly logging a value using the same name.\n",
"\n",
"Vectors are presented in Run Details as a chart, and are directly comparable in experiment reports when placed in a chart. \n",
"\n",
"**Note:** vectors logged into the run are expected to be relatively small. Logging very large vectors into Azure ML can result in reduced performance. If you need to store large amounts of data associated with the run, you can write the data to file that will be uploaded."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fibonacci_values = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]\n",
"scaled_values = (i * scale_factor for i in fibonacci_values)\n",
"\n",
"# Log a list of values. Note this will generate a single-variable line chart.\n",
"run.log_list(name='Fibonacci', value=scaled_values)\n",
"\n",
"for i in tqdm(range(-10, 10)):\n",
" # log a metric value repeatedly, this will generate a single-variable line chart.\n",
" run.log(name='Sigmoid', value=1 / (1 + np.exp(-i)))\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Logging tables\n",
"Tables are good for recording related sets of information such as accuracy tables, confusion matrices, etc. \n",
"You can log a table in two ways:\n",
"* Create a dictionary of lists where each list represents a column in the table and call ``log_table()``\n",
"* Repeatedly call ``log_row()`` providing the same table name with a consistent set of named args as the column values\n",
"\n",
"Tables are presented in Run Details as a chart using the first two columns of the table \n",
"\n",
"**Note:** tables logged into the run are expected to be relatively small. Logging very large tables into Azure ML can result in reduced performance. If you need to store large amounts of data associated with the run, you can write the data to file that will be uploaded."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# create a dictionary to hold a table of values\n",
"sines = {}\n",
"sines['angle'] = []\n",
"sines['sine'] = []\n",
"\n",
"for i in tqdm(range(-10, 10)):\n",
" angle = i / 2.0 * scale_factor\n",
" \n",
" # log a 2 (or more) values as a metric repeatedly. This will generate a 2-variable line chart if you have 2 numerical columns.\n",
" run.log_row(name='Cosine Wave', angle=angle, cos=np.cos(angle))\n",
" \n",
" sines['angle'].append(angle)\n",
" sines['sine'].append(np.sin(angle))\n",
"\n",
"# log a dictionary as a table, this will generate a 2-variable chart if you have 2 numerical columns\n",
"run.log_table(name='Sine Wave', value=sines)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Logging images\n",
"You can directly log _matplotlib_ plots and arbitrary images to your run record. This code logs a _matplotlib_ pyplot object. Images show up in the run details page in the Azure ML Portal."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"# Create a plot\n",
"import matplotlib.pyplot as plt\n",
"angle = np.linspace(-3, 3, 50) * scale_factor\n",
"plt.plot(angle,np.tanh(angle), label='tanh')\n",
"plt.legend(fontsize=12)\n",
"plt.title('Hyperbolic Tangent', fontsize=16)\n",
"plt.grid(True)\n",
"\n",
"# Log the plot to the run. To log an arbitrary image, use the form run.log_image(name, path='./image_path.png')\n",
"run.log_image(name='Hyperbolic Tangent', plot=plt)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Uploading files\n",
"\n",
"Files can also be uploaded explicitly and stored as artifacts along with the run record. These files are also visible in the *Outputs* tab of the Run Details page.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"file_name = 'outputs/myfile.txt'\n",
"\n",
"with open(file_name, \"w\") as f:\n",
" f.write('This is an output file that will be uploaded.\\n')\n",
"\n",
"# Upload the file explicitly into artifacts \n",
"run.upload_file(name = file_name, path_or_stream = file_name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Completing the run\n",
"\n",
"Calling `run.complete()` marks the run as completed and triggers the output file collection. If for any reason you need to indicate the run failed or simply need to cancel the run you can call `run.fail()` or `run.cancel()`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run.complete()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"## Analyzing results"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can refresh the run in the Azure portal to see all of your results. In many cases you will want to analyze runs that were performed previously to inspect the contents or compare results. Runs can be fetched from their parent Experiment object using the ``Run()`` constructor or the ``experiment.get_runs()`` method. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fetched_run = Run(experiment, run_id)\n",
"fetched_run"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Call ``run.get_metrics()`` to retrieve all the metrics from a run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fetched_run.get_metrics()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"See the files uploaded for this run by calling ``run.get_file_names()``"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fetched_run.get_file_names()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once you know the file names in a run, you can download the files using the ``run.download_file()`` method"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"os.makedirs('files', exist_ok=True)\n",
"\n",
"for f in run.get_file_names():\n",
" dest = os.path.join('files', f.split('/')[-1])\n",
" print('Downloading file {} to {}...'.format(f, dest))\n",
" fetched_run.download_file(f, dest) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Tagging a run\n",
"Often when you analyze the results of a run, you may need to tag that run with important personal or external information. You can add a tag to a run using the ``run.tag()`` method. AzureML supports valueless and valued tags."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"fetched_run.tag(\"My Favorite Run\")\n",
"fetched_run.tag(\"Competition Rank\", 1)\n",
"\n",
"fetched_run.get_tags()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Next steps\n",
"To experiment more with logging and to understand how metrics can be visualized, go back to the *Start a run* section, try changing the category and scale_factor values and going through the notebook several times. Play with the KPI, charting, and column selection options on the experiment's Run History reports page to see how the various metrics can be combined and visualized.\n",
"\n",
"After learning about all of the logging options, go to the [train on remote vm](..\\train-on-remote-vm\\train-on-remote-vm.ipynb) notebook and experiment with logging from remote compute contexts."
]
}
],
"metadata": {
"authors": [
{
"name": "roastala"
}
],
"kernelspec": {
"display_name": "Python 3.6",
"language": "python",
"name": "python36"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,8 @@
name: logging-api
dependencies:
- numpy
- matplotlib
- tqdm
- pip:
- azureml-sdk
- azureml-widgets

View File

@@ -0,0 +1,7 @@
# Copyright (c) Microsoft. All rights reserved.
# Licensed under the MIT license.
from azureml.core import Run
submitted_run = Run.get_context()
submitted_run.log(name="message", value="Hello from run!")

View File

@@ -0,0 +1,11 @@
# Copyright (c) Microsoft. All rights reserved.
# Licensed under the MIT license.
from azureml.core import Run
run = Run.get_context()
child_runs = run.create_children(count=5)
for c, child in enumerate(child_runs):
child.log(name="Hello from child run ", value=c)
child.complete()

View File

@@ -0,0 +1,8 @@
# Copyright (c) Microsoft. All rights reserved.
# Licensed under the MIT license.
import time
print("Wait for 10 seconds..")
time.sleep(10)
print("Done waiting")

View File

@@ -0,0 +1,602 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Copyright (c) Microsoft Corporation. All rights reserved.\n",
"\n",
"Licensed under the MIT License."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/track-and-monitor-experiments/manage-runs/manage-runs.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Manage runs\n",
"\n",
"## Table of contents\n",
"\n",
"1. [Introduction](#Introduction)\n",
"1. [Setup](#Setup)\n",
"1. [Start, monitor and complete a run](#Start,-monitor-and-complete-a-run)\n",
"1. [Add properties and tags](#Add-properties-and-tags)\n",
"1. [Query properties and tags](#Query-properties-and-tags)\n",
"1. [Start and query child runs](#Start-and-query-child-runs)\n",
"1. [Cancel or fail runs](#Cancel-or-fail-runs)\n",
"1. [Reproduce a run](#Reproduce-a-run)\n",
"1. [Next steps](#Next-steps)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Introduction\n",
"\n",
"When you're building enterprise-grade machine learning models, it is important to track, organize, monitor and reproduce your training runs. For example, you might want to trace the lineage behind a model deployed to production, and re-run the training experiment to troubleshoot issues. \n",
"\n",
"This notebooks shows examples how to use Azure Machine Learning services to manage your training runs."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setup\n",
"\n",
"If you are using an Azure Machine Learning Notebook VM, you are all set. Otherwise, go through the [configuration](../../../configuration.ipynb) Notebook first if you haven't already to establish your connection to the AzureML Workspace. Also, if you're new to Azure ML, we recommend that you go through [the tutorial](https://docs.microsoft.com/en-us/azure/machine-learning/service/tutorial-train-models-with-aml) first to learn the basic concepts.\n",
"\n",
"Let's first import required packages, check Azure ML SDK version, connect to your workspace and create an Experiment to hold the runs."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import azureml.core\n",
"from azureml.core import Workspace, Experiment, Run\n",
"from azureml.core import ScriptRunConfig\n",
"\n",
"print(azureml.core.VERSION)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ws = Workspace.from_config()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"exp = Experiment(workspace=ws, name=\"explore-runs\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Start, monitor and complete a run\n",
"\n",
"A run is an unit of execution, typically to train a model, but for other purposes as well, such as loading or transforming data. Runs are tracked by Azure ML service, and can be instrumented with metrics and artifact logging.\n",
"\n",
"A simplest way to start a run in your interactive Python session is to call *Experiment.start_logging* method. You can then log metrics from within the run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"notebook_run = exp.start_logging()\n",
"\n",
"notebook_run.log(name=\"message\", value=\"Hello from run!\")\n",
"\n",
"print(notebook_run.get_status())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use *get_status method* to get the status of the run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(notebook_run.get_status())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Also, you can simply enter the run to get a link to Azure Portal details"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"notebook_run"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Method *get_details* gives you more details on the run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"notebook_run.get_details()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use *complete* method to end the run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"notebook_run.complete()\n",
"print(notebook_run.get_status())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also use Python's *with...as* pattern. The run will automatically complete when moving out of scope. This way you don't need to manually complete the run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with exp.start_logging() as notebook_run:\n",
" notebook_run.log(name=\"message\", value=\"Hello from run!\")\n",
" print(\"Is it still running?\",notebook_run.get_status())\n",
" \n",
"print(\"Has it completed?\",notebook_run.get_status())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, let's look at submitting a run as a separate Python process. To keep the example simple, we submit the run on local computer. Other targets could include remote VMs and Machine Learning Compute clusters in your Azure ML Workspace.\n",
"\n",
"We use *hello.py* script as an example. To perform logging, we need to get a reference to the Run instance from within the scope of the script. We do this using *Run.get_context* method."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!more hello.py"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's submit the run on a local computer. A standard pattern in Azure ML SDK is to create run configuration, and then use *Experiment.submit* method."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run_config = ScriptRunConfig(source_directory='.', script='hello.py')\n",
"\n",
"local_script_run = exp.submit(run_config)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can view the status of the run as before"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(local_script_run.get_status())\n",
"local_script_run"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Submitted runs have additional log files you can inspect using *get_details_with_logs*."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"local_script_run.get_details_with_logs()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use *wait_for_completion* method to block the local execution until remote run is complete."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"local_script_run.wait_for_completion(show_output=True)\n",
"print(local_script_run.get_status())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Add properties and tags\n",
"\n",
"Properties and tags help you organize your runs. You can use them to describe, for example, who authored the run, what the results were, and what machine learning approach was used. And as you'll later learn, properties and tags can be used to query the history of your runs to find the important ones.\n",
"\n",
"For example, let's add \"author\" property to the run:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"local_script_run.add_properties({\"author\":\"azureml-user\"})\n",
"print(local_script_run.get_properties())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Properties are immutable. Once you assign a value it cannot be changed, making them useful as a permanent record for auditing purposes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"try:\n",
" local_script_run.add_properties({\"author\":\"different-user\"})\n",
"except Exception as e:\n",
" print(e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Tags on the other hand can be changed:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"local_script_run.tag(\"quality\", \"great run\")\n",
"print(local_script_run.get_tags())"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"local_script_run.tag(\"quality\", \"fantastic run\")\n",
"print(local_script_run.get_tags())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also add a simple string tag. It appears in the tag dictionary with value of None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"local_script_run.tag(\"worth another look\")\n",
"print(local_script_run.get_tags())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Query properties and tags\n",
"\n",
"You can quary runs within an experiment that match specific properties and tags. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"list(exp.get_runs(properties={\"author\":\"azureml-user\"},tags={\"quality\":\"fantastic run\"}))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"list(exp.get_runs(properties={\"author\":\"azureml-user\"},tags=\"worth another look\"))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Start and query child runs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can use child runs to group together related runs, for example different hyperparameter tuning iterations.\n",
"\n",
"Let's use *hello_with_children* script to create a batch of 5 child runs from within a submitted run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!more hello_with_children.py"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run_config = ScriptRunConfig(source_directory='.', script='hello_with_children.py')\n",
"\n",
"local_script_run = exp.submit(run_config)\n",
"local_script_run.wait_for_completion(show_output=True)\n",
"print(local_script_run.get_status())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can start child runs one by one. Note that this is less efficient than submitting a batch of runs, because each creation results in a network call.\n",
"\n",
"Child runs too complete automatically as they move out of scope."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"with exp.start_logging() as parent_run:\n",
" for c,count in enumerate(range(5)):\n",
" with parent_run.child_run() as child:\n",
" child.log(name=\"Hello from child run\", value=c)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To query the child runs belonging to specific parent, use *get_children* method."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"list(parent_run.get_children())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cancel or fail runs\n",
"\n",
"Sometimes, you realize that the run is not performing as intended, and you want to cancel it instead of waiting for it to complete.\n",
"\n",
"As an example, let's create a Python script with a delay in the middle."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"!more hello_with_delay.py"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can use *cancel* method to cancel a run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run_config = ScriptRunConfig(source_directory='.', script='hello_with_delay.py')\n",
"\n",
"local_script_run = exp.submit(run_config)\n",
"print(\"Did the run start?\",local_script_run.get_status())\n",
"local_script_run.cancel()\n",
"print(\"Did the run cancel?\",local_script_run.get_status())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also mark an unsuccessful run as failed."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"local_script_run = exp.submit(run_config)\n",
"local_script_run.fail()\n",
"print(local_script_run.get_status())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Reproduce a run\n",
"\n",
"When updating or troubleshooting on a model deployed to production, you sometimes need to revisit the original training run that produced the model. To help you with this, Azure ML service by default creates snapshots of your scripts a the time of run submission:\n",
"\n",
"You can use *restore_snapshot* to obtain a zip package of the latest snapshot of the script folder. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"local_script_run.restore_snapshot(path=\"snapshots\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can then extract the zip package, examine the code, and submit your run again."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Next steps\n",
"\n",
" * To learn more about logging APIs, see [logging API notebook](./logging-api/logging-api.ipynb)\n",
" * To learn more about remote runs, see [train on AML compute notebook](./train-on-amlcompute/train-on-amlcompute.ipynb)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"authors": [
{
"name": "roastala"
}
],
"kernelspec": {
"display_name": "Python 3.6",
"language": "python",
"name": "python36"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,4 @@
name: manage-runs
dependencies:
- pip:
- azureml-sdk

View File

@@ -0,0 +1,562 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Copyright (c) Microsoft Corporation. All rights reserved.\n",
"\n",
"Licensed under the MIT License."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/track-and-monitor-experiments/tensorboard/tensorboard.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Tensorboard Integration with Run History\n",
"\n",
"1. Run a Tensorflow job locally and view its TB output live.\n",
"2. The same, for a DSVM.\n",
"3. And once more, with an AmlCompute cluster.\n",
"4. Finally, we'll collect all of these historical runs together into a single Tensorboard graph."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Prerequisites\n",
"* Understand the [architecture and terms](https://docs.microsoft.com/azure/machine-learning/service/concept-azure-machine-learning-architecture) introduced by Azure Machine Learning\n",
"* If you are using an Azure Machine Learning Notebook VM, you are all set. Otherwise, go through the [configuration notebook](../../../configuration.ipynb) notebook to:\n",
" * install the AML SDK\n",
" * create a workspace and its configuration file (`config.json`)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Check core SDK version number\n",
"import azureml.core\n",
"\n",
"print(\"SDK version:\", azureml.core.VERSION)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Diagnostics\n",
"Opt-in diagnostics for better experience, quality, and security of future releases."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"Diagnostics"
]
},
"outputs": [],
"source": [
"from azureml.telemetry import set_diagnostics_collection\n",
"\n",
"set_diagnostics_collection(send_diagnostics=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Initialize Workspace\n",
"\n",
"Initialize a workspace object from persisted configuration."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core import Workspace\n",
"\n",
"ws = Workspace.from_config()\n",
"print('Workspace name: ' + ws.name, \n",
" 'Azure region: ' + ws.location, \n",
" 'Subscription id: ' + ws.subscription_id, \n",
" 'Resource group: ' + ws.resource_group, sep='\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Set experiment name and create project\n",
"Choose a name for your run history container in the workspace, and create a folder for the project."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from os import path, makedirs\n",
"experiment_name = 'tensorboard-demo'\n",
"\n",
"# experiment folder\n",
"exp_dir = './sample_projects/' + experiment_name\n",
"\n",
"if not path.exists(exp_dir):\n",
" makedirs(exp_dir)\n",
"\n",
"# runs we started in this session, for the finale\n",
"runs = []"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Download Tensorflow Tensorboard demo code\n",
"\n",
"Tensorflow's repository has an MNIST demo with extensive Tensorboard instrumentation. We'll use it here for our purposes.\n",
"\n",
"Note that we don't need to make any code changes at all - the code works without modification from the Tensorflow repository."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"import os\n",
"\n",
"tf_code = requests.get(\"https://raw.githubusercontent.com/tensorflow/tensorflow/r1.8/tensorflow/examples/tutorials/mnist/mnist_with_summaries.py\")\n",
"with open(os.path.join(exp_dir, \"mnist_with_summaries.py\"), \"w\") as file:\n",
" file.write(tf_code.text)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Configure and run locally\n",
"\n",
"We'll start by running this locally. While it might not initially seem that useful to use this for a local run - why not just run TB against the files generated locally? - even in this case there is some value to using this feature. Your local run will be registered in the run history, and your Tensorboard logs will be uploaded to the artifact store associated with this run. Later, you'll be able to restore the logs from any run, regardless of where it happened.\n",
"\n",
"Note that for this run, you will need to install Tensorflow on your local machine by yourself. Further, the Tensorboard module (that is, the one included with Tensorflow) must be accessible to this notebook's kernel, as the local machine is what runs Tensorboard."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.runconfig import RunConfiguration\n",
"\n",
"# Create a run configuration.\n",
"run_config = RunConfiguration()\n",
"run_config.environment.python.user_managed_dependencies = True\n",
"\n",
"# You can choose a specific Python environment by pointing to a Python path \n",
"#run_config.environment.python.interpreter_path = '/home/ninghai/miniconda3/envs/sdk2/bin/python'"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core import Experiment\n",
"from azureml.core.script_run_config import ScriptRunConfig\n",
"\n",
"logs_dir = os.path.join(os.curdir, \"logs\")\n",
"data_dir = os.path.abspath(os.path.join(os.curdir, \"mnist_data\"))\n",
"\n",
"if not path.exists(data_dir):\n",
" makedirs(data_dir)\n",
"\n",
"os.environ[\"TEST_TMPDIR\"] = data_dir\n",
"\n",
"# Writing logs to ./logs results in their being uploaded to Artifact Service,\n",
"# and thus, made accessible to our Tensorboard instance.\n",
"arguments_list = [\"--log_dir\", logs_dir]\n",
"\n",
"# Create an experiment\n",
"exp = Experiment(ws, experiment_name)\n",
"\n",
"# If you would like the run to go for longer, add --max_steps 5000 to the arguments list:\n",
"# arguments_list += [\"--max_steps\", \"5000\"]\n",
"\n",
"script = ScriptRunConfig(exp_dir,\n",
" script=\"mnist_with_summaries.py\",\n",
" run_config=run_config,\n",
" arguments=arguments_list)\n",
"\n",
"run = exp.submit(script)\n",
"# You can also wait for the run to complete\n",
"# run.wait_for_completion(show_output=True)\n",
"runs.append(run)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Start Tensorboard\n",
"\n",
"Now, while the run is in progress, we just need to start Tensorboard with the run as its target, and it will begin streaming logs."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"tensorboard-sample"
]
},
"outputs": [],
"source": [
"from azureml.tensorboard import Tensorboard\n",
"\n",
"# The Tensorboard constructor takes an array of runs, so be sure and pass it in as a single-element array here\n",
"tb = Tensorboard([run])\n",
"\n",
"# If successful, start() returns a string with the URI of the instance.\n",
"tb.start()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Stop Tensorboard\n",
"\n",
"When you're done, make sure to call the `stop()` method of the Tensorboard object, or it will stay running even after your job completes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tb.stop()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Now, with a DSVM\n",
"\n",
"Tensorboard uploading works with all compute targets. Here we demonstrate it from a DSVM.\n",
"Note that the Tensorboard instance itself will be run by the notebook kernel. Again, this means this notebook's kernel must have access to the Tensorboard module.\n",
"\n",
"If you are unfamiliar with DSVM configuration, check [Train in a remote VM](../../training/train-on-remote-vm/train-on-remote-vm.ipynb) for a more detailed breakdown.\n",
"\n",
"**Note**: To streamline the compute that Azure Machine Learning creates, we are making updates to support creating only single to multi-node `AmlCompute`. The `DSVMCompute` class will be deprecated in a later release, but the DSVM can be created using the below single line command and then attached(like any VM) using the sample code below. Also note, that we only support Linux VMs for remote execution from AML and the commands below will spin a Linux VM only.\n",
"\n",
"```shell\n",
"# create a DSVM in your resource group\n",
"# note you need to be at least a contributor to the resource group in order to execute this command successfully.\n",
"(myenv) $ az vm create --resource-group <resource_group_name> --name <some_vm_name> --image microsoft-dsvm:linux-data-science-vm-ubuntu:linuxdsvmubuntu:latest --admin-username <username> --admin-password <password> --generate-ssh-keys --authentication-type password\n",
"```\n",
"You can also use [this url](https://portal.azure.com/#create/microsoft-dsvm.linux-data-science-vm-ubuntulinuxdsvmubuntu) to create the VM using the Azure Portal."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.compute import ComputeTarget, RemoteCompute\n",
"from azureml.core.compute_target import ComputeTargetException\n",
"\n",
"username = os.getenv('AZUREML_DSVM_USERNAME', default='<my_username>')\n",
"address = os.getenv('AZUREML_DSVM_ADDRESS', default='<ip_address_or_fqdn>')\n",
"\n",
"compute_target_name = 'cpudsvm'\n",
"# if you want to connect using SSH key instead of username/password you can provide parameters private_key_file and private_key_passphrase \n",
"try:\n",
" attached_dsvm_compute = RemoteCompute(workspace=ws, name=compute_target_name)\n",
" print('found existing:', attached_dsvm_compute.name)\n",
"except ComputeTargetException:\n",
" config = RemoteCompute.attach_configuration(username=username,\n",
" address=address,\n",
" ssh_port=22,\n",
" private_key_file='./.ssh/id_rsa')\n",
" attached_dsvm_compute = ComputeTarget.attach(ws, compute_target_name, config)\n",
" \n",
" attached_dsvm_compute.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Submit run using TensorFlow estimator\n",
"\n",
"Instead of manually configuring the DSVM environment, we can use the TensorFlow estimator and everything is set up automatically."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.train.dnn import TensorFlow\n",
"\n",
"script_params = {\"--log_dir\": \"./logs\"}\n",
"\n",
"# If you want the run to go longer, set --max-steps to a higher number.\n",
"# script_params[\"--max_steps\"] = \"5000\"\n",
"\n",
"tf_estimator = TensorFlow(source_directory=exp_dir,\n",
" compute_target=attached_dsvm_compute,\n",
" entry_script='mnist_with_summaries.py',\n",
" script_params=script_params)\n",
"\n",
"run = exp.submit(tf_estimator)\n",
"\n",
"runs.append(run)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Start Tensorboard with this run\n",
"\n",
"Just like before."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# The Tensorboard constructor takes an array of runs, so be sure and pass it in as a single-element array here\n",
"tb = Tensorboard([run])\n",
"\n",
"# If successful, start() returns a string with the URI of the instance.\n",
"tb.start()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Stop Tensorboard\n",
"\n",
"When you're done, make sure to call the `stop()` method of the Tensorboard object, or it will stay running even after your job completes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tb.stop()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Once more, with an AmlCompute cluster\n",
"\n",
"Just to prove we can, let's create an AmlCompute CPU cluster, and run our demo there, as well."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.compute import ComputeTarget, AmlCompute\n",
"\n",
"# choose a name for your cluster\n",
"cluster_name = \"cpucluster\"\n",
"\n",
"cts = ws.compute_targets\n",
"found = False\n",
"if cluster_name in cts and cts[cluster_name].type == 'AmlCompute':\n",
" found = True\n",
" print('Found existing compute target.')\n",
" compute_target = cts[cluster_name]\n",
"if not found:\n",
" print('Creating a new compute target...')\n",
" compute_config = AmlCompute.provisioning_configuration(vm_size='STANDARD_D2_V2', \n",
" max_nodes=4)\n",
"\n",
" # create the cluster\n",
" compute_target = ComputeTarget.create(ws, cluster_name, compute_config)\n",
"\n",
"compute_target.wait_for_completion(show_output=True, min_node_count=None)\n",
"\n",
"# use get_status() to get a detailed status for the current cluster. \n",
"# print(compute_target.get_status().serialize())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Submit run using TensorFlow estimator\n",
"\n",
"Again, we can use the TensorFlow estimator and everything is set up automatically."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"script_params = {\"--log_dir\": \"./logs\"}\n",
"\n",
"# If you want the run to go longer, set --max-steps to a higher number.\n",
"# script_params[\"--max_steps\"] = \"5000\"\n",
"\n",
"tf_estimator = TensorFlow(source_directory=exp_dir,\n",
" compute_target=compute_target,\n",
" entry_script='mnist_with_summaries.py',\n",
" script_params=script_params)\n",
"\n",
"run = exp.submit(tf_estimator)\n",
"\n",
"runs.append(run)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Start Tensorboard with this run\n",
"\n",
"Once more..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# The Tensorboard constructor takes an array of runs, so be sure and pass it in as a single-element array here\n",
"tb = Tensorboard([run])\n",
"\n",
"# If successful, start() returns a string with the URI of the instance.\n",
"tb.start()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Stop Tensorboard\n",
"\n",
"When you're done, make sure to call the `stop()` method of the Tensorboard object, or it will stay running even after your job completes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tb.stop()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Finale\n",
"\n",
"If you've paid close attention, you'll have noticed that we've been saving the run objects in an array as we went along. We can start a Tensorboard instance that combines all of these run objects into a single process. This way, you can compare historical runs. You can even do this with live runs; if you made some of those previous runs longer via the `--max_steps` parameter, they might still be running, and you'll see them live in this instance as well."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# The Tensorboard constructor takes an array of runs...\n",
"# and it turns out that we have been building one of those all along.\n",
"tb = Tensorboard(runs)\n",
"\n",
"# If successful, start() returns a string with the URI of the instance.\n",
"tb.start()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Stop Tensorboard\n",
"\n",
"As you might already know, make sure to call the `stop()` method of the Tensorboard object, or it will stay running (until you kill the kernel associated with this notebook, at least)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tb.stop()"
]
}
],
"metadata": {
"authors": [
{
"name": "roastala"
}
],
"kernelspec": {
"display_name": "Python 3.6",
"language": "python",
"name": "python36"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,6 @@
name: tensorboard
dependencies:
- pip:
- azureml-sdk
- azureml-tensorboard
- tensorflow

View File

@@ -0,0 +1,322 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Copyright (c) Microsoft Corporation. All rights reserved.\n",
"\n",
"Licensed under the MIT License."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/using-mlflow/deploy-model/deploy-model.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Deploy Model as Azure Machine Learning Web Service using MLflow\n",
"\n",
"This example shows you how to use mlflow together with Azure Machine Learning services for deploying a model as a web service. You'll learn how to:\n",
"\n",
" 1. Retrieve a previously trained scikit-learn model\n",
" 2. Create a Docker image from the model\n",
" 3. Deploy the model as a web service on Azure Container Instance\n",
" 4. Make a scoring request against the web service.\n",
"\n",
"## Prerequisites and Set-up\n",
"\n",
"This notebook requires you to first complete the [Use MLflow with Azure Machine Learning for Local Training Run](../train-local/train-local.ipnyb) or [Use MLflow with Azure Machine Learning for Remote Training Run](../train-remote/train-remote.ipnyb) notebook, so as to have an experiment run with uploaded model in your Azure Machine Learning Workspace.\n",
"\n",
"Also install following packages if you haven't already\n",
"\n",
"```\n",
"pip install azureml-mlflow pandas\n",
"```\n",
"\n",
"Then, import necessary packages:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import mlflow\n",
"import azureml.mlflow\n",
"import azureml.core\n",
"from azureml.core import Workspace\n",
"\n",
"# Check core SDK version number\n",
"print(\"SDK version:\", azureml.core.VERSION)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Connect to workspace and set MLflow tracking URI\n",
"\n",
"Setting the tracking URI is required for retrieving the model and creating an image using the MLflow APIs."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ws = Workspace.from_config()\n",
"\n",
"mlflow.set_tracking_uri(ws.get_mlflow_tracking_uri())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Retrieve model from previous run\n",
"\n",
"Let's retrieve the experiment from training notebook, and list the runs within that experiment."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"experiment_name = \"experiment-with-mlflow\"\n",
"exp = ws.experiments[experiment_name]\n",
"\n",
"runs = list(exp.get_runs())\n",
"runs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, let's select the most recent training run and find its ID. You also need to specify the path in run history where the model was saved. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"runid = runs[0].id\n",
"model_save_path = \"model\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create Docker image\n",
"\n",
"To create a Docker image with Azure Machine Learning for Model Management, use ```mlflow.azureml.build_image``` method. Specify the model path, your workspace, run ID and other parameters.\n",
"\n",
"MLflow automatically recognizes the model framework as scikit-learn, and creates the scoring logic and includes library dependencies for you.\n",
"\n",
"Note that the image creation can take several minutes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import mlflow.azureml\n",
"\n",
"azure_image, azure_model = mlflow.azureml.build_image(model_uri=\"runs:/{}/{}\".format(runid, model_save_path),\n",
" workspace=ws,\n",
" model_name='diabetes-sklearn-model',\n",
" image_name='diabetes-sklearn-image',\n",
" synchronous=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Deploy web service\n",
"\n",
"Let's use Azure Machine Learning SDK to deploy the image as a web service. \n",
"\n",
"First, specify the deployment configuration. Azure Container Instance is a suitable choice for a quick dev-test deployment, while Azure Kubernetes Service is suitable for scalable production deployments.\n",
"\n",
"Then, deploy the image using Azure Machine Learning SDK's ```deploy_from_image``` method.\n",
"\n",
"Note that the deployment can take several minutes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.webservice import AciWebservice, Webservice\n",
"\n",
"\n",
"aci_config = AciWebservice.deploy_configuration(cpu_cores=1, \n",
" memory_gb=1, \n",
" tags={\"method\" : \"sklearn\"}, \n",
" description='Diabetes model',\n",
" location='eastus2')\n",
"\n",
"\n",
"# Deploy the image to Azure Container Instances (ACI) for real-time serving\n",
"webservice = Webservice.deploy_from_image(\n",
" image=azure_image, workspace=ws, name=\"diabetes-model-1\", deployment_config=aci_config)\n",
"\n",
"\n",
"webservice.wait_for_deployment(show_output=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Make a scoring request\n",
"\n",
"Let's take the first few rows of test data and score them using the web service"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"test_rows = [\n",
" [0.01991321, 0.05068012, 0.10480869, 0.07007254, -0.03596778,\n",
" -0.0266789 , -0.02499266, -0.00259226, 0.00371174, 0.04034337],\n",
" [-0.01277963, -0.04464164, 0.06061839, 0.05285819, 0.04796534,\n",
" 0.02937467, -0.01762938, 0.03430886, 0.0702113 , 0.00720652],\n",
" [ 0.03807591, 0.05068012, 0.00888341, 0.04252958, -0.04284755,\n",
" -0.02104223, -0.03971921, -0.00259226, -0.01811827, 0.00720652]]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"MLflow-based web service for scikit-learn model requires the data to be converted to Pandas DataFrame, and then serialized as JSON. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"import pandas as pd\n",
"\n",
"test_rows_as_json = pd.DataFrame(test_rows).to_json(orient=\"split\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's pass the conveted and serialized data to web service to get the predictions."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"predictions = webservice.run(test_rows_as_json)\n",
"\n",
"print(predictions)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can use the web service's scoring URI to make a raw HTTP request"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"webservice.scoring_uri"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can diagnose the web service using ```get_logs``` method."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"webservice.get_logs()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Next Steps\n",
"\n",
"Learn about [model management and inference in Azure Machine Learning service](https://docs.microsoft.com/en-us/azure/machine-learning/service/concept-model-management-and-deployment)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"authors": [
{
"name": "rastala"
}
],
"kernelspec": {
"display_name": "Python 3.6",
"language": "python",
"name": "python36"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,8 @@
name: deploy-model
dependencies:
- scikit-learn
- matplotlib
- pip:
- azureml-sdk
- azureml-mlflow
- pandas

View File

@@ -0,0 +1,150 @@
# Copyright (c) 2017, PyTorch Team
# All rights reserved
# Licensed under BSD 3-Clause License.
# This example is based on PyTorch MNIST example:
# https://github.com/pytorch/examples/blob/master/mnist/main.py
import mlflow
import mlflow.pytorch
from mlflow.utils.environment import _mlflow_conda_env
import warnings
import cloudpickle
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import torchvision
from torchvision import datasets, transforms
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 20, 5, 1)
self.conv2 = nn.Conv2d(20, 50, 5, 1)
self.fc1 = nn.Linear(4 * 4 * 50, 500)
self.fc2 = nn.Linear(500, 10)
def forward(self, x):
# Added the view for reshaping score requests
x = x.view(-1, 1, 28, 28)
x = F.relu(self.conv1(x))
x = F.max_pool2d(x, 2, 2)
x = F.relu(self.conv2(x))
x = F.max_pool2d(x, 2, 2)
x = x.view(-1, 4 * 4 * 50)
x = F.relu(self.fc1(x))
x = self.fc2(x)
return F.log_softmax(x, dim=1)
def train(args, model, device, train_loader, optimizer, epoch):
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()
if batch_idx % args.log_interval == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
# Use MLflow logging
mlflow.log_metric("epoch_loss", loss.item())
def test(args, model, device, test_loader):
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
output = model(data)
# sum up batch loss
test_loss += F.nll_loss(output, target, reduction="sum").item()
# get the index of the max log-probability
pred = output.argmax(dim=1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(test_loader.dataset)
print("\n")
print("Test set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n".format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
# Use MLflow logging
mlflow.log_metric("average_loss", test_loss)
class Args(object):
pass
# Training settings
args = Args()
setattr(args, 'batch_size', 64)
setattr(args, 'test_batch_size', 1000)
setattr(args, 'epochs', 3) # Higher number for better convergence
setattr(args, 'lr', 0.01)
setattr(args, 'momentum', 0.5)
setattr(args, 'no_cuda', True)
setattr(args, 'seed', 1)
setattr(args, 'log_interval', 10)
setattr(args, 'save_model', True)
use_cuda = not args.no_cuda and torch.cuda.is_available()
torch.manual_seed(args.seed)
device = torch.device("cuda" if use_cuda else "cpu")
kwargs = {'num_workers': 1, 'pin_memory': True} if use_cuda else {}
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=args.batch_size, shuffle=True, **kwargs)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST(
'../data',
train=False,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))])),
batch_size=args.test_batch_size, shuffle=True, **kwargs)
def driver():
warnings.filterwarnings("ignore")
# Dependencies for deploying the model
pytorch_index = "https://download.pytorch.org/whl/"
pytorch_version = "cpu/torch-1.1.0-cp36-cp36m-linux_x86_64.whl"
deps = [
"cloudpickle=={}".format(cloudpickle.__version__),
pytorch_index + pytorch_version,
"torchvision=={}".format(torchvision.__version__),
"Pillow=={}".format("6.0.0")
]
with mlflow.start_run() as run:
model = Net().to(device)
optimizer = optim.SGD(
model.parameters(),
lr=args.lr,
momentum=args.momentum)
for epoch in range(1, args.epochs + 1):
train(args, model, device, train_loader, optimizer, epoch)
test(args, model, device, test_loader)
# Log model to run history using MLflow
if args.save_model:
model_env = _mlflow_conda_env(additional_pip_deps=deps)
mlflow.pytorch.log_model(model, "model", conda_env=model_env)
return run
if __name__ == "__main__":
driver()

View File

@@ -0,0 +1,481 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Copyright (c) Microsoft Corporation. All rights reserved.\n",
"\n",
"Licensed under the MIT License."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/using-mlflow/train-deploy-pytorch/train-deploy-pytorch.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Use MLflow with Azure Machine Learning to Train and Deploy PyTorch Image Classifier\n",
"\n",
"This example shows you how to use MLflow together with Azure Machine Learning services for tracking the metrics and artifacts while training a PyTorch model to classify MNIST digit images, and then deploy the model as a web service. You'll learn how to:\n",
"\n",
" 1. Set up MLflow tracking URI so as to use Azure ML\n",
" 2. Create experiment\n",
" 3. Instrument your model with MLflow tracking\n",
" 4. Train a PyTorch model locally\n",
" 5. Train a model on GPU compute on Azure\n",
" 6. View your experiment within your Azure ML Workspace in Azure Portal\n",
" 7. Create a Docker image from the trained model\n",
" 8. Deploy the model as a web service on Azure Container Instance\n",
" 9. Call the model to make predictions\n",
" \n",
"### Pre-requisites\n",
" \n",
"Make sure you have completed the [Configuration](../../../configuration.ipnyb) notebook to set up your Azure Machine Learning workspace and ensure other common prerequisites are met.\n",
"\n",
"Also, install mlflow-azureml package using ```pip install mlflow-azureml```. Note that mlflow-azureml installs mlflow package itself as a dependency, if you haven't done so previously.\n",
"\n",
"### Set-up\n",
"\n",
"Import packages and check versions of Azure ML SDK and MLflow installed on your computer. Then connect to your Workspace."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import sys, os\n",
"import mlflow\n",
"import mlflow.azureml\n",
"import mlflow.sklearn\n",
"\n",
"import azureml.core\n",
"from azureml.core import Workspace\n",
"\n",
"\n",
"print(\"SDK version:\", azureml.core.VERSION)\n",
"print(\"MLflow version:\", mlflow.version.VERSION)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ws = Workspace.from_config()\n",
"ws.get_details()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Set tracking URI\n",
"\n",
"Set the MLFlow tracking URI to point to your Azure ML Workspace. The subsequent logging calls from MLFlow APIs will go to Azure ML services and will be tracked under your Workspace."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mlflow.set_tracking_uri(ws.get_mlflow_tracking_uri())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create Experiment\n",
"\n",
"In both MLflow and Azure ML, training runs are grouped into experiments. Let's create one for our experimentation."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"experiment_name = \"pytorch-with-mlflow\"\n",
"mlflow.set_experiment(experiment_name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Train model locally while logging metrics and artifacts\n",
"\n",
"The ```scripts/train.py``` program contains the code to load the image dataset, and train and test the model. Within this program, the train.driver function wraps the end-to-end workflow.\n",
"\n",
"Within the driver, the ```mlflow.start_run``` starts MLflow tracking. Then, ```mlflow.log_metric``` functions are used to track the convergence of the neural network training iterations. Finally ```mlflow.pytorch.save_model``` is used to save the trained model in framework-aware manner.\n",
"\n",
"Let's add the program to search path, import it as a module, and then invoke the driver function. Note that the training can take few minutes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"lib_path = os.path.abspath(\"scripts\")\n",
"sys.path.append(lib_path)\n",
"\n",
"import train"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run = train.driver()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can view the metrics of the run at Azure Portal"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(azureml.mlflow.get_portal_url(run))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Train model on GPU compute on Azure\n",
"\n",
"Next, let's run the same script on GPU-enabled compute for faster training. If you've completed the the [Configuration](../../../configuration.ipnyb) notebook, you should have a GPU cluster named \"gpu-cluster\" available in your workspace. Otherwise, follow the instructions in the notebook to create one. For simplicity, this example uses single process on single VM to train the model.\n",
"\n",
"Create a PyTorch estimator to specify the training configuration: script, compute as well as additional packages needed. To enable MLflow tracking, include ```azureml-mlflow``` as pip package. The low-level specifications for the training run are encapsulated in the estimator instance."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.train.dnn import PyTorch\n",
"\n",
"pt = PyTorch(source_directory=\"./scripts\", \n",
" entry_script = \"train.py\", \n",
" compute_target = \"gpu-cluster\", \n",
" node_count = 1, \n",
" process_count_per_node = 1, \n",
" use_gpu=True,\n",
" pip_packages = [\"azureml-mlflow\", \"Pillow==6.0.0\"])\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get a reference to the experiment you created previously, but this time, as Azure Machine Learning experiment object.\n",
"\n",
"Then, use ```Experiment.submit``` method to start the remote training run. Note that the first training run often takes longer as Azure Machine Learning service builds the Docker image for executing the script. Subsequent runs will be faster as cached image is used."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core import Experiment\n",
"\n",
"exp = Experiment(ws, experiment_name)\n",
"run = exp.submit(pt)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can monitor the run and its metrics on Azure Portal."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Also, you can wait for run to complete."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Deploy model as web service\n",
"\n",
"To deploy a web service, first create a Docker image, and then deploy that Docker image on inferencing compute.\n",
"\n",
"The ```mlflow.azureml.build_image``` function builds a Docker image from saved PyTorch model in a framework-aware manner. It automatically creates the PyTorch-specific inferencing wrapper code and specififies package dependencies for you."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run.get_file_names()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then build a docker image using *runs:/&lt;run.id&gt;/model* as the model_uri path.\n",
"\n",
"Note that the image building can take several minutes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"model_path = \"model\"\n",
"\n",
"\n",
"azure_image, azure_model = mlflow.azureml.build_image(model_uri='runs:/{}/{}'.format(run.id, model_path),\n",
" workspace=ws,\n",
" model_name='pytorch_mnist',\n",
" image_name='pytorch-mnist-img',\n",
" synchronous=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, deploy the Docker image to Azure Container Instance: a serverless compute capable of running a single container. You can tag and add descriptions to help keep track of your web service. \n",
"\n",
"[Other inferencing compute choices](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-deploy-and-where) include Azure Kubernetes Service which provides scalable endpoint suitable for production use.\n",
"\n",
"Note that the service deployment can take several minutes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.webservice import AciWebservice, Webservice\n",
"\n",
"aci_config = AciWebservice.deploy_configuration(cpu_cores=2, \n",
" memory_gb=5, \n",
" tags={\"data\": \"MNIST\", \"method\" : \"pytorch\"}, \n",
" description=\"Predict using webservice\")\n",
"\n",
"\n",
"# Deploy the image to Azure Container Instances (ACI) for real-time serving\n",
"webservice = Webservice.deploy_from_image(\n",
" image=azure_image, workspace=ws, name=\"pytorch-mnist-1\", deployment_config=aci_config)\n",
"\n",
"\n",
"webservice.wait_for_deployment()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once the deployment has completed you can check the scoring URI of the web service."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Scoring URI is: {}\".format(webservice.scoring_uri))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In case of a service creation issue, you can use ```webservice.get_logs()``` to get logs to debug."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Make predictions using web service\n",
"\n",
"To make the web service, create a test data set as normalized PyTorch tensors. \n",
"\n",
"Then, let's define a utility function that takes a random image and converts it into format and shape suitable for as input to PyTorch inferencing end-point. The conversion is done by: \n",
"\n",
" 1. Select a random (image, label) tuple\n",
" 2. Take the image and converting the tensor to NumPy array \n",
" 3. Reshape array into 1 x 1 x N array\n",
" * 1 image in batch, 1 color channel, N = 784 pixels for MNIST images\n",
" * Note also ```x = x.view(-1, 1, 28, 28)``` in net definition in ```train.py``` program to shape incoming scoring requests.\n",
" 4. Convert the NumPy array to list to make it into a built-in type.\n",
" 5. Create a dictionary {\"data\", &lt;list&gt;} that can be converted to JSON string for web service requests."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from torchvision import datasets, transforms\n",
"import random\n",
"import numpy as np\n",
"\n",
"test_data = datasets.MNIST('../data', train=False, transform=transforms.Compose([\n",
" transforms.ToTensor(),\n",
" transforms.Normalize((0.1307,), (0.3081,))]))\n",
"\n",
"\n",
"def get_random_image():\n",
" image_idx = random.randint(0,len(test_data))\n",
" image_as_tensor = test_data[image_idx][0]\n",
" return {\"data\": elem for elem in image_as_tensor.numpy().reshape(1,1,-1).tolist()}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Then, invoke the web service using a random test image. Convert the dictionary containing the image to JSON string before passing it to web service.\n",
"\n",
"The response contains the raw scores for each label, with greater value indicating higher probability. Sort the labels and select the one with greatest score to get the prediction. Let's also plot the image sent to web service for comparison purposes."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline\n",
"\n",
"import json\n",
"import matplotlib.pyplot as plt\n",
"\n",
"test_image = get_random_image()\n",
"\n",
"response = webservice.run(json.dumps(test_image))\n",
"\n",
"response = sorted(response[0].items(), key = lambda x: x[1], reverse = True)\n",
"\n",
"\n",
"print(\"Predicted label:\", response[0][0])\n",
"plt.imshow(np.array(test_image[\"data\"]).reshape(28,28), cmap = \"gray\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also call the web service using a raw POST method against the web service"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"\n",
"response = requests.post(url=webservice.scoring_uri, data=json.dumps(test_image),headers={\"Content-type\": \"application/json\"})\n",
"print(response.text)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"authors": [
{
"name": "roastala"
}
],
"celltoolbar": "Edit Metadata",
"kernelspec": {
"display_name": "Python 3.6",
"language": "python",
"name": "python36"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
},
"name": "mlflow-sparksummit-pytorch",
"notebookId": 2495374963457641
},
"nbformat": 4,
"nbformat_minor": 1
}

View File

@@ -0,0 +1,8 @@
name: train-and-deploy-pytorch
dependencies:
- matplotlib
- pip:
- azureml-sdk
- azureml-mlflow
- https://download.pytorch.org/whl/cpu/torch-1.1.0-cp35-cp35m-win_amd64.whl
- https://download.pytorch.org/whl/cpu/torchvision-0.3.0-cp35-cp35m-win_amd64.whl

View File

@@ -0,0 +1,248 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Copyright (c) Microsoft Corporation. All rights reserved.\n",
"\n",
"Licensed under the MIT License."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/using-mlflow/train-local/train-local.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Use MLflow with Azure Machine Learning for Local Training Run\n",
"\n",
"This example shows you how to use mlflow tracking APIs together with Azure Machine Learning services for storing your metrics and artifacts, from local Notebook run. You'll learn how to:\n",
"\n",
" 1. Set up MLflow tracking URI so as to use Azure ML\n",
" 2. Create experiment\n",
" 3. Train a model on your local computer while logging metrics and artifacts\n",
" 4. View your experiment within your Azure ML Workspace in Azure Portal.\n",
"\n",
"## Prerequisites and Set-up\n",
"\n",
"Make sure you have completed the [Configuration](../../../configuration.ipnyb) notebook to set up your Azure Machine Learning workspace and ensure other common prerequisites are met.\n",
"\n",
"Install azureml-mlflow package before running this notebook. Note that mlflow itself gets installed as dependency if you haven't installed it yet.\n",
"\n",
"```\n",
"pip install azureml-mlflow\n",
"```\n",
"\n",
"This example also uses scikit-learn and matplotlib packages. Install them:\n",
"```\n",
"pip install scikit-learn matplotlib\n",
"```\n",
"\n",
"Then, import necessary packages"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import mlflow\n",
"import mlflow.sklearn\n",
"import azureml.core\n",
"from azureml.core import Workspace\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# Check core SDK version number\n",
"print(\"SDK version:\", azureml.core.VERSION)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Set tracking URI\n",
"\n",
"Set the MLflow tracking URI to point to your Azure ML Workspace. The subsequent logging calls from MLflow APIs will go to Azure ML services and will be tracked under your Workspace."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ws = Workspace.from_config()\n",
"\n",
"mlflow.set_tracking_uri(ws.get_mlflow_tracking_uri())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create Experiment\n",
"\n",
"In both MLflow and Azure ML, training runs are grouped into experiments. Let's create one for our experimentation."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"experiment_name = \"experiment-with-mlflow\"\n",
"mlflow.set_experiment(experiment_name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create training and test data set\n",
"\n",
"This example uses diabetes dataset to build a simple regression model. Let's load the dataset and split it into training and test sets."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"from sklearn.datasets import load_diabetes\n",
"from sklearn.linear_model import Ridge\n",
"from sklearn.metrics import mean_squared_error\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"X, y = load_diabetes(return_X_y = True)\n",
"columns = ['age', 'gender', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']\n",
"X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)\n",
"data = {\n",
" \"train\":{\"X\": X_train, \"y\": y_train}, \n",
" \"test\":{\"X\": X_test, \"y\": y_test}\n",
"}\n",
"\n",
"print (\"Data contains\", len(data['train']['X']), \"training samples and\",len(data['test']['X']), \"test samples\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Train while logging metrics and artifacts\n",
"\n",
"Next, start a mlflow run to train a scikit-learn regression model. Note that the training script has been instrumented using MLflow to:\n",
" * Log model hyperparameter alpha value\n",
" * Log mean squared error against test set\n",
" * Save the scikit-learn based regression model produced by training\n",
" * Save an image that shows actuals vs predictions against test set.\n",
" \n",
"These metrics and artifacts have been recorded to your Azure ML Workspace; in the next step you'll learn how to view them."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Create a run object in the experiment\n",
"model_save_path = \"model\"\n",
"\n",
"with mlflow.start_run() as run:\n",
" # Log the algorithm parameter alpha to the run\n",
" mlflow.log_metric('alpha', 0.03)\n",
" # Create, fit, and test the scikit-learn Ridge regression model\n",
" regression_model = Ridge(alpha=0.03)\n",
" regression_model.fit(data['train']['X'], data['train']['y'])\n",
" preds = regression_model.predict(data['test']['X'])\n",
"\n",
" # Log mean squared error\n",
" print('Mean Squared Error is', mean_squared_error(data['test']['y'], preds))\n",
" mlflow.log_metric('mse', mean_squared_error(data['test']['y'], preds))\n",
" \n",
" # Save the model to the outputs directory for capture\n",
" mlflow.sklearn.log_model(regression_model,model_save_path)\n",
" \n",
" # Plot actuals vs predictions and save the plot within the run\n",
" fig = plt.figure(1)\n",
" idx = np.argsort(data['test']['y'])\n",
" plt.plot(data['test']['y'][idx],preds[idx])\n",
" fig.savefig(\"actuals_vs_predictions.png\")\n",
" mlflow.log_artifact(\"actuals_vs_predictions.png\") "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can open the report page for your experiment and runs within it from Azure Portal.\n",
"\n",
"Select one of the runs to view the metrics, and the plot you saved. The saved scikit-learn model appears under **outputs** tab."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ws.experiments[experiment_name]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Next steps\n",
"\n",
"Try out these notebooks to learn more about MLflow-Azure Machine Learning integration:\n",
"\n",
" * [Train a model using remote compute on Azure Cloud](../train-on-remote/train-on-remote.ipynb)\n",
" * [Deploy the model as a web service](../deploy-model/deploy-model.ipynb)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"authors": [
{
"name": "rastala"
}
],
"kernelspec": {
"display_name": "Python 3.6",
"language": "python",
"name": "python36"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,7 @@
name: train-local
dependencies:
- scikit-learn
- matplotlib
- pip:
- azureml-sdk
- azureml-mlflow

View File

@@ -0,0 +1,318 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Copyright (c) Microsoft Corporation. All rights reserved.\n",
"\n",
"Licensed under the MIT License."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/track-and-monitor-experiments/using-mlflow/train-remote/train-remote.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Use MLflow with Azure Machine Learning for Remote Training Run\n",
"\n",
"This example shows you how to use MLflow tracking APIs together with Azure Machine Learning services for storing your metrics and artifacts, from local Notebook run. You'll learn how to:\n",
"\n",
" 1. Set up MLflow tracking URI so as to use Azure ML\n",
" 2. Create experiment\n",
" 3. Train a model on Machine Learning Compute while logging metrics and artifacts\n",
" 4. View your experiment within your Azure ML Workspace in Azure Portal."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Prerequisites\n",
"\n",
"Make sure you have completed the [Configuration](../../../configuration.ipnyb) notebook to set up your Azure Machine Learning workspace and ensure other common prerequisites are met."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Set-up\n",
"\n",
"Check Azure ML SDK version installed on your computer, and then connect to your Workspace."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Check core SDK version number\n",
"import azureml.core\n",
"from azureml.core import Workspace, Experiment\n",
"\n",
"print(\"SDK version:\", azureml.core.VERSION)\n",
"\n",
"ws = Workspace.from_config()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's also create a Machine Learning Compute cluster for submitting the remote run. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core.compute import ComputeTarget, AmlCompute\n",
"from azureml.core.compute_target import ComputeTargetException\n",
"\n",
"# Choose a name for your CPU cluster\n",
"cpu_cluster_name = \"cpu-cluster\"\n",
"\n",
"# Verify that cluster does not exist already\n",
"try:\n",
" cpu_cluster = ComputeTarget(workspace=ws, name=cpu_cluster_name)\n",
" print(\"Found existing cpu-cluster\")\n",
"except ComputeTargetException:\n",
" print(\"Creating new cpu-cluster\")\n",
" \n",
" # Specify the configuration for the new cluster\n",
" compute_config = AmlCompute.provisioning_configuration(vm_size=\"STANDARD_D2_V2\",\n",
" min_nodes=0,\n",
" max_nodes=1)\n",
"\n",
" # Create the cluster with the specified name and configuration\n",
" cpu_cluster = ComputeTarget.create(ws, cpu_cluster_name, compute_config)\n",
" \n",
" # Wait for the cluster to complete, show the output log\n",
" cpu_cluster.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Create Azure ML Experiment"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The following steps show how to submit a training Python script to a cluster as an Azure ML run, while logging happens through MLflow APIs to your Azure ML Workspace. Let's first create an experiment to hold the training runs."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core import Experiment\n",
"\n",
"experiment_name = \"experiment-with-mlflow\"\n",
"exp = Experiment(workspace=ws, name=experiment_name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Instrument remote training script using MLflow"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's use [*train_diabetes.py*](train_diabetes.py) to train a regression model against diabetes dataset as the example. Note that the training script uses mlflow.start_run() to start logging, and then logs metrics, saves the trained scikit-learn model, and saves a plot as an artifact.\n",
"\n",
"Run following command to view the script file. Notice the mlflow logging statements, and also notice that the script doesn't have explicit dependencies on azureml library."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"training_script = 'train_diabetes.py'\n",
"with open(training_script, 'r') as f:\n",
" print(f.read())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Submit Run to Cluster \n",
"\n",
"Let's submit the run to cluster. When running on the remote cluster as submitted run, Azure ML sets the MLflow tracking URI to point to your Azure ML Workspace, so that the metrics and artifacts are automatically logged there.\n",
"\n",
"Note that you have to specify the packages your script depends on, including *azureml-mlflow* that implicitly enables the MLflow logging to Azure ML. \n",
"\n",
"First, create a environment with Docker enable and required package dependencies specified."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"mlflow"
]
},
"outputs": [],
"source": [
"from azureml.core import Environment\n",
"from azureml.core.conda_dependencies import CondaDependencies\n",
"\n",
"env = Environment(name=\"mlflow-env\")\n",
"\n",
"env.docker.enabled = True\n",
"\n",
"# Specify conda dependencies with scikit-learn and temporary pointers to mlflow extensions\n",
"cd = CondaDependencies.create(\n",
" conda_packages=[\"scikit-learn\", \"matplotlib\"],\n",
" pip_packages=[\"azureml-mlflow\", \"numpy\"]\n",
" )\n",
"\n",
"env.python.conda_dependencies = cd"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, specify a script run configuration that includes the training script, environment and CPU cluster created earlier."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from azureml.core import ScriptRunConfig\n",
"\n",
"src = ScriptRunConfig(source_directory=\".\", script=training_script)\n",
"src.run_config.environment = env\n",
"src.run_config.target = cpu_cluster.name"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, submit the run. Note that the first instance of the run typically takes longer as the Docker-based environment is created, several minutes. Subsequent runs reuse the image and are faster."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run = exp.submit(src)\n",
"run.wait_for_completion(show_output=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can navigate to your Azure ML Workspace at Azure Portal to view the run metrics and artifacts. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also get the metrics and bring them to your local notebook, and view the details of the run."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"run.get_metrics()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ws.get_details()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Next steps\n",
"\n",
" * [Deploy the model as a web service](../deploy-model/deploy-model.ipynb)\n",
" * [Learn more about Azure Machine Learning compute options](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-set-up-training-targets)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"authors": [
{
"name": "rastala"
}
],
"kernelspec": {
"display_name": "Python 3.6",
"language": "python",
"name": "python36"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -0,0 +1,4 @@
name: train-remote
dependencies:
- pip:
- azureml-sdk

View File

@@ -0,0 +1,46 @@
# Copyright (c) Microsoft. All rights reserved.
# Licensed under the MIT license.
import numpy as np
from sklearn.datasets import load_diabetes
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
import mlflow
import mlflow.sklearn
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
with mlflow.start_run():
X, y = load_diabetes(return_X_y=True)
columns = ['age', 'gender', 'bmi', 'bp', 's1', 's2', 's3', 's4', 's5', 's6']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
data = {
"train": {"X": X_train, "y": y_train},
"test": {"X": X_test, "y": y_test}}
mlflow.log_metric("Training samples", len(data['train']['X']))
mlflow.log_metric("Test samples", len(data['test']['X']))
# Log the algorithm parameter alpha to the run
mlflow.log_metric('alpha', 0.03)
# Create, fit, and test the scikit-learn Ridge regression model
regression_model = Ridge(alpha=0.03)
regression_model.fit(data['train']['X'], data['train']['y'])
preds = regression_model.predict(data['test']['X'])
# Log mean squared error
print('Mean Squared Error is', mean_squared_error(data['test']['y'], preds))
mlflow.log_metric('mse', mean_squared_error(data['test']['y'], preds))
# Save the model to the outputs directory for capture
mlflow.sklearn.log_model(regression_model, "model")
# Plot actuals vs predictions and save the plot within the run
fig = plt.figure(1)
idx = np.argsort(data['test']['y'])
plt.plot(data['test']['y'][idx], preds[idx])
fig.savefig("actuals_vs_predictions.png")
mlflow.log_artifact("actuals_vs_predictions.png")

View File

@@ -286,7 +286,11 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {
"tags": [
"estimator-remarks-sample"
]
},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.train.estimator import Estimator\n", "from azureml.train.estimator import Estimator\n",

View File

@@ -252,7 +252,11 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {
"tags": [
"dnn-chainer-remarks-sample"
]
},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.train.dnn import Chainer\n", "from azureml.train.dnn import Chainer\n",

View File

@@ -250,7 +250,11 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {
"tags": [
"dnn-pytorch-remarks-sample"
]
},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.train.dnn import PyTorch\n", "from azureml.train.dnn import PyTorch\n",

View File

@@ -412,7 +412,11 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {
"tags": [
"dnn-tensorflow-remarks-sample"
]
},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.train.dnn import TensorFlow\n", "from azureml.train.dnn import TensorFlow\n",

View File

@@ -7,8 +7,6 @@ Follow these sample notebooks to learn:
3. [Train on remote VM](train-on-remote-vm): train a model using a remote Azure VM as compute target. 3. [Train on remote VM](train-on-remote-vm): train a model using a remote Azure VM as compute target.
4. [Train on ML Compute](train-on-amlcompute): train a model using an ML Compute cluster as compute target. 4. [Train on ML Compute](train-on-amlcompute): train a model using an ML Compute cluster as compute target.
5. [Train in an HDI Spark cluster](train-in-spark): train a Spark ML model using an HDInsight Spark cluster as compute target. 5. [Train in an HDI Spark cluster](train-in-spark): train a Spark ML model using an HDInsight Spark cluster as compute target.
6. [Logging API](logging-api): experiment with various logging functions to create runs and automatically generate graphs. 6. [Train and hyperparameter tune on Iris Dataset with Scikit-learn](train-hyperparameter-tune-deploy-with-sklearn): train a model using the Scikit-learn estimator and tune hyperparameters with Hyperdrive.
7. [Manage runs](manage-runs): learn different ways how to start runs and child runs, monitor them, and cancel them.
8. [Train and hyperparameter tune on Iris Dataset with Scikit-learn](train-hyperparameter-tune-deploy-with-sklearn): train a model using the Scikit-learn estimator and tune hyperparameters with Hyperdrive.
![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/training/README.png) ![Impressions](https://PixelServer20190423114238.azurewebsites.net/api/impressions/MachineLearningNotebooks/how-to-use-azureml/training/README.png)

View File

@@ -298,7 +298,11 @@
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": null,
"metadata": {}, "metadata": {
"tags": [
"sklearn-remarks-sample"
]
},
"outputs": [], "outputs": [],
"source": [ "source": [
"from azureml.train.sklearn import SKLearn\n", "from azureml.train.sklearn import SKLearn\n",

View File

@@ -332,7 +332,11 @@
"\n", "\n",
"* [Train on ML Compute](../../train-on-amlcompute)\n", "* [Train on ML Compute](../../train-on-amlcompute)\n",
"\n", "\n",
"* [Train on remote VM](../../train-on-remote-vm)" "* [Train on remote VM](../../train-on-remote-vm)\n",
"\n",
"Learn more about registering and deploying a model:\n",
"\n",
"* [Model Register and Deploy](../../deploy-to-cloud/model-register-and-deploy.ipynb)"
] ]
}, },
{ {

View File

@@ -46,10 +46,9 @@
"pd.set_option('display.max_columns', None)\n", "pd.set_option('display.max_columns', None)\n",
"\n", "\n",
"cache_location = mkdtemp()\n", "cache_location = mkdtemp()\n",
"dataset_root = \"https://dprepdata.blob.core.windows.net/demo\"\n", "green_path = \"https://dprepdata.blob.core.windows.net/demo/green-small/*\"\n",
"\n", "yellow_path = \"https://dprepdata.blob.core.windows.net/demo/yellow-small/*\"\n",
"green_path = \"/\".join([dataset_root, \"green-small/*\"])\n", "# (optional) Download and view a subset of the data: https://dprepdata.blob.core.windows.net/demo/green-small/green_tripdata_2013-08.csv\n",
"yellow_path = \"/\".join([dataset_root, \"yellow-small/*\"])\n",
"\n", "\n",
"print(\"Retrieving data from the following two sources:\")\n", "print(\"Retrieving data from the following two sources:\")\n",
"print(green_path)\n", "print(green_path)\n",

View File

@@ -0,0 +1,45 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEg09d0uWdyo9c
uKbaJss7BT/NNuBw0Nh2pyHzLCJHyShcRi8UcmAeTlaMXdyr5NqTjqc1VT+CZA/o
IZQxbFfkt87pyRmbIw34B1rCy3/FuT4o6n+rcWaRppBo8bBt1+9P7GID3KS0HWuk
fWoAJaODsuC+mlbuB2s6CwPKbF8X30YGTL12SN73o4xewU8BDRUrSQEG1Gh5+5sV
3abQFx/4DYNVqWQy4e15N5QkV8qCa06wCGAgq6NkgnVZVRZbxS2VQo2V+xEFkJEG
yhtfTS+pRLsvTZQoIoYC+E7gAYmB9KhLPtX50DJ/xmI93/qL4Yt6pcjioecq4//n
NORKAFHBAgMBAAECggEAYab67p3ZmsLI4QOlbmyuu0KNhPXLLGSr3LKLDWMWGeQd
WVVLGfcISqcVHSWbfhP4hjDyaG9XYv1EZk8hbDnxp2eru8NCJTSTQXiuInSrpt65
w+1byh9NH/3Mb0oDKWKPuoC16ENh2VtxXUkxPqd1jQF761uY7Snkn/BPTuzxiFN8
Swrhum4b0CZf1XS4rTuk0b8tgSilGbk1DVMYANmQGb5TjMKjAJHzTIF5LYosXppQ
q8xr24XRMpz4m9KuGZTPePZ3ycGadnQV205uE0fuCsru1V5xsNYKh9LYJYWPyD49
L4eFHgLc2uVL9XFJZ7wujW0z5ZxyhWwObHoWvYrRjQKBgQD4frvJ7W8wJxNDa+3k
rKVnN+vjCSLDqc3HVZPvVkEhZRXAx6PSTYJVAMi2ULdhoxrT6jDwsN7KA1qpqb9n
NOttuAqFrJLPRRTjc5YjvBL1Yb4/wFUMR4OgrhhtwIEXlftXN830zlW1Wvo6S8o1
vkGG9KuoVhfroyu4XAJpokd6CwKBgQDKcqvKIzhrF7Oed3STIpLJieeE0n+Dkz+I
AEXm1E7ulT57BYTYO2jLLSUYnetew+QL85cXFSsuEUgH3H2fhckBdq8jcjJGi+YB
7OA1WLUyvDvM6E6CxguzdNNNbtmhXNyLCOrxjiV35wzj47y/UPcWrURQZgzaxovH
+c8mPeeO4wKBgQDB/GVqwFDxXT+7fVDsGB7TUiNyTBp4dmFvAA6JY2Nax4fQw8jO
jrV02DTXpnFR5js2PXdRHjH9r9qh4iLKVdSIBYkpS0wcREiHOx907Ag8yL31FJcQ
C+/kiqQFYaclG29naef8+OqNteTrh2jmxYxv5ybuNa9cwzeJJ0K25fk4ewKBgQCl
2tooqUAgZHOQILdNj2aIXEVjSHyVE75ZsjeSS187EOP2L2hNKibJRXv9terNYVjj
/bVLgNk2TYwgfKAiX510aIJFXNoZd6WA8EojCkCwhwvK7IrdkliltdEiv+zlyMkZ
0r2AFf9WQuEJllrctf0oA91SrLhdR4ne1CbEYrThFwKBgEoK2tStBVypdnAZe7mI
ahk4Lv3QYqwD+qd8H6VRwbX1EtggWCQh0jAohcCzn2HHq+zjUlT3RF7ey46z0gel
+58sKj7uAHuHJ+pg8xI0CWS8Vy6E2hT5bCanb0rKXguuwx+90Kn/xj/yAK7CeIId
PrJHSlG9/au3N6cbVM65RHPG
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIICoTCCAYkCAgPoMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNVBAMMCUNMSS1Mb2dp
bjAiGA8yMDE5MDcxNjAxMDEwNloYDzIwMjAwNzE2MDEwMTA4WjAUMRIwEAYDVQQD
DAlDTEktTG9naW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEg09d
0uWdyo9cuKbaJss7BT/NNuBw0Nh2pyHzLCJHyShcRi8UcmAeTlaMXdyr5NqTjqc1
VT+CZA/oIZQxbFfkt87pyRmbIw34B1rCy3/FuT4o6n+rcWaRppBo8bBt1+9P7GID
3KS0HWukfWoAJaODsuC+mlbuB2s6CwPKbF8X30YGTL12SN73o4xewU8BDRUrSQEG
1Gh5+5sV3abQFx/4DYNVqWQy4e15N5QkV8qCa06wCGAgq6NkgnVZVRZbxS2VQo2V
+xEFkJEGyhtfTS+pRLsvTZQoIoYC+E7gAYmB9KhLPtX50DJ/xmI93/qL4Yt6pcji
oecq4//nNORKAFHBAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAIDer4wNPbb+FEGs
P+qwYWkDoDHjk3zG2bw8LEjp28PfzlXg5ng2W/rcNHnWTxkDSp7xCaJLhNuCRXx6
vF8sNsQscW9219ZWv5OSETYivLDX1It24ZepAetWmM4NAamU9ZkJHIVidpyZPtZ+
I9PvrTh44KW8VaPhhR5Gv0cUgq4rjhyHCyk8ZpEB4fO83/1fu5MnQUsPvqzrlgEa
p3/GwG7AGSye0QyWdjrt2rcO0QWrCelZdkFut8kV0FHOzrrEgvoLDBlgzN9/qY+a
Yb0+kqR1WBr58HZRG4i4abRpI49xMNp+egASN/8tPSsaR2BIsVmXBSg9Bd+k/f1V
IUg8NDw=
-----END CERTIFICATE-----

Some files were not shown because too many files have changed in this diff Show More