Treine modelos de aprendizagem scikit em escala com o Azure Machine Learning

APLICA-SE A: Python SDK azure-ai-ml v2 (atual)

Neste artigo, saiba como executar seus scripts de treinamento scikit-learn com o SDK do Python do Azure Machine Learning v2.

Os scripts de exemplo neste artigo são usados para classificar imagens de flores de íris para criar um modelo de aprendizado de máquina baseado no conjunto de dados de íris do scikit-learn.

Quer esteja a treinar um modelo de aprendizagem científica de aprendizagem automática a partir do zero ou esteja a trazer um modelo existente para a nuvem, pode utilizar o Azure Machine Learning para expandir trabalhos de formação de código aberto utilizando recursos de computação em nuvem elástica. Você pode criar, implantar, versionar e monitorar modelos de nível de produção com o Azure Machine Learning.

Pré-requisitos

Você pode executar o código deste artigo em uma instância de computação do Azure Machine Learning ou em seu próprio Jupyter Notebook.

  • Instância de computação do Azure Machine Learning

    • Conclua Crie recursos para começar a criar uma instância de computação. Cada instância de computação inclui um servidor de notebook dedicado pré-carregado com o SDK e o repositório de exemplo de blocos de anotações.
    • Selecione a guia do bloco de anotações no estúdio do Azure Machine Learning. Na pasta de treinamento de exemplos, localize um bloco de anotações concluído e expandido navegando até este diretório: v2 > sdk > jobs > single-step > scikit-learn > train-hyperparameter-tune-deploy-with-sklearn.
    • Você pode usar o código pré-preenchido na pasta de treinamento de exemplo para concluir este tutorial.
  • Seu servidor de notebook Jupyter.

Configurar o trabalho

Esta seção configura o trabalho para treinamento carregando os pacotes Python necessários, conectando-se a um espaço de trabalho, criando um recurso de computação para executar um trabalho de comando e criando um ambiente para executar o trabalho.

Conectar-se ao espaço de trabalho

Primeiro, você precisa se conectar ao seu espaço de trabalho do Azure Machine Learning. O espaço de trabalho do Azure Machine Learning é o recurso de nível superior para o serviço. Ele fornece um local centralizado para trabalhar com todos os artefatos criados quando você usa o Aprendizado de Máquina do Azure.

Estamos usando DefaultAzureCredential para ter acesso ao espaço de trabalho. Essa credencial deve ser capaz de lidar com a maioria dos cenários de autenticação do SDK do Azure.

Se DefaultAzureCredential não funcionar para você, consulte azure-identity reference documentation ou Set up authentication para obter mais credenciais disponíveis.

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

# Authentication package
from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()

Se preferir usar um navegador para entrar e autenticar, remova os comentários no código a seguir e use-o.

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

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

Em seguida, obtenha um identificador para o espaço de trabalho fornecendo sua ID de Assinatura, nome do Grupo de Recursos e nome do espaço de trabalho. Para encontrar estes parâmetros:

  1. Procure no canto superior direito da barra de ferramentas do estúdio do Azure Machine Learning o nome do seu espaço de trabalho.
  2. Selecione o nome do espaço de trabalho para mostrar o Grupo de Recursos e a ID da Assinatura.
  3. Copie os valores para Grupo de Recursos e ID de Assinatura para o código.
# 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>",
)

O resultado da execução desse script é um identificador de espaço de trabalho que você usa para gerenciar outros recursos e trabalhos.

Nota

A criação MLClient não conectará o cliente ao espaço de trabalho. A inicialização do cliente é preguiçosa e aguardará a primeira vez que precisar fazer uma chamada. Neste artigo, isso acontecerá durante a criação da computação.

Criar um recurso de computação

O Azure Machine Learning precisa de um recurso de computação para executar um trabalho. Esse recurso pode ser máquinas de um ou vários nós com Linux ou sistema operacional Windows, ou uma malha de computação específica, como o Spark.

No script de exemplo a seguir, provisionamos um Linux compute cluster. Você pode ver a Azure Machine Learning pricing página para obter a lista completa de tamanhos e preços de VM. Só precisamos de um cluster básico para este exemplo; assim, escolhemos um modelo Standard_DS3_v2 com 2 núcleos vCPU e 7 GB de RAM para criar uma computação do Azure Machine Learning.

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}"
)

