Como criar uma rotina de previsão personalizada com o Keras

Logotipo do Colab Executar este tutorial como um notebook no Colab (em inglês) Logotipo do GitHub Ver o notebook no GitHub (em inglês)

Neste tutorial, você verá como implantar um modelo Keras treinado para o AI Platform Prediction e exibir previsões usando uma rotina personalizada. Isso permite personalizar como o AI Platform Prediction responderá a cada solicitação de previsão.

Neste exemplo, você usará uma rotina de previsão personalizada para pré-processar entradas de previsão, dimensionando-a, e para pós-processar a saída da previsão, convertendo as saídas de probabilidade softmax em strings de rótulo.

No tutorial, há várias etapas:

  • Treinamento local de um modelo simples do Keras
  • Criação e implantação de uma rotina de previsão personalizada no AI Platform Prediction
  • Exibição das solicitações de previsão dessa implantação

Conjunto de dados

Neste tutorial, usamos o conjunto de dados Iris da R.A. Fisher. Ele é pequeno, mas muito usado para testar técnicas de machine learning. Cada instância tem quatro atributos numéricos, que são medidas diferentes de uma flor, e um rótulo de destino que a marca como um dos três tipos de flor de íris: Iris setosa, Iris versicolor ou Iris virginica.

Neste tutorial, usamos a cópia do conjunto de dados Iris incluído na biblioteca do scikit-learn (em inglês).

Objetivo

O objetivo é treinar um modelo que use as medidas de uma flor como entrada para prever o tipo de iris dela.

O foco deste tutorial está mais no uso desse modelo com o AI Platform Prediction do que na criação do modelo em si.

Custos

Neste tutorial, há componentes faturáveis do Google Cloud.

  • AI Platform Prediction
  • Cloud Storage

Consulte os preços do AI Platform Prediction e do Cloud Storage. Use a calculadora de preços para gerar uma estimativa de custo com base no uso projetado.

Antes de começar

É necessário realizar várias etapas antes de treinar e implantar um modelo no AI Platform Prediction:

  • Configure o ambiente de desenvolvimento local.
  • Configure um projeto do Google Cloud com o faturamento e as APIs necessárias ativadas.
  • Crie um bucket do Cloud Storage para armazenar o pacote de treinamento e o modelo treinado.

Configurar o ambiente de desenvolvimento local

Você precisa dos itens a seguir para concluir este tutorial:

  • Python 3
  • virtualenv
  • SDK do Cloud

No guia do Google Cloud sobre como configurar um ambiente de desenvolvimento do Python (em inglês), apresentamos instruções detalhadas para atender a esses requisitos. As etapas a seguir compõem um conjunto resumido de instruções:

  1. Instale o Python 3.

  2. Instale o virtualenv e crie um ambiente virtual que use o Python 3.

  3. Ative esse ambiente.

  4. Conclua as etapas na seção a seguir para instalar o SDK do Cloud.

Configurar seu projeto do Google Cloud

  1. Faça login na sua conta do Google.

    Se você ainda não tiver uma, inscreva-se.

  2. No Console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar a página do seletor de projetos

  3. Verifique se o faturamento está ativado para seu projeto na nuvem. Saiba como confirmar se o faturamento está ativado para o projeto.

  4. Ative as APIs AI Platform Training & Prediction and Compute Engine.

    Ative as APIs

  5. Instale e inicialize o SDK do Cloud..

Autenticar a conta do GCP

Para configurar a autenticação, é necessário criar uma chave da conta de serviço e definir uma variável de ambiente para o caminho do arquivo dessa chave.

  1. Crie uma chave da conta de serviço para autenticação:
    1. No Console do Cloud, acesse a página Criar chave da conta de serviço.

      Acessar a página "Criar chave da conta de serviço"
    2. Na lista suspensa Conta de serviço, selecione Nova conta de serviço.
    3. No campo Nome da conta de serviço, insira um nome.
    4. Na lista suspensa Papel, selecione Machine Learning Engine > Administrador do ML Engine e Storage > Administrador de objeto do Storage.

      Observação: o campo Papel autoriza a conta de serviço a acessar recursos. Se quiser visualizar e alterar esse campo mais tarde, use o Console do Cloud. Se você estiver desenvolvendo um app de produção, talvez seja necessário especificar permissões mais granulares do que Machine Learning Engine > Administrador do ML Engine e Storage > Administrador de objeto do Storage. Para mais informações, consulte Controle de acesso para o AI Platform Prediction.
    5. Clique em Criar. O download de um arquivo JSON com a chave é feito no computador.
  2. Defina a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS como o caminho do arquivo JSON que contém a chave da conta de serviço. Essa variável aplica-se apenas à sessão de shell atual. Portanto, se você abrir uma nova sessão, defina a variável novamente.

Criar um bucket do Cloud Storage

Para implantar uma rotina de predição personalizada, faça upload dos artefatos de modelo treinados e do código personalizado no Cloud Storage.

Defina o nome do bucket do Cloud Storage como uma variável de ambiente. Ele precisa ser exclusivo em todos os buckets do Cloud Storage:

