Bagikan melalui


Melatih model scikit-learn dalam skala besar dengan Azure Machine Learning

BERLAKU UNTUK: Python SDK azure-ai-ml v2 (saat ini)

Dalam artikel ini, pelajari cara menjalankan skrip pelatihan scikit-learn Anda dengan Azure Pembelajaran Mesin Python SDK v2.

Contoh skrip dalam artikel ini digunakan untuk mengklasifikasikan gambar bunga iris untuk membangun model pembelajaran mesin berdasarkan himpunan data iris scikit-learn.

Baik melatih model scikit-learn pembelajaran mesin dari awal atau membawa model yang ada ke cloud, Anda dapat menggunakan Azure Machine Learning untuk memperluas skala pekerjaan pelatihan sumber terbuka menggunakan sumber daya komputasi cloud elastis. Anda dapat membuat, menyebarkan, membuat versi, dan memantau model tingkat produksi dengan Azure Machine Learning.

Prasyarat

Anda dapat menjalankan kode untuk artikel ini di instans komputasi Azure Pembelajaran Mesin, atau Jupyter Notebook Anda sendiri.

  • Instans komputasi Azure Machine Learning

    • Selesaikan Buat sumber daya untuk mulai membuat instans komputasi. Setiap instans komputasi menyertakan server notebook khusus yang dimuat sebelumnya dengan SDK dan repositori sampel notebook.
    • Pilih tab notebook di studio Azure Machine Learning. Di folder pelatihan sampel, temukan notebook yang telah selesai dan diperluas dengan menavigasi ke direktori ini: pekerjaan sdk > v2 > scikit-learn > > > train-hyperparameter-tune-deploy-with-sklearn.
    • Anda dapat menggunakan kode yang telah diisi sebelumnya di folder pelatihan sampel untuk menyelesaikan tutorial ini.
  • Server notebook Jupyter Anda.

Menyiapkan pekerjaan

Bagian ini menyiapkan pekerjaan untuk pelatihan dengan memuat paket Python yang diperlukan, menyambungkan ke ruang kerja, membuat sumber daya komputasi untuk menjalankan pekerjaan perintah, dan membuat lingkungan untuk menjalankan pekerjaan.

Menyambungkan ke ruang kerja

Pertama, Anda perlu menyambungkan ke ruang kerja Azure Pembelajaran Mesin Anda. Ruang kerja Azure Machine Learning adalah sumber daya tingkat teratas untuk layanan ini. Ini memberi Anda tempat terpusat untuk bekerja dengan semua artefak yang Anda buat saat menggunakan Azure Pembelajaran Mesin.

Kami menggunakan DefaultAzureCredential untuk mendapatkan akses ke ruang kerja. Kredensial ini harus mampu menangani sebagian besar skenario autentikasi Azure SDK.

Jika DefaultAzureCredential tidak berfungsi untuk Anda, lihat azure-identity reference documentation atau Set up authentication untuk kredensial yang tersedia lainnya.

# Handle to the workspace
from azure.ai.ml import MLClient

# Authentication package
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()

Jika Anda lebih suka menggunakan browser untuk masuk dan mengautentikasi, Anda harus menghapus komentar dalam kode berikut dan menggunakannya sebagai gantinya.

# Handle to the workspace
# from azure.ai.ml import MLClient

# Authentication package
# from azure.identity import InteractiveBrowserCredential
# credential = InteractiveBrowserCredential()

Selanjutnya, dapatkan handel ke ruang kerja dengan memberikan ID Langganan, nama Grup Sumber Daya, dan nama ruang kerja Anda. Untuk menemukan parameter ini:

  1. Lihat di sudut kanan atas toolbar studio Azure Pembelajaran Mesin untuk nama ruang kerja Anda.
  2. Pilih nama ruang kerja Anda untuk menampilkan Grup Sumber Daya dan ID Langganan Anda.
  3. Salin nilai untuk Grup Sumber Daya dan ID Langganan ke dalam kode.
# Get a handle to the workspace
ml_client = MLClient(
    credential=credential,
    subscription_id="<SUBSCRIPTION_ID>",
    resource_group_name="<RESOURCE_GROUP>",
    workspace_name="<AML_WORKSPACE_NAME>",
)