Criar um ambiente de trabalho

Para executar um trabalho do Azure Machine Learning, você precisa de um ambiente. Um ambiente do Azure Machine Learning encapsula as dependências (como tempo de execução de software e bibliotecas) necessárias para executar seu script de treinamento de aprendizado de máquina em seu recurso de computação. Esse ambiente é semelhante a um ambiente Python em sua máquina local.

O Azure Machine Learning permite que você use um ambiente com curadoria (ou pronto) ou crie um ambiente personalizado usando uma imagem do Docker ou uma configuração Conda. Neste artigo, você cria um ambiente personalizado para seus trabalhos, usando um arquivo Conda YAML.

Criar um ambiente personalizado

Para criar seu ambiente personalizado, defina suas dependências Conda em um arquivo YAML. Primeiro, crie um diretório para armazenar o arquivo. Neste exemplo, nomeamos o diretório env.

import os

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

Em seguida, crie o arquivo no diretório dependencies. Neste exemplo, nomeamos o arquivo conda.ymlcomo .

%%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

A especificação contém alguns pacotes usuais (como numpy e pip) que você usa em seu trabalho.

Em seguida, use o arquivo YAML para criar e registrar esse ambiente personalizado em seu espaço de trabalho. O ambiente é empacotado em um contêiner do Docker em tempo de execução.

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}"
)

Para obter mais informações sobre como criar e usar ambientes, consulte Criar e usar ambientes de software no Azure Machine Learning.

[Opcional] Crie um ambiente personalizado com o Intel® Extension for Scikit-Learn

Quer acelerar seus scripts de aprendizado de scikit no hardware Intel? Tente adicionar Intel® Extension for Scikit-Learn em seu arquivo conda yaml e siga as etapas subsequentes detalhadas acima. Mostraremos como habilitar essas otimizações mais adiante neste exemplo:

%%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

Configurar e enviar seu trabalho de treinamento

Nesta seção, abordamos como executar um trabalho de treinamento, usando um script de treinamento que fornecemos. Para começar, crie o trabalho de treinamento configurando o comando para executar o script de treinamento. Em seguida, envie o trabalho de treinamento para ser executado no Azure Machine Learning.

Preparar o guião de formação

Neste artigo, fornecemos o script de treinamento train_iris.py. Na prática, você deve ser capaz de usar qualquer script de treinamento personalizado como está e executá-lo com o Azure Machine Learning sem precisar modificar seu código.

Nota

O script de treinamento fornecido faz o seguinte:

  • mostra como registrar algumas métricas em sua execução do Azure Machine Learning;
  • descarrega e extrai os dados de formação utilizando iris = datasets.load_iris();
  • treina um modelo, depois salva-o e registra-o.

Para usar e acessar seus próprios dados, veja como ler e gravar dados em um trabalho para disponibilizar dados durante o treinamento.

Para usar o script de treinamento, primeiro crie um diretório onde você armazenará o arquivo.

import os

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

Em seguida, crie o arquivo de script no diretório de origem.

%%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()

[Opcional] Habilite a extensão Intel® para otimizações do Scikit-Learn para obter mais desempenho no hardware Intel

Se você tiver instalado o Intel® Extension for Scikit-Learn (como demonstrado na seção anterior), poderá ativar as otimizações de desempenho adicionando as duas linhas de código à parte superior do arquivo de script, conforme mostrado abaixo.

Para saber mais sobre o Intel® Extension for Scikit-Learn, visite a documentação do pacote.

%%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()

Construa o trabalho de formação

Agora que você tem todos os ativos necessários para executar seu trabalho, é hora de criá-lo usando o SDK do Python do Azure Machine Learning v2. Para executar o trabalho, criamos um commandarquivo .

Um Aprendizado command de Máquina do Azure é um recurso que especifica todos os detalhes necessários para executar seu código de treinamento na nuvem. Esses detalhes incluem as entradas e saídas, tipo de hardware a ser usado, software a ser instalado e como executar seu código. O command contém informações para executar um único comando.

Configurar o comando