BUCKET_NAME="your-bucket-name"

Selecione uma região onde o AI Platform Prediction esteja disponível e crie outra variável de ambiente.

REGION="us-central1"

Crie o bucket do Cloud Storage nessa região e, posteriormente, use a mesma região para treinamento e previsão. Execute o comando a seguir para criar o bucket, caso ele ainda não exista:

gsutil mb -l $REGION gs://$BUCKET_NAME

Como criar e treinar um modelo do Keras

Muitas vezes, não é possível usar os dados na forma bruta para treinar um modelo de machine learning. Mesmo quando é possível, o pré-processamento dos dados antes de usá-los para treinamento às vezes pode melhorar o modelo.

Se você espera que a entrada da predição tenha o mesmo formato que os dados de treinamento, aplique o pré-processamento idêntico durante o treinamento e a predição para garantir que o modelo faça predições consistentes.

Nesta seção, crie um módulo de pré-processamento e use-o como parte do treinamento. Em seguida, exporte um pré-processador com as características aprendidas durante o treinamento para usar posteriormente na rotina de predição personalizada.

Instalar dependências para treinamento local

O treinamento local requer várias dependências:

pip install numpy scikit-learn 'tensorflow>=1.13,<2'

Escrever o código do pré-processador

É possível melhorar o modelo realizando o escalonamento dos dados de treinamento de modo que cada coluna de atributo numérico tenha uma média de 0 e um desvio padrão de 1.

Crie preprocess.py, que contém uma classe para fazer esse escalonamento:

import numpy as np

class MySimpleScaler(object):
  def __init__(self):
    self._means = None
    self._stds = None

  def preprocess(self, data):
    if self._means is None: # during training only
      self._means = np.mean(data, axis=0)

    if self._stds is None: # during training only
      self._stds = np.std(data, axis=0)
      if not self._stds.all():
        raise ValueError('At least one column has standard deviation of 0.')

    return (data - self._means) / self._stds

Uma instância de MySimpleScaler salva as médias e os desvios padrão de cada coluna de atributo no primeiro uso. Em seguida, ela usa essas estatísticas de resumo para escalonar os dados encontrados posteriormente.

Isso permite armazenar as características da distribuição de treinamento e usá-las em um pré-processamento idêntico no momento da predição.

Treinar o modelo

Em seguida, use preprocess.MySimpleScaler para pré-processar os dados da íris e, em seguida, treine uma rede neural simples usando o Keras.

No final, exporte o modelo Keras treinado como um arquivo HDF5 (.h5) e exporte a instância de MySimpleScaler como um arquivo pickle (.pkl):

import pickle

from sklearn.datasets import load_iris
import tensorflow as tf

from preprocess import MySimpleScaler

iris = load_iris()
scaler = MySimpleScaler()
num_classes = len(iris.target_names)
X = scaler.preprocess(iris.data)
y = tf.keras.utils.to_categorical(iris.target, num_classes=num_classes)