Hasil menjalankan skrip ini adalah handel ruang kerja yang Anda gunakan untuk mengelola sumber daya dan pekerjaan lain.

Catatan

Membuat MLClient tidak akan menghubungkan klien ke ruang kerja. Inisialisasi klien malas dan akan menunggu untuk pertama kalinya perlu melakukan panggilan. Dalam artikel ini, ini akan terjadi selama pembuatan komputasi.

Buat sumber daya komputasi

Azure Pembelajaran Mesin memerlukan sumber daya komputasi untuk menjalankan pekerjaan. Sumber daya ini dapat berupa mesin tunggal atau multi-simpul dengan OS Linux atau Windows, atau kain komputasi tertentu seperti Spark.

Dalam contoh skrip berikut, kami menyediakan Linux compute cluster. Anda dapat melihat Azure Machine Learning pricing halaman untuk daftar lengkap ukuran dan harga VM. Kita hanya memerlukan kluster dasar untuk contoh ini; dengan demikian, kami memilih model Standard_DS3_v2 dengan 2 inti vCPU dan RAM 7 GB untuk membuat komputasi Azure Pembelajaran Mesin.

from azure.ai.ml.entities import AmlCompute

# Name assigned to the compute cluster
cpu_compute_target = "cpu-cluster"

try:
    # let's see if the compute target already exists
    cpu_cluster = ml_client.compute.get(cpu_compute_target)
    print(
        f"You already have a cluster named {cpu_compute_target}, we'll reuse it as is."
    )

except Exception:
    print("Creating a new cpu compute target...")

    # Let's create the Azure ML compute object with the intended parameters
    cpu_cluster = AmlCompute(
        name=cpu_compute_target,
        # Azure ML Compute is the on-demand VM service
        type="amlcompute",
        # VM Family
        size="STANDARD_DS3_V2",
        # Minimum running nodes when there is no job running
        min_instances=0,
        # Nodes in cluster
        max_instances=4,
        # How many seconds will the node running after the job termination
        idle_time_before_scale_down=180,
        # Dedicated or LowPriority. The latter is cheaper but there is a chance of job termination
        tier="Dedicated",
    )

    # Now, we pass the object to MLClient's create_or_update method
    cpu_cluster = ml_client.compute.begin_create_or_update(cpu_cluster).result()

print(
    f"AMLCompute with name {cpu_cluster.name} is created, the compute size is {cpu_cluster.size}"
)

Membuat lingkungan pekerjaan

Untuk menjalankan pekerjaan Azure Pembelajaran Mesin, Anda memerlukan lingkungan. Lingkungan Azure Pembelajaran Mesin merangkum dependensi (seperti runtime perangkat lunak dan pustaka) yang diperlukan untuk menjalankan skrip pelatihan pembelajaran mesin Anda pada sumber daya komputasi Anda. Lingkungan ini mirip dengan lingkungan Python di komputer lokal Anda.

Azure Pembelajaran Mesin memungkinkan Anda menggunakan lingkungan yang dikumpulkan (atau siap) atau membuat lingkungan kustom menggunakan gambar Docker atau konfigurasi Conda. Dalam artikel ini, Anda membuat lingkungan kustom untuk pekerjaan Anda, menggunakan file YAML Conda.

Membuat lingkungan kustom

Untuk membuat lingkungan kustom, Anda menentukan dependensi Conda Anda dalam file YAML. Pertama, buat direktori untuk menyimpan file. Dalam contoh ini, kami telah menamai direktori env.

import os

dependencies_dir = "./env"
os.makedirs(dependencies_dir, exist_ok=True)

Kemudian, buat file di direktori dependensi. Dalam contoh ini, kami telah menamai file conda.yml.

%%writefile {dependencies_dir}/conda.yaml
name: sklearn-env
channels:
  - conda-forge
dependencies:
  - python=3.8
  - pip=21.2.4
  - scikit-learn=0.24.2
  - scipy=1.7.1
  - pip:  
    - azureml-mlflow==1.42.0
    - mlflow-skinny==2.3.2

Spesifikasi berisi beberapa paket biasa (seperti numpy dan pip) yang Anda gunakan dalam pekerjaan Anda.