Você usa o propósito command geral para executar o script de treinamento e executar as tarefas desejadas. Crie um Command objeto para especificar os detalhes de configuração do seu trabalho de treinamento.

  • As entradas para este comando incluem o número de épocas, taxa de aprendizagem, momento e diretório de saída.
  • Para os valores dos parâmetros:
    • fornecer o cluster cpu_compute_target = "cpu-cluster" de computação que você criou para executar esse comando;
    • fornecer o ambiente sklearn-env personalizado que você criou para executar o trabalho do Azure Machine Learning;
    • Configure a própria ação da linha de comando — nesse caso, o comando é python train_iris.py. Você pode acessar as entradas e saídas no comando através da ${{ ... }} notação;
    • configurar os metadados, como o nome para exibição e o nome do experimento; onde um experimento é um contêiner para todas as iterações que se faz em um determinado projeto. Todos os trabalhos enviados com o mesmo nome de experimento seriam listados um ao lado do outro no estúdio do Azure Machine Learning.
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",
)

Submeter o trabalho

Agora é hora de enviar o trabalho para ser executado no Azure Machine Learning. Desta vez, você usa create_or_update em ml_client.jobs.

ml_client.jobs.create_or_update(job)

Depois de concluído, o trabalho registra um modelo em seu espaço de trabalho (como resultado do treinamento) e gera um link para exibir o trabalho no estúdio do Azure Machine Learning.

Aviso

O Azure Machine Learning executa scripts de treinamento copiando todo o diretório de origem. Se você tiver dados confidenciais que não deseja carregar, use um arquivo .ignore ou não o inclua no diretório de origem.

O que acontece durante a execução do trabalho

À medida que o trabalho é executado, ele passa pelas seguintes etapas:

  • Preparação: Uma imagem docker é criada de acordo com o ambiente definido. A imagem é carregada no registro de contêiner do espaço de trabalho e armazenada em cache para execuções posteriores. Os logs também são transmitidos para o histórico de execução e podem ser visualizados para monitorar o progresso. Se um ambiente com curadoria for especificado, a imagem armazenada em cache que faz o backup desse ambiente curado será usada.

  • Dimensionamento: o cluster tenta aumentar a escala se o cluster exigir mais nós para executar a execução do que os disponíveis no momento.

  • Em execução: Todos os scripts na pasta de script src são carregados no destino de computação, os armazenamentos de dados são montados ou copiados e o script é executado. As saídas do stdout e da pasta ./logs são transmitidas para o histórico de execução e podem ser usadas para monitorar a execução.

Ajustar hiperparâmetros do modelo

Agora que você já viu como fazer um treinamento simples de aprendizagem Scikit usando o SDK, vamos ver se você pode melhorar ainda mais a precisão do seu modelo. Você pode ajustar e otimizar os hiperparâmetros do nosso modelo usando os sweep recursos do Azure Machine Learning.

Para ajustar os hiperparâmetros do modelo, defina o espaço de parâmetros no qual pesquisar durante o treinamento. Você faz isso substituindo alguns dos parâmetros (kernel e penalty) passados para o trabalho de treinamento por entradas especiais do azure.ml.sweep pacote.

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]),
)

Em seguida, você configura a varredura no trabalho de comando, usando alguns parâmetros específicos da varredura, como a métrica primária a ser observada e o algoritmo de amostragem a ser usado.

No código a seguir, usamos amostragem aleatória para tentar diferentes conjuntos de configuração de hiperparâmetros na tentativa de maximizar nossa métrica primária, 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,
)

Agora, você pode enviar este trabalho como antes. Desta vez, você está executando um trabalho de varredura que varre seu trabalho de trem.

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)

Você pode monitorar o trabalho usando o link da interface do usuário do estúdio que é apresentado durante a execução do trabalho.

Encontre e registe o melhor modelo

Uma vez concluídas todas as execuções, você pode encontrar a execução que produziu o modelo com a mais alta precisão.

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
        )
    )

Em seguida, pode registar este modelo.

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

Implementar o modelo

Depois de registrar seu modelo, você pode implantá-lo da mesma maneira que qualquer outro modelo registrado no Azure Machine Learning. Para obter mais informações sobre implantação, consulte Implantar e pontuar um modelo de aprendizado de máquina com ponto de extremidade online gerenciado usando o Python SDK v2.

Próximos passos

Neste artigo, você treinou e registrou um modelo scikit-learn, e aprendeu sobre as opções de implantação. Consulte estes outros artigos para saber mais sobre o Azure Machine Learning.