model = tf.keras.Sequential()
model.add(tf.keras.layers.Dense(25, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(25, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(num_classes, activation=tf.nn.softmax))
model.compile(
  optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(X, y, epochs=10, batch_size=1)

model.save('model.h5')
with open ('preprocessor.pkl', 'wb') as f:
  pickle.dump(scaler, f)

Como implantar uma rotina de predição personalizada

Para implantar uma rotina de predição personalizada a fim de exibir as predições do modelo treinado, faça o seguinte:

  • Crie um preditor personalizado para processar as solicitações.
  • Empacote o preditor e o módulo de pré-processamento.
  • Faça upload dos artefatos do modelo e do código personalizado no Cloud Storage.
  • Implante a rotina de previsão personalizada no AI Platform Prediction.

Criar um previsor personalizado

Para implantar uma rotina de previsão personalizada, é necessário criar uma classe que implemente a interface do Predictor. Isso informa ao AI Platform Prediction como carregar o modelo e processar as solicitações de previsão.

Escreva o seguinte código em predictor.py:

import os
import pickle

import numpy as np
from sklearn.datasets import load_iris
import tensorflow as tf

class MyPredictor(object):
  def __init__(self, model, preprocessor):
    self._model = model
    self._preprocessor = preprocessor
    self._class_names = load_iris().target_names

  def predict(self, instances, **kwargs):
    inputs = np.asarray(instances)
    preprocessed_inputs = self._preprocessor.preprocess(inputs)
    outputs = self._model.predict(preprocessed_inputs)
    if kwargs.get('probabilities'):
      return outputs.tolist()
    else:
      return [self._class_names[index] for index in np.argmax(outputs, axis=1)]

  @classmethod
  def from_path(cls, model_dir):
    model_path = os.path.join(model_dir, 'model.h5')
    model = tf.keras.models.load_model(model_path)

    preprocessor_path = os.path.join(model_dir, 'preprocessor.pkl')
    with open(preprocessor_path, 'rb') as f:
      preprocessor = pickle.load(f)

    return cls(model, preprocessor)

Além de usar o pré-processador definido durante o treinamento, esse previsor executa uma etapa de pós-processamento que converte a saída softmax da rede neural (uma matriz que indica a probabilidade de cada rótulo ser o correto) no rótulo com a maior probabilidade.

No entanto, se o previsor receber um argumento de palavra-chave de probabilities com o valor True, ele retornará a matriz de probabilidade. Na última parte deste tutorial, você verá como fornecer esse argumento de palavra-chave.

Empacotar o código personalizado

Você precisa empacotar predictor.py e preprocess.py como um pacote de distribuição de origem .tar.gz. Depois, forneça esse pacote ao AI Platform Prediction para que seu código personalizado seja usado para exibir previsões.

Escreva o seguinte setup.py para definir seu pacote:

from setuptools import setup

setup(
    name='my_custom_code',
    version='0.1',
    scripts=['predictor.py', 'preprocess.py'])

Execute o seguinte comando para criar dist/my_custom_code-0.1.tar.gz:

python setup.py sdist --formats=gztar

Fazer upload dos artefatos do modelo e do código personalizado no Cloud Storage

Antes de implantar o modelo para a exibição de previsões, o AI Platform Prediction precisa acessar os seguintes arquivos no Cloud Storage:

  • model.h5 (artefato do modelo)
  • preprocessor.pkl (artefato do modelo)
  • my_custom_code-0.1.tar.gz (código personalizado)

Os artefatos do modelo precisam ser armazenados juntos em um diretório de modelo que o Predictor pode acessar como o argumento model_dir no método de classe from_path. O código personalizado não precisa estar no mesmo diretório. Execute os comandos a seguir para fazer upload dos arquivos:

gsutil cp ./dist/my_custom_code-0.1.tar.gz gs://$BUCKET_NAME/custom_prediction_routine_tutorial/my_custom_code-0.1.tar.gz
gsutil cp model.h5 preprocessor.pkl gs://$BUCKET_NAME/custom_prediction_routine_tutorial/model/

Implantar a rotina de previsão personalizada

Crie um recurso de modelo e um de versão para implantar uma rotina de previsão personalizada. Primeiramente, defina as variáveis de ambiente com os nomes dos recursos:

MODEL_NAME='IrisPredictor'
VERSION_NAME='v1'

Em seguida, crie o modelo:

gcloud ai-platform models create $MODEL_NAME \
  --regions $REGION

Na sequência, crie uma versão. Nesta etapa, insira os caminhos para os artefatos e o código personalizado que você enviou ao Cloud Storage:

gcloud components install beta

gcloud beta ai-platform versions create $VERSION_NAME \
  --model $MODEL_NAME \
  --runtime-version 1.13 \
  --python-version 3.5 \
  --origin gs://$BUCKET_NAME/custom_prediction_routine_tutorial/model/ \
  --package-uris gs://$BUCKET_NAME/custom_prediction_routine_tutorial/my_custom_code-0.1.tar.gz \
  --prediction-class predictor.MyPredictor

Saiba mais sobre as opções que você precisa especificar ao implantar uma rotina de previsão personalizada.

Como exibir previsões on-line

Teste a implantação enviando uma solicitação de predição on-line. Instale primeiro a biblioteca de cliente de APIs do Google para Python:

pip install --upgrade google-api-python-client

Em seguida, envie duas instâncias de dados da íris para a versão implantada executando o seguinte código Python:

import googleapiclient.discovery

instances = [
  [6.7, 3.1, 4.7, 1.5],
  [4.6, 3.1, 1.5, 0.2],
]

service = googleapiclient.discovery.build('ml', 'v1')
name = 'projects/{}/models/{}/versions/{}'.format(PROJECT_ID, MODEL_NAME, VERSION_NAME)

response = service.projects().predict(
    name=name,
    body={'instances': instances}
).execute()

if 'error' in response:
    raise RuntimeError(response['error'])
else:
  print(response['predictions'])
['versicolor', 'setosa']

Como enviar argumentos de palavra-chave

Ao enviar uma solicitação de previsão para uma rotina de previsão personalizada, é possível inserir mais campos no corpo da solicitação. O método predict do Predictor os recebe como campos do dicionário **kwargs.

O código a seguir envia a mesma solicitação de antes, mas, desta vez, adiciona um campo probabilities ao corpo da solicitação:

response = service.projects().predict(
    name=name,
    body={'instances': instances, 'probabilities': True}
).execute()

if 'error' in response:
    raise RuntimeError(response['error'])
else:
  print(response['predictions'])
[[0.0019204545533284545, 0.8623144626617432, 0.13576509058475494], [0.999488353729248, 0.000511515187099576, 1.293626752385535e-07]]

Como fazer a limpeza

Para limpar todos os recursos do GCP usados neste projeto, exclua o projeto do GCP usado no tutorial.

Também é possível limpar recursos individuais com os comandos a seguir:

# Delete version resource
gcloud ai-platform versions delete $VERSION_NAME --quiet --model $MODEL_NAME

# Delete model resource
gcloud ai-platform models delete $MODEL_NAME --quiet

# Delete Cloud Storage objects that were created
gsutil -m rm -r gs://$BUCKET_NAME/custom_prediction_routine_tutorial

A seguir