Selanjutnya, gunakan file YAML untuk membuat dan mendaftarkan lingkungan kustom ini di ruang kerja Anda. Lingkungan dikemas ke dalam kontainer Docker saat runtime.

from azure.ai.ml.entities import Environment

custom_env_name = "sklearn-env"

job_env = Environment(
    name=custom_env_name,
    description="Custom environment for sklearn image classification",
    conda_file=os.path.join(dependencies_dir, "conda.yaml"),
    image="mcr.microsoft.com/azureml/openmpi4.1.0-ubuntu20.04:latest",
)
job_env = ml_client.environments.create_or_update(job_env)

print(
    f"Environment with name {job_env.name} is registered to workspace, the environment version is {job_env.version}"
)

Untuk informasi selengkapnya tentang membuat dan menggunakan lingkungan, lihat Membuat dan menggunakan lingkungan perangkat lunak di Azure Machine Learning.

[Opsional] Membuat lingkungan kustom dengan Ekstensi Intel® untuk Scikit-Learn

Ingin mempercepat skrip scikit-learn Anda di perangkat keras Intel? Coba tambahkan Ekstensi Intel® untuk Scikit-Learn ke dalam file yaml conda Anda dan ikuti langkah-langkah berikutnya yang dirinci di atas. Kami akan menunjukkan kepada Anda cara mengaktifkan pengoptimalan ini nanti dalam contoh ini:

%%writefile {dependencies_dir}/conda.yaml
name: sklearn-env
channels:
  - conda-forge
dependencies:
  - python=3.8
  - pip=21.2.4
  - scikit-learn=0.24.2
  - scikit-learn-intelex
  - scipy=1.7.1
  - pip:  
    - azureml-mlflow==1.42.0
    - mlflow-skinny==2.3.2

Mengonfigurasi dan mengirimkan pekerjaan pelatihan Anda

Di bagian ini, kami membahas cara menjalankan pekerjaan pelatihan, menggunakan skrip pelatihan yang telah kami sediakan. Untuk memulai, Anda membangun pekerjaan pelatihan dengan mengonfigurasi perintah untuk menjalankan skrip pelatihan. Kemudian, Anda mengirimkan pekerjaan pelatihan untuk dijalankan di Azure Pembelajaran Mesin.

Menyiapkan skrip pelatihan

Dalam artikel ini, kami telah menyediakan skrip pelatihan train_iris.py. Dalam praktiknya, Anda harus dapat mengambil skrip pelatihan kustom apa adanya dan menjalankannya dengan Azure Pembelajaran Mesin tanpa harus mengubah kode Anda.

Catatan

Skrip pelatihan yang disediakan melakukan hal berikut:

  • memperlihatkan cara mencatat beberapa metrik ke eksekusi Azure Pembelajaran Mesin Anda;
  • mengunduh dan mengekstrak data pelatihan menggunakan iris = datasets.load_iris(); dan
  • melatih model, lalu menyimpan dan mendaftarkannya.

Untuk menggunakan dan mengakses data Anda sendiri, lihat cara membaca dan menulis data dalam pekerjaan untuk membuat data tersedia selama pelatihan.

Untuk menggunakan skrip pelatihan, pertama-tama buat direktori tempat Anda akan menyimpan file.

import os

src_dir = "./src"
os.makedirs(src_dir, exist_ok=True)

Selanjutnya, buat file skrip di direktori sumber.

%%writefile {src_dir}/train_iris.py
# Modified from https://www.geeksforgeeks.org/multiclass-classification-using-scikit-learn/

import argparse
import os

# importing necessary libraries
import numpy as np

from sklearn import datasets
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split

import joblib

