Compare commits
8 Commits
azureml-sd
...
azureml-sd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34a67c1f8b | ||
|
|
34898828be | ||
|
|
a7c3a0fdb8 | ||
|
|
6d11cdfa0a | ||
|
|
11e8ed2bab | ||
|
|
12c06a4168 | ||
|
|
1f75dc9725 | ||
|
|
1a1a42d525 |
@@ -40,6 +40,7 @@ The [How to use Azure ML](./how-to-use-azureml) folder contains specific example
|
|||||||
- [Deployment](./how-to-use-azureml/deployment) - Examples showing how to deploy and manage machine learning models and solutions
|
- [Deployment](./how-to-use-azureml/deployment) - Examples showing how to deploy and manage machine learning models and solutions
|
||||||
- [Azure Databricks](./how-to-use-azureml/azure-databricks) - Examples showing how to use Azure ML with Azure Databricks
|
- [Azure Databricks](./how-to-use-azureml/azure-databricks) - Examples showing how to use Azure ML with Azure Databricks
|
||||||
- [Monitor Models](./how-to-use-azureml/monitor-models) - Examples showing how to enable model monitoring services such as DataDrift
|
- [Monitor Models](./how-to-use-azureml/monitor-models) - Examples showing how to enable model monitoring services such as DataDrift
|
||||||
|
- [Reinforcement Learning](./how-to-use-azureml/reinforcement-learning) - Examples showing how to train reinforcement learning agents
|
||||||
|
|
||||||
---
|
---
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"import azureml.core\n",
|
"import azureml.core\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ jupyter notebook
|
|||||||
- Dataset: forecasting for a bike-sharing
|
- Dataset: forecasting for a bike-sharing
|
||||||
- Example of training an automated ML forecasting model on multiple time-series
|
- Example of training an automated ML forecasting model on multiple time-series
|
||||||
|
|
||||||
- [auto-ml-forecasting-function.ipynb](forecasting-high-frequency/auto-ml-forecasting-function.ipynb)
|
- [auto-ml-forecasting-function.ipynb](forecasting-forecast-function/auto-ml-forecasting-function.ipynb)
|
||||||
- Example of training an automated ML forecasting model on multiple time-series
|
- Example of training an automated ML forecasting model on multiple time-series
|
||||||
|
|
||||||
- [auto-ml-forecasting-beer-remote.ipynb](forecasting-beer-remote/auto-ml-forecasting-beer-remote.ipynb)
|
- [auto-ml-forecasting-beer-remote.ipynb](forecasting-beer-remote/auto-ml-forecasting-beer-remote.ipynb)
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -93,7 +93,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -491,8 +491,8 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"test_run = run_inference(test_experiment, compute_target, script_folder, best_dnn_run, test_dataset,\n",
|
"test_run = run_inference(test_experiment, compute_target, script_folder, best_dnn_run,\n",
|
||||||
" target_column_name, model_name)"
|
" train_dataset, test_dataset, target_column_name, model_name)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from azureml.core.run import Run
|
|||||||
|
|
||||||
|
|
||||||
def run_inference(test_experiment, compute_target, script_folder, train_run,
|
def run_inference(test_experiment, compute_target, script_folder, train_run,
|
||||||
test_dataset, target_column_name, model_name):
|
train_dataset, test_dataset, target_column_name, model_name):
|
||||||
|
|
||||||
train_run.download_file('outputs/conda_env_v_1_0_0.yml',
|
train_run.download_file('outputs/conda_env_v_1_0_0.yml',
|
||||||
'inference/condafile.yml')
|
'inference/condafile.yml')
|
||||||
@@ -22,7 +22,10 @@ def run_inference(test_experiment, compute_target, script_folder, train_run,
|
|||||||
'--target_column_name': target_column_name,
|
'--target_column_name': target_column_name,
|
||||||
'--model_name': model_name
|
'--model_name': model_name
|
||||||
},
|
},
|
||||||
inputs=[test_dataset.as_named_input('test_data')],
|
inputs=[
|
||||||
|
train_dataset.as_named_input('train_data'),
|
||||||
|
test_dataset.as_named_input('test_data')
|
||||||
|
],
|
||||||
compute_target=compute_target,
|
compute_target=compute_target,
|
||||||
environment_definition=inference_env)
|
environment_definition=inference_env)
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
import numpy as np
|
|
||||||
import argparse
|
import argparse
|
||||||
from azureml.core import Run
|
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
from sklearn.externals import joblib
|
from sklearn.externals import joblib
|
||||||
from azureml.automl.core.shared import constants, metrics
|
|
||||||
|
from azureml.automl.runtime.shared.score import scoring, constants
|
||||||
|
from azureml.core import Run
|
||||||
from azureml.core.model import Model
|
from azureml.core.model import Model
|
||||||
|
|
||||||
|
|
||||||
@@ -29,22 +32,26 @@ model = joblib.load(model_path)
|
|||||||
run = Run.get_context()
|
run = Run.get_context()
|
||||||
# get input dataset by name
|
# get input dataset by name
|
||||||
test_dataset = run.input_datasets['test_data']
|
test_dataset = run.input_datasets['test_data']
|
||||||
|
train_dataset = run.input_datasets['train_data']
|
||||||
|
|
||||||
X_test_df = test_dataset.drop_columns(columns=[target_column_name]) \
|
X_test_df = test_dataset.drop_columns(columns=[target_column_name]) \
|
||||||
.to_pandas_dataframe()
|
.to_pandas_dataframe()
|
||||||
y_test_df = test_dataset.with_timestamp_columns(None) \
|
y_test_df = test_dataset.with_timestamp_columns(None) \
|
||||||
.keep_columns(columns=[target_column_name]) \
|
.keep_columns(columns=[target_column_name]) \
|
||||||
.to_pandas_dataframe()
|
.to_pandas_dataframe()
|
||||||
|
y_train_df = test_dataset.with_timestamp_columns(None) \
|
||||||
|
.keep_columns(columns=[target_column_name]) \
|
||||||
|
.to_pandas_dataframe()
|
||||||
|
|
||||||
predicted = model.predict_proba(X_test_df)
|
predicted = model.predict_proba(X_test_df)
|
||||||
|
|
||||||
# use automl metrics module
|
# Use the AutoML scoring module
|
||||||
scores = metrics.compute_metrics_classification(
|
class_labels = np.unique(np.concatenate((y_train_df.values, y_test_df.values)))
|
||||||
np.array(predicted),
|
train_labels = model.classes_
|
||||||
np.array(y_test_df),
|
classification_metrics = list(constants.CLASSIFICATION_SCALAR_SET)
|
||||||
class_labels=model.classes_,
|
scores = scoring.score_classification(y_test_df.values, predicted,
|
||||||
metrics=list(constants.Metric.SCALAR_CLASSIFICATION_SET)
|
classification_metrics,
|
||||||
)
|
class_labels, train_labels)
|
||||||
|
|
||||||
print("scores:")
|
print("scores:")
|
||||||
print(scores)
|
print(scores)
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -114,7 +114,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import pandas as pd
|
|
||||||
import numpy as np
|
|
||||||
import argparse
|
import argparse
|
||||||
from azureml.core import Run
|
|
||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
from pandas.tseries.frequencies import to_offset
|
||||||
from sklearn.externals import joblib
|
from sklearn.externals import joblib
|
||||||
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
||||||
from azureml.automl.core.shared import constants, metrics
|
|
||||||
from pandas.tseries.frequencies import to_offset
|
from azureml.automl.runtime.shared.score import scoring, constants
|
||||||
|
from azureml.core import Run
|
||||||
|
|
||||||
|
|
||||||
def align_outputs(y_predicted, X_trans, X_test, y_test,
|
def align_outputs(y_predicted, X_trans, X_test, y_test,
|
||||||
@@ -299,12 +302,11 @@ print(df_all[target_column_name])
|
|||||||
print("predicted values:::")
|
print("predicted values:::")
|
||||||
print(df_all['predicted'])
|
print(df_all['predicted'])
|
||||||
|
|
||||||
# use automl metrics module
|
# Use the AutoML scoring module
|
||||||
scores = metrics.compute_metrics_regression(
|
regression_metrics = list(constants.REGRESSION_SCALAR_SET)
|
||||||
df_all['predicted'],
|
y_test = np.array(df_all[target_column_name])
|
||||||
df_all[target_column_name],
|
y_pred = np.array(df_all['predicted'])
|
||||||
list(constants.Metric.SCALAR_REGRESSION_SET),
|
scores = scoring.score_regression(y_test, y_pred, regression_metrics)
|
||||||
None, None, None)
|
|
||||||
|
|
||||||
print("scores:")
|
print("scores:")
|
||||||
print(scores)
|
print(scores)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -510,16 +510,16 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.automl.core.shared import constants, metrics\n",
|
"from azureml.automl.core.shared import constants\n",
|
||||||
|
"from azureml.automl.runtime.shared.score import scoring\n",
|
||||||
"from sklearn.metrics import mean_absolute_error, mean_squared_error\n",
|
"from sklearn.metrics import mean_absolute_error, mean_squared_error\n",
|
||||||
"from matplotlib import pyplot as plt\n",
|
"from matplotlib import pyplot as plt\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# use automl metrics module\n",
|
"# use automl metrics module\n",
|
||||||
"scores = metrics.compute_metrics_regression(\n",
|
"scores = scoring.score_regression(\n",
|
||||||
" df_all['predicted'],\n",
|
" y_test=df_all[target_column_name],\n",
|
||||||
" df_all[target_column_name],\n",
|
" y_pred=df_all['predicted'],\n",
|
||||||
" list(constants.Metric.SCALAR_REGRESSION_SET),\n",
|
" metrics=list(constants.Metric.SCALAR_REGRESSION_SET))\n",
|
||||||
" None, None, None)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"[Test data scores]\\n\")\n",
|
"print(\"[Test data scores]\\n\")\n",
|
||||||
"for key, value in scores.items(): \n",
|
"for key, value in scores.items(): \n",
|
||||||
|
|||||||
@@ -97,7 +97,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -465,7 +465,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Forecast Function\n",
|
"### Forecast Function\n",
|
||||||
"For forecasting, we will use the forecast function instead of the predict function. Using the predict method would result in getting predictions for EVERY horizon the forecaster can predict at. This is useful when training and evaluating the performance of the forecaster at various horizons, but the level of detail is excessive for normal use. Forecast function also can handle more complicated scenarios, see notebook on [high frequency forecasting](https://github.com/Azure/MachineLearningNotebooks/blob/master/how-to-use-azureml/automated-machine-learning/forecasting-high-frequency/auto-ml-forecasting-function.ipynb)."
|
"For forecasting, we will use the forecast function instead of the predict function. Using the predict method would result in getting predictions for EVERY horizon the forecaster can predict at. This is useful when training and evaluating the performance of the forecaster at various horizons, but the level of detail is excessive for normal use. Forecast function also can handle more complicated scenarios, see the [forecast function notebook](../forecasting-forecast-function/auto-ml-forecasting-function.ipynb)."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -507,15 +507,15 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.automl.core.shared import constants, metrics\n",
|
"from azureml.automl.core.shared import constants\n",
|
||||||
|
"from azureml.automl.runtime.shared.score import scoring\n",
|
||||||
"from matplotlib import pyplot as plt\n",
|
"from matplotlib import pyplot as plt\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# use automl metrics module\n",
|
"# use automl metrics module\n",
|
||||||
"scores = metrics.compute_metrics_regression(\n",
|
"scores = scoring.score_regression(\n",
|
||||||
" df_all['predicted'],\n",
|
" y_test=df_all[target_column_name],\n",
|
||||||
" df_all[target_column_name],\n",
|
" y_pred=df_all['predicted'],\n",
|
||||||
" list(constants.Metric.SCALAR_REGRESSION_SET),\n",
|
" metrics=list(constants.Metric.SCALAR_REGRESSION_SET))\n",
|
||||||
" None, None, None)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"[Test data scores]\\n\")\n",
|
"print(\"[Test data scores]\\n\")\n",
|
||||||
"for key, value in scores.items(): \n",
|
"for key, value in scores.items(): \n",
|
||||||
@@ -667,15 +667,15 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.automl.core.shared import constants, metrics\n",
|
"from azureml.automl.core.shared import constants\n",
|
||||||
|
"from azureml.automl.runtime.shared.score import scoring\n",
|
||||||
"from matplotlib import pyplot as plt\n",
|
"from matplotlib import pyplot as plt\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# use automl metrics module\n",
|
"# use automl metrics module\n",
|
||||||
"scores = metrics.compute_metrics_regression(\n",
|
"scores = scoring.score_regression(\n",
|
||||||
" df_all['predicted'],\n",
|
" y_test=df_all[target_column_name],\n",
|
||||||
" df_all[target_column_name],\n",
|
" y_pred=df_all['predicted'],\n",
|
||||||
" list(constants.Metric.SCALAR_REGRESSION_SET),\n",
|
" metrics=list(constants.Metric.SCALAR_REGRESSION_SET))\n",
|
||||||
" None, None, None)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"[Test data scores]\\n\")\n",
|
"print(\"[Test data scores]\\n\")\n",
|
||||||
"for key, value in scores.items(): \n",
|
"for key, value in scores.items(): \n",
|
||||||
|
|||||||
@@ -35,7 +35,6 @@
|
|||||||
"Terminology:\n",
|
"Terminology:\n",
|
||||||
"* forecast origin: the last period when the target value is known\n",
|
"* forecast origin: the last period when the target value is known\n",
|
||||||
"* forecast periods(s): the period(s) for which the value of the target is desired.\n",
|
"* forecast periods(s): the period(s) for which the value of the target is desired.\n",
|
||||||
"* forecast horizon: the number of forecast periods\n",
|
|
||||||
"* lookback: how many past periods (before forecast origin) the model function depends on. The larger of number of lags and length of rolling window.\n",
|
"* lookback: how many past periods (before forecast origin) the model function depends on. The larger of number of lags and length of rolling window.\n",
|
||||||
"* prediction context: `lookback` periods immediately preceding the forecast origin\n",
|
"* prediction context: `lookback` periods immediately preceding the forecast origin\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -95,7 +94,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -720,6 +719,90 @@
|
|||||||
"X_show[['date', 'grain', 'ext_predictor', '_automl_target_col']]\n",
|
"X_show[['date', 'grain', 'ext_predictor', '_automl_target_col']]\n",
|
||||||
"# prediction is in _automl_target_col"
|
"# prediction is in _automl_target_col"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Forecasting farther than the maximum horizon <a id=\"recursive forecasting\"></a>\n",
|
||||||
|
"When the forecast destination, or the latest date in the prediction data frame, is farther into the future than the specified maximum horizon, the `forecast()` function will still make point predictions out to the later date using a recursive operation mode. Internally, the method recursively applies the regular forecaster to generate context so that we can forecast further into the future. \n",
|
||||||
|
"\n",
|
||||||
|
"To illustrate the use-case and operation of recursive forecasting, we'll consider an example with a single time-series where the forecasting period directly follows the training period and is twice as long as the maximum horizon given at training time.\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"Internally, we apply the forecaster in an iterative manner and finish the forecast task in two interations. In the first iteration, we apply the forecaster and get the prediction for the first max-horizon periods (y_pred1). In the second iteraction, y_pred1 is used as the context to produce the prediction for the next max-horizon periods (y_pred2). The combination of (y_pred1 and y_pred2) gives the results for the total forecast periods. \n",
|
||||||
|
"\n",
|
||||||
|
"A caveat: forecast accuracy will likely be worse the farther we predict into the future since errors are compounded with recursive application of the forecaster.\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# generate the same kind of test data we trained on, but with a single grain/time-series and test period twice as long as the max_horizon\n",
|
||||||
|
"_, _, X_test_long, y_test_long = get_timeseries(train_len=n_train_periods,\n",
|
||||||
|
" test_len=max_horizon*2,\n",
|
||||||
|
" time_column_name=TIME_COLUMN_NAME,\n",
|
||||||
|
" target_column_name=TARGET_COLUMN_NAME,\n",
|
||||||
|
" grain_column_name=GRAIN_COLUMN_NAME,\n",
|
||||||
|
" grains=1)\n",
|
||||||
|
"\n",
|
||||||
|
"print(X_test_long.groupby(GRAIN_COLUMN_NAME)[TIME_COLUMN_NAME].min())\n",
|
||||||
|
"print(X_test_long.groupby(GRAIN_COLUMN_NAME)[TIME_COLUMN_NAME].max())"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# forecast() function will invoke the recursive forecast method internally.\n",
|
||||||
|
"y_pred_long, X_trans_long = fitted_model.forecast(X_test_long)\n",
|
||||||
|
"y_pred_long"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# What forecast() function does in this case is equivalent to iterating it twice over the test set as the following. \n",
|
||||||
|
"y_pred1, _ = fitted_model.forecast(X_test_long[:max_horizon])\n",
|
||||||
|
"y_pred_all, _ = fitted_model.forecast(X_test_long, np.concatenate((y_pred1, np.full(max_horizon, np.nan))))\n",
|
||||||
|
"np.array_equal(y_pred_all, y_pred_long)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"#### Confidence interval and distributional forecasts\n",
|
||||||
|
"AutoML cannot currently estimate forecast errors beyond the maximum horizon set during training, so the `forecast_quantiles()` function will return missing values for quantiles not equal to 0.5 beyond the maximum horizon. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"fitted_model.forecast_quantiles(X_test_long)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Similarly with the simple senarios illustrated above, forecasting farther than the max horizon in other senarios like 'multiple grain', 'Destination-date forecast', and 'forecast away from the training data' are also automatically handled by the `forecast()` function. "
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 21 KiB |
@@ -82,7 +82,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -336,7 +336,11 @@
|
|||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"metadata": {},
|
"metadata": {
|
||||||
|
"tags": [
|
||||||
|
"sample-featurizationconfig-remarks"
|
||||||
|
]
|
||||||
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"featurization_config = FeaturizationConfig()\n",
|
"featurization_config = FeaturizationConfig()\n",
|
||||||
@@ -545,7 +549,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"If you are used to scikit pipelines, perhaps you expected `predict(X_test)`. However, forecasting requires a more general interface that also supplies the past target `y` values. Please use `forecast(X,y)` as `predict(X)` is reserved for internal purposes on forecasting models.\n",
|
"If you are used to scikit pipelines, perhaps you expected `predict(X_test)`. However, forecasting requires a more general interface that also supplies the past target `y` values. Please use `forecast(X,y)` as `predict(X)` is reserved for internal purposes on forecasting models.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The [forecast function notebook](https://github.com/Azure/MachineLearningNotebooks/blob/master/how-to-use-azureml/automated-machine-learning/forecasting-high-frequency/auto-ml-forecasting-function.ipynb) demonstrates the use of the forecast function for a variety of use cases. Also, please see the [API documentation for the forecast function](https://docs.microsoft.com/en-us/python/api/azureml-automl-runtime/azureml.automl.runtime.shared.model_wrappers.forecastingpipelinewrapper?view=azure-ml-py#forecast-x-pred--typing-union-pandas-core-frame-dataframe--nonetype----none--y-pred--typing-union-pandas-core-frame-dataframe--numpy-ndarray--nonetype----none--forecast-destination--typing-union-pandas--libs-tslibs-timestamps-timestamp--nonetype----none--ignore-data-errors--bool---false-----typing-tuple-numpy-ndarray--pandas-core-frame-dataframe-)."
|
"The [forecast function notebook](../forecasting-forecast-function/auto-ml-forecasting-function.ipynb)."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -576,15 +580,15 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.automl.core.shared import constants, metrics\n",
|
"from azureml.automl.core.shared import constants\n",
|
||||||
|
"from azureml.automl.runtime.shared.score import scoring\n",
|
||||||
"from matplotlib import pyplot as plt\n",
|
"from matplotlib import pyplot as plt\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# use automl metrics module\n",
|
"# use automl scoring module\n",
|
||||||
"scores = metrics.compute_metrics_regression(\n",
|
"scores = scoring.score_regression(\n",
|
||||||
" df_all['predicted'],\n",
|
" y_test=df_all[target_column_name],\n",
|
||||||
" df_all[target_column_name],\n",
|
" y_pred=df_all['predicted'],\n",
|
||||||
" list(constants.Metric.SCALAR_REGRESSION_SET),\n",
|
" metrics=list(constants.Metric.SCALAR_REGRESSION_SET))\n",
|
||||||
" None, None, None)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"[Test data scores]\\n\")\n",
|
"print(\"[Test data scores]\\n\")\n",
|
||||||
"for key, value in scores.items(): \n",
|
"for key, value in scores.items(): \n",
|
||||||
|
|||||||
@@ -28,7 +28,8 @@
|
|||||||
"1. [Setup](#Setup)\n",
|
"1. [Setup](#Setup)\n",
|
||||||
"1. [Train](#Train)\n",
|
"1. [Train](#Train)\n",
|
||||||
"1. [Results](#Results)\n",
|
"1. [Results](#Results)\n",
|
||||||
"1. [Test](#Test)\n",
|
"1. [Test](#Tests)\n",
|
||||||
|
"1. [Explanation](#Explanation)\n",
|
||||||
"1. [Acknowledgements](#Acknowledgements)"
|
"1. [Acknowledgements](#Acknowledgements)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -49,9 +50,9 @@
|
|||||||
"2. Configure AutoML using `AutoMLConfig`.\n",
|
"2. Configure AutoML using `AutoMLConfig`.\n",
|
||||||
"3. Train the model.\n",
|
"3. Train the model.\n",
|
||||||
"4. Explore the results.\n",
|
"4. Explore the results.\n",
|
||||||
"5. Visualization model's feature importance in azure portal\n",
|
"5. Test the fitted model.\n",
|
||||||
"6. Explore any model's explanation and explore feature importance in azure portal\n",
|
"6. Explore any model's explanation and explore feature importance in azure portal.\n",
|
||||||
"7. Test the fitted model."
|
"7. Create an AKS cluster, deploy the webservice of AutoML scoring model and the explainer model to the AKS and consume the web service."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -95,7 +96,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -255,9 +256,9 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Analyze results\n",
|
"### Analyze results\n",
|
||||||
"\n",
|
"\n",
|
||||||
"### Retrieve the Best Model\n",
|
"#### Retrieve the Best Model\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Below we select the best pipeline from our iterations. The `get_output` method on `automl_classifier` returns the best run and the fitted model for the last invocation. Overloads on `get_output` allow you to retrieve the best run and fitted model for *any* logged metric or for a particular *iteration*."
|
"Below we select the best pipeline from our iterations. The `get_output` method on `automl_classifier` returns the best run and the fitted model for the last invocation. Overloads on `get_output` allow you to retrieve the best run and fitted model for *any* logged metric or for a particular *iteration*."
|
||||||
]
|
]
|
||||||
@@ -284,9 +285,80 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Best Model 's explanation\n",
|
"## Tests\n",
|
||||||
"Retrieve the explanation from the best_run which includes explanations for engineered features and raw features.\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
|
"Now that the model is trained, split the data in the same way the data was split for training (The difference here is the data is being split locally) and then run the test data through the trained model to get the predicted values."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# convert the test data to dataframe\n",
|
||||||
|
"X_test_df = validation_data.drop_columns(columns=[label_column_name]).to_pandas_dataframe()\n",
|
||||||
|
"y_test_df = validation_data.keep_columns(columns=[label_column_name], validate=True).to_pandas_dataframe()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# call the predict functions on the model\n",
|
||||||
|
"y_pred = fitted_model.predict(X_test_df)\n",
|
||||||
|
"y_pred"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Calculate metrics for the prediction\n",
|
||||||
|
"\n",
|
||||||
|
"Now visualize the data on a scatter plot to show what our truth (actual) values are compared to the predicted values \n",
|
||||||
|
"from the trained model that was returned."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from sklearn.metrics import confusion_matrix\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"import itertools\n",
|
||||||
|
"\n",
|
||||||
|
"cf =confusion_matrix(y_test_df.values,y_pred)\n",
|
||||||
|
"plt.imshow(cf,cmap=plt.cm.Blues,interpolation='nearest')\n",
|
||||||
|
"plt.colorbar()\n",
|
||||||
|
"plt.title('Confusion Matrix')\n",
|
||||||
|
"plt.xlabel('Predicted')\n",
|
||||||
|
"plt.ylabel('Actual')\n",
|
||||||
|
"class_labels = ['False','True']\n",
|
||||||
|
"tick_marks = np.arange(len(class_labels))\n",
|
||||||
|
"plt.xticks(tick_marks,class_labels)\n",
|
||||||
|
"plt.yticks([-0.5,0,1,1.5],['','False','True',''])\n",
|
||||||
|
"# plotting text value inside cells\n",
|
||||||
|
"thresh = cf.max() / 2.\n",
|
||||||
|
"for i,j in itertools.product(range(cf.shape[0]),range(cf.shape[1])):\n",
|
||||||
|
" plt.text(j,i,format(cf[i,j],'d'),horizontalalignment='center',color='white' if cf[i,j] >thresh else 'black')\n",
|
||||||
|
"plt.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Explanation\n",
|
||||||
|
"In this section, we will show how to compute model explanations and visualize the explanations using azureml-explain-model package. We will also show how to run the automl model and the explainer model through deploying an AKS web service.\n",
|
||||||
|
"\n",
|
||||||
|
"Besides retrieving an existing model explanation for an AutoML model, you can also explain your AutoML model with different test data. The following steps will allow you to compute and visualize engineered feature importance based on your test data.\n",
|
||||||
|
"\n",
|
||||||
|
"### Run the explanation\n",
|
||||||
"#### Download engineered feature importance from artifact store\n",
|
"#### Download engineered feature importance from artifact store\n",
|
||||||
"You can use ExplanationClient to download the engineered feature explanations from the artifact store of the best_run. You can also use azure portal url to view the dash board visualization of the feature importance values of the engineered features."
|
"You can use ExplanationClient to download the engineered feature explanations from the artifact store of the best_run. You can also use azure portal url to view the dash board visualization of the feature importance values of the engineered features."
|
||||||
]
|
]
|
||||||
@@ -303,14 +375,6 @@
|
|||||||
"print(\"You can visualize the engineered explanations under the 'Explanations (preview)' tab in the AutoML run at:-\\n\" + best_run.get_portal_url())"
|
"print(\"You can visualize the engineered explanations under the 'Explanations (preview)' tab in the AutoML run at:-\\n\" + best_run.get_portal_url())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Explanations\n",
|
|
||||||
"In this section, we will show how to compute model explanations and visualize the explanations using azureml-explain-model package. Besides retrieving an existing model explanation for an AutoML model, you can also explain your AutoML model with different test data. The following steps will allow you to compute and visualize engineered feature importance based on your test data."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -403,6 +467,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
"# Compute the engineered explanations\n",
|
||||||
"engineered_explanations = explainer.explain(['local', 'global'], eval_dataset=automl_explainer_setup_obj.X_test_transform)\n",
|
"engineered_explanations = explainer.explain(['local', 'global'], eval_dataset=automl_explainer_setup_obj.X_test_transform)\n",
|
||||||
"print(engineered_explanations.get_feature_importance_dict())\n",
|
"print(engineered_explanations.get_feature_importance_dict())\n",
|
||||||
"print(\"You can visualize the engineered explanations under the 'Explanations (preview)' tab in the AutoML run at:-\\n\" + automl_run.get_portal_url())"
|
"print(\"You can visualize the engineered explanations under the 'Explanations (preview)' tab in the AutoML run at:-\\n\" + automl_run.get_portal_url())"
|
||||||
@@ -412,41 +477,37 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Test the fitted model\n",
|
"#### Initialize the scoring Explainer, save and upload it for later use in scoring explanation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from azureml.explain.model.scoring.scoring_explainer import TreeScoringExplainer\n",
|
||||||
|
"import joblib\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Now that the model is trained, split the data in the same way the data was split for training (The difference here is the data is being split locally) and then run the test data through the trained model to get the predicted values."
|
"# Initialize the ScoringExplainer\n",
|
||||||
]
|
"scoring_explainer = TreeScoringExplainer(explainer.explainer, feature_maps=[automl_explainer_setup_obj.feature_map])\n",
|
||||||
},
|
"\n",
|
||||||
{
|
"# Pickle scoring explainer locally to './scoring_explainer.pkl'\n",
|
||||||
"cell_type": "code",
|
"scoring_explainer_file_name = 'scoring_explainer.pkl'\n",
|
||||||
"execution_count": null,
|
"with open(scoring_explainer_file_name, 'wb') as stream:\n",
|
||||||
"metadata": {},
|
" joblib.dump(scoring_explainer, stream)\n",
|
||||||
"outputs": [],
|
"\n",
|
||||||
"source": [
|
"# Upload the scoring explainer to the automl run\n",
|
||||||
"# convert the test data to dataframe\n",
|
"automl_run.upload_file('outputs/scoring_explainer.pkl', scoring_explainer_file_name)"
|
||||||
"X_test_df = validation_data.drop_columns(columns=[label_column_name]).to_pandas_dataframe()\n",
|
|
||||||
"y_test_df = validation_data.keep_columns(columns=[label_column_name], validate=True).to_pandas_dataframe()"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# call the predict functions on the model\n",
|
|
||||||
"y_pred = fitted_model.predict(X_test_df)\n",
|
|
||||||
"y_pred"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Calculate metrics for the prediction\n",
|
"### Deploying the scoring and explainer models to a web service to Azure Kubernetes Service (AKS)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Now visualize the data on a scatter plot to show what our truth (actual) values are compared to the predicted values \n",
|
"We use the TreeScoringExplainer from azureml.explain.model package to create the scoring explainer which will be used to compute the raw and engineered feature importances at the inference time. In the cell below, we register the AutoML model and the scoring explainer with the Model Management Service."
|
||||||
"from the trained model that was returned."
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -455,25 +516,238 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from sklearn.metrics import confusion_matrix\n",
|
"# Register trained automl model present in the 'outputs' folder in the artifacts\n",
|
||||||
"import numpy as np\n",
|
"original_model = automl_run.register_model(model_name='automl_model', \n",
|
||||||
"import itertools\n",
|
" model_path='outputs/model.pkl')\n",
|
||||||
|
"scoring_explainer_model = automl_run.register_model(model_name='scoring_explainer',\n",
|
||||||
|
" model_path='outputs/scoring_explainer.pkl')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"#### Create the conda dependencies for setting up the service\n",
|
||||||
"\n",
|
"\n",
|
||||||
"cf =confusion_matrix(y_test_df.values,y_pred)\n",
|
"We need to create the conda dependencies comprising of the azureml-explain-model, azureml-train-automl and azureml-defaults packages."
|
||||||
"plt.imshow(cf,cmap=plt.cm.Blues,interpolation='nearest')\n",
|
]
|
||||||
"plt.colorbar()\n",
|
},
|
||||||
"plt.title('Confusion Matrix')\n",
|
{
|
||||||
"plt.xlabel('Predicted')\n",
|
"cell_type": "code",
|
||||||
"plt.ylabel('Actual')\n",
|
"execution_count": null,
|
||||||
"class_labels = ['False','True']\n",
|
"metadata": {},
|
||||||
"tick_marks = np.arange(len(class_labels))\n",
|
"outputs": [],
|
||||||
"plt.xticks(tick_marks,class_labels)\n",
|
"source": [
|
||||||
"plt.yticks([-0.5,0,1,1.5],['','False','True',''])\n",
|
"from azureml.automl.core.shared import constants\n",
|
||||||
"# plotting text value inside cells\n",
|
"from azureml.core.environment import Environment\n",
|
||||||
"thresh = cf.max() / 2.\n",
|
"\n",
|
||||||
"for i,j in itertools.product(range(cf.shape[0]),range(cf.shape[1])):\n",
|
"automl_run.download_file(constants.CONDA_ENV_FILE_PATH, 'myenv.yml')\n",
|
||||||
" plt.text(j,i,format(cf[i,j],'d'),horizontalalignment='center',color='white' if cf[i,j] >thresh else 'black')\n",
|
"myenv = Environment.from_conda_specification(name=\"myenv\", file_path=\"myenv.yml\")\n",
|
||||||
"plt.show()"
|
"myenv"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"#### Write the Entry Script\n",
|
||||||
|
"Write the script that will be used to predict on your model"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%%writefile score.py\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"import os\n",
|
||||||
|
"import pickle\n",
|
||||||
|
"import azureml.train.automl\n",
|
||||||
|
"import azureml.explain.model\n",
|
||||||
|
"from azureml.train.automl.runtime.automl_explain_utilities import AutoMLExplainerSetupClass, \\\n",
|
||||||
|
" automl_setup_model_explanations\n",
|
||||||
|
"import joblib\n",
|
||||||
|
"from azureml.core.model import Model\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def init():\n",
|
||||||
|
" global automl_model\n",
|
||||||
|
" global scoring_explainer\n",
|
||||||
|
"\n",
|
||||||
|
" # Retrieve the path to the model file using the model name\n",
|
||||||
|
" # Assume original model is named original_prediction_model\n",
|
||||||
|
" automl_model_path = Model.get_model_path('automl_model')\n",
|
||||||
|
" scoring_explainer_path = Model.get_model_path('scoring_explainer')\n",
|
||||||
|
"\n",
|
||||||
|
" automl_model = joblib.load(automl_model_path)\n",
|
||||||
|
" scoring_explainer = joblib.load(scoring_explainer_path)\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def run(raw_data):\n",
|
||||||
|
" data = pd.read_json(raw_data, orient='records') \n",
|
||||||
|
" # Make prediction\n",
|
||||||
|
" predictions = automl_model.predict(data)\n",
|
||||||
|
" # Setup for inferencing explanations\n",
|
||||||
|
" automl_explainer_setup_obj = automl_setup_model_explanations(automl_model,\n",
|
||||||
|
" X_test=data, task='classification')\n",
|
||||||
|
" # Retrieve model explanations for engineered explanations\n",
|
||||||
|
" engineered_local_importance_values = scoring_explainer.explain(automl_explainer_setup_obj.X_test_transform) \n",
|
||||||
|
" # You can return any data type as long as it is JSON-serializable\n",
|
||||||
|
" return {'predictions': predictions.tolist(),\n",
|
||||||
|
" 'engineered_local_importance_values': engineered_local_importance_values}\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"#### 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",
|
||||||
|
"inf_config = InferenceConfig(entry_script='score.py', environment=myenv)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"#### Provision the AKS Cluster\n",
|
||||||
|
"This is a one time setup. You can reuse this cluster for multiple deployments after it has been created. If you delete the cluster or the resource group that contains it, then you would have to recreate it."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from azureml.core.compute import ComputeTarget, AksCompute\n",
|
||||||
|
"from azureml.core.compute_target import ComputeTargetException\n",
|
||||||
|
"\n",
|
||||||
|
"# Choose a name for your cluster.\n",
|
||||||
|
"aks_name = 'scoring-explain'\n",
|
||||||
|
"\n",
|
||||||
|
"# Verify that cluster does not exist already\n",
|
||||||
|
"try:\n",
|
||||||
|
" aks_target = ComputeTarget(workspace=ws, name=aks_name)\n",
|
||||||
|
" print('Found existing cluster, use it.')\n",
|
||||||
|
"except ComputeTargetException:\n",
|
||||||
|
" prov_config = AksCompute.provisioning_configuration(vm_size='STANDARD_D3_V2')\n",
|
||||||
|
" aks_target = ComputeTarget.create(workspace=ws, \n",
|
||||||
|
" name=aks_name,\n",
|
||||||
|
" provisioning_configuration=prov_config)\n",
|
||||||
|
"aks_target.wait_for_completion(show_output=True)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"#### Deploy web service to AKS"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Set the web service configuration (using default here)\n",
|
||||||
|
"from azureml.core.webservice import AksWebservice\n",
|
||||||
|
"from azureml.core.model import Model\n",
|
||||||
|
"\n",
|
||||||
|
"aks_config = AksWebservice.deploy_configuration()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"aks_service_name ='model-scoring-local-aks'\n",
|
||||||
|
"\n",
|
||||||
|
"aks_service = Model.deploy(workspace=ws,\n",
|
||||||
|
" name=aks_service_name,\n",
|
||||||
|
" models=[scoring_explainer_model, original_model],\n",
|
||||||
|
" inference_config=inf_config,\n",
|
||||||
|
" deployment_config=aks_config,\n",
|
||||||
|
" deployment_target=aks_target)\n",
|
||||||
|
"\n",
|
||||||
|
"aks_service.wait_for_deployment(show_output = True)\n",
|
||||||
|
"print(aks_service.state)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"#### View the service logs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"aks_service.get_logs()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"#### Consume the web service using run method to do the scoring and explanation of scoring.\n",
|
||||||
|
"We test the web sevice by passing data. Run() method retrieves API keys behind the scenes to make sure that call is authenticated."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Serialize the first row of the test data into json\n",
|
||||||
|
"X_test_json = X_test_df[:1].to_json(orient='records')\n",
|
||||||
|
"print(X_test_json)\n",
|
||||||
|
"\n",
|
||||||
|
"# Call the service to get the predictions and the engineered and raw explanations\n",
|
||||||
|
"output = aks_service.run(X_test_json)\n",
|
||||||
|
"\n",
|
||||||
|
"# Print the predicted value\n",
|
||||||
|
"print('predictions:\\n{}\\n'.format(output['predictions']))\n",
|
||||||
|
"# Print the engineered feature importances for the predicted value\n",
|
||||||
|
"print('engineered_local_importance_values:\\n{}\\n'.format(output['engineered_local_importance_values']))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"#### Clean up\n",
|
||||||
|
"Delete the service."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"aks_service.delete()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -98,7 +98,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -242,7 +242,11 @@
|
|||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"metadata": {},
|
"metadata": {
|
||||||
|
"tags": [
|
||||||
|
"sample-featurizationconfig-remarks2"
|
||||||
|
]
|
||||||
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"featurization_config = FeaturizationConfig()\n",
|
"featurization_config = FeaturizationConfig()\n",
|
||||||
@@ -260,7 +264,11 @@
|
|||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"metadata": {},
|
"metadata": {
|
||||||
|
"tags": [
|
||||||
|
"sample-featurizationconfig-remarks3"
|
||||||
|
]
|
||||||
|
},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"automl_settings = {\n",
|
"automl_settings = {\n",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import azureml.train.automl
|
|||||||
import azureml.explain.model
|
import azureml.explain.model
|
||||||
from azureml.train.automl.runtime.automl_explain_utilities import AutoMLExplainerSetupClass, \
|
from azureml.train.automl.runtime.automl_explain_utilities import AutoMLExplainerSetupClass, \
|
||||||
automl_setup_model_explanations
|
automl_setup_model_explanations
|
||||||
from sklearn.externals import joblib
|
import joblib
|
||||||
from azureml.core.model import Model
|
from azureml.core.model import Model
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,14 @@ import os
|
|||||||
|
|
||||||
from azureml.core.run import Run
|
from azureml.core.run import Run
|
||||||
from azureml.core.experiment import Experiment
|
from azureml.core.experiment import Experiment
|
||||||
from sklearn.externals import joblib
|
|
||||||
from azureml.core.dataset import Dataset
|
from azureml.core.dataset import Dataset
|
||||||
from azureml.train.automl.runtime.automl_explain_utilities import AutoMLExplainerSetupClass, \
|
from azureml.train.automl.runtime.automl_explain_utilities import AutoMLExplainerSetupClass, \
|
||||||
automl_setup_model_explanations, automl_check_model_if_explainable
|
automl_setup_model_explanations, automl_check_model_if_explainable
|
||||||
from azureml.explain.model.mimic.models.lightgbm_model import LGBMExplainableModel
|
from azureml.explain.model.mimic.models.lightgbm_model import LGBMExplainableModel
|
||||||
from azureml.explain.model.mimic_wrapper import MimicWrapper
|
from azureml.explain.model.mimic_wrapper import MimicWrapper
|
||||||
from azureml.automl.core.shared.constants import MODEL_PATH
|
from azureml.automl.core.shared.constants import MODEL_PATH
|
||||||
from azureml.explain.model.scoring.scoring_explainer import TreeScoringExplainer, save
|
from azureml.explain.model.scoring.scoring_explainer import TreeScoringExplainer
|
||||||
|
import joblib
|
||||||
|
|
||||||
OUTPUT_DIR = './outputs/'
|
OUTPUT_DIR = './outputs/'
|
||||||
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||||
@@ -74,7 +73,8 @@ print("Engineered and raw explanations computed successfully")
|
|||||||
scoring_explainer = TreeScoringExplainer(explainer.explainer, feature_maps=[automl_explainer_setup_obj.feature_map])
|
scoring_explainer = TreeScoringExplainer(explainer.explainer, feature_maps=[automl_explainer_setup_obj.feature_map])
|
||||||
|
|
||||||
# Pickle scoring explainer locally
|
# Pickle scoring explainer locally
|
||||||
save(scoring_explainer, exist_ok=True)
|
with open('scoring_explainer.pkl', 'wb') as stream:
|
||||||
|
joblib.dump(scoring_explainer, stream)
|
||||||
|
|
||||||
# Upload the scoring explainer to the automl run
|
# Upload the scoring explainer to the automl run
|
||||||
automl_run.upload_file('outputs/scoring_explainer.pkl', 'scoring_explainer.pkl')
|
automl_run.upload_file('outputs/scoring_explainer.pkl', 'scoring_explainer.pkl')
|
||||||
|
|||||||
@@ -92,7 +92,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ dependencies:
|
|||||||
- python=3.6.2
|
- python=3.6.2
|
||||||
- pip:
|
- pip:
|
||||||
- azureml-defaults
|
- azureml-defaults
|
||||||
- scikit-learn
|
- scikit-learn==0.19.1
|
||||||
- numpy
|
- numpy
|
||||||
- inference-schema[numpy-support]
|
- inference-schema[numpy-support]
|
||||||
|
|||||||
@@ -233,7 +233,8 @@
|
|||||||
" 'inference-schema[numpy-support]',\n",
|
" 'inference-schema[numpy-support]',\n",
|
||||||
" 'joblib',\n",
|
" 'joblib',\n",
|
||||||
" 'numpy',\n",
|
" 'numpy',\n",
|
||||||
" 'scikit-learn'\n",
|
" 'scikit-learn==0.19.1',\n",
|
||||||
|
" 'scipy'\n",
|
||||||
"])\n",
|
"])\n",
|
||||||
"inference_config = InferenceConfig(entry_script='score.py', environment=environment)\n",
|
"inference_config = InferenceConfig(entry_script='score.py', environment=environment)\n",
|
||||||
"# if cpu and memory_in_gb parameters are not provided\n",
|
"# if cpu and memory_in_gb parameters are not provided\n",
|
||||||
|
|||||||
@@ -108,9 +108,9 @@
|
|||||||
"environment.python.conda_dependencies = CondaDependencies.create(pip_packages=[\n",
|
"environment.python.conda_dependencies = CondaDependencies.create(pip_packages=[\n",
|
||||||
" 'azureml-defaults',\n",
|
" 'azureml-defaults',\n",
|
||||||
" 'inference-schema[numpy-support]',\n",
|
" 'inference-schema[numpy-support]',\n",
|
||||||
" 'joblib',\n",
|
|
||||||
" 'numpy',\n",
|
" 'numpy',\n",
|
||||||
" 'scikit-learn'\n",
|
" 'scikit-learn==0.19.1',\n",
|
||||||
|
" 'scipy'\n",
|
||||||
"])"
|
"])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Enabling App Insights for Services in Production\n",
|
"# Enabling App Insights for Services in Production\n",
|
||||||
"With this notebook, you can learn how to enable App Insights for standard service monitoring, plus, we provide examples for doing custom logging within a scoring files in a model. \n",
|
"With this notebook, you can learn how to enable App Insights for standard service monitoring, plus, we provide examples for doing custom logging within a scoring files in a model.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"## What does Application Insights monitor?\n",
|
"## What does Application Insights monitor?\n",
|
||||||
@@ -45,11 +45,13 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
"import azureml.core\n",
|
||||||
|
"import json\n",
|
||||||
|
"\n",
|
||||||
"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 AksWebservice\n",
|
"from azureml.core.webservice import AksWebservice\n",
|
||||||
"import azureml.core\n",
|
"\n",
|
||||||
"import json\n",
|
|
||||||
"print(azureml.core.VERSION)"
|
"print(azureml.core.VERSION)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -67,7 +69,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"ws = Workspace.from_config()\n",
|
"ws = Workspace.from_config()\n",
|
||||||
"print(ws.name, ws.resource_group, ws.location, ws.subscription_id, sep = '\\n')"
|
"print(ws.name, ws.resource_group, ws.location, ws.subscription_id, sep='\\n')"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,13 +86,13 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"#Register the model\n",
|
"from azureml.core import Model\n",
|
||||||
"from azureml.core.model import Model\n",
|
"\n",
|
||||||
"model = Model.register(model_path = \"sklearn_regression_model.pkl\", # this points to a local file\n",
|
"model = Model.register(model_path=\"sklearn_regression_model.pkl\", # This points to a local file.\n",
|
||||||
" model_name = \"sklearn_regression_model.pkl\", # this is the name the model is registered as\n",
|
" model_name=\"sklearn_regression_model.pkl\", # This is the name the model is registered as.\n",
|
||||||
" tags = {'area': \"diabetes\", 'type': \"regression\"},\n",
|
" tags={'area': \"diabetes\", 'type': \"regression\"},\n",
|
||||||
" description = \"Ridge regression model to predict diabetes\",\n",
|
" description=\"Ridge regression model to predict diabetes\",\n",
|
||||||
" workspace = ws)\n",
|
" workspace=ws)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print(model.name, model.description, model.version)"
|
"print(model.name, model.description, model.version)"
|
||||||
]
|
]
|
||||||
@@ -120,7 +122,7 @@
|
|||||||
"import os\n",
|
"import os\n",
|
||||||
"import pickle\n",
|
"import pickle\n",
|
||||||
"import json\n",
|
"import json\n",
|
||||||
"import numpy \n",
|
"import numpy\n",
|
||||||
"from sklearn.externals import joblib\n",
|
"from sklearn.externals import joblib\n",
|
||||||
"from sklearn.linear_model import Ridge\n",
|
"from sklearn.linear_model import Ridge\n",
|
||||||
"import time\n",
|
"import time\n",
|
||||||
@@ -129,15 +131,15 @@
|
|||||||
" global model\n",
|
" global model\n",
|
||||||
" #Print statement for appinsights custom traces:\n",
|
" #Print statement for appinsights custom traces:\n",
|
||||||
" print (\"model initialized\" + time.strftime(\"%H:%M:%S\"))\n",
|
" print (\"model initialized\" + time.strftime(\"%H:%M:%S\"))\n",
|
||||||
" \n",
|
"\n",
|
||||||
" # AZUREML_MODEL_DIR is an environment variable created during deployment.\n",
|
" # AZUREML_MODEL_DIR is an environment variable created during deployment.\n",
|
||||||
" # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)\n",
|
" # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)\n",
|
||||||
" # For multiple models, it points to the folder containing all deployed models (./azureml-models)\n",
|
" # For multiple models, it points to the folder containing all deployed models (./azureml-models)\n",
|
||||||
" model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_regression_model.pkl')\n",
|
" model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_regression_model.pkl')\n",
|
||||||
" \n",
|
"\n",
|
||||||
" # deserialize the model file back into a sklearn model\n",
|
" # deserialize the model file back into a sklearn model\n",
|
||||||
" model = joblib.load(model_path)\n",
|
" model = joblib.load(model_path)\n",
|
||||||
" \n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# note you can pass in multiple rows for scoring\n",
|
"# note you can pass in multiple rows for scoring\n",
|
||||||
"def run(raw_data):\n",
|
"def run(raw_data):\n",
|
||||||
@@ -168,7 +170,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"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'],\n",
|
"myenv = CondaDependencies.create(conda_packages=['numpy','scikit-learn'],\n",
|
||||||
" pip_packages=['azureml-defaults'])\n",
|
" pip_packages=['azureml-defaults'])\n",
|
||||||
@@ -190,9 +192,8 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.core.model import InferenceConfig\n",
|
|
||||||
"from azureml.core.environment import Environment\n",
|
"from azureml.core.environment import Environment\n",
|
||||||
"\n",
|
"from azureml.core.model import InferenceConfig\n",
|
||||||
"\n",
|
"\n",
|
||||||
"myenv = Environment.from_conda_specification(name=\"myenv\", file_path=\"myenv.yml\")\n",
|
"myenv = Environment.from_conda_specification(name=\"myenv\", file_path=\"myenv.yml\")\n",
|
||||||
"inference_config = InferenceConfig(entry_script=\"score.py\", environment=myenv)"
|
"inference_config = InferenceConfig(entry_script=\"score.py\", environment=myenv)"
|
||||||
@@ -213,11 +214,11 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"from azureml.core.webservice import AciWebservice\n",
|
"from azureml.core.webservice import AciWebservice\n",
|
||||||
"\n",
|
"\n",
|
||||||
"aci_deployment_config = 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",
|
||||||
" enable_app_insights = True)"
|
" enable_app_insights=True)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -226,29 +227,14 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.core.webservice import Webservice\n",
|
"aci_service_name = \"aci-service-appinsights\"\n",
|
||||||
|
"\n",
|
||||||
|
"aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aci_deployment_config, overwrite=True)\n",
|
||||||
|
"aci_service.wait_for_deployment(show_output=True)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"aci_service_name = 'my-aci-service-4'\n",
|
|
||||||
"aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aci_deployment_config)\n",
|
|
||||||
"aci_service.wait_for_deployment(True)\n",
|
|
||||||
"print(aci_service.state)"
|
"print(aci_service.state)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"%%time\n",
|
|
||||||
"\n",
|
|
||||||
"test_sample = json.dumps({'data': [\n",
|
|
||||||
" [1,28,13,45,54,6,57,8,8,10], \n",
|
|
||||||
" [101,9,8,37,6,45,4,3,2,41]\n",
|
|
||||||
"]})\n",
|
|
||||||
"test_sample = bytes(test_sample,encoding='utf8')"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
@@ -256,7 +242,15 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"if aci_service.state == \"Healthy\":\n",
|
"if aci_service.state == \"Healthy\":\n",
|
||||||
" prediction = aci_service.run(input_data=test_sample)\n",
|
" test_sample = json.dumps({\n",
|
||||||
|
" \"data\": [\n",
|
||||||
|
" [1,28,13,45,54,6,57,8,8,10],\n",
|
||||||
|
" [101,9,8,37,6,45,4,3,2,41]\n",
|
||||||
|
" ]\n",
|
||||||
|
" })\n",
|
||||||
|
"\n",
|
||||||
|
" prediction = aci_service.run(test_sample)\n",
|
||||||
|
"\n",
|
||||||
" print(prediction)\n",
|
" print(prediction)\n",
|
||||||
"else:\n",
|
"else:\n",
|
||||||
" raise ValueError(\"Service deployment isn't healthy, can't call the service. Error: \", aci_service.error)"
|
" raise ValueError(\"Service deployment isn't healthy, can't call the service. Error: \", aci_service.error)"
|
||||||
@@ -282,14 +276,21 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Use the default configuration (can also provide parameters to customize)\n",
|
"from azureml.exceptions import ComputeTargetException\n",
|
||||||
"prov_config = AksCompute.provisioning_configuration()\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"aks_name = 'my-aks-test3' \n",
|
"aks_name = \"my-aks\"\n",
|
||||||
"# Create the cluster\n",
|
"\n",
|
||||||
"aks_target = ComputeTarget.create(workspace = ws, \n",
|
"try:\n",
|
||||||
" name = aks_name, \n",
|
" aks_target = ComputeTarget(ws, aks_name)\n",
|
||||||
" provisioning_configuration = prov_config)"
|
" print(\"Using existing AKS cluster {}.\".format(aks_name))\n",
|
||||||
|
"except ComputeTargetException:\n",
|
||||||
|
" print(\"Creating a new AKS cluster {}.\".format(aks_name))\n",
|
||||||
|
"\n",
|
||||||
|
" # Use the default configuration (can also provide parameters to customize).\n",
|
||||||
|
" prov_config = AksCompute.provisioning_configuration()\n",
|
||||||
|
" aks_target = ComputeTarget.create(workspace=ws,\n",
|
||||||
|
" name=aks_name,\n",
|
||||||
|
" provisioning_configuration=prov_config)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -299,7 +300,8 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"%%time\n",
|
"%%time\n",
|
||||||
"aks_target.wait_for_completion(show_output = True)"
|
"if aks_target.provisioning_state != \"Succeeded\":\n",
|
||||||
|
" aks_target.wait_for_completion(show_output=True)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -323,13 +325,13 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"```python \n",
|
"```python\n",
|
||||||
"%%time\n",
|
"%%time\n",
|
||||||
"resource_id = '/subscriptions/<subscriptionid>/resourcegroups/<resourcegroupname>/providers/Microsoft.ContainerService/managedClusters/<aksservername>'\n",
|
"resource_id = '/subscriptions/<subscriptionid>/resourcegroups/<resourcegroupname>/providers/Microsoft.ContainerService/managedClusters/<aksservername>'\n",
|
||||||
"create_name= 'myaks4'\n",
|
"create_name= 'myaks4'\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, \n",
|
"aks_target = ComputeTarget.attach(workspace=ws,\n",
|
||||||
" name = create_name, \n",
|
" name=create_name,\n",
|
||||||
" attach_configuration=attach_config)\n",
|
" attach_configuration=attach_config)\n",
|
||||||
"## Wait for the operation to complete\n",
|
"## Wait for the operation to complete\n",
|
||||||
"aks_target.wait_for_provisioning(True)```"
|
"aks_target.wait_for_provisioning(True)```"
|
||||||
@@ -349,7 +351,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"#Set the web service configuration\n",
|
"# Set the web service configuration.\n",
|
||||||
"aks_deployment_config = AksWebservice.deploy_configuration(enable_app_insights=True)"
|
"aks_deployment_config = AksWebservice.deploy_configuration(enable_app_insights=True)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -366,15 +368,16 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"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-service-appinsights\"\n",
|
||||||
" aks_service = Model.deploy(ws,\n",
|
" aks_service = Model.deploy(ws,\n",
|
||||||
" aks_service_name, \n",
|
" aks_service_name,\n",
|
||||||
" [model], \n",
|
" [model],\n",
|
||||||
" inference_config, \n",
|
" inference_config,\n",
|
||||||
" aks_deployment_config, \n",
|
" aks_deployment_config,\n",
|
||||||
" deployment_target = aks_target) \n",
|
" deployment_target=aks_target,\n",
|
||||||
" aks_service.wait_for_deployment(show_output = True)\n",
|
" overwrite=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",
|
||||||
" raise ValueError(\"AKS provisioning failed. Error: \", aks_service.error)"
|
" raise ValueError(\"AKS provisioning failed. Error: \", aks_service.error)"
|
||||||
@@ -395,13 +398,14 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"%%time\n",
|
"%%time\n",
|
||||||
"\n",
|
"\n",
|
||||||
"test_sample = json.dumps({'data': [\n",
|
|
||||||
" [1,28,13,45,54,6,57,8,8,10], \n",
|
|
||||||
" [101,9,8,37,6,45,4,3,2,41]\n",
|
|
||||||
"]})\n",
|
|
||||||
"test_sample = bytes(test_sample,encoding='utf8')\n",
|
|
||||||
"\n",
|
|
||||||
"if aks_service.state == \"Healthy\":\n",
|
"if aks_service.state == \"Healthy\":\n",
|
||||||
|
" test_sample = json.dumps({\n",
|
||||||
|
" \"data\": [\n",
|
||||||
|
" [1,28,13,45,54,6,57,8,8,10],\n",
|
||||||
|
" [101,9,8,37,6,45,4,3,2,41]\n",
|
||||||
|
" ]\n",
|
||||||
|
" })\n",
|
||||||
|
"\n",
|
||||||
" prediction = aks_service.run(input_data=test_sample)\n",
|
" prediction = aks_service.run(input_data=test_sample)\n",
|
||||||
" print(prediction)\n",
|
" print(prediction)\n",
|
||||||
"else:\n",
|
"else:\n",
|
||||||
@@ -435,7 +439,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"aks_service.update(enable_app_insights=False)\n",
|
"aks_service.update(enable_app_insights=False)\n",
|
||||||
"aks_service.wait_for_deployment(show_output = True)"
|
"aks_service.wait_for_deployment(show_output=True)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -115,6 +115,11 @@
|
|||||||
"# Convert from CoreML into ONNX\n",
|
"# Convert from CoreML into ONNX\n",
|
||||||
"onnx_model = onnxmltools.convert_coreml(coreml_model, 'TinyYOLOv2')\n",
|
"onnx_model = onnxmltools.convert_coreml(coreml_model, 'TinyYOLOv2')\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"# Fix the preprocessor bias in the ImageScaler\n",
|
||||||
|
"for init in onnx_model.graph.initializer:\n",
|
||||||
|
" if init.name == 'scalerPreprocessor_bias':\n",
|
||||||
|
" init.dims[1] = 1\n",
|
||||||
|
"\n",
|
||||||
"# Save ONNX model\n",
|
"# Save ONNX model\n",
|
||||||
"onnxmltools.utils.save_model(onnx_model, 'tinyyolov2.onnx')\n",
|
"onnxmltools.utils.save_model(onnx_model, 'tinyyolov2.onnx')\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -255,7 +260,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"from azureml.core.conda_dependencies import CondaDependencies \n",
|
"from azureml.core.conda_dependencies import CondaDependencies \n",
|
||||||
"\n",
|
"\n",
|
||||||
"myenv = CondaDependencies.create(pip_packages=[\"numpy\", \"onnxruntime==0.4.0\", \"azureml-core\", \"azureml-defaults\"])\n",
|
"myenv = CondaDependencies.create(pip_packages=[\"numpy\", \"onnxruntime\", \"azureml-core\", \"azureml-defaults\"])\n",
|
||||||
"\n",
|
"\n",
|
||||||
"with open(\"myenv.yml\",\"w\") as f:\n",
|
"with open(\"myenv.yml\",\"w\") as f:\n",
|
||||||
" f.write(myenv.serialize_to_string())"
|
" f.write(myenv.serialize_to_string())"
|
||||||
@@ -316,7 +321,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"aci_service_name = 'my-aci-service-15ad'\n",
|
"aci_service_name = 'my-aci-service-tiny-yolo'\n",
|
||||||
"print(\"Service\", aci_service_name)\n",
|
"print(\"Service\", aci_service_name)\n",
|
||||||
"aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aciconfig)\n",
|
"aci_service = Model.deploy(ws, aci_service_name, [model], inference_config, aciconfig)\n",
|
||||||
"aci_service.wait_for_deployment(True)\n",
|
"aci_service.wait_for_deployment(True)\n",
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ dependencies:
|
|||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- numpy
|
- numpy
|
||||||
- git+https://github.com/apple/coremltools@v2.1
|
- git+https://github.com/apple/coremltools@v2.1
|
||||||
|
- onnx<1.7.0
|
||||||
- onnxmltools
|
- onnxmltools
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ dependencies:
|
|||||||
- azureml-widgets
|
- azureml-widgets
|
||||||
- matplotlib
|
- matplotlib
|
||||||
- numpy
|
- numpy
|
||||||
- onnx
|
- onnx<1.7.0
|
||||||
- opencv-python-headless
|
- opencv-python-headless
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ dependencies:
|
|||||||
- azureml-widgets
|
- azureml-widgets
|
||||||
- matplotlib
|
- matplotlib
|
||||||
- numpy
|
- numpy
|
||||||
- onnx
|
- onnx<1.7.0
|
||||||
- opencv-python-headless
|
- opencv-python-headless
|
||||||
|
|||||||
@@ -0,0 +1,354 @@
|
|||||||
|
{
|
||||||
|
"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": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Deploying a web service to Azure Kubernetes Service (AKS)\n",
|
||||||
|
"This notebook shows the steps for deploying a service: registering a model, provisioning a cluster with ssl (one time action), and deploying a service to it. \n",
|
||||||
|
"We then test and delete the service, image and model."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from azureml.core import Workspace\n",
|
||||||
|
"from azureml.core.compute import AksCompute, ComputeTarget\n",
|
||||||
|
"from azureml.core.webservice import Webservice, AksWebservice\n",
|
||||||
|
"from azureml.core.model import Model"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import azureml.core\n",
|
||||||
|
"print(azureml.core.VERSION)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Get workspace\n",
|
||||||
|
"Load existing workspace from the config file info."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from azureml.core.workspace 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": [
|
||||||
|
"# Register the model\n",
|
||||||
|
"Register an existing trained model, add descirption and tags."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"#Register the model\n",
|
||||||
|
"from azureml.core.model import Model\n",
|
||||||
|
"model = Model.register(model_path = \"sklearn_regression_model.pkl\", # this points to a local file\n",
|
||||||
|
" model_name = \"sklearn_model\", # this is the name the model is registered as\n",
|
||||||
|
" tags = {'area': \"diabetes\", 'type': \"regression\"},\n",
|
||||||
|
" description = \"Ridge regression model to predict diabetes\",\n",
|
||||||
|
" workspace = ws)\n",
|
||||||
|
"\n",
|
||||||
|
"print(model.name, model.description, model.version)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Create the Environment\n",
|
||||||
|
"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==0.19.1', 'scipy'], pip_packages=['azureml-defaults', 'inference-schema'])\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"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%%writefile score.py\n",
|
||||||
|
"import os\n",
|
||||||
|
"import pickle\n",
|
||||||
|
"import json\n",
|
||||||
|
"import numpy\n",
|
||||||
|
"from sklearn.externals import joblib\n",
|
||||||
|
"from sklearn.linear_model import Ridge\n",
|
||||||
|
"from inference_schema.schema_decorators import input_schema, output_schema\n",
|
||||||
|
"from inference_schema.parameter_types.standard_py_parameter_type import StandardPythonParameterType\n",
|
||||||
|
"\n",
|
||||||
|
"def init():\n",
|
||||||
|
" global model\n",
|
||||||
|
" # AZUREML_MODEL_DIR is an environment variable created during deployment.\n",
|
||||||
|
" # It is the path to the model folder (./azureml-models/$MODEL_NAME/$VERSION)\n",
|
||||||
|
" # For multiple models, it points to the folder containing all deployed models (./azureml-models)\n",
|
||||||
|
" model_path = os.path.join(os.getenv('AZUREML_MODEL_DIR'), 'sklearn_regression_model.pkl')\n",
|
||||||
|
" # deserialize the model file back into a sklearn model\n",
|
||||||
|
" model = joblib.load(model_path)\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"standard_sample_input = {'a': 10, 'b': 9, 'c': 8, 'd': 7, 'e': 6, 'f': 5, 'g': 4, 'h': 3, 'i': 2, 'j': 1 }\n",
|
||||||
|
"standard_sample_output = {'outcome': 1}\n",
|
||||||
|
"\n",
|
||||||
|
"@input_schema('param', StandardPythonParameterType(standard_sample_input))\n",
|
||||||
|
"@output_schema(StandardPythonParameterType(standard_sample_output))\n",
|
||||||
|
"def run(param):\n",
|
||||||
|
" try:\n",
|
||||||
|
" raw_data = [param['a'], param['b'], param['c'], param['d'], param['e'], param['f'], param['g'], param['h'], param['i'], param['j']]\n",
|
||||||
|
" data = numpy.array([raw_data])\n",
|
||||||
|
" result = model.predict(data)\n",
|
||||||
|
" return { 'outcome' : result[0] }\n",
|
||||||
|
" except Exception as e:\n",
|
||||||
|
" error = str(e)\n",
|
||||||
|
" return error"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# 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",
|
||||||
|
"inf_config = InferenceConfig(entry_script='score.py', environment=myenv)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Provision the AKS Cluster with SSL\n",
|
||||||
|
"This is a one time setup. You can reuse this cluster for multiple deployments after it has been created. If you delete the cluster or the resource group that contains it, then you would have to recreate it.\n",
|
||||||
|
"\n",
|
||||||
|
"See code snippet below. Check the documentation [here](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-secure-web-service) for more details"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Use the default configuration (can also provide parameters to customize)\n",
|
||||||
|
"\n",
|
||||||
|
"provisioning_config = AksCompute.provisioning_configuration()\n",
|
||||||
|
"# Leaf domain label generates a name using the formula\n",
|
||||||
|
"# \"<leaf-domain-label>######.<azure-region>.cloudapp.azure.net\"\n",
|
||||||
|
"# where \"######\" is a random series of characters\n",
|
||||||
|
"provisioning_config.enable_ssl(leaf_domain_label = \"contoso\")\n",
|
||||||
|
"\n",
|
||||||
|
"aks_name = 'my-aks-ssl-1' \n",
|
||||||
|
"# Create the cluster\n",
|
||||||
|
"aks_target = ComputeTarget.create(workspace = ws, \n",
|
||||||
|
" name = aks_name, \n",
|
||||||
|
" provisioning_configuration = provisioning_config)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%%time\n",
|
||||||
|
"aks_target.wait_for_completion(show_output = True)\n",
|
||||||
|
"print(aks_target.provisioning_state)\n",
|
||||||
|
"print(aks_target.provisioning_errors)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Deploy web service to AKS"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"tags": [
|
||||||
|
"sample-deploy-to-aks"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%%time\n",
|
||||||
|
"\n",
|
||||||
|
"aks_config = AksWebservice.deploy_configuration()\n",
|
||||||
|
"\n",
|
||||||
|
"aks_service_name ='aks-service-ssl-1'\n",
|
||||||
|
"\n",
|
||||||
|
"aks_service = Model.deploy(workspace=ws,\n",
|
||||||
|
" name=aks_service_name,\n",
|
||||||
|
" models=[model],\n",
|
||||||
|
" inference_config=inf_config,\n",
|
||||||
|
" deployment_config=aks_config,\n",
|
||||||
|
" deployment_target=aks_target,\n",
|
||||||
|
" overwrite=True)\n",
|
||||||
|
"\n",
|
||||||
|
"aks_service.wait_for_deployment(show_output = True)\n",
|
||||||
|
"print(aks_service.state)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Test the web service using run method\n",
|
||||||
|
"We test the web sevice by passing data.\n",
|
||||||
|
"Run() method retrieves API keys behind the scenes to make sure that call is authenticated."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%%time\n",
|
||||||
|
"import json\n",
|
||||||
|
"\n",
|
||||||
|
"standard_sample_input = json.dumps({'param': {'a': 10, 'b': 9, 'c': 8, 'd': 7, 'e': 6, 'f': 5, 'g': 4, 'h': 3, 'i': 2, 'j': 1 }})\n",
|
||||||
|
"\n",
|
||||||
|
"aks_service.run(input_data=standard_sample_input)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Clean up\n",
|
||||||
|
"Delete the service, image and model."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%%time\n",
|
||||||
|
"aks_service.delete()\n",
|
||||||
|
"model.delete()"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "vaidyas"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"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
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
name: production-deploy-to-aks-ssl
|
||||||
|
dependencies:
|
||||||
|
- pip:
|
||||||
|
- azureml-sdk
|
||||||
|
- matplotlib
|
||||||
|
- tqdm
|
||||||
|
- scipy
|
||||||
|
- sklearn
|
||||||
@@ -109,7 +109,7 @@
|
|||||||
"from azureml.core import Environment\n",
|
"from azureml.core import Environment\n",
|
||||||
"from azureml.core.conda_dependencies import CondaDependencies \n",
|
"from azureml.core.conda_dependencies import CondaDependencies \n",
|
||||||
"\n",
|
"\n",
|
||||||
"conda_deps = CondaDependencies.create(conda_packages=['numpy','scikit-learn'], pip_packages=['azureml-defaults'])\n",
|
"conda_deps = CondaDependencies.create(conda_packages=['numpy','scikit-learn==0.19.1','scipy'], pip_packages=['azureml-defaults'])\n",
|
||||||
"myenv = Environment(name='myenv')\n",
|
"myenv = Environment(name='myenv')\n",
|
||||||
"myenv.python.conda_dependencies = conda_deps"
|
"myenv.python.conda_dependencies = conda_deps"
|
||||||
]
|
]
|
||||||
@@ -300,7 +300,8 @@
|
|||||||
" 'inference-schema[numpy-support]',\n",
|
" 'inference-schema[numpy-support]',\n",
|
||||||
" 'joblib',\n",
|
" 'joblib',\n",
|
||||||
" 'numpy',\n",
|
" 'numpy',\n",
|
||||||
" 'scikit-learn'\n",
|
" 'scikit-learn==0.19.1',\n",
|
||||||
|
" 'scipy'\n",
|
||||||
"])\n",
|
"])\n",
|
||||||
"inference_config = InferenceConfig(entry_script='score.py', environment=environment)\n",
|
"inference_config = InferenceConfig(entry_script='score.py', environment=environment)\n",
|
||||||
"# if cpu and memory_in_gb parameters are not provided\n",
|
"# if cpu and memory_in_gb parameters are not provided\n",
|
||||||
|
|||||||
@@ -1,260 +0,0 @@
|
|||||||
{
|
|
||||||
"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": [
|
|
||||||
""
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"# Register TensorFlow SavedModel and deploy as webservice\n",
|
|
||||||
"\n",
|
|
||||||
"Following this notebook, you will:\n",
|
|
||||||
"\n",
|
|
||||||
" - Learn how to register a TF SavedModel in your Azure Machine Learning Workspace.\n",
|
|
||||||
" - Deploy your model as a web service in an Azure Container Instance."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Prerequisites\n",
|
|
||||||
"\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) to install the Azure Machine Learning Python SDK and create a workspace."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"import azureml.core\n",
|
|
||||||
"\n",
|
|
||||||
"# Check core SDK version number.\n",
|
|
||||||
"print('SDK version:', azureml.core.VERSION)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Initialize workspace\n",
|
|
||||||
"\n",
|
|
||||||
"Create a [Workspace](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.core.workspace%28class%29?view=azure-ml-py) object from your 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": [
|
|
||||||
"### Download the Model\n",
|
|
||||||
"\n",
|
|
||||||
"Download and extract the model from https://amlsamplenotebooksdata.blob.core.windows.net/data/flowers_model.tar.gz to \"models\" directory"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"import os\n",
|
|
||||||
"import tarfile\n",
|
|
||||||
"import urllib.request\n",
|
|
||||||
"\n",
|
|
||||||
"# create directory for model\n",
|
|
||||||
"model_dir = 'models'\n",
|
|
||||||
"if not os.path.isdir(model_dir):\n",
|
|
||||||
" os.mkdir(model_dir)\n",
|
|
||||||
"\n",
|
|
||||||
"url=\"https://amlsamplenotebooksdata.blob.core.windows.net/data/flowers_model.tar.gz\"\n",
|
|
||||||
"response = urllib.request.urlretrieve(url, model_dir + \"/flowers_model.tar.gz\")\n",
|
|
||||||
"tar = tarfile.open(model_dir + \"/flowers_model.tar.gz\", \"r:gz\")\n",
|
|
||||||
"tar.extractall(model_dir)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Register model\n",
|
|
||||||
"\n",
|
|
||||||
"Register a file or folder as a model by calling [Model.register()](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.core.model.model?view=azure-ml-py#register-workspace--model-path--model-name--tags-none--properties-none--description-none--datasets-none--model-framework-none--model-framework-version-none--child-paths-none-). For this example, we have provided a TensorFlow SavedModel (`flowers_model` in the notebook's directory).\n",
|
|
||||||
"\n",
|
|
||||||
"In addition to the content of the model file itself, your registered model will also store model metadata -- model description, tags, and framework information -- that will be useful when managing and deploying models in your workspace. Using tags, for instance, you can categorize your models and apply filters when listing models in your workspace. Also, marking this model with the scikit-learn framework will simplify deploying it as a web service, as we'll see later."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {
|
|
||||||
"tags": [
|
|
||||||
"register model from file"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"from azureml.core import Model\n",
|
|
||||||
"\n",
|
|
||||||
"model = Model.register(workspace=ws,\n",
|
|
||||||
" model_name='flowers', # Name of the registered model in your workspace.\n",
|
|
||||||
" model_path= model_dir + '/flowers_model', # Local Tensorflow SavedModel folder to upload and register as a model.\n",
|
|
||||||
" model_framework=Model.Framework.TENSORFLOW, # Framework used to create the model.\n",
|
|
||||||
" model_framework_version='1.14.0', # Version of Tensorflow used to create the model.\n",
|
|
||||||
" description='Flowers model')\n",
|
|
||||||
"\n",
|
|
||||||
"print('Name:', model.name)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Deploy model\n",
|
|
||||||
"\n",
|
|
||||||
"Deploy your model as a web service using [Model.deploy()](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.core.model.model?view=azure-ml-py#deploy-workspace--name--models--inference-config--deployment-config-none--deployment-target-none-). Web services take one or more models, load them in an environment, and run them on one of several supported deployment targets.\n",
|
|
||||||
"\n",
|
|
||||||
"For this example, we will deploy your TensorFlow SavedModel to an Azure Container Instance (ACI)."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"### Use a default environment (for supported models)\n",
|
|
||||||
"\n",
|
|
||||||
"The Azure Machine Learning service provides a default environment for supported model frameworks, including TensorFlow, based on the metadata you provided when registering your model. This is the easiest way to deploy your model.\n",
|
|
||||||
"\n",
|
|
||||||
"**Note**: This step can take several minutes."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"from azureml.core import Webservice\n",
|
|
||||||
"from azureml.exceptions import WebserviceException\n",
|
|
||||||
"\n",
|
|
||||||
"service_name = 'tensorflow-flower-service'\n",
|
|
||||||
"\n",
|
|
||||||
"# Remove any existing service under the same name.\n",
|
|
||||||
"try:\n",
|
|
||||||
" Webservice(ws, service_name).delete()\n",
|
|
||||||
"except WebserviceException:\n",
|
|
||||||
" pass\n",
|
|
||||||
"\n",
|
|
||||||
"service = Model.deploy(ws, service_name, [model])\n",
|
|
||||||
"service.wait_for_deployment(show_output=True)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"After your model is deployed, perform a call to the web service."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"import requests\n",
|
|
||||||
"\n",
|
|
||||||
"headers = {'Content-Type': 'application/json'}\n",
|
|
||||||
"\n",
|
|
||||||
"if service.auth_enabled:\n",
|
|
||||||
" headers['Authorization'] = 'Bearer '+ service.get_keys()[0]\n",
|
|
||||||
"elif service.token_auth_enabled:\n",
|
|
||||||
" headers['Authorization'] = 'Bearer '+ service.get_token()[0]\n",
|
|
||||||
"\n",
|
|
||||||
"scoring_uri = service.scoring_uri # If you have a SavedModel with classify and regress, \n",
|
|
||||||
" # you can change the scoring_uri from 'uri:predict' to 'uri:classify' or 'uri:regress'.\n",
|
|
||||||
"print(scoring_uri)\n",
|
|
||||||
"\n",
|
|
||||||
"with open('tensorflow-flower-predict-input.json', 'rb') as data_file:\n",
|
|
||||||
" response = requests.post(\n",
|
|
||||||
" scoring_uri, data=data_file, headers=headers)\n",
|
|
||||||
"print(response.status_code)\n",
|
|
||||||
"print(response.elapsed)\n",
|
|
||||||
"print(response.json())"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"When you are finished testing your service, clean up the deployment."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"service.delete()"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "vaidyas"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"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.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 2
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
name: tensorflow-model-register-and-deploy
|
|
||||||
dependencies:
|
|
||||||
- pip:
|
|
||||||
- azureml-sdk
|
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
"\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",
|
"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",
|
"\n",
|
||||||
"|  |\n",
|
"|  |\n",
|
||||||
"|:--:|\n"
|
"|:--:|\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -261,6 +261,10 @@
|
|||||||
"if pandas_ver:\n",
|
"if pandas_ver:\n",
|
||||||
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
||||||
"# specify CondaDependencies obj\n",
|
"# specify CondaDependencies obj\n",
|
||||||
|
"# The CondaDependencies specifies the conda and pip packages that are installed in the environment\n",
|
||||||
|
"# the submitted job is run in. Note the remote environment(s) needs to be similar to the local\n",
|
||||||
|
"# environment, otherwise if a model is trained or deployed in a different environment this can\n",
|
||||||
|
"# cause errors. Please take extra care when specifying your dependencies in a production environment.\n",
|
||||||
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
||||||
" pip_packages=azureml_pip_packages)\n",
|
" pip_packages=azureml_pip_packages)\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -379,6 +383,10 @@
|
|||||||
"if pandas_ver:\n",
|
"if pandas_ver:\n",
|
||||||
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
||||||
"# specify CondaDependencies obj\n",
|
"# specify CondaDependencies obj\n",
|
||||||
|
"# The CondaDependencies specifies the conda and pip packages that are installed in the environment\n",
|
||||||
|
"# the submitted job is run in. Note the remote environment(s) needs to be similar to the local\n",
|
||||||
|
"# environment, otherwise if a model is trained or deployed in a different environment this can\n",
|
||||||
|
"# cause errors. Please take extra care when specifying your dependencies in a production environment.\n",
|
||||||
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
||||||
" pip_packages=azureml_pip_packages)\n",
|
" pip_packages=azureml_pip_packages)\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -509,6 +517,10 @@
|
|||||||
"if pandas_ver:\n",
|
"if pandas_ver:\n",
|
||||||
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
||||||
"# specify CondaDependencies obj\n",
|
"# specify CondaDependencies obj\n",
|
||||||
|
"# The CondaDependencies specifies the conda and pip packages that are installed in the environment\n",
|
||||||
|
"# the submitted job is run in. Note the remote environment(s) needs to be similar to the local\n",
|
||||||
|
"# environment, otherwise if a model is trained or deployed in a different environment this can\n",
|
||||||
|
"# cause errors. Please take extra care when specifying your dependencies in a production environment.\n",
|
||||||
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
||||||
" pip_packages=azureml_pip_packages)\n",
|
" pip_packages=azureml_pip_packages)\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -672,7 +684,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# retrieve model for visualization and deployment\n",
|
"# retrieve model for visualization and deployment\n",
|
||||||
"from azureml.core.model import Model\n",
|
"from azureml.core.model import Model\n",
|
||||||
"from sklearn.externals import joblib\n",
|
"import joblib\n",
|
||||||
"original_model = Model(ws, 'model_explain_model_on_amlcomp')\n",
|
"original_model = Model(ws, 'model_explain_model_on_amlcomp')\n",
|
||||||
"model_path = original_model.download(exist_ok=True)\n",
|
"model_path = original_model.download(exist_ok=True)\n",
|
||||||
"original_model = joblib.load(model_path)"
|
"original_model = joblib.load(model_path)"
|
||||||
@@ -692,7 +704,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# retrieve x_test for visualization\n",
|
"# retrieve x_test for visualization\n",
|
||||||
"from sklearn.externals import joblib\n",
|
"import joblib\n",
|
||||||
"x_test_path = './x_test_boston_housing.pkl'\n",
|
"x_test_path = './x_test_boston_housing.pkl'\n",
|
||||||
"run.download_file('x_test_boston_housing.pkl', output_file_path=x_test_path)"
|
"run.download_file('x_test_boston_housing.pkl', output_file_path=x_test_path)"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from interpret.ext.blackbox import TabularExplainer
|
|||||||
from azureml.contrib.interpret.explanation.explanation_client import ExplanationClient
|
from azureml.contrib.interpret.explanation.explanation_client import ExplanationClient
|
||||||
from sklearn.model_selection import train_test_split
|
from sklearn.model_selection import train_test_split
|
||||||
from azureml.core.run import Run
|
from azureml.core.run import Run
|
||||||
from sklearn.externals import joblib
|
import joblib
|
||||||
import os
|
import os
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import numpy as np
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
from sklearn.externals import joblib
|
import joblib
|
||||||
from sklearn.linear_model import LogisticRegression
|
from sklearn.linear_model import LogisticRegression
|
||||||
from azureml.core.model import Model
|
from azureml.core.model import Model
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import numpy as np
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
from sklearn.externals import joblib
|
import joblib
|
||||||
from sklearn.linear_model import LogisticRegression
|
from sklearn.linear_model import LogisticRegression
|
||||||
from azureml.core.model import Model
|
from azureml.core.model import Model
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from sklearn.model_selection import train_test_split\n",
|
"from sklearn.model_selection import train_test_split\n",
|
||||||
"from sklearn.externals import joblib\n",
|
"import joblib\n",
|
||||||
"from sklearn.preprocessing import StandardScaler, OneHotEncoder\n",
|
"from sklearn.preprocessing import StandardScaler, OneHotEncoder\n",
|
||||||
"from sklearn.impute import SimpleImputer\n",
|
"from sklearn.impute import SimpleImputer\n",
|
||||||
"from sklearn.pipeline import Pipeline\n",
|
"from sklearn.pipeline import Pipeline\n",
|
||||||
@@ -346,6 +346,10 @@
|
|||||||
"if pandas_ver:\n",
|
"if pandas_ver:\n",
|
||||||
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
||||||
"# specify CondaDependencies obj\n",
|
"# specify CondaDependencies obj\n",
|
||||||
|
"# The CondaDependencies specifies the conda and pip packages that are installed in the environment\n",
|
||||||
|
"# the submitted job is run in. Note the remote environment(s) needs to be similar to the local\n",
|
||||||
|
"# environment, otherwise if a model is trained or deployed in a different environment this can\n",
|
||||||
|
"# cause errors. Please take extra care when specifying your dependencies in a production environment.\n",
|
||||||
"myenv = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
"myenv = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
||||||
" pip_packages=['sklearn-pandas', 'pyyaml'] + azureml_pip_packages,\n",
|
" pip_packages=['sklearn-pandas', 'pyyaml'] + azureml_pip_packages,\n",
|
||||||
" pin_sdk_version=False)\n",
|
" pin_sdk_version=False)\n",
|
||||||
@@ -413,9 +417,9 @@
|
|||||||
"headers = {'Content-Type':'application/json'}\n",
|
"headers = {'Content-Type':'application/json'}\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# send request to service\n",
|
"# send request to service\n",
|
||||||
|
"print(\"POST to url\", service.scoring_uri)\n",
|
||||||
"resp = requests.post(service.scoring_uri, sample_data, headers=headers)\n",
|
"resp = requests.post(service.scoring_uri, sample_data, headers=headers)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"POST to url\", service.scoring_uri)\n",
|
|
||||||
"# can covert back to Python objects from json string if desired\n",
|
"# can covert back to Python objects from json string if desired\n",
|
||||||
"print(\"prediction:\", resp.text)\n",
|
"print(\"prediction:\", resp.text)\n",
|
||||||
"result = json.loads(resp.text)"
|
"result = json.loads(resp.text)"
|
||||||
|
|||||||
@@ -63,7 +63,7 @@
|
|||||||
"7.\tCreate an image and register it in the image registry.\n",
|
"7.\tCreate an image and register it in the image registry.\n",
|
||||||
"8.\tDeploy the image as a web service in Azure.\n",
|
"8.\tDeploy the image as a web service in Azure.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"|  |\n",
|
"|  |\n",
|
||||||
"|:--:|"
|
"|:--:|"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -264,6 +264,10 @@
|
|||||||
"if pandas_ver:\n",
|
"if pandas_ver:\n",
|
||||||
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
||||||
"# specify CondaDependencies obj\n",
|
"# specify CondaDependencies obj\n",
|
||||||
|
"# The CondaDependencies specifies the conda and pip packages that are installed in the environment\n",
|
||||||
|
"# the submitted job is run in. Note the remote environment(s) needs to be similar to the local\n",
|
||||||
|
"# environment, otherwise if a model is trained or deployed in a different environment this can\n",
|
||||||
|
"# cause errors. Please take extra care when specifying your dependencies in a production environment.\n",
|
||||||
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
"run_config.environment.python.conda_dependencies = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
||||||
" pip_packages=['sklearn_pandas', 'pyyaml'] + azureml_pip_packages,\n",
|
" pip_packages=['sklearn_pandas', 'pyyaml'] + azureml_pip_packages,\n",
|
||||||
" pin_sdk_version=False)\n",
|
" pin_sdk_version=False)\n",
|
||||||
@@ -325,7 +329,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"# retrieve model for visualization and deployment\n",
|
"# retrieve model for visualization and deployment\n",
|
||||||
"from azureml.core.model import Model\n",
|
"from azureml.core.model import Model\n",
|
||||||
"from sklearn.externals import joblib\n",
|
"import joblib\n",
|
||||||
"original_model = Model(ws, 'amlcompute_deploy_model')\n",
|
"original_model = Model(ws, 'amlcompute_deploy_model')\n",
|
||||||
"model_path = original_model.download(exist_ok=True)\n",
|
"model_path = original_model.download(exist_ok=True)\n",
|
||||||
"original_svm_model = joblib.load(model_path)"
|
"original_svm_model = joblib.load(model_path)"
|
||||||
@@ -352,7 +356,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# retrieve x_test for visualization\n",
|
"# retrieve x_test for visualization\n",
|
||||||
"from sklearn.externals import joblib\n",
|
"import joblib\n",
|
||||||
"x_test_path = './x_test.pkl'\n",
|
"x_test_path = './x_test.pkl'\n",
|
||||||
"run.download_file('x_test_ibm.pkl', output_file_path=x_test_path)\n",
|
"run.download_file('x_test_ibm.pkl', output_file_path=x_test_path)\n",
|
||||||
"x_test = joblib.load(x_test_path)"
|
"x_test = joblib.load(x_test_path)"
|
||||||
@@ -432,6 +436,10 @@
|
|||||||
"if pandas_ver:\n",
|
"if pandas_ver:\n",
|
||||||
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
" pandas_dep = 'pandas=={}'.format(pandas_ver)\n",
|
||||||
"# specify CondaDependencies obj\n",
|
"# specify CondaDependencies obj\n",
|
||||||
|
"# The CondaDependencies specifies the conda and pip packages that are installed in the environment\n",
|
||||||
|
"# the submitted job is run in. Note the remote environment(s) needs to be similar to the local\n",
|
||||||
|
"# environment, otherwise if a model is trained or deployed in a different environment this can\n",
|
||||||
|
"# cause errors. Please take extra care when specifying your dependencies in a production environment.\n",
|
||||||
"myenv = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
"myenv = CondaDependencies.create(conda_packages=[sklearn_dep, pandas_dep],\n",
|
||||||
" pip_packages=['sklearn-pandas', 'pyyaml'] + azureml_pip_packages,\n",
|
" pip_packages=['sklearn-pandas', 'pyyaml'] + azureml_pip_packages,\n",
|
||||||
" pin_sdk_version=False)\n",
|
" pin_sdk_version=False)\n",
|
||||||
@@ -495,9 +503,9 @@
|
|||||||
"headers = {'Content-Type':'application/json'}\n",
|
"headers = {'Content-Type':'application/json'}\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# send request to service\n",
|
"# send request to service\n",
|
||||||
|
"print(\"POST to url\", service.scoring_uri)\n",
|
||||||
"resp = requests.post(service.scoring_uri, input_data, headers=headers)\n",
|
"resp = requests.post(service.scoring_uri, input_data, headers=headers)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"POST to url\", service.scoring_uri)\n",
|
|
||||||
"# can covert back to Python objects from json string if desired\n",
|
"# can covert back to Python objects from json string if desired\n",
|
||||||
"print(\"prediction:\", resp.text)"
|
"print(\"prediction:\", resp.text)"
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import os
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import zipfile
|
import zipfile
|
||||||
from sklearn.model_selection import train_test_split
|
from sklearn.model_selection import train_test_split
|
||||||
from sklearn.externals import joblib
|
import joblib
|
||||||
from sklearn.preprocessing import StandardScaler, OneHotEncoder
|
from sklearn.preprocessing import StandardScaler, OneHotEncoder
|
||||||
from sklearn.impute import SimpleImputer
|
from sklearn.impute import SimpleImputer
|
||||||
from sklearn.pipeline import Pipeline
|
from sklearn.pipeline import Pipeline
|
||||||
|
|||||||
@@ -252,7 +252,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"binaries_folder = \"azurebatch/job_binaries\"\n",
|
"binaries_folder = \"azurebatch/job_binaries\"\n",
|
||||||
"if not os.path.isdir(binaries_folder):\n",
|
"if not os.path.isdir(binaries_folder):\n",
|
||||||
" os.mkdir(binaries_folder)\n",
|
" os.makedirs(binaries_folder)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"file_name=\"azurebatch.cmd\"\n",
|
"file_name=\"azurebatch.cmd\"\n",
|
||||||
"with open(path.join(binaries_folder, file_name), 'w') as f:\n",
|
"with open(path.join(binaries_folder, file_name), 'w') as f:\n",
|
||||||
|
|||||||
@@ -0,0 +1,510 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"Copyright (c) Microsoft Corporation. All rights reserved. \n",
|
||||||
|
"Licensed under the MIT License."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Showcasing Dataset and PipelineParameter\n",
|
||||||
|
"\n",
|
||||||
|
"This notebook demonstrates how a [**FileDataset**](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.data.filedataset?view=azure-ml-py) or [**TabularDataset**](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.data.tabulardataset?view=azure-ml-py) can be parametrized with [**PipelineParameters**](https://docs.microsoft.com/en-us/python/api/azureml-pipeline-core/azureml.pipeline.core.pipelineparameter?view=azure-ml-py) in an AML [Pipeline](https://docs.microsoft.com/en-us/python/api/azureml-pipeline-core/azureml.pipeline.core.pipeline(class)?view=azure-ml-py). By parametrizing datasets, you can dynamically run pipeline experiments with different datasets without any code change.\n",
|
||||||
|
"\n",
|
||||||
|
"A common use case is building a training pipeline with a sample of your training data for quick iterative development. When you're ready to test and deploy your pipeline at scale, you can pass in your full training dataset to the pipeline experiment without making any changes to your training script. \n",
|
||||||
|
" \n",
|
||||||
|
"To see more about how parameters work between steps, please refer [aml-pipelines-with-data-dependency-steps](https://aka.ms/pl-data-dep).\n",
|
||||||
|
"\n",
|
||||||
|
"* [How to create a Pipeline with a Dataset PipelineParameter](#index1)\n",
|
||||||
|
"* [How to submit a Pipeline with a Dataset PipelineParameter](#index2)\n",
|
||||||
|
"* [How to submit a Pipeline and change the Dataset PipelineParameter value from the sdk](#index3)\n",
|
||||||
|
"* [How to submit a Pipeline and change the Dataset PipelineParameter value using a REST call](#index4)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Azure Machine Learning and Pipeline SDK-specific imports"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import azureml.core\n",
|
||||||
|
"from azureml.core import Workspace, Experiment, Dataset\n",
|
||||||
|
"from azureml.core.compute import ComputeTarget, AmlCompute\n",
|
||||||
|
"from azureml.data.dataset_consumption_config import DatasetConsumptionConfig\n",
|
||||||
|
"from azureml.widgets import RunDetails\n",
|
||||||
|
"\n",
|
||||||
|
"from azureml.pipeline.core import PipelineParameter\n",
|
||||||
|
"from azureml.pipeline.core import Pipeline, PipelineRun\n",
|
||||||
|
"from azureml.pipeline.steps import PythonScriptStep\n",
|
||||||
|
"\n",
|
||||||
|
"# Check core SDK version number\n",
|
||||||
|
"print(\"SDK version:\", azureml.core.VERSION)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Initialize Workspace\n",
|
||||||
|
"\n",
|
||||||
|
"Initialize a workspace object from persisted configuration. If you are using an Azure Machine Learning Notebook VM, you are all set. Otherwise, make sure the config file is present at .\\config.json\n",
|
||||||
|
"\n",
|
||||||
|
"If you don't have a config.json file, go through the [configuration Notebook](https://aka.ms/pl-config) first.\n",
|
||||||
|
"\n",
|
||||||
|
"This sets you up with a working config file that has information on your workspace, subscription id, etc."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"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": [
|
||||||
|
"## Create an Azure ML experiment\n",
|
||||||
|
"\n",
|
||||||
|
"Let's create an experiment named \"showcasing-dataset\" and a folder to hold the training scripts. The script runs will be recorded under the experiment in Azure."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Choose a name for the run history container in the workspace.\n",
|
||||||
|
"experiment_name = 'showcasing-dataset'\n",
|
||||||
|
"source_directory = '.'\n",
|
||||||
|
"\n",
|
||||||
|
"experiment = Experiment(ws, experiment_name)\n",
|
||||||
|
"experiment"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Create or Attach an AmlCompute cluster\n",
|
||||||
|
"You will need to create a [compute target](https://docs.microsoft.com/azure/machine-learning/service/concept-azure-machine-learning-architecture#compute-target) for your AutoML run. In this tutorial, you get the default `AmlCompute` as your training compute resource."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Choose a name for your cluster.\n",
|
||||||
|
"amlcompute_cluster_name = \"cpu-cluster\"\n",
|
||||||
|
"\n",
|
||||||
|
"found = False\n",
|
||||||
|
"# Check if this compute target already exists in the workspace.\n",
|
||||||
|
"cts = ws.compute_targets\n",
|
||||||
|
"if amlcompute_cluster_name in cts and cts[amlcompute_cluster_name].type == 'AmlCompute':\n",
|
||||||
|
" found = True\n",
|
||||||
|
" print('Found existing compute target.')\n",
|
||||||
|
" compute_target = cts[amlcompute_cluster_name]\n",
|
||||||
|
" \n",
|
||||||
|
"if not found:\n",
|
||||||
|
" print('Creating a new compute target...')\n",
|
||||||
|
" provisioning_config = AmlCompute.provisioning_configuration(vm_size = \"STANDARD_D2_V2\", # for GPU, use \"STANDARD_NC6\"\n",
|
||||||
|
" #vm_priority = 'lowpriority', # optional\n",
|
||||||
|
" max_nodes = 4)\n",
|
||||||
|
"\n",
|
||||||
|
" # Create the cluster.\n",
|
||||||
|
" compute_target = ComputeTarget.create(ws, amlcompute_cluster_name, provisioning_config)\n",
|
||||||
|
" \n",
|
||||||
|
" # Can poll for a minimum number of nodes and for a specific timeout.\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, timeout_in_minutes = 10)\n",
|
||||||
|
" \n",
|
||||||
|
" # For a more detailed view of current AmlCompute status, use get_status()."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Dataset Configuration\n",
|
||||||
|
"\n",
|
||||||
|
"The following steps detail how to create a [FileDataset](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.data.filedataset?view=azure-ml-py) and [TabularDataset](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.data.tabulardataset?view=azure-ml-py) from an external CSV file, and configure them to be used by a [Pipeline](https://docs.microsoft.com/en-us/python/api/azureml-pipeline-core/azureml.pipeline.core.pipeline(class)?view=azure-ml-py):\n",
|
||||||
|
"\n",
|
||||||
|
"1. Create a dataset from a csv file\n",
|
||||||
|
"2. Create a [PipelineParameter](https://docs.microsoft.com/en-us/python/api/azureml-pipeline-core/azureml.pipeline.core.pipelineparameter?view=azure-ml-py) object and set the `default_value` to the dataset. [PipelineParameter](https://docs.microsoft.com/en-us/python/api/azureml-pipeline-core/azureml.pipeline.core.pipelineparameter?view=azure-ml-py) objects enabled arguments to be passed into Pipelines when they are resubmitted after creation. The `name` is referenced later on when we submit additional pipeline runs with different input datasets. \n",
|
||||||
|
"3. Create a [DatasetConsumptionConfig](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.data.dataset_consumption_config.datasetconsumptionconfig?view=azure-ml-py) object from the [PiepelineParameter](https://docs.microsoft.com/en-us/python/api/azureml-pipeline-core/azureml.pipeline.core.pipelineparameter?view=azure-ml-py). The [DatasetConsumptionConfig](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.data.dataset_consumption_config.datasetconsumptionconfig?view=azure-ml-py) object specifies how the dataset should be used by the remote compute where the pipeline is run. **NOTE** only [DatasetConsumptionConfig](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.data.dataset_consumption_config.datasetconsumptionconfig?view=azure-ml-py) objects built on [FileDataset](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.data.filedataset?view=azure-ml-py) can be set `as_mount()` or `as_download()` on the remote compute."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {
|
||||||
|
"tags": [
|
||||||
|
"datapath-remarks-sample"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"file_dataset = Dataset.File.from_files('https://dprepdata.blob.core.windows.net/demo/Titanic.csv')\n",
|
||||||
|
"file_pipeline_param = PipelineParameter(name=\"file_ds_param\", default_value=file_dataset)\n",
|
||||||
|
"file_ds_consumption = DatasetConsumptionConfig(\"file_dataset\", file_pipeline_param).as_mount()\n",
|
||||||
|
"\n",
|
||||||
|
"tabular_dataset = Dataset.Tabular.from_delimited_files('https://dprepdata.blob.core.windows.net/demo/Titanic.csv')\n",
|
||||||
|
"tabular_pipeline_param = PipelineParameter(name=\"tabular_ds_param\", default_value=tabular_dataset)\n",
|
||||||
|
"tabular_ds_consumption = DatasetConsumptionConfig(\"tabular_dataset\", tabular_pipeline_param)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"We will setup a training script to ingest our passed-in datasets and print their contents. **NOTE** the names of the datasets referenced inside the training script correspond to the `name` of their respective [DatasetConsumptionConfig](https://docs.microsoft.com/en-us/python/api/azureml-core/azureml.data.dataset_consumption_config.datasetconsumptionconfig?view=azure-ml-py) objects we defined above."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"%%writefile train_with_dataset.py\n",
|
||||||
|
"from azureml.core import Run\n",
|
||||||
|
"\n",
|
||||||
|
"input_file_ds_path = Run.get_context().input_datasets['file_dataset']\n",
|
||||||
|
"with open(input_file_ds_path, 'r') as f:\n",
|
||||||
|
" content = f.read()\n",
|
||||||
|
" print(content)\n",
|
||||||
|
"\n",
|
||||||
|
"input_tabular_ds = Run.get_context().input_datasets['tabular_dataset']\n",
|
||||||
|
"tabular_df = input_tabular_ds.to_pandas_dataframe()\n",
|
||||||
|
"print(tabular_df)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<a id='index1'></a>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Create a Pipeline with a Dataset PipelineParameter\n",
|
||||||
|
"\n",
|
||||||
|
"Note that the ```file_ds_consumption``` and ```tabular_ds_consumption``` are specified as both arguments and inputs to create a step."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"train_step = PythonScriptStep(\n",
|
||||||
|
" name=\"train_step\",\n",
|
||||||
|
" script_name=\"train_with_dataset.py\",\n",
|
||||||
|
" arguments=[\"--param1\", file_ds_consumption, \"--param2\", tabular_ds_consumption],\n",
|
||||||
|
" inputs=[file_ds_consumption, tabular_ds_consumption],\n",
|
||||||
|
" compute_target=compute_target,\n",
|
||||||
|
" source_directory=source_directory)\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"train_step created\")\n",
|
||||||
|
"\n",
|
||||||
|
"pipeline = Pipeline(workspace=ws, steps=[train_step])\n",
|
||||||
|
"print(\"pipeline with the train_step created\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<a id='index2'></a>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Submit a Pipeline with a Dataset PipelineParameter\n",
|
||||||
|
"\n",
|
||||||
|
"Pipelines can be submitted with default values of PipelineParameters by not specifying any parameters."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Pipeline will run with default file_ds and tabular_ds\n",
|
||||||
|
"pipeline_run = experiment.submit(pipeline)\n",
|
||||||
|
"print(\"Pipeline is submitted for execution\")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"RunDetails(pipeline_run).show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"pipeline_run.wait_for_completion()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<a id='index3'></a>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Submit a Pipeline with a different Dataset PipelineParameter value from the SDK\n",
|
||||||
|
"\n",
|
||||||
|
"The training pipeline can be reused with different input datasets by passing them in as PipelineParameters"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"iris_file_ds = Dataset.File.from_files('https://raw.githubusercontent.com/Azure/MachineLearningNotebooks/'\n",
|
||||||
|
" '4e7b3784d50e81c313c62bcdf9a330194153d9cd/how-to-use-azureml/work-with-data/'\n",
|
||||||
|
" 'datasets-tutorial/train-with-datasets/train-dataset/iris.csv')\n",
|
||||||
|
"\n",
|
||||||
|
"iris_tabular_ds = Dataset.Tabular.from_delimited_files('https://raw.githubusercontent.com/Azure/MachineLearningNotebooks/'\n",
|
||||||
|
" '4e7b3784d50e81c313c62bcdf9a330194153d9cd/how-to-use-azureml/work-with-data/'\n",
|
||||||
|
" 'datasets-tutorial/train-with-datasets/train-dataset/iris.csv')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"pipeline_run_with_params = experiment.submit(pipeline, pipeline_parameters={'file_ds_param': iris_file_ds, 'tabular_ds_param': iris_tabular_ds}) "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"RunDetails(pipeline_run_with_params).show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"pipeline_run_with_params.wait_for_completion()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<a id='index4'></a>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"## Dynamically Set the Dataset PipelineParameter Values using a REST Call\n",
|
||||||
|
"\n",
|
||||||
|
"Let's publish the pipeline we created previously, so we can generate a pipeline endpoint. We can then submit the iris datasets to the pipeline REST endpoint by passing in their IDs. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"published_pipeline = pipeline.publish(name=\"Dataset_Pipeline\", description=\"Pipeline to test Dataset PipelineParameter\", continue_on_step_failure=True)\n",
|
||||||
|
"published_pipeline"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"published_pipeline.submit(ws, experiment_name=\"publishedexperiment\", pipeline_parameters={'file_ds_param': iris_file_ds, 'tabular_ds_param': iris_tabular_ds})"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from azureml.core.authentication import InteractiveLoginAuthentication\n",
|
||||||
|
"import requests\n",
|
||||||
|
"\n",
|
||||||
|
"auth = InteractiveLoginAuthentication()\n",
|
||||||
|
"aad_token = auth.get_authentication_header()\n",
|
||||||
|
"\n",
|
||||||
|
"rest_endpoint = published_pipeline.endpoint\n",
|
||||||
|
"\n",
|
||||||
|
"print(\"You can perform HTTP POST on URL {} to trigger this pipeline\".format(rest_endpoint))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# specify the param when running the pipeline\n",
|
||||||
|
"response = requests.post(rest_endpoint, \n",
|
||||||
|
" headers=aad_token, \n",
|
||||||
|
" json={\"ExperimentName\": \"MyRestPipeline\",\n",
|
||||||
|
" \"RunSource\": \"SDK\",\n",
|
||||||
|
" \"DataSetDefinitionValueAssignments\": {\"file_ds_param\": {\"SavedDataSetReference\": {\"Id\": iris_file_ds.id}},\n",
|
||||||
|
" \"tabular_ds_param\": {\"SavedDataSetReference\": {\"Id\": iris_tabular_ds.id}}}\n",
|
||||||
|
" }\n",
|
||||||
|
" )"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"try:\n",
|
||||||
|
" response.raise_for_status()\n",
|
||||||
|
"except Exception: \n",
|
||||||
|
" raise Exception('Received bad response from the endpoint: {}\\n'\n",
|
||||||
|
" 'Response Code: {}\\n'\n",
|
||||||
|
" 'Headers: {}\\n'\n",
|
||||||
|
" 'Content: {}'.format(rest_endpoint, response.status_code, response.headers, response.content))\n",
|
||||||
|
"\n",
|
||||||
|
"run_id = response.json().get('Id')\n",
|
||||||
|
"print('Submitted pipeline run: ', run_id)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"published_pipeline_run_via_rest = PipelineRun(ws.experiments[\"MyRestPipeline\"], run_id)\n",
|
||||||
|
"RunDetails(published_pipeline_run_via_rest).show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"published_pipeline_run_via_rest.wait_for_completion()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"<a id='index5'></a>"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "rafarmah"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"category": "tutorial",
|
||||||
|
"compute": [
|
||||||
|
"AML Compute"
|
||||||
|
],
|
||||||
|
"datasets": [
|
||||||
|
"Custom"
|
||||||
|
],
|
||||||
|
"deployment": [
|
||||||
|
"None"
|
||||||
|
],
|
||||||
|
"exclude_from_index": false,
|
||||||
|
"framework": [
|
||||||
|
"Azure ML"
|
||||||
|
],
|
||||||
|
"friendly_name": "How to use Dataset as a PipelineParameter",
|
||||||
|
"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.7"
|
||||||
|
},
|
||||||
|
"order_index": 13,
|
||||||
|
"star_tag": [
|
||||||
|
"featured"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"None"
|
||||||
|
],
|
||||||
|
"task": "Demonstrates the use of Dataset as a PipelineParameter"
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
name: aml-pipelines-showcasing-dataset-and-pipelineparameter
|
||||||
|
dependencies:
|
||||||
|
- pip:
|
||||||
|
- azureml-sdk
|
||||||
|
- azureml-widgets
|
||||||
@@ -510,7 +510,7 @@
|
|||||||
" inputs=[step_1_input],\n",
|
" inputs=[step_1_input],\n",
|
||||||
" num_workers=1,\n",
|
" num_workers=1,\n",
|
||||||
" python_script_path=python_script_path,\n",
|
" python_script_path=python_script_path,\n",
|
||||||
" python_script_params={'arg1', pipeline_param, 'arg2},\n",
|
" python_script_params={'arg1', pipeline_param, 'arg2'},\n",
|
||||||
" run_name='DB_Python_demo',\n",
|
" run_name='DB_Python_demo',\n",
|
||||||
" compute_target=databricks_compute,\n",
|
" compute_target=databricks_compute,\n",
|
||||||
" allow_reuse=True\n",
|
" allow_reuse=True\n",
|
||||||
|
|||||||
@@ -279,8 +279,7 @@
|
|||||||
"# Specify CondaDependencies obj, add necessary packages\n",
|
"# Specify CondaDependencies obj, add necessary packages\n",
|
||||||
"aml_run_config.environment.python.conda_dependencies = CondaDependencies.create(\n",
|
"aml_run_config.environment.python.conda_dependencies = CondaDependencies.create(\n",
|
||||||
" conda_packages=['pandas','scikit-learn'], \n",
|
" conda_packages=['pandas','scikit-learn'], \n",
|
||||||
" pip_packages=['azureml-sdk[automl,explain]', 'pyarrow'], \n",
|
" pip_packages=['azureml-sdk[automl,explain]', 'pyarrow'])\n",
|
||||||
" pin_sdk_version=False)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"print (\"Run configuration created.\")"
|
"print (\"Run configuration created.\")"
|
||||||
]
|
]
|
||||||
@@ -692,7 +691,6 @@
|
|||||||
" debug_log = 'automated_ml_errors.log',\n",
|
" debug_log = 'automated_ml_errors.log',\n",
|
||||||
" path = train_model_folder,\n",
|
" path = train_model_folder,\n",
|
||||||
" compute_target = aml_compute,\n",
|
" compute_target = aml_compute,\n",
|
||||||
" run_configuration = aml_run_config,\n",
|
|
||||||
" featurization = 'auto',\n",
|
" featurization = 'auto',\n",
|
||||||
" training_data = training_dataset,\n",
|
" training_data = training_dataset,\n",
|
||||||
" label_column_name = 'cost',\n",
|
" label_column_name = 'cost',\n",
|
||||||
|
|||||||
@@ -2,18 +2,16 @@
|
|||||||
|
|
||||||
Azure Machine Learning Batch Inference targets large inference jobs that are not time-sensitive. Batch Inference provides cost-effective inference compute scaling, with unparalleled throughput for asynchronous applications. It is optimized for high-throughput, fire-and-forget inference over large collections of data.
|
Azure Machine Learning Batch Inference targets large inference jobs that are not time-sensitive. Batch Inference provides cost-effective inference compute scaling, with unparalleled throughput for asynchronous applications. It is optimized for high-throughput, fire-and-forget inference over large collections of data.
|
||||||
|
|
||||||
# Getting Started with Batch Inference Public Preview
|
# Getting Started with Batch Inference
|
||||||
|
|
||||||
Batch inference public preview offers a platform in which to do large inference or generic parallel map-style operations. Below introduces the major steps to use this new functionality. For a quick try, please follow the prerequisites and simply run the sample notebooks provided in this directory.
|
Batch inference offers a platform in which to do large inference or generic parallel map-style operations. Below introduces the major steps to use this new functionality. For a quick try, please follow the prerequisites and simply run the sample notebooks provided in this directory.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
### Python package installation
|
### Python package installation
|
||||||
Following the convention of most AzureML Public Preview features, Batch Inference SDK is currently available as a contrib package.
|
|
||||||
|
|
||||||
If you're unfamiliar with creating a new Python environment, you may follow this example for [creating a conda environment](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-configure-environment#local). Batch Inference package can be installed through the following pip command.
|
If you're unfamiliar with creating a new Python environment, you may follow this example for [creating a conda environment](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-configure-environment#local). Batch Inference package can be installed through the following pip command.
|
||||||
```
|
```
|
||||||
pip install azureml-contrib-pipeline-steps
|
pip install azureml-pipeline-steps
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creation of Azure Machine Learning Workspace
|
### Creation of Azure Machine Learning Workspace
|
||||||
@@ -66,9 +64,8 @@ base_image_registry.password = "password"
|
|||||||
|
|
||||||
## Create a batch inference job
|
## Create a batch inference job
|
||||||
|
|
||||||
**ParallelRunStep** is a newly added step in the azureml.contrib.pipeline.steps package. You will use it to add a step to create a batch inference job with your Azure machine learning pipeline. (Use batch inference without an Azure machine learning pipeline is not supported yet). ParallelRunStep has all the following parameters:
|
**ParallelRunStep** is a newly added step in the azureml.pipeline.steps package. You will use it to add a step to create a batch inference job with your Azure machine learning pipeline. (Use batch inference without an Azure machine learning pipeline is not supported yet). ParallelRunStep has all the following parameters:
|
||||||
- **name**: this name will be used to register batch inference service, has the following naming restrictions: (unique, 3-32 chars and regex ^\[a-z\]([-a-z0-9]*[a-z0-9])?$)
|
- **name**: this name will be used to register batch inference service, has the following naming restrictions: (unique, 3-32 chars and regex ^\[a-z\]([-a-z0-9]*[a-z0-9])?$)
|
||||||
- **models**: zero or more model names already registered in Azure Machine Learning model registry.
|
|
||||||
- **parallel_run_config**: ParallelRunConfig as defined above.
|
- **parallel_run_config**: ParallelRunConfig as defined above.
|
||||||
- **inputs**: one or more Dataset objects.
|
- **inputs**: one or more Dataset objects.
|
||||||
- **output**: this should be a PipelineData object encapsulating an Azure BLOB container path.
|
- **output**: this should be a PipelineData object encapsulating an Azure BLOB container path.
|
||||||
|
|||||||
@@ -23,11 +23,6 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"In this notebook, we will demonstrate how to make predictions on large quantities of data asynchronously using the ML pipelines with Azure Machine Learning. Batch inference (or batch scoring) provides cost-effective inference, with unparalleled throughput for asynchronous applications. Batch prediction pipelines can scale to perform inference on terabytes of production data. Batch prediction is optimized for high throughput, fire-and-forget predictions for a large collection of data.\n",
|
"In this notebook, we will demonstrate how to make predictions on large quantities of data asynchronously using the ML pipelines with Azure Machine Learning. Batch inference (or batch scoring) provides cost-effective inference, with unparalleled throughput for asynchronous applications. Batch prediction pipelines can scale to perform inference on terabytes of production data. Batch prediction is optimized for high throughput, fire-and-forget predictions for a large collection of data.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"> **Note**\n",
|
|
||||||
"This notebook uses public preview functionality (ParallelRunStep). Please install azureml-contrib-pipeline-steps package before running this notebook. Pandas is used to display job results.\n",
|
|
||||||
"```\n",
|
|
||||||
"pip install azureml-contrib-pipeline-steps pandas\n",
|
|
||||||
"```\n",
|
|
||||||
"> **Tip**\n",
|
"> **Tip**\n",
|
||||||
"If your system requires low-latency processing (to process a single document or small set of documents quickly), use [real-time scoring](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-consume-web-service) instead of batch prediction.\n",
|
"If your system requires low-latency processing (to process a single document or small set of documents quickly), use [real-time scoring](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-consume-web-service) instead of batch prediction.\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -86,7 +81,6 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"import os\n",
|
"import os\n",
|
||||||
"from azureml.core.compute import AmlCompute, ComputeTarget\n",
|
"from azureml.core.compute import AmlCompute, ComputeTarget\n",
|
||||||
"from azureml.core.compute_target import ComputeTargetException\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"# choose a name for your cluster\n",
|
"# choose a name for your cluster\n",
|
||||||
"compute_name = os.environ.get(\"AML_COMPUTE_CLUSTER_NAME\", \"cpu-cluster\")\n",
|
"compute_name = os.environ.get(\"AML_COMPUTE_CLUSTER_NAME\", \"cpu-cluster\")\n",
|
||||||
@@ -184,9 +178,20 @@
|
|||||||
"mnist_ds_name = 'mnist_sample_data'\n",
|
"mnist_ds_name = 'mnist_sample_data'\n",
|
||||||
"\n",
|
"\n",
|
||||||
"path_on_datastore = mnist_data.path('mnist')\n",
|
"path_on_datastore = mnist_data.path('mnist')\n",
|
||||||
"input_mnist_ds = Dataset.File.from_files(path=path_on_datastore, validate=False)\n",
|
"input_mnist_ds = Dataset.File.from_files(path=path_on_datastore, validate=False)"
|
||||||
"registered_mnist_ds = input_mnist_ds.register(ws, mnist_ds_name, create_new_version=True)\n",
|
]
|
||||||
"named_mnist_ds = registered_mnist_ds.as_named_input(mnist_ds_name)"
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from azureml.data.dataset_consumption_config import DatasetConsumptionConfig\n",
|
||||||
|
"from azureml.pipeline.core import PipelineParameter\n",
|
||||||
|
"\n",
|
||||||
|
"pipeline_param = PipelineParameter(name=\"mnist_param\", default_value=input_mnist_ds)\n",
|
||||||
|
"input_mnist_ds_consumption = DatasetConsumptionConfig(\"minist_param_config\", pipeline_param).as_mount()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -306,8 +311,6 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"import os\n",
|
|
||||||
"\n",
|
|
||||||
"scripts_folder = \"Code\"\n",
|
"scripts_folder = \"Code\"\n",
|
||||||
"script_file = \"digit_identification.py\"\n",
|
"script_file = \"digit_identification.py\"\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -341,8 +344,8 @@
|
|||||||
"from azureml.core import Environment\n",
|
"from azureml.core import Environment\n",
|
||||||
"from azureml.core.runconfig import CondaDependencies, DEFAULT_CPU_IMAGE\n",
|
"from azureml.core.runconfig import CondaDependencies, DEFAULT_CPU_IMAGE\n",
|
||||||
"\n",
|
"\n",
|
||||||
"batch_conda_deps = CondaDependencies.create(pip_packages=[\"tensorflow==1.15.2\", \"pillow\"])\n",
|
"batch_conda_deps = CondaDependencies.create(pip_packages=[\"tensorflow==1.15.2\", \"pillow\", \n",
|
||||||
"\n",
|
" \"azureml-core\", \"azureml-dataprep[fuse]\"])\n",
|
||||||
"batch_env = Environment(name=\"batch_environment\")\n",
|
"batch_env = Environment(name=\"batch_environment\")\n",
|
||||||
"batch_env.python.conda_dependencies = batch_conda_deps\n",
|
"batch_env.python.conda_dependencies = batch_conda_deps\n",
|
||||||
"batch_env.docker.enabled = True\n",
|
"batch_env.docker.enabled = True\n",
|
||||||
@@ -362,17 +365,21 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.contrib.pipeline.steps import ParallelRunStep, ParallelRunConfig\n",
|
"from azureml.pipeline.core import PipelineParameter\n",
|
||||||
|
"from azureml.pipeline.steps import ParallelRunStep, ParallelRunConfig\n",
|
||||||
"\n",
|
"\n",
|
||||||
"parallel_run_config = ParallelRunConfig(\n",
|
"parallel_run_config = ParallelRunConfig(\n",
|
||||||
" source_directory=scripts_folder,\n",
|
" source_directory=scripts_folder,\n",
|
||||||
" entry_script=script_file,\n",
|
" entry_script=script_file,\n",
|
||||||
" mini_batch_size=\"5\",\n",
|
" mini_batch_size=PipelineParameter(name=\"batch_size_param\", default_value=\"5\"),\n",
|
||||||
" error_threshold=10,\n",
|
" error_threshold=10,\n",
|
||||||
" output_action=\"append_row\",\n",
|
" output_action=\"append_row\",\n",
|
||||||
|
" append_row_file_name=\"mnist_outputs.txt\",\n",
|
||||||
" environment=batch_env,\n",
|
" environment=batch_env,\n",
|
||||||
" compute_target=compute_target,\n",
|
" compute_target=compute_target,\n",
|
||||||
" node_count=2)"
|
" process_count_per_node=PipelineParameter(name=\"process_count_param\", default_value=2),\n",
|
||||||
|
" node_count=2\n",
|
||||||
|
")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -392,10 +399,8 @@
|
|||||||
"parallelrun_step = ParallelRunStep(\n",
|
"parallelrun_step = ParallelRunStep(\n",
|
||||||
" name=\"predict-digits-mnist\",\n",
|
" name=\"predict-digits-mnist\",\n",
|
||||||
" parallel_run_config=parallel_run_config,\n",
|
" parallel_run_config=parallel_run_config,\n",
|
||||||
" inputs=[ named_mnist_ds ],\n",
|
" inputs=[ input_mnist_ds_consumption ],\n",
|
||||||
" output=output_dir,\n",
|
" output=output_dir,\n",
|
||||||
" models=[ model ],\n",
|
|
||||||
" arguments=[ ],\n",
|
|
||||||
" allow_reuse=True\n",
|
" allow_reuse=True\n",
|
||||||
")"
|
")"
|
||||||
]
|
]
|
||||||
@@ -454,6 +459,47 @@
|
|||||||
"pipeline_run.wait_for_completion(show_output=True)"
|
"pipeline_run.wait_for_completion(show_output=True)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Resubmit a with different dataset\n",
|
||||||
|
"Since we made the input a `PipelineParameter`, we can resubmit with a different dataset without having to create an entirely new experiment. We'll use the same datastore but use only a single image."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"path_on_datastore = mnist_data.path('mnist/0.png')\n",
|
||||||
|
"single_image_ds = Dataset.File.from_files(path=path_on_datastore, validate=False)\n",
|
||||||
|
"single_image_ds._ensure_saved(ws)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"pipeline_run_2 = experiment.submit(pipeline, \n",
|
||||||
|
" pipeline_parameters={\"mnist_param\": single_image_ds, \n",
|
||||||
|
" \"batch_size_param\": \"1\",\n",
|
||||||
|
" \"process_count_param\": 1}\n",
|
||||||
|
")"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"pipeline_run_2.wait_for_completion(show_output=True)"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -480,7 +526,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"for root, dirs, files in os.walk(\"mnist_results\"):\n",
|
"for root, dirs, files in os.walk(\"mnist_results\"):\n",
|
||||||
" for file in files:\n",
|
" for file in files:\n",
|
||||||
" if file.endswith('parallel_run_step.txt'):\n",
|
" if file.endswith('mnist_outputs.txt'):\n",
|
||||||
" result_file = os.path.join(root,file)\n",
|
" result_file = os.path.join(root,file)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"df = pd.read_csv(result_file, delimiter=\":\", header=None)\n",
|
"df = pd.read_csv(result_file, delimiter=\":\", header=None)\n",
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ name: file-dataset-image-inference-mnist
|
|||||||
dependencies:
|
dependencies:
|
||||||
- pip:
|
- pip:
|
||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- azureml-contrib-pipeline-steps
|
- azureml-pipeline-steps
|
||||||
- azureml-widgets
|
- azureml-widgets
|
||||||
- pandas
|
- pandas
|
||||||
|
|||||||
@@ -23,11 +23,6 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"In this notebook, we will demonstrate how to make predictions on large quantities of data asynchronously using the ML pipelines with Azure Machine Learning. Batch inference (or batch scoring) provides cost-effective inference, with unparalleled throughput for asynchronous applications. Batch prediction pipelines can scale to perform inference on terabytes of production data. Batch prediction is optimized for high throughput, fire-and-forget predictions for a large collection of data.\n",
|
"In this notebook, we will demonstrate how to make predictions on large quantities of data asynchronously using the ML pipelines with Azure Machine Learning. Batch inference (or batch scoring) provides cost-effective inference, with unparalleled throughput for asynchronous applications. Batch prediction pipelines can scale to perform inference on terabytes of production data. Batch prediction is optimized for high throughput, fire-and-forget predictions for a large collection of data.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"> **Note**\n",
|
|
||||||
"This notebook uses public preview functionality (ParallelRunStep). Please install azureml-contrib-pipeline-steps package before running this notebook. Pandas is used to display job results.\n",
|
|
||||||
"```\n",
|
|
||||||
"pip install azureml-contrib-pipeline-steps pandas\n",
|
|
||||||
"```\n",
|
|
||||||
"> **Tip**\n",
|
"> **Tip**\n",
|
||||||
"If your system requires low-latency processing (to process a single document or small set of documents quickly), use [real-time scoring](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-consume-web-service) instead of batch prediction.\n",
|
"If your system requires low-latency processing (to process a single document or small set of documents quickly), use [real-time scoring](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-consume-web-service) instead of batch prediction.\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -84,7 +79,6 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"import os\n",
|
"import os\n",
|
||||||
"from azureml.core.compute import AmlCompute, ComputeTarget\n",
|
"from azureml.core.compute import AmlCompute, ComputeTarget\n",
|
||||||
"from azureml.core.compute_target import ComputeTargetException\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"# choose a name for your cluster\n",
|
"# choose a name for your cluster\n",
|
||||||
"compute_name = os.environ.get(\"AML_COMPUTE_CLUSTER_NAME\", \"cpu-cluster\")\n",
|
"compute_name = os.environ.get(\"AML_COMPUTE_CLUSTER_NAME\", \"cpu-cluster\")\n",
|
||||||
@@ -304,7 +298,8 @@
|
|||||||
"from azureml.core import Environment\n",
|
"from azureml.core import Environment\n",
|
||||||
"from azureml.core.runconfig import CondaDependencies\n",
|
"from azureml.core.runconfig import CondaDependencies\n",
|
||||||
"\n",
|
"\n",
|
||||||
"predict_conda_deps = CondaDependencies.create(pip_packages=[ \"scikit-learn==0.20.3\" ])\n",
|
"predict_conda_deps = CondaDependencies.create(pip_packages=[\"scikit-learn==0.20.3\",\n",
|
||||||
|
" \"azureml-core\", \"azureml-dataprep[pandas,fuse]\"])\n",
|
||||||
"\n",
|
"\n",
|
||||||
"predict_env = Environment(name=\"predict_environment\")\n",
|
"predict_env = Environment(name=\"predict_environment\")\n",
|
||||||
"predict_env.python.conda_dependencies = predict_conda_deps\n",
|
"predict_env.python.conda_dependencies = predict_conda_deps\n",
|
||||||
@@ -325,19 +320,21 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.contrib.pipeline.steps import ParallelRunStep, ParallelRunConfig\n",
|
"from azureml.pipeline.steps import ParallelRunStep, ParallelRunConfig\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# In a real-world scenario, you'll want to shape your process per node and nodes to fit your problem domain.\n",
|
"# In a real-world scenario, you'll want to shape your process per node and nodes to fit your problem domain.\n",
|
||||||
"parallel_run_config = ParallelRunConfig(\n",
|
"parallel_run_config = ParallelRunConfig(\n",
|
||||||
" source_directory=scripts_folder,\n",
|
" source_directory=scripts_folder,\n",
|
||||||
" entry_script=script_file, # the user script to run against each input\n",
|
" entry_script=script_file, # the user script to run against each input\n",
|
||||||
" mini_batch_size='5MB',\n",
|
" mini_batch_size='5MB',\n",
|
||||||
" error_threshold=5,\n",
|
" error_threshold=5,\n",
|
||||||
" output_action='append_row',\n",
|
" output_action='append_row',\n",
|
||||||
" environment=predict_env,\n",
|
" append_row_file_name=\"iris_outputs.txt\",\n",
|
||||||
" compute_target=compute_target, \n",
|
" environment=predict_env,\n",
|
||||||
" node_count=3,\n",
|
" compute_target=compute_target, \n",
|
||||||
" run_invocation_timeout=600)"
|
" node_count=3,\n",
|
||||||
|
" run_invocation_timeout=600\n",
|
||||||
|
")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -359,7 +356,6 @@
|
|||||||
" inputs=[named_iris_ds],\n",
|
" inputs=[named_iris_ds],\n",
|
||||||
" output=output_folder,\n",
|
" output=output_folder,\n",
|
||||||
" parallel_run_config=parallel_run_config,\n",
|
" parallel_run_config=parallel_run_config,\n",
|
||||||
" models=[model],\n",
|
|
||||||
" arguments=['--model_name', 'iris'],\n",
|
" arguments=['--model_name', 'iris'],\n",
|
||||||
" allow_reuse=True\n",
|
" allow_reuse=True\n",
|
||||||
")"
|
")"
|
||||||
@@ -453,7 +449,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"for root, dirs, files in os.walk(\"iris_results\"):\n",
|
"for root, dirs, files in os.walk(\"iris_results\"):\n",
|
||||||
" for file in files:\n",
|
" for file in files:\n",
|
||||||
" if file.endswith('parallel_run_step.txt'):\n",
|
" if file.endswith('iris_outputs.txt'):\n",
|
||||||
" result_file = os.path.join(root,file)\n",
|
" result_file = os.path.join(root,file)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# cleanup output format\n",
|
"# cleanup output format\n",
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ name: tabular-dataset-inference-iris
|
|||||||
dependencies:
|
dependencies:
|
||||||
- pip:
|
- pip:
|
||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- azureml-contrib-pipeline-steps
|
- azureml-pipeline-steps
|
||||||
- azureml-widgets
|
- azureml-widgets
|
||||||
- pandas
|
- pandas
|
||||||
|
|||||||
@@ -26,11 +26,8 @@
|
|||||||
"2. Run neural style on each image using one of the provided models (from `pytorch` pretrained models for this example).\n",
|
"2. Run neural style on each image using one of the provided models (from `pytorch` pretrained models for this example).\n",
|
||||||
"3. Stitch the image back into a video.\n",
|
"3. Stitch the image back into a video.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"> **Note**\n",
|
"> **Tip**\n",
|
||||||
"This notebook uses public preview functionality (ParallelRunStep). Please install azureml-contrib-pipeline-steps package before running this notebook.\n",
|
"If your system requires low-latency processing (to process a single document or small set of documents quickly), use [real-time scoring](https://docs.microsoft.com/en-us/azure/machine-learning/service/how-to-consume-web-service) instead of batch prediction."
|
||||||
"```\n",
|
|
||||||
"pip install azureml-contrib-pipeline-steps\n",
|
|
||||||
"```"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -356,7 +353,9 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"from azureml.pipeline.core.graph import PipelineParameter\n",
|
"from azureml.pipeline.core.graph import PipelineParameter\n",
|
||||||
"# create a parameter for style (one of \"candy\", \"mosaic\") to transfer the images to\n",
|
"# create a parameter for style (one of \"candy\", \"mosaic\") to transfer the images to\n",
|
||||||
"style_param = PipelineParameter(name=\"style\", default_value=\"mosaic\")"
|
"style_param = PipelineParameter(name=\"style\", default_value=\"mosaic\")\n",
|
||||||
|
"# create a parameter for the number of nodes to use in step no. 2 (style transfer)\n",
|
||||||
|
"nodecount_param = PipelineParameter(name=\"nodecount\", default_value=2)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -415,6 +414,8 @@
|
|||||||
"parallel_cd.add_conda_package(\"pytorch\")\n",
|
"parallel_cd.add_conda_package(\"pytorch\")\n",
|
||||||
"parallel_cd.add_conda_package(\"torchvision\")\n",
|
"parallel_cd.add_conda_package(\"torchvision\")\n",
|
||||||
"parallel_cd.add_conda_package(\"pillow<7\") # needed for torchvision==0.4.0\n",
|
"parallel_cd.add_conda_package(\"pillow<7\") # needed for torchvision==0.4.0\n",
|
||||||
|
"parallel_cd.add_pip_package(\"azureml-core\")\n",
|
||||||
|
"parallel_cd.add_pip_package(\"azureml-dataprep[fuse]\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"styleenvironment = Environment(name=\"styleenvironment\")\n",
|
"styleenvironment = Environment(name=\"styleenvironment\")\n",
|
||||||
"styleenvironment.python.conda_dependencies=parallel_cd\n",
|
"styleenvironment.python.conda_dependencies=parallel_cd\n",
|
||||||
@@ -427,17 +428,20 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.contrib.pipeline.steps import ParallelRunConfig\n",
|
"from azureml.pipeline.core import PipelineParameter\n",
|
||||||
|
"from azureml.pipeline.steps import ParallelRunConfig\n",
|
||||||
"\n",
|
"\n",
|
||||||
"parallel_run_config = ParallelRunConfig(\n",
|
"parallel_run_config = ParallelRunConfig(\n",
|
||||||
" environment=styleenvironment,\n",
|
" environment=styleenvironment,\n",
|
||||||
" entry_script='transform.py',\n",
|
" entry_script='transform.py',\n",
|
||||||
" output_action='summary_only',\n",
|
" output_action='summary_only',\n",
|
||||||
" mini_batch_size=\"1\",\n",
|
" mini_batch_size=\"1\",\n",
|
||||||
" error_threshold=1,\n",
|
" error_threshold=1,\n",
|
||||||
" source_directory=scripts_folder,\n",
|
" source_directory=scripts_folder,\n",
|
||||||
" compute_target=gpu_cluster, \n",
|
" compute_target=gpu_cluster, \n",
|
||||||
" node_count=3)"
|
" node_count=nodecount_param,\n",
|
||||||
|
" process_count_per_node=2\n",
|
||||||
|
")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -446,7 +450,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.contrib.pipeline.steps import ParallelRunStep\n",
|
"from azureml.pipeline.steps import ParallelRunStep\n",
|
||||||
"from datetime import datetime\n",
|
"from datetime import datetime\n",
|
||||||
"\n",
|
"\n",
|
||||||
"parallel_step_name = 'styletransfer-' + datetime.now().strftime('%Y%m%d%H%M')\n",
|
"parallel_step_name = 'styletransfer-' + datetime.now().strftime('%Y%m%d%H%M')\n",
|
||||||
@@ -455,9 +459,6 @@
|
|||||||
" name=parallel_step_name,\n",
|
" name=parallel_step_name,\n",
|
||||||
" inputs=[ffmpeg_images_file_dataset], # Input file share/blob container/file dataset\n",
|
" inputs=[ffmpeg_images_file_dataset], # Input file share/blob container/file dataset\n",
|
||||||
" output=processed_images, # Output file share/blob container\n",
|
" output=processed_images, # Output file share/blob container\n",
|
||||||
" models=[mosaic_model, candy_model],\n",
|
|
||||||
" tags = {'scenario': \"batch inference\", 'type': \"demo\"},\n",
|
|
||||||
" properties = {'area': \"style transfer\"},\n",
|
|
||||||
" arguments=[\"--style\", style_param],\n",
|
" arguments=[\"--style\", style_param],\n",
|
||||||
" parallel_run_config=parallel_run_config,\n",
|
" parallel_run_config=parallel_run_config,\n",
|
||||||
" allow_reuse=True #[optional - default value True]\n",
|
" allow_reuse=True #[optional - default value True]\n",
|
||||||
@@ -666,7 +667,8 @@
|
|||||||
"response = requests.post(rest_endpoint, \n",
|
"response = requests.post(rest_endpoint, \n",
|
||||||
" headers=aad_token,\n",
|
" headers=aad_token,\n",
|
||||||
" json={\"ExperimentName\": experiment_name,\n",
|
" json={\"ExperimentName\": experiment_name,\n",
|
||||||
" \"ParameterAssignments\": {\"style\": \"candy\", \"aml_node_count\": 2}})\n",
|
" \"ParameterAssignments\": {\"style\": \"candy\", \"NodeCount\": 3}})\n",
|
||||||
|
"\n",
|
||||||
"run_id = response.json()[\"Id\"]\n",
|
"run_id = response.json()[\"Id\"]\n",
|
||||||
"\n",
|
"\n",
|
||||||
"from azureml.pipeline.core.run import PipelineRun\n",
|
"from azureml.pipeline.core.run import PipelineRun\n",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ name: pipeline-style-transfer
|
|||||||
dependencies:
|
dependencies:
|
||||||
- pip:
|
- pip:
|
||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- azureml-contrib-pipeline-steps
|
|
||||||
- azureml-pipeline-steps
|
- azureml-pipeline-steps
|
||||||
- azureml-widgets
|
- azureml-widgets
|
||||||
- requests
|
- requests
|
||||||
|
|||||||
@@ -381,7 +381,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"run.cancel()"
|
"run.wait_for_completion(show_output=True)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ dependencies:
|
|||||||
- azureml-monitoring
|
- azureml-monitoring
|
||||||
- scikit-learn
|
- scikit-learn
|
||||||
- numpy
|
- numpy
|
||||||
|
- packaging
|
||||||
- inference-schema[numpy-support]
|
- inference-schema[numpy-support]
|
||||||
|
|||||||
@@ -4,7 +4,13 @@ import numpy as np
|
|||||||
from azureml.monitoring import ModelDataCollector
|
from azureml.monitoring import ModelDataCollector
|
||||||
from inference_schema.parameter_types.numpy_parameter_type import NumpyParameterType
|
from inference_schema.parameter_types.numpy_parameter_type import NumpyParameterType
|
||||||
from inference_schema.schema_decorators import input_schema, output_schema
|
from inference_schema.schema_decorators import input_schema, output_schema
|
||||||
from sklearn.externals import joblib
|
# sklearn.externals.joblib is removed in 0.23
|
||||||
|
from sklearn import __version__ as sklearnver
|
||||||
|
from packaging.version import Version
|
||||||
|
if Version(sklearnver) < Version("0.23.0"):
|
||||||
|
from sklearn.externals import joblib
|
||||||
|
else:
|
||||||
|
import joblib
|
||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
|
|||||||
@@ -11,19 +11,29 @@ Taxonomies for products and languages: https://review.docs.microsoft.com/new-hop
|
|||||||
|
|
||||||
This is an introduction to the [Azure Machine Learning](https://docs.microsoft.com/en-us/azure/machine-learning/service/) Reinforcement Learning (Public Preview) using the [Ray](https://github.com/ray-project/ray/) framework.
|
This is an introduction to the [Azure Machine Learning](https://docs.microsoft.com/en-us/azure/machine-learning/service/) Reinforcement Learning (Public Preview) using the [Ray](https://github.com/ray-project/ray/) framework.
|
||||||
|
|
||||||
Using these samples, you will be able to do the following.
|
## What is reinforcement learning?
|
||||||
|
|
||||||
1. Use an Azure Machine Learning workspace, set up virtual network and create compute clusters for running Ray.
|
Reinforcement learning is an approach to machine learning to train agents to make a sequence of decisions. This technique has gained popularity over the last few years as breakthroughs have been made to teach reinforcement learning agents to excel at complex tasks like playing video games. There are many practical real-world use cases as well, including robotics, chemistry, online recommendations, advertising and more.
|
||||||
2. Run some experiments to train a reinforcement learning agent using Ray and RLlib.
|
|
||||||
|
In reinforcement learning, the goal is to train an agent *policy* that outputs actions based on the agent’s observations of its environment. Actions result in further observations and *rewards* for taking the actions. In reinforcement learning, the full reward for policy actions may take many steps to obtain. Learning a policy involves many trial-and-error runs of the agent interacting with the environment and improving its policy.
|
||||||
|
|
||||||
|
## Reinforcement learning on Azure Machine Learning
|
||||||
|
|
||||||
|
Reinforcement learning support in Azure Machine Learning service enables data scientists to scale training to many powerful CPU or GPU enabled VMs using [Azure Machine Learning compute clusters](https://docs.microsoft.com/en-us/azure/machine-learning/how-to-set-up-training-targets#amlcompute) which automatically provision, manage, and scale down these VMs to help manage your costs.
|
||||||
|
|
||||||
|
Using these samples, you will learn how to do the following.
|
||||||
|
|
||||||
|
1. Use an Azure Machine Learning workspace, set up virtual network and create compute clusters for distributed training.
|
||||||
|
2. Train reinforcement learning agents using Ray RLlib.
|
||||||
|
|
||||||
## Contents
|
## Contents
|
||||||
|
|
||||||
| File/folder | Description |
|
| File/folder | Description |
|
||||||
|-------------------|--------------------------------------------|
|
|-------------------|--------------------------------------------|
|
||||||
| [devenv_setup.ipynb](setup/devenv_setup.ipynb) | Notebook to setup development environment for Azure ML RL |
|
| [devenv_setup.ipynb](setup/devenv_setup.ipynb) | Notebook to setup virtual network for using Azure Machine Learning. Needed for the Pong and Minecraft examples. |
|
||||||
| [cartpole_ci.ipynb](cartpole-on-compute-instance/cartpole_ci.ipynb) | Notebook to train a Cartpole playing agent on an Azure ML Compute Instance |
|
| [cartpole_ci.ipynb](cartpole-on-compute-instance/cartpole_ci.ipynb) | Notebook to train a Cartpole playing agent on an Azure Machine Learning Compute Instance |
|
||||||
| [cartpole_cc.ipynb](cartpole-on-single-compute/cartpole_cc.ipynb) | Notebook to train a Cartpole playing agent on an Azure ML Compute Cluster (single node) |
|
| [cartpole_sc.ipynb](cartpole-on-single-compute/cartpole_sc.ipynb) | Notebook to train a Cartpole playing agent on an Azure Machine Learning Compute Cluster (single node) |
|
||||||
| [pong_rllib.ipynb](atari-on-distributed-compute/pong_rllib.ipynb) | Notebook to train Pong agent using RLlib on multiple compute targets |
|
| [pong_rllib.ipynb](atari-on-distributed-compute/pong_rllib.ipynb) | Notebook for distributed training of Pong agent using RLlib on multiple compute targets |
|
||||||
| [minecraft.ipynb](minecraft-on-distributed-compute/minecraft.ipynb) | Notebook to train an agent to navigate through a lava maze in the Minecraft game |
|
| [minecraft.ipynb](minecraft-on-distributed-compute/minecraft.ipynb) | Notebook to train an agent to navigate through a lava maze in the Minecraft game |
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
@@ -32,9 +42,10 @@ To make use of these samples, you need the following.
|
|||||||
|
|
||||||
* A Microsoft Azure subscription.
|
* A Microsoft Azure subscription.
|
||||||
* A Microsoft Azure resource group.
|
* A Microsoft Azure resource group.
|
||||||
* An Azure Machine Learning Workspace in the resource group. Please make sure that the VM sizes `STANDARD_NC6` and `STANDARD_D2_V2` are supported in the workspace's region.
|
* An Azure Machine Learning Workspace in the resource group.
|
||||||
* A virtual network set up in the resource group.
|
* Azure Machine Learning training compute. These samples use the VM sizes `STANDARD_NC6` and `STANDARD_D2_V2`. If these are not available in your region,
|
||||||
* A virtual network is needed for the examples training on multiple compute targets.
|
you can replace them with other sizes.
|
||||||
|
* A virtual network set up in the resource group for samples that use multiple compute targets. The Cartpole examples do not need a virtual network.
|
||||||
* The [devenv_setup.ipynb](setup/devenv_setup.ipynb) notebook shows you how to create a virtual network. You can alternatively use an existing virtual network, make sure it's in the same region as workspace is.
|
* The [devenv_setup.ipynb](setup/devenv_setup.ipynb) notebook shows you how to create a virtual network. You can alternatively use an existing virtual network, make sure it's in the same region as workspace is.
|
||||||
* Any network security group defined on the virtual network must allow network traffic on ports used by Azure infrastructure services. This is described in more detail in the [devenv_setup.ipynb](setup/devenv_setup.ipynb) notebook.
|
* Any network security group defined on the virtual network must allow network traffic on ports used by Azure infrastructure services. This is described in more detail in the [devenv_setup.ipynb](setup/devenv_setup.ipynb) notebook.
|
||||||
|
|
||||||
@@ -43,10 +54,10 @@ To make use of these samples, you need the following.
|
|||||||
|
|
||||||
You can run these samples in the following ways.
|
You can run these samples in the following ways.
|
||||||
|
|
||||||
* On an Azure ML Compute Instance or Notebook VM.
|
* On an Azure Machine Learning Compute Instance or Azure Data Science Virtual Machine (DSVM).
|
||||||
* On a workstation with Python and the Azure ML Python SDK installed.
|
* On a workstation with Python and the Azure ML Python SDK installed.
|
||||||
|
|
||||||
### Azure ML Compute Instance or Notebook VM
|
### Compute Instance or DSVM
|
||||||
#### Update packages
|
#### Update packages
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,237 @@
|
|||||||
|
import sys
|
||||||
|
import csv
|
||||||
|
from azure.mgmt.network import NetworkManagementClient
|
||||||
|
|
||||||
|
|
||||||
|
def check_port_in_port_range(expected_port: str,
|
||||||
|
dest_port_range: str):
|
||||||
|
"""
|
||||||
|
Check if a port is within a port range
|
||||||
|
Port range maybe like *, 8080 or 8888-8889
|
||||||
|
"""
|
||||||
|
|
||||||
|
if dest_port_range == '*':
|
||||||
|
return True
|
||||||
|
|
||||||
|
dest_ports = dest_port_range.split('-')
|
||||||
|
|
||||||
|
if len(dest_ports) == 1 and \
|
||||||
|
int(dest_ports[0]) == int(expected_port):
|
||||||
|
return True
|
||||||
|
|
||||||
|
if len(dest_ports) == 2 and \
|
||||||
|
int(dest_ports[0]) <= int(expected_port) and \
|
||||||
|
int(dest_ports[1]) >= int(expected_port):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_port_in_destination_port_ranges(expected_port: str,
|
||||||
|
dest_port_ranges: list):
|
||||||
|
"""
|
||||||
|
Check if a port is within a given list of port ranges
|
||||||
|
i.e. check if port 8080 is in port ranges of 22,80,8080-8090,443
|
||||||
|
"""
|
||||||
|
|
||||||
|
for dest_port_range in dest_port_ranges:
|
||||||
|
if check_port_in_port_range(expected_port, dest_port_range) is True:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_ports_in_destination_port_ranges(expected_ports: list,
|
||||||
|
dest_port_ranges: list):
|
||||||
|
"""
|
||||||
|
Check if all ports in a given port list are within a given list
|
||||||
|
of port ranges
|
||||||
|
i.e. check if port 8080,8081 are in port ranges of 22,80,8080-8090,443
|
||||||
|
"""
|
||||||
|
|
||||||
|
for expected_port in expected_ports:
|
||||||
|
if check_port_in_destination_port_ranges(
|
||||||
|
expected_port, dest_port_ranges) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_source_address_prefix(source_address_prefix: str):
|
||||||
|
"""Check if source address prefix is BatchNodeManagement or default"""
|
||||||
|
|
||||||
|
required_prefix = 'BatchNodeManagement'
|
||||||
|
default_prefix = 'default'
|
||||||
|
|
||||||
|
if source_address_prefix.lower() == required_prefix.lower() or \
|
||||||
|
source_address_prefix.lower() == default_prefix.lower():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_protocol(protocol: str):
|
||||||
|
"""Check if protocol is supported - Tcp/Any"""
|
||||||
|
|
||||||
|
required_protocol = 'Tcp'
|
||||||
|
any_protocol = 'Any'
|
||||||
|
|
||||||
|
if required_protocol.lower() == protocol.lower() or \
|
||||||
|
any_protocol.lower() == protocol.lower():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_direction(direction: str):
|
||||||
|
"""Check if port direction is inbound"""
|
||||||
|
|
||||||
|
required_direction = 'Inbound'
|
||||||
|
|
||||||
|
if required_direction.lower() == direction.lower():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_provisioning_state(provisioning_state: str):
|
||||||
|
"""Check if the provisioning state is succeeded"""
|
||||||
|
|
||||||
|
required_provisioning_state = 'Succeeded'
|
||||||
|
|
||||||
|
if required_provisioning_state.lower() == provisioning_state.lower():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_rule_for_Azure_ML(rule):
|
||||||
|
"""Check if the ports required for Azure Machine Learning are open"""
|
||||||
|
|
||||||
|
required_ports = ['29876', '29877']
|
||||||
|
|
||||||
|
if check_source_address_prefix(rule.source_address_prefix) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if check_protocol(rule.protocol) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if check_direction(rule.direction) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if check_provisioning_state(rule.provisioning_state) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if rule.destination_port_range is not None:
|
||||||
|
if check_ports_in_destination_port_ranges(
|
||||||
|
required_ports,
|
||||||
|
[rule.destination_port_range]) is False:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if check_ports_in_destination_port_ranges(
|
||||||
|
required_ports,
|
||||||
|
rule.destination_port_ranges) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_vnet_security_rules(auth_object,
|
||||||
|
vnet_subscription_id,
|
||||||
|
vnet_resource_group,
|
||||||
|
vnet_name,
|
||||||
|
save_to_file=False):
|
||||||
|
"""
|
||||||
|
Check all the rules of virtual network if required ports for Azure Machine
|
||||||
|
Learning are open
|
||||||
|
"""
|
||||||
|
|
||||||
|
network_client = NetworkManagementClient(
|
||||||
|
auth_object,
|
||||||
|
vnet_subscription_id)
|
||||||
|
|
||||||
|
# get the vnet
|
||||||
|
vnet = network_client.virtual_networks.get(
|
||||||
|
resource_group_name=vnet_resource_group,
|
||||||
|
virtual_network_name=vnet_name)
|
||||||
|
|
||||||
|
vnet_location = vnet.location
|
||||||
|
vnet_info = []
|
||||||
|
|
||||||
|
if vnet.subnets is None or len(vnet.subnets) == 0:
|
||||||
|
print('WARNING: No subnet found for VNet:', vnet_name)
|
||||||
|
|
||||||
|
# for each subnet of the vnet
|
||||||
|
for subnet in vnet.subnets:
|
||||||
|
if subnet.network_security_group is None:
|
||||||
|
print('WARNING: No network security group found for subnet.',
|
||||||
|
'Subnet',
|
||||||
|
subnet.id.split("/")[-1])
|
||||||
|
else:
|
||||||
|
# get all the rules
|
||||||
|
network_security_group_name = \
|
||||||
|
subnet.network_security_group.id.split("/")[-1]
|
||||||
|
network_security_group_resource_group_name = \
|
||||||
|
subnet.network_security_group.id.split("/")[4]
|
||||||
|
network_security_group_subscription_id = \
|
||||||
|
subnet.network_security_group.id.split("/")[2]
|
||||||
|
|
||||||
|
security_rules = list(network_client.security_rules.list(
|
||||||
|
network_security_group_resource_group_name,
|
||||||
|
network_security_group_name))
|
||||||
|
|
||||||
|
rule_matched = None
|
||||||
|
for rule in security_rules:
|
||||||
|
rule_info = []
|
||||||
|
# add vnet details
|
||||||
|
rule_info.append(vnet_name)
|
||||||
|
rule_info.append(vnet_subscription_id)
|
||||||
|
rule_info.append(vnet_resource_group)
|
||||||
|
rule_info.append(vnet_location)
|
||||||
|
# add subnet details
|
||||||
|
rule_info.append(subnet.id.split("/")[-1])
|
||||||
|
rule_info.append(network_security_group_name)
|
||||||
|
rule_info.append(network_security_group_subscription_id)
|
||||||
|
rule_info.append(network_security_group_resource_group_name)
|
||||||
|
# add rule details
|
||||||
|
rule_info.append(rule.priority)
|
||||||
|
rule_info.append(rule.name)
|
||||||
|
rule_info.append(rule.source_address_prefix)
|
||||||
|
if rule.destination_port_range is not None:
|
||||||
|
rule_info.append(rule.destination_port_range)
|
||||||
|
else:
|
||||||
|
rule_info.append(rule.destination_port_ranges)
|
||||||
|
rule_info.append(rule.direction)
|
||||||
|
rule_info.append(rule.provisioning_state)
|
||||||
|
vnet_info.append(rule_info)
|
||||||
|
|
||||||
|
if check_rule_for_Azure_ML(rule) is True:
|
||||||
|
rule_matched = rule
|
||||||
|
|
||||||
|
if rule_matched is not None:
|
||||||
|
print("INFORMATION: Rule matched with required ports. Subnet:",
|
||||||
|
subnet.id.split("/")[-1], "Rule:", rule.name)
|
||||||
|
else:
|
||||||
|
print("WARNING: No rule matched with required ports. Subnet:",
|
||||||
|
subnet.id.split("/")[-1])
|
||||||
|
|
||||||
|
if save_to_file is True:
|
||||||
|
file_name = vnet_name + ".csv"
|
||||||
|
with open(file_name, mode='w') as vnet_rule_file:
|
||||||
|
vnet_rule_file_writer = csv.writer(
|
||||||
|
vnet_rule_file,
|
||||||
|
delimiter=',',
|
||||||
|
quotechar='"',
|
||||||
|
quoting=csv.QUOTE_MINIMAL)
|
||||||
|
header = ['VNet_Name', 'VNet_Subscription_ID',
|
||||||
|
'VNet_Resource_Group', 'VNet_Location',
|
||||||
|
'Subnet_Name', 'NSG_Name',
|
||||||
|
'NSG_Subscription_ID', 'NSG_Resource_Group',
|
||||||
|
'Rule_Priority', 'Rule_Name', 'Rule_Source',
|
||||||
|
'Rule_Destination_Ports', 'Rule_Direction',
|
||||||
|
'Rule_Provisioning_State']
|
||||||
|
vnet_rule_file_writer.writerow(header)
|
||||||
|
vnet_rule_file_writer.writerows(vnet_info)
|
||||||
|
|
||||||
|
print("INFORMATION: Network security group rules for your virtual \
|
||||||
|
network are saved in file", file_name)
|
||||||
@@ -23,17 +23,18 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
ray.init(address=args.ray_address)
|
ray.init(address=args.ray_address)
|
||||||
|
|
||||||
tune.run(run_or_experiment=args.run,
|
tune.run(
|
||||||
config={
|
run_or_experiment=args.run,
|
||||||
"env": args.env,
|
config={
|
||||||
"num_gpus": args.config["num_gpus"],
|
"env": args.env,
|
||||||
"num_workers": args.config["num_workers"],
|
"num_gpus": args.config["num_gpus"],
|
||||||
"callbacks": {"on_train_result": callbacks.on_train_result},
|
"num_workers": args.config["num_workers"],
|
||||||
"sample_batch_size": 50,
|
"callbacks": {"on_train_result": callbacks.on_train_result},
|
||||||
"train_batch_size": 1000,
|
"sample_batch_size": 50,
|
||||||
"num_sgd_iter": 2,
|
"train_batch_size": 1000,
|
||||||
"num_data_loader_buffers": 2,
|
"num_sgd_iter": 2,
|
||||||
"model": {"dim": 42},
|
"num_data_loader_buffers": 2,
|
||||||
},
|
"model": {"dim": 42},
|
||||||
stop=args.stop,
|
},
|
||||||
local_dir='./logs')
|
stop=args.stop,
|
||||||
|
local_dir='./logs')
|
||||||
|
|||||||
@@ -13,15 +13,15 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
""
|
""
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Azure ML Reinforcement Learning Sample - Pong problem\n",
|
"# Reinforcement Learning in Azure Machine Learning - Pong problem\n",
|
||||||
"Azure ML Reinforcement Learning (Azure ML RL) is a managed service for running distributed RL (reinforcement learning) simulation and training using the Ray framework.\n",
|
"Reinforcement Learning in Azure Machine Learning is a managed service for running distributed reinforcement learning training and simulation using the open source Ray framework.\n",
|
||||||
"This example uses Ray RLlib to train a Pong playing agent on a multi-node cluster.\n",
|
"This example uses Ray RLlib to train a Pong playing agent on a multi-node cluster.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"## Pong problem\n",
|
"## Pong problem\n",
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"The goal here is to train an agent to win an episode of Pong game against opponent with the score of at least 18 points. An episode in Pong runs until one of the players reaches a score of 21. Episodes are a terminology that is used across all the [OpenAI gym](https://gym.openai.com/envs/Pong-v0/) environments that contains a strictly defined task.\n",
|
"The goal here is to train an agent to win an episode of Pong game against opponent with the score of at least 18 points. An episode in Pong runs until one of the players reaches a score of 21. Episodes are a terminology that is used across all the [OpenAI gym](https://gym.openai.com/envs/Pong-v0/) environments that contains a strictly defined task.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Training a Pong agent is a CPU intensive task and this example demonstrates the use of Azure ML RL service to train an agent faster in a distributed, parallel environment. You'll learn more about using the head and the worker compute targets to train an agent in this notebook below."
|
"Training a Pong agent is a compute-intensive task and this example demonstrates the use of Reinforcement Learning in Azure Machine Learning service to train an agent faster in a distributed, parallel environment. You'll learn more about using the head and the worker compute targets to train an agent in this notebook below."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"## Prerequisite\n",
|
"## Prerequisite\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The user should have completed the [Azure ML Reinforcement Learning Sample - Setting Up Development Environment](../setup/devenv_setup.ipynb) to setup a virtual network. This virtual network will be used here for head and worker compute targets. It is highly recommended that the user should go through the [Azure ML Reinforcement Learning Sample - Cartpole Problem](../cartpole-on-single-compute/cartpole_cc.ipynb) to understand the basics of Azure ML RL and Ray RLlib used in this notebook."
|
"The user should have completed the [Reinforcement Learning in Azure Machine Learning - Setting Up Development Environment](../setup/devenv_setup.ipynb) to setup a virtual network. This virtual network will be used here for head and worker compute targets. It is highly recommended that the user should go through the [Reinforcement Learning in Azure Machine Learning - Cartpole Problem on Single Compute](../cartpole-on-single-compute/cartpole_sc.ipynb) to understand the basics of Reinforcement Learning in Azure Machine Learning and Ray RLlib used in this notebook."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"* Connecting to a workspace to enable communication between your local machine and remote resources\n",
|
"* Connecting to a workspace to enable communication between your local machine and remote resources\n",
|
||||||
"* Creating an experiment to track all your runs\n",
|
"* Creating an experiment to track all your runs\n",
|
||||||
"* Creating a remote head and worker compute target on a vnet to use for training"
|
"* Creating remote head and worker compute target on a virtual network to use for training"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -88,19 +88,19 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"%matplotlib inline\n",
|
"%matplotlib inline\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Azure ML core imports\n",
|
"# Azure Machine Learning core imports\n",
|
||||||
"import azureml.core\n",
|
"import azureml.core\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Check core SDK version number\n",
|
"# Check core SDK version number\n",
|
||||||
"print(\"Azure ML SDK Version: \", azureml.core.VERSION)"
|
"print(\"Azure Machine Learning SDK Version: \", azureml.core.VERSION)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Get Azure ML workspace\n",
|
"### Get Azure Machine Learning workspace\n",
|
||||||
"Get a reference to an existing Azure ML workspace."
|
"Get a reference to an existing Azure Machine Learning workspace."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Create Azure ML experiment\n",
|
"### Create Azure Machine Learning experiment\n",
|
||||||
"Create an experiment to track the runs in your workspace."
|
"Create an experiment to track the runs in your workspace."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -140,9 +140,9 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Specify the name of your vnet\n",
|
"### Specify the name of your virtual network\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The resource group you use must contain a vnet. Specify the name of the vnet here created in the [Azure ML Reinforcement Learning Sample - Setting Up Development Environment](../setup/devenv_setup.ipynb)."
|
"The resource group you use must contain a virtual network. Specify the name of the virtual network here created in the [Azure Machine Learning Reinforcement Learning Sample - Setting Up Development Environment](../setup/devenv_setup.ipynb)."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -159,9 +159,27 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Create head computing cluster\n",
|
"Ensure that the virtual network is configured correctly with required ports open. It is possible that you have configured rules with broader range of ports that allows ports 29876-29877 to be opened. Kindly review your network security group rules. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from files.networkutils import *\n",
|
||||||
"\n",
|
"\n",
|
||||||
"In this example, we show how to set up separate compute clusters for the Ray head and Ray worker nodes. First we define the head cluster with GPU for the Ray head node. One CPU of the head node will be used for the Ray head process and the rest of the CPUs will be used by the Ray worker processes."
|
"check_vnet_security_rules(ws._auth_object, ws.subscription_id, ws.resource_group, vnet_name, True)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Create head compute target\n",
|
||||||
|
"\n",
|
||||||
|
"In this example, we show how to set up separate compute targets for the Ray head and Ray worker nodes. First we define the head cluster with GPU for the Ray head node. One CPU of the head node will be used for the Ray head process and the rest of the CPUs will be used by the Ray worker processes."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -186,15 +204,17 @@
|
|||||||
" if head_compute_target.provisioning_state == 'Succeeded':\n",
|
" if head_compute_target.provisioning_state == 'Succeeded':\n",
|
||||||
" print('found head compute target. just use it', head_compute_name)\n",
|
" print('found head compute target. just use it', head_compute_name)\n",
|
||||||
" else: \n",
|
" else: \n",
|
||||||
" raise Exception('found head compute target but it is in state', head_compute_target.provisioning_state)\n",
|
" raise Exception(\n",
|
||||||
|
" 'found head compute target but it is in state', head_compute_target.provisioning_state)\n",
|
||||||
"else:\n",
|
"else:\n",
|
||||||
" print('creating a new head compute target...')\n",
|
" print('creating a new head compute target...')\n",
|
||||||
" provisioning_config = AmlCompute.provisioning_configuration(vm_size=head_vm_size,\n",
|
" provisioning_config = AmlCompute.provisioning_configuration(\n",
|
||||||
" min_nodes=head_compute_min_nodes, \n",
|
" vm_size=head_vm_size,\n",
|
||||||
" max_nodes=head_compute_max_nodes,\n",
|
" min_nodes=head_compute_min_nodes, \n",
|
||||||
" vnet_resourcegroup_name=ws.resource_group,\n",
|
" max_nodes=head_compute_max_nodes,\n",
|
||||||
" vnet_name=vnet_name,\n",
|
" vnet_resourcegroup_name=ws.resource_group,\n",
|
||||||
" subnet_name='default')\n",
|
" vnet_name=vnet_name,\n",
|
||||||
|
" subnet_name='default')\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Create the cluster\n",
|
" # Create the cluster\n",
|
||||||
" head_compute_target = ComputeTarget.create(ws, head_compute_name, provisioning_config)\n",
|
" head_compute_target = ComputeTarget.create(ws, head_compute_name, provisioning_config)\n",
|
||||||
@@ -203,7 +223,7 @@
|
|||||||
" # If no min node count is provided it will use the scale settings for the cluster\n",
|
" # If no min node count is provided it will use the scale settings for the cluster\n",
|
||||||
" head_compute_target.wait_for_completion(show_output=True, min_node_count=None, timeout_in_minutes=20)\n",
|
" head_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()\n",
|
" # For a more detailed view of current AmlCompute status, use get_status()\n",
|
||||||
" print(head_compute_target.get_status().serialize())"
|
" print(head_compute_target.get_status().serialize())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -211,9 +231,9 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Create worker computing cluster\n",
|
"### Create worker compute target\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Now we create a compute cluster with CPUs for the additional Ray worker nodes. CPUs in these worker nodes are used by Ray worker processes. Each Ray worker node may have multiple Ray worker processes depending on CPUs on the worker node. Ray can distribute multiple worker tasks on each worker node."
|
"Now we create a compute target with CPUs for the additional Ray worker nodes. CPUs in these worker nodes are used by Ray worker processes. Each Ray worker node, depending on the CPUs on the node, may have multiple Ray worker processes. There can be multiple worker tasks on each worker process (core)."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -222,7 +242,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Choose a name for your Ray worker cluster\n",
|
"# Choose a name for your Ray worker compute target\n",
|
||||||
"worker_compute_name = 'worker-cpu'\n",
|
"worker_compute_name = 'worker-cpu'\n",
|
||||||
"worker_compute_min_nodes = 0 \n",
|
"worker_compute_min_nodes = 0 \n",
|
||||||
"worker_compute_max_nodes = 4\n",
|
"worker_compute_max_nodes = 4\n",
|
||||||
@@ -237,24 +257,26 @@
|
|||||||
" if worker_compute_target.provisioning_state == 'Succeeded':\n",
|
" if worker_compute_target.provisioning_state == 'Succeeded':\n",
|
||||||
" print('found worker compute target. just use it', worker_compute_name)\n",
|
" print('found worker compute target. just use it', worker_compute_name)\n",
|
||||||
" else: \n",
|
" else: \n",
|
||||||
" raise Exception('found worker compute target but it is in state', head_compute_target.provisioning_state)\n",
|
" raise Exception(\n",
|
||||||
|
" 'found worker compute target but it is in state', head_compute_target.provisioning_state)\n",
|
||||||
"else:\n",
|
"else:\n",
|
||||||
" print('creating a new worker compute target...')\n",
|
" print('creating a new worker compute target...')\n",
|
||||||
" provisioning_config = AmlCompute.provisioning_configuration(vm_size=worker_vm_size,\n",
|
" provisioning_config = AmlCompute.provisioning_configuration(\n",
|
||||||
" min_nodes=worker_compute_min_nodes, \n",
|
" vm_size=worker_vm_size,\n",
|
||||||
" max_nodes=worker_compute_max_nodes,\n",
|
" min_nodes=worker_compute_min_nodes,\n",
|
||||||
" vnet_resourcegroup_name=ws.resource_group,\n",
|
" max_nodes=worker_compute_max_nodes,\n",
|
||||||
" vnet_name=vnet_name,\n",
|
" vnet_resourcegroup_name=ws.resource_group,\n",
|
||||||
" subnet_name='default')\n",
|
" vnet_name=vnet_name,\n",
|
||||||
|
" subnet_name='default')\n",
|
||||||
"\n",
|
"\n",
|
||||||
" # Create the cluster\n",
|
" # Create the compute target\n",
|
||||||
" worker_compute_target = ComputeTarget.create(ws, worker_compute_name, provisioning_config)\n",
|
" worker_compute_target = ComputeTarget.create(ws, worker_compute_name, provisioning_config)\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Can poll for a minimum number of nodes and for a specific timeout. \n",
|
" # Can poll for a minimum number of nodes and for a specific timeout. \n",
|
||||||
" # If no min node count is provided it will use the scale settings for the cluster\n",
|
" # If no min node count is provided it will use the scale settings for the cluster\n",
|
||||||
" worker_compute_target.wait_for_completion(show_output=True, min_node_count=None, timeout_in_minutes=20)\n",
|
" worker_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()\n",
|
" # For a more detailed view of current AmlCompute status, use get_status()\n",
|
||||||
" print(worker_compute_target.get_status().serialize())"
|
" print(worker_compute_target.get_status().serialize())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -262,12 +284,12 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Train Pong Agent Using Azure ML RL\n",
|
"## Train Pong Agent\n",
|
||||||
"To facilitate reinforcement learning, Azure Machine Learning Python SDK provides a high level abstraction, the _ReinforcementLearningEstimator_ class, which allows users to easily construct RL run configurations for the underlying RL framework. Azure ML RL initially supports the [Ray framework](https://ray.io/) and its highly customizable [RLLib](https://ray.readthedocs.io/en/latest/rllib.html#rllib-scalable-reinforcement-learning). In this section we show how to use _ReinforcementLearningEstimator_ and Ray/RLLib framework to train a Pong playing agent.\n",
|
"To facilitate reinforcement learning, Azure Machine Learning Python SDK provides a high level abstraction, the _ReinforcementLearningEstimator_ class, which allows users to easily construct reinforcement learning run configurations for the underlying reinforcement learning framework. Reinforcement Learning in Azure Machine Learning supports the open source [Ray framework](https://ray.io/) and its highly customizable [RLLib](https://ray.readthedocs.io/en/latest/rllib.html#rllib-scalable-reinforcement-learning). In this section we show how to use _ReinforcementLearningEstimator_ and Ray/RLLib framework to train a Pong playing agent.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"### Define worker configuration\n",
|
"### Define worker configuration\n",
|
||||||
"Define a `WorkerConfiguration` using your worker compute target. We also specify the number of nodes in the worker compute target to be used for training and additional PIP packages to install on those nodes as a part of setup.\n",
|
"Define a `WorkerConfiguration` using your worker compute target. We specify the number of nodes in the worker compute target to be used for training and additional PIP packages to install on those nodes as a part of setup.\n",
|
||||||
"In this case, we define the PIP packages as dependencies for both head and worker nodes. With this setup, the game simulations will run directly on the worker compute nodes."
|
"In this case, we define the PIP packages as dependencies for both head and worker nodes. With this setup, the game simulations will run directly on the worker compute nodes."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -285,7 +307,7 @@
|
|||||||
"# Specify the Ray worker configuration\n",
|
"# Specify the Ray worker configuration\n",
|
||||||
"worker_conf = WorkerConfiguration(\n",
|
"worker_conf = WorkerConfiguration(\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Azure ML compute cluster to run Ray workers\n",
|
" # Azure Machine Learning compute target to run Ray workers\n",
|
||||||
" compute_target=worker_compute_target, \n",
|
" compute_target=worker_compute_target, \n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Number of worker nodes\n",
|
" # Number of worker nodes\n",
|
||||||
@@ -305,7 +327,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"### Create reinforcement learning estimator\n",
|
"### Create reinforcement learning estimator\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The `ReinforcementLearningEstimator` is used to submit a job to Azure Machine Learning to start the Ray experiment run. We define the training script parameters here that will be passed to estimator. \n",
|
"The `ReinforcementLearningEstimator` is used to submit a job to Azure Machine Learning to start the Ray experiment run. We define the training script parameters here that will be passed to the estimator. \n",
|
||||||
"\n",
|
"\n",
|
||||||
"We specify `episode_reward_mean` to 18 as we want to stop the training as soon as the trained agent reaches an average win margin of at least 18 point over opponent over all episodes in the training epoch.\n",
|
"We specify `episode_reward_mean` to 18 as we want to stop the training as soon as the trained agent reaches an average win margin of at least 18 point over opponent over all episodes in the training epoch.\n",
|
||||||
"Number of Ray worker processes are defined by parameter `num_workers`. We set it to 13 as we have 13 CPUs available in our compute targets. Multiple Ray worker processes parallelizes agent training and helps in achieving our goal faster. \n",
|
"Number of Ray worker processes are defined by parameter `num_workers`. We set it to 13 as we have 13 CPUs available in our compute targets. Multiple Ray worker processes parallelizes agent training and helps in achieving our goal faster. \n",
|
||||||
@@ -348,7 +370,7 @@
|
|||||||
" \"--stop\": '\\'{\"episode_reward_mean\": 18, \"time_total_s\": 3600}\\'',\n",
|
" \"--stop\": '\\'{\"episode_reward_mean\": 18, \"time_total_s\": 3600}\\'',\n",
|
||||||
"}\n",
|
"}\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# RL estimator\n",
|
"# Reinforcement learning estimator\n",
|
||||||
"rl_estimator = ReinforcementLearningEstimator(\n",
|
"rl_estimator = ReinforcementLearningEstimator(\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Location of source files\n",
|
" # Location of source files\n",
|
||||||
@@ -361,7 +383,7 @@
|
|||||||
" # Defined above.\n",
|
" # Defined above.\n",
|
||||||
" script_params=script_params,\n",
|
" script_params=script_params,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # The Azure ML compute target set up for Ray head nodes\n",
|
" # The Azure Machine Learning compute target set up for Ray head nodes\n",
|
||||||
" compute_target=head_compute_target,\n",
|
" compute_target=head_compute_target,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Pip packages\n",
|
" # Pip packages\n",
|
||||||
@@ -370,7 +392,7 @@
|
|||||||
" # GPU usage\n",
|
" # GPU usage\n",
|
||||||
" use_gpu=True,\n",
|
" use_gpu=True,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # RL framework. Currently must be Ray.\n",
|
" # Reinforcement learning framework. Currently must be Ray.\n",
|
||||||
" rl_framework=Ray(),\n",
|
" rl_framework=Ray(),\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Ray worker configuration defined above.\n",
|
" # Ray worker configuration defined above.\n",
|
||||||
@@ -394,23 +416,24 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Training script\n",
|
"### Training script\n",
|
||||||
"As recommended in [RLLib](https://ray.readthedocs.io/en/latest/rllib.html) documentations, we use Ray [Tune](https://ray.readthedocs.io/en/latest/tune.html) API to run training algorithm. All the RLLib built-in trainers are compatible with the Tune API. Here we use tune.run() to execute a built-in training algorithm. For convenience, down below you can see part of the entry script where we make this call.\n",
|
"As recommended in [RLlib](https://ray.readthedocs.io/en/latest/rllib.html) documentations, we use Ray [Tune](https://ray.readthedocs.io/en/latest/tune.html) API to run the training algorithm. All the RLlib built-in trainers are compatible with the Tune API. Here we use tune.run() to execute a built-in training algorithm. For convenience, down below you can see part of the entry script where we make this call.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"```python\n",
|
"```python\n",
|
||||||
" tune.run(run_or_experiment=args.run,\n",
|
" tune.run(\n",
|
||||||
" config={\n",
|
" run_or_experiment=args.run,\n",
|
||||||
" \"env\": args.env,\n",
|
" config={\n",
|
||||||
" \"num_gpus\": args.config[\"num_gpus\"],\n",
|
" \"env\": args.env,\n",
|
||||||
" \"num_workers\": args.config[\"num_workers\"],\n",
|
" \"num_gpus\": args.config[\"num_gpus\"],\n",
|
||||||
" \"callbacks\": {\"on_train_result\": callbacks.on_train_result},\n",
|
" \"num_workers\": args.config[\"num_workers\"],\n",
|
||||||
" \"sample_batch_size\": 50,\n",
|
" \"callbacks\": {\"on_train_result\": callbacks.on_train_result},\n",
|
||||||
" \"train_batch_size\": 1000,\n",
|
" \"sample_batch_size\": 50,\n",
|
||||||
" \"num_sgd_iter\": 2,\n",
|
" \"train_batch_size\": 1000,\n",
|
||||||
" \"num_data_loader_buffers\": 2,\n",
|
" \"num_sgd_iter\": 2,\n",
|
||||||
" \"model\": {\"dim\": 42},\n",
|
" \"num_data_loader_buffers\": 2,\n",
|
||||||
" },\n",
|
" \"model\": {\"dim\": 42},\n",
|
||||||
" stop=args.stop,\n",
|
" },\n",
|
||||||
" local_dir='./logs')\n",
|
" stop=args.stop,\n",
|
||||||
|
" local_dir='./logs')\n",
|
||||||
"```"
|
"```"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -437,7 +460,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"### Monitor the run\n",
|
"### Monitor the run\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Azure ML provides a Jupyter widget to show the real-time status of an experiment run. You could use this widget to monitor the status of runs. The widget shows the list of two child runs, one for head compute target run and one for worker compute target run, as well. You can click on the link under Status to see the details of the child run."
|
"Azure Machine Learning provides a Jupyter widget to show the status of an experiment run. You could use this widget to monitor the status of the runs. The widget shows the list of two child runs, one for head compute target run and one for worker compute target run. You can click on the link under **Status** to see the details of the child run. It will also show the metrics being logged."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -455,9 +478,29 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
|
"### Stop the run\n",
|
||||||
|
"\n",
|
||||||
|
"To stop the run, call `run.cancel()`."
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# Uncomment line below to cancel the run\n",
|
||||||
|
"# run.cancel()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Wait for completion\n",
|
||||||
"Wait for the run to complete before proceeding. If you want to stop the run, you may skip this and move to next section below. \n",
|
"Wait for the run to complete before proceeding. If you want to stop the run, you may skip this and move to next section below. \n",
|
||||||
"\n",
|
"\n",
|
||||||
"**Note: the run may take anywhere from 30 minutes to 45 minutes to complete.**"
|
"**Note: The run may take anywhere from 30 minutes to 45 minutes to complete.**"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -469,24 +512,6 @@
|
|||||||
"run.wait_for_completion()"
|
"run.wait_for_completion()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"### Stop the run\n",
|
|
||||||
"\n",
|
|
||||||
"To cancel the run, call run.cancel()."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# run.cancel()"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
@@ -539,8 +564,8 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"We observe that during the training over multiple episodes, the agent learn to win the Pong game against opponent with our target of 18 points in each episode of 21 points.\n",
|
"We observe that during the training over multiple episodes, the agent learns to win the Pong game against opponent with our target of 18 points in each episode of 21 points.\n",
|
||||||
"**Congratulations!! You have trained your Pong agent to win a game marvelously.**"
|
"**Congratulations!! You have trained your Pong agent to win a game.**"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -570,7 +595,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Next\n",
|
"## Next\n",
|
||||||
"In this example, you learnt how to solve distributed RL training problems using head and worker compute targets. This is currently the last introductory tutorial for Azure Machine Learning service's Reinforcement Learning offering. We would love to hear your feedback to build the features you need!"
|
"In this example, you learned how to solve distributed reinforcement learning training problems using head and worker compute targets. This was an introductory tutorial on Reinforement Learning in Azure Machine Learning service offering. We would love to hear your feedback to build the features you need!"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -595,7 +620,7 @@
|
|||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.7.4"
|
"version": "3.6.9"
|
||||||
},
|
},
|
||||||
"notice": "Copyright (c) Microsoft Corporation. All rights reserved.\u00e2\u20ac\u00afLicensed under the MIT License.\u00e2\u20ac\u00af "
|
"notice": "Copyright (c) Microsoft Corporation. All rights reserved.\u00e2\u20ac\u00afLicensed under the MIT License.\u00e2\u20ac\u00af "
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,18 +13,18 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
""
|
""
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Azure ML Reinforcement Learning Sample - Cartpole Problem on Compute Instance\n",
|
"# Reinforcement Learning in Azure Machine Learning - Cartpole Problem on Compute Instance\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Azure ML Reinforcement Learning (Azure ML RL) is a managed service for running reinforcement learning training and simulation. With Azure MLRL, data scientists can start developing RL systems on one machine, and scale to compute clusters with 100\u00e2\u20ac\u2122s of nodes if needed.\n",
|
"Reinforcement Learning in Azure Machine Learning is a managed service for running reinforcement learning training and simulation. With Reinforcement Learning in Azure Machine Learning, data scientists can start developing reinforcement learning systems on one machine, and scale to compute targets with 100\u00e2\u20ac\u2122s of nodes if needed.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"This example shows how to use Azure ML RL to train a Cartpole playing agent on a compute instance."
|
"This example shows how to use Reinforcement Learning in Azure Machine Learning to train a Cartpole playing agent on a compute instance."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Prerequisite\n",
|
"### Prerequisite\n",
|
||||||
"The user should have completed the Azure Machine Learning Tutorial: [Get started creating your first ML experiment with the Python SDK](https://docs.microsoft.com/en-us/azure/machine-learning/tutorial-1st-experiment-sdk-setup). You will need to make sure that you have a valid subscription id, a resource group and a workspace. All datastores and datasets you use should be associated with your workspace."
|
"The user should have completed the Azure Machine Learning Tutorial: [Get started creating your first ML experiment with the Python SDK](https://docs.microsoft.com/en-us/azure/machine-learning/tutorial-1st-experiment-sdk-setup). You will need to make sure that you have a valid subscription ID, a resource group, and an Azure Machine Learning workspace. All datastores and datasets you use should be associated with your workspace."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -75,8 +75,8 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Azure ML SDK \n",
|
"### Azure Machine Learning SDK \n",
|
||||||
"Display the Azure ML SDK version."
|
"Display the Azure Machine Learning SDK version."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -86,15 +86,15 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"import azureml.core\n",
|
"import azureml.core\n",
|
||||||
"print(\"Azure ML SDK Version: \", azureml.core.VERSION)"
|
"print(\"Azure Machine Learning SDK Version: \", azureml.core.VERSION)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Get Azure ML workspace\n",
|
"### Get Azure Machine Learning workspace\n",
|
||||||
"Get a reference to an existing Azure ML workspace."
|
"Get a reference to an existing Azure Machine Learning workspace."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -161,21 +161,34 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
"from azureml.core.compute import ComputeTarget, ComputeInstance\n",
|
||||||
|
"from azureml.core.compute_target import ComputeTargetException\n",
|
||||||
|
"\n",
|
||||||
"# Load current compute instance info\n",
|
"# Load current compute instance info\n",
|
||||||
"current_compute_instance = load_nbvm()\n",
|
"current_compute_instance = load_nbvm()\n",
|
||||||
"print(\"Current compute instance:\", current_compute_instance)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"# For this demo, let's use the current compute instance as the compute target, if available\n",
|
"# For this demo, let's use the current compute instance as the compute target, if available\n",
|
||||||
"if current_compute_instance:\n",
|
"if current_compute_instance:\n",
|
||||||
|
" print(\"Current compute instance:\", current_compute_instance)\n",
|
||||||
" instance_name = current_compute_instance['instance']\n",
|
" instance_name = current_compute_instance['instance']\n",
|
||||||
"else:\n",
|
"else:\n",
|
||||||
" instance_name = next(iter(ws.compute_targets))\n",
|
" instance_name = \"cartpole-ci-stdd2v2\"\n",
|
||||||
|
" try:\n",
|
||||||
|
" instance = ComputeInstance(workspace=ws, name=instance_name)\n",
|
||||||
|
" print('Found existing instance, use it.')\n",
|
||||||
|
" except ComputeTargetException:\n",
|
||||||
|
" print(\"Creating new compute instance...\")\n",
|
||||||
|
" compute_config = ComputeInstance.provisioning_configuration(\n",
|
||||||
|
" vm_size='STANDARD_D2_V2'\n",
|
||||||
|
" )\n",
|
||||||
|
" instance = ComputeInstance.create(ws, instance_name, compute_config)\n",
|
||||||
|
" instance.wait_for_completion(show_output=True)\n",
|
||||||
|
" print(\"Instance name:\", instance_name)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"compute_target = ws.compute_targets[instance_name]\n",
|
"compute_target = ws.compute_targets[instance_name]\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"Compute target status:\")\n",
|
"print(\"Compute target status:\")\n",
|
||||||
"print(compute_target.get_status().serialize())\n",
|
"print(compute_target.get_status().serialize())\n",
|
||||||
"\n",
|
|
||||||
"print(\"Compute target size:\")\n",
|
"print(\"Compute target size:\")\n",
|
||||||
"print(compute_target.size(ws))"
|
"print(compute_target.size(ws))"
|
||||||
]
|
]
|
||||||
@@ -184,7 +197,7 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Create Azure ML experiment\n",
|
"### Create Azure Machine Learning experiment\n",
|
||||||
"Create an experiment to track the runs in your workspace. "
|
"Create an experiment to track the runs in your workspace. "
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -204,8 +217,8 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Train Cartpole Agent Using Azure ML RL\n",
|
"## Train Cartpole Agent\n",
|
||||||
"To facilitate reinforcement learning, Azure Machine Learning Python SDK provides a high level abstraction, the _ReinforcementLearningEstimator_ class, which allows users to easily construct RL run configurations for the underlying RL framework. Azure ML RL initially supports the [Ray framework](https://ray.io/) and its highly customizable [RLlib](https://ray.readthedocs.io/en/latest/rllib.html#rllib-scalable-reinforcement-learning). In this section we show how to use _ReinforcementLearningEstimator_ and Ray/RLlib framework to train a cartpole playing agent. "
|
"To facilitate reinforcement learning, Azure Machine Learning Python SDK provides a high level abstraction, the _ReinforcementLearningEstimator_ class, which allows users to easily construct reinforcement learning run configurations for the underlying reinforcement learning framework. Reinforcement Learning in Azure Machine Learning supports the open source [Ray framework](https://ray.io/) and its highly customizable [RLlib](https://ray.readthedocs.io/en/latest/rllib.html#rllib-scalable-reinforcement-learning). In this section we show how to use _ReinforcementLearningEstimator_ and Ray/RLlib framework to train a cartpole playing agent. "
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -222,7 +235,7 @@
|
|||||||
"- `entry_script`, path to your entry script relative to the source directory,\n",
|
"- `entry_script`, path to your entry script relative to the source directory,\n",
|
||||||
"- `script_params`, constant parameters to be passed to each run of training script,\n",
|
"- `script_params`, constant parameters to be passed to each run of training script,\n",
|
||||||
"- `compute_target`, reference to the compute target in which the trainer and worker(s) jobs will be executed,\n",
|
"- `compute_target`, reference to the compute target in which the trainer and worker(s) jobs will be executed,\n",
|
||||||
"- `rl_framework`, the RL framework to be used (currently must be Ray).\n",
|
"- `rl_framework`, the reinforcement learning framework to be used (currently must be Ray).\n",
|
||||||
"\n",
|
"\n",
|
||||||
"We use the `script_params` parameter to pass in general and algorithm-specific parameters to the training script.\n"
|
"We use the `script_params` parameter to pass in general and algorithm-specific parameters to the training script.\n"
|
||||||
]
|
]
|
||||||
@@ -273,10 +286,10 @@
|
|||||||
" # A dictionary of arguments to pass to the training script specified in ``entry_script``\n",
|
" # A dictionary of arguments to pass to the training script specified in ``entry_script``\n",
|
||||||
" script_params=script_params,\n",
|
" script_params=script_params,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # The Azure ML compute target set up for Ray head nodes\n",
|
" # The Azure Machine Learning compute target set up for Ray head nodes\n",
|
||||||
" compute_target=compute_target,\n",
|
" compute_target=compute_target,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # RL framework. Currently must be Ray.\n",
|
" # Reinforcement learning framework. Currently must be Ray.\n",
|
||||||
" rl_framework=Ray()\n",
|
" rl_framework=Ray()\n",
|
||||||
")"
|
")"
|
||||||
]
|
]
|
||||||
@@ -345,11 +358,11 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Monitor experiment\n",
|
"### Monitor experiment\n",
|
||||||
"Azure ML provides a Jupyter widget to show the real-time status of an experiment run. You could use this widget to monitor status of the runs.\n",
|
"Azure Machine Learning provides a Jupyter widget to show the status of an experiment run. You could use this widget to monitor the status of the runs.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Note that _ReinforcementLearningEstimator_ creates at least two runs: (a) A parent run, i.e. the run returned above, and (b) a collection of child runs. The number of the child runs depends on the configuration of the reinforcement learning estimator. In our simple scenario, configured above, only one child run will be created.\n",
|
"Note that _ReinforcementLearningEstimator_ creates at least two runs: (a) A parent run, i.e. the run returned above, and (b) a collection of child runs. The number of the child runs depends on the configuration of the reinforcement learning estimator. In our simple scenario, configured above, only one child run will be created.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The widget will show a list of the child runs as well. You can click on the link under **Status** to see the details of a child run."
|
"The widget will show a list of the child runs as well. You can click on the link under **Status** to see the details of a child run. It will also show the metrics being logged."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -369,7 +382,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"### Stop the run\n",
|
"### Stop the run\n",
|
||||||
"\n",
|
"\n",
|
||||||
"To cancel the run, call `training_run.cancel()`."
|
"To stop the run, call `training_run.cancel()`."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -577,10 +590,10 @@
|
|||||||
" training_artifacts_ds.as_named_input('artifacts_dataset'),\n",
|
" training_artifacts_ds.as_named_input('artifacts_dataset'),\n",
|
||||||
" training_artifacts_ds.as_named_input('artifacts_path').as_mount()],\n",
|
" training_artifacts_ds.as_named_input('artifacts_path').as_mount()],\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # The Azure ML compute target\n",
|
" # The Azure Machine Learning compute target\n",
|
||||||
" compute_target=compute_target,\n",
|
" compute_target=compute_target,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # RL framework. Currently must be Ray.\n",
|
" # Reinforcement learning framework. Currently must be Ray.\n",
|
||||||
" rl_framework=Ray(),\n",
|
" rl_framework=Ray(),\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Additional pip packages to install\n",
|
" # Additional pip packages to install\n",
|
||||||
@@ -654,7 +667,11 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# To archive the created experiment:\n",
|
"# To archive the created experiment:\n",
|
||||||
"#exp.archive()"
|
"#exp.archive()\n",
|
||||||
|
"\n",
|
||||||
|
"# To delete created compute instance\n",
|
||||||
|
"if not current_compute_instance:\n",
|
||||||
|
" compute_target.delete()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -662,7 +679,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Next\n",
|
"## Next\n",
|
||||||
"This example was about running Azure ML RL (Ray/RLlib Framework) on compute instance. Please see [Cartpole problem](../cartpole-on-single-compute/cartpole_cc.ipynb)\n",
|
"This example was about running Reinforcement Learning in Azure Machine Learning (Ray/RLlib Framework) on a compute instance. Please see [Cartpole Problem on Single Compute](../cartpole-on-single-compute/cartpole_sc.ipynb)\n",
|
||||||
"example which uses Ray RLlib to train a Cartpole playing agent on a single node remote compute.\n"
|
"example which uses Ray RLlib to train a Cartpole playing agent on a single node remote compute.\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ dependencies:
|
|||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- azureml-contrib-reinforcementlearning
|
- azureml-contrib-reinforcementlearning
|
||||||
- azureml-widgets
|
- azureml-widgets
|
||||||
|
- azureml-dataprep
|
||||||
|
|||||||
@@ -13,18 +13,18 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
""
|
""
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Azure ML Reinforcement Learning Sample - Cartpole Problem\n",
|
"# Reinforcement Learning in Azure Machine Learning - Cartpole Problem on Single Compute\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Azure ML Reinforcement Learning (Azure ML RL) is a managed service for running reinforcement learning training and simulation. With Azure MLRL, data scientists can start developing RL systems on one machine, and scale to compute clusters with 100\u00e2\u20ac\u2122s of nodes if needed.\n",
|
"Reinforcement Learning in Azure Machine Learning is a managed service for running reinforcement learning training and simulation. With Reinforcement Learning in Azure Machine Learning, data scientists can start developing reinforcement learning systems on one machine, and scale to compute targets with 100\u00e2\u20ac\u2122s of nodes if needed.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"This example shows how to use Azure ML RL to train a Cartpole playing agent on a single machine. "
|
"This example shows how to use Reinforcement Learning in Azure Machine Learning to train a Cartpole playing agent on a single compute. "
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Prerequisite\n",
|
"### Prerequisite\n",
|
||||||
"The user should have completed the Azure Machine Learning Tutorial: [Get started creating your first ML experiment with the Python SDK](https://docs.microsoft.com/en-us/azure/machine-learning/tutorial-1st-experiment-sdk-setup). You will need to make sure that you have a valid subscription id, a resource group and a workspace. All datastores and datasets you use should be associated with your workspace."
|
"The user should have completed the Azure Machine Learning Tutorial: [Get started creating your first ML experiment with the Python SDK](https://docs.microsoft.com/en-us/azure/machine-learning/tutorial-1st-experiment-sdk-setup). You will need to make sure that you have a valid subscription ID, a resource group, and an Azure Machine Learning workspace. All datastores and datasets you use should be associated with your workspace."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -75,8 +75,8 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Azure ML SDK \n",
|
"### Azure Machine Learning SDK \n",
|
||||||
"Display the Azure ML SDK version."
|
"Display the Azure Machine Learning SDK version."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -87,15 +87,15 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"import azureml.core\n",
|
"import azureml.core\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"Azure ML SDK Version: \", azureml.core.VERSION)"
|
"print(\"Azure Machine Learning SDK Version: \", azureml.core.VERSION)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Get Azure ML workspace\n",
|
"### Get Azure Machine Learning workspace\n",
|
||||||
"Get a reference to an existing Azure ML workspace."
|
"Get a reference to an existing Azure Machine Learning workspace."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"A compute target is a designated compute resource where you run your training and simulation scripts. This location may be your local machine or a cloud-based compute resource. The code below shows how to create a cloud-based compute target. For more information see [What are compute targets in Azure Machine Learning?](https://docs.microsoft.com/en-us/azure/machine-learning/concept-compute-target)\n",
|
"A compute target is a designated compute resource where you run your training and simulation scripts. This location may be your local machine or a cloud-based compute resource. The code below shows how to create a cloud-based compute target. For more information see [What are compute targets in Azure Machine Learning?](https://docs.microsoft.com/en-us/azure/machine-learning/concept-compute-target)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"**Note: Creation of a compute resource can take several minutes**"
|
"**Note: Creation of a compute resource can take several minutes**. Please make sure to change `STANDARD_D2_V2` to a [size available in your region](https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines)."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Create Azure ML experiment\n",
|
"### Create Azure Machine Learning experiment\n",
|
||||||
"Create an experiment to track the runs in your workspace. "
|
"Create an experiment to track the runs in your workspace. "
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"from azureml.core.experiment import Experiment\n",
|
"from azureml.core.experiment import Experiment\n",
|
||||||
"\n",
|
"\n",
|
||||||
"experiment_name = 'CartPole-v0-CC'\n",
|
"experiment_name = 'CartPole-v0-SC'\n",
|
||||||
"exp = Experiment(workspace=ws, name=experiment_name)"
|
"exp = Experiment(workspace=ws, name=experiment_name)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -178,8 +178,8 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Train Cartpole Agent Using Azure ML RL\n",
|
"## Train Cartpole Agent\n",
|
||||||
"To facilitate reinforcement learning, Azure Machine Learning Python SDK provides a high level abstraction, the _ReinforcementLearningEstimator_ class, which allows users to easily construct RL run configurations for the underlying RL framework. Azure ML RL initially supports the [Ray framework](https://ray.io/) and its highly customizable [RLlib](https://ray.readthedocs.io/en/latest/rllib.html#rllib-scalable-reinforcement-learning). In this section we show how to use _ReinforcementLearningEstimator_ and Ray/RLlib framework to train a cartpole playing agent. "
|
"To facilitate reinforcement learning, Azure Machine Learning Python SDK provides a high level abstraction, the _ReinforcementLearningEstimator_ class, which allows users to easily construct reinforcement learning run configurations for the underlying reinforcement learning framework. Reinforcement Learning in Azure Machine Learning supports the open source [Ray framework](https://ray.io/) and its highly customizable [RLlib](https://ray.readthedocs.io/en/latest/rllib.html#rllib-scalable-reinforcement-learning). In this section we show how to use _ReinforcementLearningEstimator_ and Ray/RLlib framework to train a cartpole playing agent. "
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -196,7 +196,7 @@
|
|||||||
"- `entry_script`, path to your entry script relative to the source directory,\n",
|
"- `entry_script`, path to your entry script relative to the source directory,\n",
|
||||||
"- `script_params`, constant parameters to be passed to each run of training script,\n",
|
"- `script_params`, constant parameters to be passed to each run of training script,\n",
|
||||||
"- `compute_target`, reference to the compute target in which the trainer and worker(s) jobs will be executed,\n",
|
"- `compute_target`, reference to the compute target in which the trainer and worker(s) jobs will be executed,\n",
|
||||||
"- `rl_framework`, the RL framework to be used (currently must be Ray).\n",
|
"- `rl_framework`, the reinforcement learning framework to be used (currently must be Ray).\n",
|
||||||
"\n",
|
"\n",
|
||||||
"We use the `script_params` parameter to pass in general and algorithm-specific parameters to the training script.\n"
|
"We use the `script_params` parameter to pass in general and algorithm-specific parameters to the training script.\n"
|
||||||
]
|
]
|
||||||
@@ -249,7 +249,7 @@
|
|||||||
" # There are two parts to this:\n",
|
" # There are two parts to this:\n",
|
||||||
" # 1. Use a custom docker file with proper instructions to install xvfb, ffmpeg, python-opengl\n",
|
" # 1. Use a custom docker file with proper instructions to install xvfb, ffmpeg, python-opengl\n",
|
||||||
" # and other dependencies. \n",
|
" # and other dependencies. \n",
|
||||||
" # TODO: Add these instructions to default rl base image and drop this docker file.\n",
|
" # TODO: Add these instructions to default reinforcement learning base image and drop this docker file.\n",
|
||||||
" \n",
|
" \n",
|
||||||
" with open(\"files/docker/Dockerfile\", \"r\") as f:\n",
|
" with open(\"files/docker/Dockerfile\", \"r\") as f:\n",
|
||||||
" dockerfile=f.read()\n",
|
" dockerfile=f.read()\n",
|
||||||
@@ -274,10 +274,10 @@
|
|||||||
" # A dictionary of arguments to pass to the training script specified in ``entry_script``\n",
|
" # A dictionary of arguments to pass to the training script specified in ``entry_script``\n",
|
||||||
" script_params=script_params,\n",
|
" script_params=script_params,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # The Azure ML compute target set up for Ray head nodes\n",
|
" # The Azure Machine Learning compute target set up for Ray head nodes\n",
|
||||||
" compute_target=compute_target,\n",
|
" compute_target=compute_target,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # RL framework. Currently must be Ray.\n",
|
" # Reinforcement learning framework. Currently must be Ray.\n",
|
||||||
" rl_framework=Ray(),\n",
|
" rl_framework=Ray(),\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Custom environmnet for Xvfb\n",
|
" # Custom environmnet for Xvfb\n",
|
||||||
@@ -350,11 +350,11 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"### Monitor experiment\n",
|
"### Monitor experiment\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Azure ML provides a Jupyter widget to show the real-time status of an experiment run. You could use this widget to monitor status of the runs.\n",
|
"Azure Machine Learning provides a Jupyter widget to show the status of an experiment run. You could use this widget to monitor the status of the runs.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Note that _ReinforcementLearningEstimator_ creates at least two runs: (a) A parent run, i.e. the run returned above, and (b) a collection of child runs. The number of the child runs depends on the configuration of the reinforcement learning estimator. In our simple scenario, configured above, only one child run will be created.\n",
|
"Note that _ReinforcementLearningEstimator_ creates at least two runs: (a) A parent run, i.e. the run returned above, and (b) a collection of child runs. The number of the child runs depends on the configuration of the reinforcement learning estimator. In our simple scenario, configured above, only one child run will be created.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The widget will show a list of the child runs as well. You can click on the link under **Status** to see the details of a child run."
|
"The widget will show a list of the child runs as well. You can click on the link under **Status** to see the details of a child run. It will also show the metrics being logged."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -373,7 +373,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Stop the run\n",
|
"### Stop the run\n",
|
||||||
"To cancel the run, call `training_run.cancel()`."
|
"To stop the run, call `training_run.cancel()`."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -393,7 +393,7 @@
|
|||||||
"### Wait for completion\n",
|
"### Wait for completion\n",
|
||||||
"Wait for the run to complete before proceeding.\n",
|
"Wait for the run to complete before proceeding.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"**Note: The length of the run depends on the provisioning time of the compute target and may take several minutes to complete.**"
|
"**Note: The length of the run depends on the provisioning time of the compute target and it may take several minutes to complete.**"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -560,18 +560,20 @@
|
|||||||
" dir_util.mkpath(destination)\n",
|
" dir_util.mkpath(destination)\n",
|
||||||
" \n",
|
" \n",
|
||||||
" try:\n",
|
" try:\n",
|
||||||
" # Mount dataset and copy movies\n",
|
" pirnt(\"Trying mounting dataset and copying movies.\")\n",
|
||||||
" # Note: We assume movie paths start with '\\'\n",
|
" # Note: We assume movie paths start with '\\'\n",
|
||||||
" mount_context = artifacts_ds.mount()\n",
|
" mount_context = artifacts_ds.mount()\n",
|
||||||
" mount_context.start()\n",
|
" mount_context.start()\n",
|
||||||
" print('Download started.')\n",
|
|
||||||
" for movie in movies:\n",
|
" for movie in movies:\n",
|
||||||
" print('Copying {} ...'.format(movie))\n",
|
" print('Copying {} ...'.format(movie))\n",
|
||||||
" shutil.copy2(path.join(mount_context.mount_point, movie[1:]), destination)\n",
|
" shutil.copy2(path.join(mount_context.mount_point, movie[1:]), destination)\n",
|
||||||
" mount_context.stop()\n",
|
" mount_context.stop()\n",
|
||||||
" except:\n",
|
" except:\n",
|
||||||
" print(\"Mounting error! Downloading all artifacts ...\")\n",
|
" print(\"Mounting failed! Going with dataset download.\")\n",
|
||||||
" artifacts_ds.download(target_path=destination, overwrite=True)\n",
|
" for i, file in enumerate(artifacts_ds.to_path()):\n",
|
||||||
|
" if file in movies:\n",
|
||||||
|
" print('Downloading {} ...'.format(file))\n",
|
||||||
|
" artifacts_ds.skip(i).take(1).download(target_path=destination, overwrite=True)\n",
|
||||||
" \n",
|
" \n",
|
||||||
" print('Downloading movies completed!')\n",
|
" print('Downloading movies completed!')\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -625,7 +627,7 @@
|
|||||||
"print(\"Last movie:\", last_movie)\n",
|
"print(\"Last movie:\", last_movie)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Download movies\n",
|
"# Download movies\n",
|
||||||
"training_movies_path = \"training\"\n",
|
"training_movies_path = path.join(\"training\", \"videos\")\n",
|
||||||
"download_movies(training_artifacts_ds, [first_movie, last_movie], training_movies_path)"
|
"download_movies(training_artifacts_ds, [first_movie, last_movie], training_movies_path)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -781,7 +783,7 @@
|
|||||||
"# 1. Use a custom docker file with proper instructions to install xvfb, ffmpeg, python-opengl\n",
|
"# 1. Use a custom docker file with proper instructions to install xvfb, ffmpeg, python-opengl\n",
|
||||||
"# and other dependencies.\n",
|
"# and other dependencies.\n",
|
||||||
"# Note: Even when the rendering is off pyhton-opengl is needed.\n",
|
"# Note: Even when the rendering is off pyhton-opengl is needed.\n",
|
||||||
"# TODO: Add these instructions to default rl base image and drop this docker file.\n",
|
"# TODO: Add these instructions to default reinforcement learning base image and drop this docker file.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"with open(\"files/docker/Dockerfile\", \"r\") as f:\n",
|
"with open(\"files/docker/Dockerfile\", \"r\") as f:\n",
|
||||||
" dockerfile=f.read()\n",
|
" dockerfile=f.read()\n",
|
||||||
@@ -811,10 +813,10 @@
|
|||||||
" training_artifacts_ds.as_named_input('artifacts_dataset'),\n",
|
" training_artifacts_ds.as_named_input('artifacts_dataset'),\n",
|
||||||
" training_artifacts_ds.as_named_input('artifacts_path').as_mount()],\n",
|
" training_artifacts_ds.as_named_input('artifacts_path').as_mount()],\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # The Azure ML compute target set up for Ray head nodes\n",
|
" # The Azure Machine Learning compute target set up for Ray head nodes\n",
|
||||||
" compute_target=compute_target,\n",
|
" compute_target=compute_target,\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # RL framework. Currently must be Ray.\n",
|
" # Reinforcement learning framework. Currently must be Ray.\n",
|
||||||
" rl_framework=Ray(),\n",
|
" rl_framework=Ray(),\n",
|
||||||
" \n",
|
" \n",
|
||||||
" # Custom environmnet for Xvfb\n",
|
" # Custom environmnet for Xvfb\n",
|
||||||
@@ -928,7 +930,7 @@
|
|||||||
"print(\"Last movie:\", last_movie)\n",
|
"print(\"Last movie:\", last_movie)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Download last movie\n",
|
"# Download last movie\n",
|
||||||
"rollout_movies_path = \"rollout\"\n",
|
"rollout_movies_path = path.join(\"rollout\", \"videos\")\n",
|
||||||
"download_movies(rollout_artifacts_ds, [last_movie], rollout_movies_path)\n",
|
"download_movies(rollout_artifacts_ds, [last_movie], rollout_movies_path)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Look for the downloaded movie in local directory\n",
|
"# Look for the downloaded movie in local directory\n",
|
||||||
@@ -996,7 +998,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Next\n",
|
"## Next\n",
|
||||||
"This example was about running Azure ML RL (Ray/RLlib Framework) on a single node. Please see [Pong problem](../atari-on-distributed-compute/pong_rllib.ipynb)\n",
|
"This example was about running Reinforcement Learning in Azure Machine Learning (Ray/RLlib Framework) on a single compute. Please see [Pong Problem](../atari-on-distributed-compute/pong_rllib.ipynb)\n",
|
||||||
"example which uses Ray RLlib to train a Pong playing agent on a multi-node cluster."
|
"example which uses Ray RLlib to train a Pong playing agent on a multi-node cluster."
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
name: cartpole_cc
|
name: cartpole_sc
|
||||||
dependencies:
|
dependencies:
|
||||||
- pip:
|
- pip:
|
||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- azureml-contrib-reinforcementlearning
|
- azureml-contrib-reinforcementlearning
|
||||||
- azureml-widgets
|
- azureml-widgets
|
||||||
|
- azureml-dataprep
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
import ray
|
import ray
|
||||||
import ray.tune as tune
|
import ray.tune as tune
|
||||||
|
|
||||||
@@ -6,8 +8,10 @@ from minecraft_environment import create_env
|
|||||||
|
|
||||||
|
|
||||||
def stop(trial_id, result):
|
def stop(trial_id, result):
|
||||||
|
max_train_time = int(os.environ.get("AML_MAX_TRAIN_TIME_SECONDS", 5 * 60 * 60))
|
||||||
|
|
||||||
return result["episode_reward_mean"] >= 1 \
|
return result["episode_reward_mean"] >= 1 \
|
||||||
or result["time_total_s"] > 5 * 60 * 60
|
or result["time_total_s"] >= max_train_time
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
@@ -110,7 +110,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"import azureml.core\n",
|
"import azureml.core\n",
|
||||||
"print(\"Azure Machine Learning SDK Version: \", azureml.core.VERSION)"
|
"print(\"Azure Machine Learning SDK Version: \", azureml.core.VERSION) "
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -209,7 +209,7 @@
|
|||||||
"# name of the Virtual Network subnet ('default' the default name)\n",
|
"# name of the Virtual Network subnet ('default' the default name)\n",
|
||||||
"subnet_name = 'default'\n",
|
"subnet_name = 'default'\n",
|
||||||
"\n",
|
"\n",
|
||||||
"gpu_cluster_name = 'gpu-cluster-nc6'\n",
|
"gpu_cluster_name = 'gpu-cl-nc6-vnet'\n",
|
||||||
"\n",
|
"\n",
|
||||||
"try:\n",
|
"try:\n",
|
||||||
" gpu_cluster = ComputeTarget(workspace=ws, name=gpu_cluster_name)\n",
|
" gpu_cluster = ComputeTarget(workspace=ws, name=gpu_cluster_name)\n",
|
||||||
@@ -250,7 +250,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"cpu_cluster_name = 'cpu-cluster-d2'\n",
|
"cpu_cluster_name = 'cpu-cl-d2-vnet'\n",
|
||||||
"\n",
|
"\n",
|
||||||
"try:\n",
|
"try:\n",
|
||||||
" cpu_cluster = ComputeTarget(workspace=ws, name=cpu_cluster_name)\n",
|
" cpu_cluster = ComputeTarget(workspace=ws, name=cpu_cluster_name)\n",
|
||||||
@@ -297,8 +297,11 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
"import os\n",
|
||||||
"from azureml.core import Environment\n",
|
"from azureml.core import Environment\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"max_train_time = os.environ.get(\"AML_MAX_TRAIN_TIME_SECONDS\", 5 * 60 * 60)\n",
|
||||||
|
"\n",
|
||||||
"def create_env(env_type):\n",
|
"def create_env(env_type):\n",
|
||||||
" env = Environment(name='minecraft-{env_type}'.format(env_type=env_type))\n",
|
" env = Environment(name='minecraft-{env_type}'.format(env_type=env_type))\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -306,6 +309,7 @@
|
|||||||
" env.docker.base_image = 'akdmsft/minecraft-{env_type}'.format(env_type=env_type)\n",
|
" env.docker.base_image = 'akdmsft/minecraft-{env_type}'.format(env_type=env_type)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" env.python.interpreter_path = \"xvfb-run -s '-screen 0 640x480x16 -ac +extension GLX +render' python\"\n",
|
" env.python.interpreter_path = \"xvfb-run -s '-screen 0 640x480x16 -ac +extension GLX +render' python\"\n",
|
||||||
|
" env.environment_variables[\"AML_MAX_TRAIN_TIME_SECONDS\"] = str(max_train_time)\n",
|
||||||
" env.python.user_managed_dependencies = True\n",
|
" env.python.user_managed_dependencies = True\n",
|
||||||
" \n",
|
" \n",
|
||||||
" return env\n",
|
" return env\n",
|
||||||
@@ -590,7 +594,6 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"import re\n",
|
"import re\n",
|
||||||
"import os\n",
|
|
||||||
"import tempfile\n",
|
"import tempfile\n",
|
||||||
"\n",
|
"\n",
|
||||||
"from azureml.core import Dataset\n",
|
"from azureml.core import Dataset\n",
|
||||||
|
|||||||
@@ -13,14 +13,14 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
""
|
""
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Azure ML Reinforcement Learning Sample - Setting Up Development Environment\n",
|
"# Reinforcement Learning in Azure Machine Learning - Setting Up Development Environment\n",
|
||||||
"\n",
|
"\n",
|
||||||
"Ray multi-node cluster setup requires all worker nodes to be able to communicate with the head node. This notebook explains you how to setup a virtual network, to be used by the Ray head and worker compute targets, created and used in other notebook examples."
|
"Ray multi-node cluster setup requires all worker nodes to be able to communicate with the head node. This notebook explains you how to setup a virtual network, to be used by the Ray head and worker compute targets, created and used in other notebook examples."
|
||||||
]
|
]
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"### Prerequisite\n",
|
"### Prerequisite\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The user should have completed the Azure Machine Learning Tutorial: [Get started creating your first ML experiment with the Python SDK](https://docs.microsoft.com/en-us/azure/machine-learning/tutorial-1st-experiment-sdk-setup). You will need to make sure that you have a valid subscription id, a resource group and a workspace."
|
"The user should have completed the Azure Machine Learning Tutorial: [Get started creating your first ML experiment with the Python SDK](https://docs.microsoft.com/en-us/azure/machine-learning/tutorial-1st-experiment-sdk-setup). You will need to make sure that you have a valid subscription ID, a resource group, and an Azure Machine Learning workspace."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -48,19 +48,17 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Azure ML Core imports\n",
|
|
||||||
"import azureml.core\n",
|
"import azureml.core\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Check core SDK version number\n",
|
"print(\"Azure Machine Learning SDK Version: \", azureml.core.VERSION)"
|
||||||
"print(\"Azure ML SDK Version: \", azureml.core.VERSION)"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"### Get Azure ML workspace\n",
|
"### Get Azure Machine Learning workspace\n",
|
||||||
"Get a reference to an existing Azure ML workspace. Please make sure that the VM sizes `STANDARD_NC6` and `STANDARD_D2_V2` are supported in the workspace's region.\n"
|
"Get a reference to an existing Azure Machine Learning workspace. Please make sure to change `STANDARD_NC6` and `STANDARD_D2_V2` to [the ones available in your region](https://azure.microsoft.com/en-us/global-infrastructure/services/?products=virtual-machines).\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -72,7 +70,7 @@
|
|||||||
"from azureml.core import Workspace\n",
|
"from azureml.core import Workspace\n",
|
||||||
"\n",
|
"\n",
|
||||||
"ws = Workspace.from_config()\n",
|
"ws = Workspace.from_config()\n",
|
||||||
"print(ws.name, ws.location, ws.resource_group, sep = ' | ') "
|
"print(ws.name, ws.location, ws.resource_group, sep = ' | ')"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -115,7 +113,7 @@
|
|||||||
"# The Azure subscription you are using\n",
|
"# The Azure subscription you are using\n",
|
||||||
"subscription_id=ws.subscription_id\n",
|
"subscription_id=ws.subscription_id\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# The resource group for the RL cluster\n",
|
"# The resource group for the reinforcement learning cluster\n",
|
||||||
"resource_group=ws.resource_group\n",
|
"resource_group=ws.resource_group\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# Azure region of the resource group\n",
|
"# Azure region of the resource group\n",
|
||||||
@@ -135,7 +133,7 @@
|
|||||||
")\n",
|
")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"async_vnet_creation.wait()\n",
|
"async_vnet_creation.wait()\n",
|
||||||
"print(\"VNet created successfully: \", async_vnet_creation.result())"
|
"print(\"Virtual network created successfully: \", async_vnet_creation.result())"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -169,7 +167,7 @@
|
|||||||
" azure.mgmt.network.models.SecurityRule(\n",
|
" azure.mgmt.network.models.SecurityRule(\n",
|
||||||
" name=security_rule_name,\n",
|
" name=security_rule_name,\n",
|
||||||
" access=azure.mgmt.network.models.SecurityRuleAccess.allow,\n",
|
" access=azure.mgmt.network.models.SecurityRuleAccess.allow,\n",
|
||||||
" description='Azure ML RL rule',\n",
|
" description='Reinforcement Learning in Azure Machine Learning rule',\n",
|
||||||
" destination_address_prefix='*',\n",
|
" destination_address_prefix='*',\n",
|
||||||
" destination_port_range='29876-29877',\n",
|
" destination_port_range='29876-29877',\n",
|
||||||
" direction=azure.mgmt.network.models.SecurityRuleDirection.inbound,\n",
|
" direction=azure.mgmt.network.models.SecurityRuleDirection.inbound,\n",
|
||||||
@@ -188,7 +186,7 @@
|
|||||||
")\n",
|
")\n",
|
||||||
"\n",
|
"\n",
|
||||||
"async_nsg_creation.wait() \n",
|
"async_nsg_creation.wait() \n",
|
||||||
"print(\"Network security group created successfully: \", async_nsg_creation.result())\n",
|
"print(\"Network security group created successfully:\", async_nsg_creation.result())\n",
|
||||||
"\n",
|
"\n",
|
||||||
"network_security_group = network_client.network_security_groups.get(\n",
|
"network_security_group = network_client.network_security_groups.get(\n",
|
||||||
" resource_group,\n",
|
" resource_group,\n",
|
||||||
@@ -202,7 +200,7 @@
|
|||||||
" network_security_group=network_security_group\n",
|
" network_security_group=network_security_group\n",
|
||||||
" )\n",
|
" )\n",
|
||||||
" \n",
|
" \n",
|
||||||
"# Create subnet on vnet\n",
|
"# Create subnet on virtual network\n",
|
||||||
"async_subnet_creation = network_client.subnets.create_or_update(\n",
|
"async_subnet_creation = network_client.subnets.create_or_update(\n",
|
||||||
" resource_group_name=resource_group,\n",
|
" resource_group_name=resource_group,\n",
|
||||||
" virtual_network_name=vnet_name,\n",
|
" virtual_network_name=vnet_name,\n",
|
||||||
@@ -213,6 +211,25 @@
|
|||||||
"async_subnet_creation.wait()\n",
|
"async_subnet_creation.wait()\n",
|
||||||
"print(\"Subnet created successfully:\", async_subnet_creation.result())"
|
"print(\"Subnet created successfully:\", async_subnet_creation.result())"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"### Review the virtual network security rules\n",
|
||||||
|
"Ensure that the virtual network is configured correctly with required ports open. It is possible that you have configured rules with broader range of ports that allows ports 29876-29877 to be opened. Kindly review your network security group rules. "
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"from files.networkutils import *\n",
|
||||||
|
"\n",
|
||||||
|
"check_vnet_security_rules(ws._auth_object, ws.subscription_id, ws.resource_group, vnet_name, True)"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
|
|||||||
@@ -0,0 +1,237 @@
|
|||||||
|
import sys
|
||||||
|
import csv
|
||||||
|
from azure.mgmt.network import NetworkManagementClient
|
||||||
|
|
||||||
|
|
||||||
|
def check_port_in_port_range(expected_port: str,
|
||||||
|
dest_port_range: str):
|
||||||
|
"""
|
||||||
|
Check if a port is within a port range
|
||||||
|
Port range maybe like *, 8080 or 8888-8889
|
||||||
|
"""
|
||||||
|
|
||||||
|
if dest_port_range == '*':
|
||||||
|
return True
|
||||||
|
|
||||||
|
dest_ports = dest_port_range.split('-')
|
||||||
|
|
||||||
|
if len(dest_ports) == 1 and \
|
||||||
|
int(dest_ports[0]) == int(expected_port):
|
||||||
|
return True
|
||||||
|
|
||||||
|
if len(dest_ports) == 2 and \
|
||||||
|
int(dest_ports[0]) <= int(expected_port) and \
|
||||||
|
int(dest_ports[1]) >= int(expected_port):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_port_in_destination_port_ranges(expected_port: str,
|
||||||
|
dest_port_ranges: list):
|
||||||
|
"""
|
||||||
|
Check if a port is within a given list of port ranges
|
||||||
|
i.e. check if port 8080 is in port ranges of 22,80,8080-8090,443
|
||||||
|
"""
|
||||||
|
|
||||||
|
for dest_port_range in dest_port_ranges:
|
||||||
|
if check_port_in_port_range(expected_port, dest_port_range) is True:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_ports_in_destination_port_ranges(expected_ports: list,
|
||||||
|
dest_port_ranges: list):
|
||||||
|
"""
|
||||||
|
Check if all ports in a given port list are within a given list
|
||||||
|
of port ranges
|
||||||
|
i.e. check if port 8080,8081 are in port ranges of 22,80,8080-8090,443
|
||||||
|
"""
|
||||||
|
|
||||||
|
for expected_port in expected_ports:
|
||||||
|
if check_port_in_destination_port_ranges(
|
||||||
|
expected_port, dest_port_ranges) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_source_address_prefix(source_address_prefix: str):
|
||||||
|
"""Check if source address prefix is BatchNodeManagement or default"""
|
||||||
|
|
||||||
|
required_prefix = 'BatchNodeManagement'
|
||||||
|
default_prefix = 'default'
|
||||||
|
|
||||||
|
if source_address_prefix.lower() == required_prefix.lower() or \
|
||||||
|
source_address_prefix.lower() == default_prefix.lower():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_protocol(protocol: str):
|
||||||
|
"""Check if protocol is supported - Tcp/Any"""
|
||||||
|
|
||||||
|
required_protocol = 'Tcp'
|
||||||
|
any_protocol = 'Any'
|
||||||
|
|
||||||
|
if required_protocol.lower() == protocol.lower() or \
|
||||||
|
any_protocol.lower() == protocol.lower():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_direction(direction: str):
|
||||||
|
"""Check if port direction is inbound"""
|
||||||
|
|
||||||
|
required_direction = 'Inbound'
|
||||||
|
|
||||||
|
if required_direction.lower() == direction.lower():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_provisioning_state(provisioning_state: str):
|
||||||
|
"""Check if the provisioning state is succeeded"""
|
||||||
|
|
||||||
|
required_provisioning_state = 'Succeeded'
|
||||||
|
|
||||||
|
if required_provisioning_state.lower() == provisioning_state.lower():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def check_rule_for_Azure_ML(rule):
|
||||||
|
"""Check if the ports required for Azure Machine Learning are open"""
|
||||||
|
|
||||||
|
required_ports = ['29876', '29877']
|
||||||
|
|
||||||
|
if check_source_address_prefix(rule.source_address_prefix) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if check_protocol(rule.protocol) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if check_direction(rule.direction) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if check_provisioning_state(rule.provisioning_state) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if rule.destination_port_range is not None:
|
||||||
|
if check_ports_in_destination_port_ranges(
|
||||||
|
required_ports,
|
||||||
|
[rule.destination_port_range]) is False:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if check_ports_in_destination_port_ranges(
|
||||||
|
required_ports,
|
||||||
|
rule.destination_port_ranges) is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def check_vnet_security_rules(auth_object,
|
||||||
|
vnet_subscription_id,
|
||||||
|
vnet_resource_group,
|
||||||
|
vnet_name,
|
||||||
|
save_to_file=False):
|
||||||
|
"""
|
||||||
|
Check all the rules of virtual network if required ports for Azure Machine
|
||||||
|
Learning are open
|
||||||
|
"""
|
||||||
|
|
||||||
|
network_client = NetworkManagementClient(
|
||||||
|
auth_object,
|
||||||
|
vnet_subscription_id)
|
||||||
|
|
||||||
|
# get the vnet
|
||||||
|
vnet = network_client.virtual_networks.get(
|
||||||
|
resource_group_name=vnet_resource_group,
|
||||||
|
virtual_network_name=vnet_name)
|
||||||
|
|
||||||
|
vnet_location = vnet.location
|
||||||
|
vnet_info = []
|
||||||
|
|
||||||
|
if vnet.subnets is None or len(vnet.subnets) == 0:
|
||||||
|
print('WARNING: No subnet found for VNet:', vnet_name)
|
||||||
|
|
||||||
|
# for each subnet of the vnet
|
||||||
|
for subnet in vnet.subnets:
|
||||||
|
if subnet.network_security_group is None:
|
||||||
|
print('WARNING: No network security group found for subnet.',
|
||||||
|
'Subnet',
|
||||||
|
subnet.id.split("/")[-1])
|
||||||
|
else:
|
||||||
|
# get all the rules
|
||||||
|
network_security_group_name = \
|
||||||
|
subnet.network_security_group.id.split("/")[-1]
|
||||||
|
network_security_group_resource_group_name = \
|
||||||
|
subnet.network_security_group.id.split("/")[4]
|
||||||
|
network_security_group_subscription_id = \
|
||||||
|
subnet.network_security_group.id.split("/")[2]
|
||||||
|
|
||||||
|
security_rules = list(network_client.security_rules.list(
|
||||||
|
network_security_group_resource_group_name,
|
||||||
|
network_security_group_name))
|
||||||
|
|
||||||
|
rule_matched = None
|
||||||
|
for rule in security_rules:
|
||||||
|
rule_info = []
|
||||||
|
# add vnet details
|
||||||
|
rule_info.append(vnet_name)
|
||||||
|
rule_info.append(vnet_subscription_id)
|
||||||
|
rule_info.append(vnet_resource_group)
|
||||||
|
rule_info.append(vnet_location)
|
||||||
|
# add subnet details
|
||||||
|
rule_info.append(subnet.id.split("/")[-1])
|
||||||
|
rule_info.append(network_security_group_name)
|
||||||
|
rule_info.append(network_security_group_subscription_id)
|
||||||
|
rule_info.append(network_security_group_resource_group_name)
|
||||||
|
# add rule details
|
||||||
|
rule_info.append(rule.priority)
|
||||||
|
rule_info.append(rule.name)
|
||||||
|
rule_info.append(rule.source_address_prefix)
|
||||||
|
if rule.destination_port_range is not None:
|
||||||
|
rule_info.append(rule.destination_port_range)
|
||||||
|
else:
|
||||||
|
rule_info.append(rule.destination_port_ranges)
|
||||||
|
rule_info.append(rule.direction)
|
||||||
|
rule_info.append(rule.provisioning_state)
|
||||||
|
vnet_info.append(rule_info)
|
||||||
|
|
||||||
|
if check_rule_for_Azure_ML(rule) is True:
|
||||||
|
rule_matched = rule
|
||||||
|
|
||||||
|
if rule_matched is not None:
|
||||||
|
print("INFORMATION: Rule matched with required ports. Subnet:",
|
||||||
|
subnet.id.split("/")[-1], "Rule:", rule.name)
|
||||||
|
else:
|
||||||
|
print("WARNING: No rule matched with required ports. Subnet:",
|
||||||
|
subnet.id.split("/")[-1])
|
||||||
|
|
||||||
|
if save_to_file is True:
|
||||||
|
file_name = vnet_name + ".csv"
|
||||||
|
with open(file_name, mode='w') as vnet_rule_file:
|
||||||
|
vnet_rule_file_writer = csv.writer(
|
||||||
|
vnet_rule_file,
|
||||||
|
delimiter=',',
|
||||||
|
quotechar='"',
|
||||||
|
quoting=csv.QUOTE_MINIMAL)
|
||||||
|
header = ['VNet_Name', 'VNet_Subscription_ID',
|
||||||
|
'VNet_Resource_Group', 'VNet_Location',
|
||||||
|
'Subnet_Name', 'NSG_Name',
|
||||||
|
'NSG_Subscription_ID', 'NSG_Resource_Group',
|
||||||
|
'Rule_Priority', 'Rule_Name', 'Rule_Source',
|
||||||
|
'Rule_Destination_Ports', 'Rule_Direction',
|
||||||
|
'Rule_Provisioning_State']
|
||||||
|
vnet_rule_file_writer.writerow(header)
|
||||||
|
vnet_rule_file_writer.writerows(vnet_info)
|
||||||
|
|
||||||
|
print("INFORMATION: Network security group rules for your virtual \
|
||||||
|
network are saved in file", file_name)
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
"\n",
|
"\n",
|
||||||
"# Check core SDK version number\n",
|
"# Check core SDK version number\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"This notebook was created using SDK version 1.5.0, you are currently running version\", azureml.core.VERSION)"
|
"print(\"This notebook was created using SDK version 1.7.0, you are currently running version\", azureml.core.VERSION)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -439,6 +439,8 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
|
"from azureml.train.dnn import TensorFlow\n",
|
||||||
|
"\n",
|
||||||
"script_params = {\"--log_dir\": \"./logs\"}\n",
|
"script_params = {\"--log_dir\": \"./logs\"}\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# If you want the run to go longer, set --max-steps to a higher number.\n",
|
"# If you want the run to go longer, set --max-steps to a higher number.\n",
|
||||||
|
|||||||
@@ -144,25 +144,18 @@
|
|||||||
"import os\n",
|
"import os\n",
|
||||||
"\n",
|
"\n",
|
||||||
"try:\n",
|
"try:\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",
|
"# If you want to connect using SSH key instead of username/password you can provide parameters private_key_file and private_key_passphrase\n",
|
||||||
" attach_config = HDInsightCompute.attach_configuration(address=os.environ.get('hdiservername', '<my_hdi_cluster_name>-ssh.azurehdinsight.net'), \n",
|
"\n",
|
||||||
" ssh_port=22, \n",
|
"# Attaching a HDInsight cluster using the public address of the HDInsight cluster is no longer supported.\n",
|
||||||
" username=os.environ.get('hdiusername', '<ssh_username>'), \n",
|
"# Instead, use resourceId of the HDInsight cluster.\n",
|
||||||
|
"# The resourceId of the HDInsight Cluster can be constructed using the following string format:\n",
|
||||||
|
"# /subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.HDInsight/clusters/<cluster_name>.\n",
|
||||||
|
"# You can also use subscription_id, resource_group and cluster_name without constructing resourceId.\n",
|
||||||
|
" attach_config = HDInsightCompute.attach_configuration(resource_id='<resource_id>',\n",
|
||||||
|
" ssh_port=22,\n",
|
||||||
|
" username=os.environ.get('hdiusername', '<ssh_username>'),\n",
|
||||||
" password=os.environ.get('hdipassword', '<my_password>'))\n",
|
" password=os.environ.get('hdipassword', '<my_password>'))\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# The following Azure regions do not support attaching a HDI Cluster using the public IP address of the HDI Cluster.\n",
|
|
||||||
"# Instead, use the Azure Resource Manager ID of the HDI Cluster with the resource_id parameter:\n",
|
|
||||||
"# US East\n",
|
|
||||||
"# US West 2\n",
|
|
||||||
"# US South Central\n",
|
|
||||||
"# The resource ID of the HDI Cluster can be constructed using the\n",
|
|
||||||
"# subscription ID, resource group name, and cluster name using the following string format:\n",
|
|
||||||
"# /subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.HDInsight/clusters/<cluster_name>. \n",
|
|
||||||
"# If in US East, US West 2, or US South Central, use the following instead:\n",
|
|
||||||
"# attach_config = HDInsightCompute.attach_configuration(resource_id='<resource_id>',\n",
|
|
||||||
"# ssh_port=22,\n",
|
|
||||||
"# username=os.environ.get('hdiusername', '<ssh_username>'),\n",
|
|
||||||
"# password=os.environ.get('hdipassword', '<my_password>'))\n",
|
|
||||||
" hdi_compute = ComputeTarget.attach(workspace=ws, \n",
|
" hdi_compute = ComputeTarget.attach(workspace=ws, \n",
|
||||||
" name='myhdi', \n",
|
" name='myhdi', \n",
|
||||||
" attach_configuration=attach_config)\n",
|
" attach_configuration=attach_config)\n",
|
||||||
|
|||||||
@@ -268,23 +268,15 @@
|
|||||||
" private_key_file='./.ssh/id_rsa')\n",
|
" private_key_file='./.ssh/id_rsa')\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
"\n",
|
||||||
"# The following Azure regions do not support attaching a virtual machine using the public IP address of the VM.\n",
|
"# Attaching a virtual machine using the public IP address of the VM is no longer supported.\n",
|
||||||
"# Instead, use the Azure Resource Manager ID of the VM with the resource_id parameter:\n",
|
"# Instead, use resourceId of the VM.\n",
|
||||||
"# US East\n",
|
"# The resourceId of the VM can be constructed using the following string format:\n",
|
||||||
"# US West 2\n",
|
"# /subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.Compute/virtualMachines/<vm_name>.\n",
|
||||||
"# US South Central\n",
|
"# You can also use subscription_id, resource_group and vm_name without constructing resourceId.\n",
|
||||||
"# The resource ID of the VM can be constructed using the\n",
|
" attach_config = RemoteCompute.attach_configuration(resource_id='<resource_id>',\n",
|
||||||
"# subscription ID, resource group name, and VM name using the following string format:\n",
|
" ssh_port=22,\n",
|
||||||
"# /subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.Compute/virtualMachines/<vm_name>. \n",
|
" username='username',\n",
|
||||||
"# If in US East, US West 2, or US South Central, use the following instead:\n",
|
" private_key_file='./.ssh/id_rsa')\n",
|
||||||
"# attach_config = RemoteCompute.attach_configuration(resource_id='<resource_id>',\n",
|
|
||||||
"# ssh_port=22,\n",
|
|
||||||
"# username='username',\n",
|
|
||||||
"# private_key_file='./.ssh/id_rsa')\n",
|
|
||||||
"\n",
|
|
||||||
" attached_dsvm_compute = ComputeTarget.attach(workspace=ws,\n",
|
|
||||||
" name=compute_target_name,\n",
|
|
||||||
" attach_configuration=attach_config)\n",
|
|
||||||
" attached_dsvm_compute.wait_for_completion(show_output=True)"
|
" attached_dsvm_compute.wait_for_completion(show_output=True)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -279,7 +279,8 @@
|
|||||||
" outputs=[prepared_fashion_ds],\n",
|
" outputs=[prepared_fashion_ds],\n",
|
||||||
" source_directory=script_folder,\n",
|
" source_directory=script_folder,\n",
|
||||||
" compute_target=compute_target,\n",
|
" compute_target=compute_target,\n",
|
||||||
" runconfig=run_config)"
|
" runconfig=run_config,\n",
|
||||||
|
" allow_reuse=False)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,6 +2,5 @@ name: pipeline-for-image-classification
|
|||||||
dependencies:
|
dependencies:
|
||||||
- pip:
|
- pip:
|
||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- azureml-dataprep
|
|
||||||
- pandas<=0.23.4
|
- pandas<=0.23.4
|
||||||
- fuse
|
- fuse
|
||||||
|
|||||||
@@ -2,5 +2,4 @@ name: tabular-timeseries-dataset-filtering
|
|||||||
dependencies:
|
dependencies:
|
||||||
- pip:
|
- pip:
|
||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- azureml-dataprep
|
|
||||||
- pandas<=0.23.4
|
- pandas<=0.23.4
|
||||||
|
|||||||
@@ -227,7 +227,13 @@
|
|||||||
"from azureml.core import Dataset, Run\n",
|
"from azureml.core import Dataset, Run\n",
|
||||||
"from sklearn.model_selection import train_test_split\n",
|
"from sklearn.model_selection import train_test_split\n",
|
||||||
"from sklearn.tree import DecisionTreeClassifier\n",
|
"from sklearn.tree import DecisionTreeClassifier\n",
|
||||||
"from sklearn.externals import joblib\n",
|
"# sklearn.externals.joblib is removed in 0.23\n",
|
||||||
|
"from sklearn import __version__ as sklearnver\n",
|
||||||
|
"from packaging.version import Version\n",
|
||||||
|
"if Version(sklearnver) < Version(\"0.23.0\"):\n",
|
||||||
|
" from sklearn.externals import joblib\n",
|
||||||
|
"else:\n",
|
||||||
|
" import joblib\n",
|
||||||
"\n",
|
"\n",
|
||||||
"run = Run.get_context()\n",
|
"run = Run.get_context()\n",
|
||||||
"# get input dataset by name\n",
|
"# get input dataset by name\n",
|
||||||
@@ -291,7 +297,7 @@
|
|||||||
" entry_script='train_iris.py', \n",
|
" entry_script='train_iris.py', \n",
|
||||||
" # pass dataset object as an input with name 'titanic'\n",
|
" # pass dataset object as an input with name 'titanic'\n",
|
||||||
" inputs=[dataset.as_named_input('iris')],\n",
|
" inputs=[dataset.as_named_input('iris')],\n",
|
||||||
" pip_packages=['azureml-dataprep[fuse]'],\n",
|
" pip_packages=['azureml-dataprep[fuse]', 'packaging'],\n",
|
||||||
" compute_target=compute_target) "
|
" compute_target=compute_target) "
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -415,11 +421,17 @@
|
|||||||
"import os\n",
|
"import os\n",
|
||||||
"import glob\n",
|
"import glob\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"from azureml.core.run import Run\n",
|
||||||
"from sklearn.linear_model import Ridge\n",
|
"from sklearn.linear_model import Ridge\n",
|
||||||
"from sklearn.metrics import mean_squared_error\n",
|
"from sklearn.metrics import mean_squared_error\n",
|
||||||
"from sklearn.model_selection import train_test_split\n",
|
"from sklearn.model_selection import train_test_split\n",
|
||||||
"from azureml.core.run import Run\n",
|
"# sklearn.externals.joblib is removed in 0.23\n",
|
||||||
"from sklearn.externals import joblib\n",
|
"from sklearn import __version__ as sklearnver\n",
|
||||||
|
"from packaging.version import Version\n",
|
||||||
|
"if Version(sklearnver) < Version(\"0.23.0\"):\n",
|
||||||
|
" from sklearn.externals import joblib\n",
|
||||||
|
"else:\n",
|
||||||
|
" import joblib\n",
|
||||||
"\n",
|
"\n",
|
||||||
"import numpy as np\n",
|
"import numpy as np\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -480,9 +492,10 @@
|
|||||||
"from azureml.core.conda_dependencies import CondaDependencies\n",
|
"from azureml.core.conda_dependencies import CondaDependencies\n",
|
||||||
"\n",
|
"\n",
|
||||||
"conda_env = Environment('conda-env')\n",
|
"conda_env = Environment('conda-env')\n",
|
||||||
"conda_env.python.conda_dependencies = CondaDependencies.create(pip_packages=['azureml-sdk',\n",
|
"conda_env.python.conda_dependencies = CondaDependencies.create(pip_packages=['azureml-core',\n",
|
||||||
" 'azureml-dataprep[pandas,fuse]',\n",
|
" 'azureml-dataprep[pandas,fuse]',\n",
|
||||||
" 'scikit-learn'])"
|
" 'scikit-learn',\n",
|
||||||
|
" 'packaging'])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ dependencies:
|
|||||||
- pip:
|
- pip:
|
||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- azureml-widgets
|
- azureml-widgets
|
||||||
- azureml-dataprep
|
|
||||||
- pandas<=0.23.4
|
- pandas<=0.23.4
|
||||||
- fuse
|
- fuse
|
||||||
- scikit-learn
|
- scikit-learn
|
||||||
|
|||||||
7
index.md
@@ -26,7 +26,7 @@ Machine Learning notebook samples and encourage efficient retrieval of topics an
|
|||||||
| :star:[Datasets with ML Pipeline](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/work-with-data/datasets-tutorial/pipeline-with-datasets/pipeline-for-image-classification.ipynb) | Train | Fashion MNIST | Remote | None | Azure ML | Dataset, Pipeline, Estimator, ScriptRun |
|
| :star:[Datasets with ML Pipeline](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/work-with-data/datasets-tutorial/pipeline-with-datasets/pipeline-for-image-classification.ipynb) | Train | Fashion MNIST | Remote | None | Azure ML | Dataset, Pipeline, Estimator, ScriptRun |
|
||||||
| :star:[Filtering data using Tabular Timeseiries Dataset related API](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/work-with-data/datasets-tutorial/timeseries-datasets/tabular-timeseries-dataset-filtering.ipynb) | Filtering | NOAA | Local | None | Azure ML | Dataset, Tabular Timeseries |
|
| :star:[Filtering data using Tabular Timeseiries Dataset related API](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/work-with-data/datasets-tutorial/timeseries-datasets/tabular-timeseries-dataset-filtering.ipynb) | Filtering | NOAA | Local | None | Azure ML | Dataset, Tabular Timeseries |
|
||||||
| :star:[Train with Datasets (Tabular and File)](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/work-with-data/datasets-tutorial/train-with-datasets/train-with-datasets.ipynb) | Train | Iris, Diabetes | Remote | None | Azure ML | Dataset, Estimator, ScriptRun |
|
| :star:[Train with Datasets (Tabular and File)](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/work-with-data/datasets-tutorial/train-with-datasets/train-with-datasets.ipynb) | Train | Iris, Diabetes | Remote | None | Azure ML | Dataset, Estimator, ScriptRun |
|
||||||
| [Forecasting away from training data](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/automated-machine-learning/forecasting-high-frequency/auto-ml-forecasting-function.ipynb) | Forecasting | None | Remote | None | Azure ML AutoML | Forecasting, Confidence Intervals |
|
| [Forecasting away from training data](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/automated-machine-learning/forecasting-forecast-function/auto-ml-forecasting-function.ipynb) | Forecasting | None | Remote | None | Azure ML AutoML | Forecasting, Confidence Intervals |
|
||||||
| [Automated ML run with basic edition features.](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/automated-machine-learning/classification-bank-marketing-all-features/auto-ml-classification-bank-marketing-all-features.ipynb) | Classification | Bankmarketing | AML | ACI | None | featurization, explainability, remote_run, AutomatedML |
|
| [Automated ML run with basic edition features.](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/automated-machine-learning/classification-bank-marketing-all-features/auto-ml-classification-bank-marketing-all-features.ipynb) | Classification | Bankmarketing | AML | ACI | None | featurization, explainability, remote_run, AutomatedML |
|
||||||
| [Classification of credit card fraudulent transactions using Automated ML](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/automated-machine-learning/classification-credit-card-fraud/auto-ml-classification-credit-card-fraud.ipynb) | Classification | Creditcard | AML Compute | None | None | remote_run, AutomatedML |
|
| [Classification of credit card fraudulent transactions using Automated ML](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/automated-machine-learning/classification-credit-card-fraud/auto-ml-classification-credit-card-fraud.ipynb) | Classification | Creditcard | AML Compute | None | None | remote_run, AutomatedML |
|
||||||
| [Automated ML run with featurization and model explainability.](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/automated-machine-learning/regression-explanation-featurization/auto-ml-regression-explanation-featurization.ipynb) | Regression | MachineData | AML | ACI | None | featurization, explainability, remote_run, AutomatedML |
|
| [Automated ML run with featurization and model explainability.](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/automated-machine-learning/regression-explanation-featurization/auto-ml-regression-explanation-featurization.ipynb) | Regression | MachineData | AML | ACI | None | featurization, explainability, remote_run, AutomatedML |
|
||||||
@@ -41,6 +41,7 @@ Machine Learning notebook samples and encourage efficient retrieval of topics an
|
|||||||
| :star:[How to Setup a Schedule for a Published Pipeline](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-setup-schedule-for-a-published-pipeline.ipynb) | Demonstrates the use of Schedules for Published Pipelines | Custom | AML Compute | None | Azure ML | None |
|
| :star:[How to Setup a Schedule for a Published Pipeline](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-setup-schedule-for-a-published-pipeline.ipynb) | Demonstrates the use of Schedules for Published Pipelines | Custom | AML Compute | None | Azure ML | None |
|
||||||
| [How to setup a versioned Pipeline Endpoint](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-setup-versioned-pipeline-endpoints.ipynb) | Demonstrates the use of PipelineEndpoint to run a specific version of the Published Pipeline | Custom | AML Compute | None | Azure ML | None |
|
| [How to setup a versioned Pipeline Endpoint](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-setup-versioned-pipeline-endpoints.ipynb) | Demonstrates the use of PipelineEndpoint to run a specific version of the Published Pipeline | Custom | AML Compute | None | Azure ML | None |
|
||||||
| :star:[How to use DataPath as a PipelineParameter](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-showcasing-datapath-and-pipelineparameter.ipynb) | Demonstrates the use of DataPath as a PipelineParameter | Custom | AML Compute | None | Azure ML | None |
|
| :star:[How to use DataPath as a PipelineParameter](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-showcasing-datapath-and-pipelineparameter.ipynb) | Demonstrates the use of DataPath as a PipelineParameter | Custom | AML Compute | None | Azure ML | None |
|
||||||
|
| :star:[How to use Dataset as a PipelineParameter](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-showcasing-dataset-and-pipelineparameter.ipynb) | Demonstrates the use of Dataset as a PipelineParameter | Custom | AML Compute | None | Azure ML | None |
|
||||||
| [How to use AdlaStep with AML Pipelines](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-use-adla-as-compute-target.ipynb) | Demonstrates the use of AdlaStep | Custom | Azure Data Lake Analytics | None | Azure ML | None |
|
| [How to use AdlaStep with AML Pipelines](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-use-adla-as-compute-target.ipynb) | Demonstrates the use of AdlaStep | Custom | Azure Data Lake Analytics | None | Azure ML | None |
|
||||||
| :star:[How to use DatabricksStep with AML Pipelines](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-use-databricks-as-compute-target.ipynb) | Demonstrates the use of DatabricksStep | Custom | Azure Databricks | None | Azure ML, Azure Databricks | None |
|
| :star:[How to use DatabricksStep with AML Pipelines](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-use-databricks-as-compute-target.ipynb) | Demonstrates the use of DatabricksStep | Custom | Azure Databricks | None | Azure ML, Azure Databricks | None |
|
||||||
| :star:[How to use AutoMLStep with AML Pipelines](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-with-automated-machine-learning-step.ipynb) | Demonstrates the use of AutoMLStep | Custom | AML Compute | None | Automated Machine Learning | None |
|
| :star:[How to use AutoMLStep with AML Pipelines](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/machine-learning-pipelines/intro-to-pipelines/aml-pipelines-with-automated-machine-learning-step.ipynb) | Demonstrates the use of AutoMLStep | Custom | AML Compute | None | Automated Machine Learning | None |
|
||||||
@@ -111,9 +112,9 @@ Machine Learning notebook samples and encourage efficient retrieval of topics an
|
|||||||
| [register-model-deploy-local-advanced](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/deploy-to-local/register-model-deploy-local-advanced.ipynb) | | | | | | |
|
| [register-model-deploy-local-advanced](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/deploy-to-local/register-model-deploy-local-advanced.ipynb) | | | | | | |
|
||||||
| [enable-app-insights-in-production-service](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/enable-app-insights-in-production-service/enable-app-insights-in-production-service.ipynb) | | | | | | |
|
| [enable-app-insights-in-production-service](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/enable-app-insights-in-production-service/enable-app-insights-in-production-service.ipynb) | | | | | | |
|
||||||
| [onnx-model-register-and-deploy](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/onnx/onnx-model-register-and-deploy.ipynb) | | | | | | |
|
| [onnx-model-register-and-deploy](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/onnx/onnx-model-register-and-deploy.ipynb) | | | | | | |
|
||||||
|
| [production-deploy-to-aks-ssl](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/production-deploy-to-aks/production-deploy-to-aks-ssl.ipynb) | | | | | | |
|
||||||
| [production-deploy-to-aks](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/production-deploy-to-aks/production-deploy-to-aks.ipynb) | | | | | | |
|
| [production-deploy-to-aks](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/production-deploy-to-aks/production-deploy-to-aks.ipynb) | | | | | | |
|
||||||
| [production-deploy-to-aks-gpu](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/production-deploy-to-aks-gpu/production-deploy-to-aks-gpu.ipynb) | | | | | | |
|
| [production-deploy-to-aks-gpu](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/production-deploy-to-aks-gpu/production-deploy-to-aks-gpu.ipynb) | | | | | | |
|
||||||
| [tensorflow-model-register-and-deploy](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/deployment/tensorflow/tensorflow-model-register-and-deploy.ipynb) | | | | | | |
|
|
||||||
| [explain-model-on-amlcompute](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/explain-model/azure-integration/remote-explanation/explain-model-on-amlcompute.ipynb) | | | | | | |
|
| [explain-model-on-amlcompute](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/explain-model/azure-integration/remote-explanation/explain-model-on-amlcompute.ipynb) | | | | | | |
|
||||||
| [save-retrieve-explanations-run-history](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/explain-model/azure-integration/run-history/save-retrieve-explanations-run-history.ipynb) | | | | | | |
|
| [save-retrieve-explanations-run-history](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/explain-model/azure-integration/run-history/save-retrieve-explanations-run-history.ipynb) | | | | | | |
|
||||||
| [train-explain-model-locally-and-deploy](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/explain-model/azure-integration/scoring-time/train-explain-model-locally-and-deploy.ipynb) | | | | | | |
|
| [train-explain-model-locally-and-deploy](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/explain-model/azure-integration/scoring-time/train-explain-model-locally-and-deploy.ipynb) | | | | | | |
|
||||||
@@ -123,7 +124,7 @@ Machine Learning notebook samples and encourage efficient retrieval of topics an
|
|||||||
| [authentication-in-azureml](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/manage-azureml-service/authentication-in-azureml/authentication-in-azureml.ipynb) | | | | | | |
|
| [authentication-in-azureml](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/manage-azureml-service/authentication-in-azureml/authentication-in-azureml.ipynb) | | | | | | |
|
||||||
| [pong_rllib](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/atari-on-distributed-compute/pong_rllib.ipynb) | | | | | | |
|
| [pong_rllib](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/atari-on-distributed-compute/pong_rllib.ipynb) | | | | | | |
|
||||||
| [cartpole_ci](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/cartpole-on-compute-instance/cartpole_ci.ipynb) | | | | | | |
|
| [cartpole_ci](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/cartpole-on-compute-instance/cartpole_ci.ipynb) | | | | | | |
|
||||||
| [cartpole_cc](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/cartpole-on-single-compute/cartpole_cc.ipynb) | | | | | | |
|
| [cartpole_sc](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/cartpole-on-single-compute/cartpole_sc.ipynb) | | | | | | |
|
||||||
| [minecraft](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/minecraft-on-distributed-compute/minecraft.ipynb) | | | | | | |
|
| [minecraft](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/minecraft-on-distributed-compute/minecraft.ipynb) | | | | | | |
|
||||||
| [devenv_setup](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/setup/devenv_setup.ipynb) | | | | | | |
|
| [devenv_setup](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/reinforcement-learning/setup/devenv_setup.ipynb) | | | | | | |
|
||||||
| [Logging APIs](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/track-and-monitor-experiments/logging-api/logging-api.ipynb) | Logging APIs and analyzing results | None | None | None | None | None |
|
| [Logging APIs](https://github.com/Azure/MachineLearningNotebooks/blob/master//how-to-use-azureml/track-and-monitor-experiments/logging-api/logging-api.ipynb) | Logging APIs and analyzing results | None | None | None | None | None |
|
||||||
|
|||||||
@@ -102,7 +102,7 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"import azureml.core\n",
|
"import azureml.core\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print(\"This notebook was created using version 1.5.0 of the Azure ML SDK\")\n",
|
"print(\"This notebook was created using version 1.7.0 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\")"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -212,7 +212,7 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
""
|
""
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -226,7 +226,7 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
""
|
""
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,9 +21,10 @@ image_size = 299
|
|||||||
num_channel = 3
|
num_channel = 3
|
||||||
|
|
||||||
|
|
||||||
def get_class_label_dict():
|
def get_class_label_dict(labels_dir):
|
||||||
label = []
|
label = []
|
||||||
proto_as_ascii_lines = tf.gfile.GFile("labels.txt").readlines()
|
labels_path = os.path.join(labels_dir, 'labels.txt')
|
||||||
|
proto_as_ascii_lines = tf.gfile.GFile(labels_path).readlines()
|
||||||
for l in proto_as_ascii_lines:
|
for l in proto_as_ascii_lines:
|
||||||
label.append(l.rstrip())
|
label.append(l.rstrip())
|
||||||
return label
|
return label
|
||||||
@@ -34,14 +35,10 @@ def init():
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Start a tensorflow model serving")
|
parser = argparse.ArgumentParser(description="Start a tensorflow model serving")
|
||||||
parser.add_argument('--model_name', dest="model_name", required=True)
|
parser.add_argument('--model_name', dest="model_name", required=True)
|
||||||
parser.add_argument('--labels_name', dest="labels_name", required=True)
|
parser.add_argument('--labels_dir', dest="labels_dir", required=True)
|
||||||
args, _ = parser.parse_known_args()
|
args, _ = parser.parse_known_args()
|
||||||
|
|
||||||
workspace = Run.get_context(allow_offline=False).experiment.workspace
|
label_dict = get_class_label_dict(args.labels_dir)
|
||||||
label_ds = Dataset.get_by_name(workspace=workspace, name=args.labels_name)
|
|
||||||
label_ds.download(target_path='.', overwrite=True)
|
|
||||||
|
|
||||||
label_dict = get_class_label_dict()
|
|
||||||
classes_num = len(label_dict)
|
classes_num = len(label_dict)
|
||||||
|
|
||||||
with slim.arg_scope(inception_v3.inception_v3_arg_scope()):
|
with slim.arg_scope(inception_v3.inception_v3_arg_scope()):
|
||||||
|
|||||||
@@ -20,14 +20,8 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"# Use Azure Machine Learning Pipelines for batch prediction\n",
|
"# Use Azure Machine Learning Pipelines for batch prediction\n",
|
||||||
"\n",
|
|
||||||
"## Note\n",
|
|
||||||
"This notebook uses public preview functionality (ParallelRunStep). Please install azureml-contrib-pipeline-steps package before running this notebook.\n",
|
|
||||||
"\n",
|
|
||||||
"\n",
|
|
||||||
"In this tutorial, you use Azure Machine Learning service pipelines to run a batch scoring image classification job. The example job uses the pre-trained [Inception-V3](https://arxiv.org/abs/1512.00567) CNN (convolutional neural network) Tensorflow model to classify unlabeled images. Machine learning pipelines optimize your workflow with speed, portability, and reuse so you can focus on your expertise, machine learning, rather than on infrastructure and automation. After building and publishing a pipeline, you can configure a REST endpoint to enable triggering the pipeline from any HTTP library on any platform.\n",
|
"In this tutorial, you use Azure Machine Learning service pipelines to run a batch scoring image classification job. The example job uses the pre-trained [Inception-V3](https://arxiv.org/abs/1512.00567) CNN (convolutional neural network) Tensorflow model to classify unlabeled images. Machine learning pipelines optimize your workflow with speed, portability, and reuse so you can focus on your expertise, machine learning, rather than on infrastructure and automation. After building and publishing a pipeline, you can configure a REST endpoint to enable triggering the pipeline from any HTTP library on any platform.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"\n",
|
|
||||||
"In this tutorial, you learn the following tasks:\n",
|
"In this tutorial, you learn the following tasks:\n",
|
||||||
"\n",
|
"\n",
|
||||||
"> * Configure workspace and download sample data\n",
|
"> * Configure workspace and download sample data\n",
|
||||||
@@ -38,7 +32,7 @@
|
|||||||
"> * Build, run, and publish a pipeline\n",
|
"> * Build, run, and publish a pipeline\n",
|
||||||
"> * Enable a REST endpoint for the pipeline\n",
|
"> * Enable a REST endpoint for the pipeline\n",
|
||||||
"\n",
|
"\n",
|
||||||
"If you don\u00e2\u20ac\u2122t have an Azure subscription, create a free account before you begin. Try the [free or paid version of Azure Machine Learning service](https://aka.ms/AMLFree) today."
|
"If you don't have an Azure subscription, create a free account before you begin. Try the [free or paid version of Azure Machine Learning service](https://aka.ms/AMLFree) today."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -129,7 +123,7 @@
|
|||||||
"from azureml.pipeline.core import PipelineData\n",
|
"from azureml.pipeline.core import PipelineData\n",
|
||||||
"\n",
|
"\n",
|
||||||
"input_images = Dataset.File.from_files((batchscore_blob, \"batchscoring/images/\"))\n",
|
"input_images = Dataset.File.from_files((batchscore_blob, \"batchscoring/images/\"))\n",
|
||||||
"label_ds = Dataset.File.from_files((batchscore_blob, \"batchscoring/labels/*.txt\"))\n",
|
"label_ds = Dataset.File.from_files((batchscore_blob, \"batchscoring/labels/\"))\n",
|
||||||
"output_dir = PipelineData(name=\"scores\", \n",
|
"output_dir = PipelineData(name=\"scores\", \n",
|
||||||
" datastore=def_data_store, \n",
|
" datastore=def_data_store, \n",
|
||||||
" output_path_on_compute=\"batchscoring/results\")"
|
" output_path_on_compute=\"batchscoring/results\")"
|
||||||
@@ -149,7 +143,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"input_images = input_images.register(workspace = ws, name = \"input_images\")\n",
|
"input_images = input_images.register(workspace = ws, name = \"input_images\")\n",
|
||||||
"label_ds = label_ds.register(workspace = ws, name = \"label_ds\")"
|
"label_ds = label_ds.register(workspace = ws, name = \"label_ds\", create_new_version=True)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -260,7 +254,7 @@
|
|||||||
"The script `batch_scoring.py` takes the following parameters, which get passed from the `ParallelRunStep` that you create later:\n",
|
"The script `batch_scoring.py` takes the following parameters, which get passed from the `ParallelRunStep` that you create later:\n",
|
||||||
"\n",
|
"\n",
|
||||||
"- `--model_name`: the name of the model being used\n",
|
"- `--model_name`: the name of the model being used\n",
|
||||||
"- `--labels_name` : the name of the `Dataset` holding the `labels.txt` file \n",
|
"- `--labels_dir` : the directory path having the `labels.txt` file \n",
|
||||||
"\n",
|
"\n",
|
||||||
"The pipelines infrastructure uses the `ArgumentParser` class to pass parameters into pipeline steps. For example, in the code below the first argument `--model_name` is given the property identifier `model_name`. In the `main()` function, this property is accessed using `Model.get_model_path(args.model_name)`."
|
"The pipelines infrastructure uses the `ArgumentParser` class to pass parameters into pipeline steps. For example, in the code below the first argument `--model_name` is given the property identifier `model_name`. In the `main()` function, this property is accessed using `Model.get_model_path(args.model_name)`."
|
||||||
]
|
]
|
||||||
@@ -296,7 +290,8 @@
|
|||||||
"from azureml.core.conda_dependencies import CondaDependencies\n",
|
"from azureml.core.conda_dependencies import CondaDependencies\n",
|
||||||
"from azureml.core.runconfig import DEFAULT_GPU_IMAGE\n",
|
"from azureml.core.runconfig import DEFAULT_GPU_IMAGE\n",
|
||||||
"\n",
|
"\n",
|
||||||
"cd = CondaDependencies.create(pip_packages=[\"tensorflow-gpu==1.15.2\", \"azureml-defaults\"])\n",
|
"cd = CondaDependencies.create(pip_packages=[\"tensorflow-gpu==1.15.2\",\n",
|
||||||
|
" \"azureml-core\", \"azureml-dataprep[fuse]\"])\n",
|
||||||
"\n",
|
"\n",
|
||||||
"env = Environment(name=\"parallelenv\")\n",
|
"env = Environment(name=\"parallelenv\")\n",
|
||||||
"env.python.conda_dependencies=cd\n",
|
"env.python.conda_dependencies=cd\n",
|
||||||
@@ -317,7 +312,7 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.contrib.pipeline.steps import ParallelRunConfig\n",
|
"from azureml.pipeline.steps import ParallelRunConfig\n",
|
||||||
"\n",
|
"\n",
|
||||||
"parallel_run_config = ParallelRunConfig(\n",
|
"parallel_run_config = ParallelRunConfig(\n",
|
||||||
" environment=env,\n",
|
" environment=env,\n",
|
||||||
@@ -356,18 +351,20 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from azureml.contrib.pipeline.steps import ParallelRunStep\n",
|
"from azureml.pipeline.steps import ParallelRunStep\n",
|
||||||
"from datetime import datetime\n",
|
"from datetime import datetime\n",
|
||||||
"\n",
|
"\n",
|
||||||
"parallel_step_name = \"batchscoring-\" + datetime.now().strftime(\"%Y%m%d%H%M\")\n",
|
"parallel_step_name = \"batchscoring-\" + datetime.now().strftime(\"%Y%m%d%H%M\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
"label_config = label_ds.as_named_input(\"labels_input\")\n",
|
||||||
|
"\n",
|
||||||
"batch_score_step = ParallelRunStep(\n",
|
"batch_score_step = ParallelRunStep(\n",
|
||||||
" name=parallel_step_name,\n",
|
" name=parallel_step_name,\n",
|
||||||
" inputs=[input_images.as_named_input(\"input_images\")],\n",
|
" inputs=[input_images.as_named_input(\"input_images\")],\n",
|
||||||
" output=output_dir,\n",
|
" output=output_dir,\n",
|
||||||
" models=[model],\n",
|
|
||||||
" arguments=[\"--model_name\", \"inception\",\n",
|
" arguments=[\"--model_name\", \"inception\",\n",
|
||||||
" \"--labels_name\", \"label_ds\"],\n",
|
" \"--labels_dir\", label_config],\n",
|
||||||
|
" side_inputs=[label_config],\n",
|
||||||
" parallel_run_config=parallel_run_config,\n",
|
" parallel_run_config=parallel_run_config,\n",
|
||||||
" allow_reuse=False\n",
|
" allow_reuse=False\n",
|
||||||
")"
|
")"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ dependencies:
|
|||||||
- pip:
|
- pip:
|
||||||
- azureml-sdk
|
- azureml-sdk
|
||||||
- azureml-pipeline-core
|
- azureml-pipeline-core
|
||||||
- azureml-contrib-pipeline-steps
|
- azureml-pipeline-steps
|
||||||
- pandas
|
- pandas
|
||||||
- requests
|
- requests
|
||||||
- azureml-widgets
|
- azureml-widgets
|
||||||
|
|||||||