import mlflow
import mlflow.sklearn

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('--kernel', type=str, default='linear',
                        help='Kernel type to be used in the algorithm')
    parser.add_argument('--penalty', type=float, default=1.0,
                        help='Penalty parameter of the error term')

    # Start Logging
    mlflow.start_run()

    # enable autologging
    mlflow.sklearn.autolog()

    args = parser.parse_args()
    mlflow.log_param('Kernel type', str(args.kernel))
    mlflow.log_metric('Penalty', float(args.penalty))

    # loading the iris dataset
    iris = datasets.load_iris()

    # X -> features, y -> label
    X = iris.data
    y = iris.target

    # dividing X, y into train and test data
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

    # training a linear SVM classifier
    from sklearn.svm import SVC
    svm_model_linear = SVC(kernel=args.kernel, C=args.penalty)
    svm_model_linear = svm_model_linear.fit(X_train, y_train)
    svm_predictions = svm_model_linear.predict(X_test)

    # model accuracy for X_test
    accuracy = svm_model_linear.score(X_test, y_test)
    print('Accuracy of SVM classifier on test set: {:.2f}'.format(accuracy))
    mlflow.log_metric('Accuracy', float(accuracy))
    # creating a confusion matrix
    cm = confusion_matrix(y_test, svm_predictions)
    print(cm)

    registered_model_name="sklearn-iris-flower-classify-model"

    ##########################
    #<save and register model>
    ##########################
    # Registering the model to the workspace
    print("Registering the model via MLFlow")
    mlflow.sklearn.log_model(
        sk_model=svm_model_linear,
        registered_model_name=registered_model_name,
        artifact_path=registered_model_name
    )

    # # Saving the model to a file
    print("Saving the model via MLFlow")
    mlflow.sklearn.save_model(
        sk_model=svm_model_linear,
        path=os.path.join(registered_model_name, "trained_model"),
    )
    ###########################
    #</save and register model>
    ###########################
    mlflow.end_run()

if __name__ == '__main__':
    main()

[Opsional] Mengaktifkan Ekstensi Intel® untuk pengoptimalan Scikit-Learn untuk performa lebih lanjut pada perangkat keras Intel

Jika Anda telah menginstal Ekstensi Intel® untuk Scikit-Learn (seperti yang ditunjukkan di bagian sebelumnya), Anda dapat mengaktifkan pengoptimalan performa dengan menambahkan dua baris kode ke bagian atas file skrip, seperti yang ditunjukkan di bawah ini.

Untuk mempelajari selengkapnya tentang Ekstensi Intel® untuk Scikit-Learn, kunjungi dokumentasi paket.

%%writefile {src_dir}/train_iris.py
# Modified from https://www.geeksforgeeks.org/multiclass-classification-using-scikit-learn/

import argparse
import os

# Import and enable Intel Extension for Scikit-learn optimizations
# where possible

from sklearnex import patch_sklearn
patch_sklearn()

# importing necessary libraries
import numpy as np


from sklearn import datasets
from sklearn.metrics import confusion_matrix
from sklearn.model_selection import train_test_split

import joblib

import mlflow
import mlflow.sklearn

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument('--kernel', type=str, default='linear',
                        help='Kernel type to be used in the algorithm')
    parser.add_argument('--penalty', type=float, default=1.0,
                        help='Penalty parameter of the error term')

    # Start Logging
    mlflow.start_run()

    # enable autologging
    mlflow.sklearn.autolog()

    args = parser.parse_args()
    mlflow.log_param('Kernel type', str(args.kernel))
    mlflow.log_metric('Penalty', float(args.penalty))

    # loading the iris dataset
    iris = datasets.load_iris()

    # X -> features, y -> label
    X = iris.data
    y = iris.target

    # dividing X, y into train and test data
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

    # training a linear SVM classifier
    from sklearn.svm import SVC
    svm_model_linear = SVC(kernel=args.kernel, C=args.penalty)
    svm_model_linear = svm_model_linear.fit(X_train, y_train)
    svm_predictions = svm_model_linear.predict(X_test)

    # model accuracy for X_test
    accuracy = svm_model_linear.score(X_test, y_test)
    print('Accuracy of SVM classifier on test set: {:.2f}'.format(accuracy))
    mlflow.log_metric('Accuracy', float(accuracy))
    # creating a confusion matrix
    cm = confusion_matrix(y_test, svm_predictions)
    print(cm)

    registered_model_name="sklearn-iris-flower-classify-model"

    ##########################
    #<save and register model>
    ##########################
    # Registering the model to the workspace
    print("Registering the model via MLFlow")
    mlflow.sklearn.log_model(
        sk_model=svm_model_linear,
        registered_model_name=registered_model_name,
        artifact_path=registered_model_name
    )

    # # Saving the model to a file
    print("Saving the model via MLFlow")
    mlflow.sklearn.save_model(
        sk_model=svm_model_linear,
        path=os.path.join(registered_model_name, "trained_model"),
    )
    ###########################
    #</save and register model>
    ###########################
    mlflow.end_run()

if __name__ == '__main__':
    main()

Membangun pekerjaan pelatihan

Sekarang setelah Anda memiliki semua aset yang diperlukan untuk menjalankan pekerjaan Anda, saatnya untuk membuatnya menggunakan Azure Pembelajaran Mesin Python SDK v2. Untuk menjalankan pekerjaan, kami membuat command.

Azure Pembelajaran Mesin command adalah sumber daya yang menentukan semua detail yang diperlukan untuk menjalankan kode pelatihan Anda di cloud. Detail ini mencakup input dan output, jenis perangkat keras yang akan digunakan, perangkat lunak untuk diinstal, dan cara menjalankan kode Anda. berisi command informasi untuk menjalankan satu perintah.

Mengonfigurasi perintah

Anda menggunakan tujuan command umum untuk menjalankan skrip pelatihan dan melakukan tugas yang Anda inginkan. Buat Command objek untuk menentukan detail konfigurasi pekerjaan pelatihan Anda.

  • Input untuk perintah ini mencakup jumlah epoch, tingkat pembelajaran, momentum, dan direktori output.
  • Untuk nilai parameter:
    • menyediakan kluster komputasi cpu_compute_target = "cpu-cluster" yang Anda buat untuk menjalankan perintah ini;
    • menyediakan lingkungan sklearn-env kustom yang Anda buat untuk menjalankan pekerjaan Azure Pembelajaran Mesin;
    • konfigurasikan tindakan baris perintah itu sendiri—dalam hal ini, perintahnya adalah python train_iris.py. Anda dapat mengakses input dan output dalam perintah melalui ${{ ... }} notasi; dan
    • mengonfigurasi metadata seperti nama tampilan dan nama eksperimen; di mana eksperimen adalah kontainer untuk semua iterasi yang dilakukan pada proyek tertentu. Semua pekerjaan yang dikirimkan dengan nama eksperimen yang sama akan dicantumkan di samping satu sama lain di studio Azure Pembelajaran Mesin.
from azure.ai.ml import command
from azure.ai.ml import Input

job = command(
    inputs=dict(kernel="linear", penalty=1.0),
    compute=cpu_compute_target,
    environment=f"{job_env.name}:{job_env.version}",
    code="./src/",
    command="python train_iris.py --kernel ${{inputs.kernel}} --penalty ${{inputs.penalty}}",
    experiment_name="sklearn-iris-flowers",
    display_name="sklearn-classify-iris-flower-images",
)

Mengirimkan pekerjaan

Sekarang saatnya untuk mengirimkan pekerjaan untuk dijalankan di Azure Pembelajaran Mesin. Kali ini Anda menggunakan create_or_update pada ml_client.jobs.

ml_client.jobs.create_or_update(job)

Setelah selesai, pekerjaan mendaftarkan model di ruang kerja Anda (sebagai hasil dari pelatihan) dan menghasilkan tautan untuk melihat pekerjaan di studio Azure Pembelajaran Mesin.

Peringatan

Azure Machine Learning menjalankan skrip pelatihan dengan menyalin seluruh direktori sumber. Jika Anda memiliki data sensitif yang tidak ingin Anda unggah, gunakan file .ignore atau jangan sertakan dalam direktori sumber.

Apa yang terjadi selama eksekusi pekerjaan

Saat pekerjaan dijalankan, pekerjaan akan melalui tahapan berikut:

  • Persiapan: Gambar docker dibuat sesuai dengan lingkungan yang ditentukan. Gambar diunggah ke registri kontainer ruang kerja dan di-cache untuk dijalankan nantinya. Log juga di-streaming ke riwayat eksekusi dan dapat ditampilkan untuk memantau perkembangan. Jika lingkungan yang dikumpulkan ditentukan, pencadangan gambar yang di-cache yang digunakan lingkungan yang dikumpulkan.

  • Penskalakan: Kluster mencoba meningkatkan skala jika kluster memerlukan lebih banyak simpul untuk menjalankan eksekusi daripada yang saat ini tersedia.

  • Berjalan: Semua skrip dalam src folder skrip diunggah ke target komputasi, penyimpanan data dipasang atau disalin, dan skrip dijalankan. Output dari stdout dan folder ./logs dialirkan ke riwayat eksekusi dan dapat digunakan untuk memantau eksekusi.

Menyetel hiperparameter model

Sekarang setelah Anda melihat cara melakukan eksekusi pelatihan Scikit-learn sederhana menggunakan SDK, mari kita lihat apakah Anda dapat lebih meningkatkan akurasi model Anda. Anda dapat menyetel dan mengoptimalkan hiperparameter model kami menggunakan kemampuan Azure Pembelajaran Mesinsweep.

Untuk menyetel hiperparameter model, tentukan ruang parameter untuk mencari selama pelatihan. Anda melakukan ini dengan mengganti beberapa parameter (kernel dan penalty) yang diteruskan ke pekerjaan pelatihan dengan input khusus dari azure.ml.sweep paket.

from azure.ai.ml.sweep import Choice

# we will reuse the command_job created before. we call it as a function so that we can apply inputs
# we do not apply the 'iris_csv' input again -- we will just use what was already defined earlier
job_for_sweep = job(
    kernel=Choice(values=["linear", "rbf", "poly", "sigmoid"]),
    penalty=Choice(values=[0.5, 1, 1.5]),
)

Kemudian, Anda mengonfigurasi pembersihan pada pekerjaan perintah, menggunakan beberapa parameter khusus sapuan, seperti metrik utama untuk ditonton dan algoritma pengambilan sampel yang akan digunakan.

Dalam kode berikut, kami menggunakan pengambilan sampel acak untuk mencoba set konfigurasi hiperparameter yang berbeda dalam upaya untuk memaksimalkan metrik utama kami, Accuracy.

sweep_job = job_for_sweep.sweep(
    compute="cpu-cluster",
    sampling_algorithm="random",
    primary_metric="Accuracy",
    goal="Maximize",
    max_total_trials=12,
    max_concurrent_trials=4,
)

Sekarang, Anda dapat mengirimkan pekerjaan ini seperti sebelumnya. Kali ini, Anda menjalankan pekerjaan pembersihan yang menyapu atas pekerjaan kereta Anda.

returned_sweep_job = ml_client.create_or_update(sweep_job)

# stream the output and wait until the job is finished
ml_client.jobs.stream(returned_sweep_job.name)

# refresh the latest status of the job after streaming
returned_sweep_job = ml_client.jobs.get(name=returned_sweep_job.name)

Anda dapat memantau pekerjaan dengan menggunakan tautan antarmuka pengguna studio yang disajikan selama pekerjaan berjalan.

Menemukan dan mendaftarkan model terbaik

Setelah semua eksekusi selesai, Anda dapat menemukan eksekusi yang menghasilkan model dengan akurasi tertinggi.

from azure.ai.ml.entities import Model

if returned_sweep_job.status == "Completed":

    # First let us get the run which gave us the best result
    best_run = returned_sweep_job.properties["best_child_run_id"]

    # lets get the model from this run
    model = Model(
        # the script stores the model as "sklearn-iris-flower-classify-model"
        path="azureml://jobs/{}/outputs/artifacts/paths/sklearn-iris-flower-classify-model/".format(
            best_run
        ),
        name="run-model-example",
        description="Model created from run.",
        type="custom_model",
    )

else:
    print(
        "Sweep job status: {}. Please wait until it completes".format(
            returned_sweep_job.status
        )
    )

Anda kemudian dapat mendaftarkan model ini.

registered_model = ml_client.models.create_or_update(model=model)

Menyebarkan model

Setelah mendaftarkan model, Anda dapat menyebarkannya dengan cara yang sama seperti model terdaftar lainnya di Azure Pembelajaran Mesin. Untuk informasi selengkapnya tentang penyebaran, lihat Menyebarkan dan menilai model pembelajaran mesin dengan titik akhir online terkelola menggunakan Python SDK v2.

Langkah berikutnya

Dalam artikel ini, Anda melatih dan mendaftarkan model scikit-learn, dan Anda belajar tentang opsi penyebaran. Lihat artikel lainnya ini untuk mempelajari selengkapnya tentang Azure Machine Learning.