Executar este tutorial como um notebook no Colab | Ver o notebook no GitHub (em inglês) |
Neste tutorial, mostramos como treinar uma rede neural no AI Platform usando a API Keras Sequential e como exibir previsões desse modelo.
O Keras é uma API de alto nível para criar e treinar modelos de aprendizado profundo. tf.keras é a implementação do TensorFlow dessa API.
Nas duas primeiras partes do tutorial, você verá o treinamento de um modelo no AI Platform com o uso do código do Keras pré-escrito, a implantação do modelo treinado no AI Platform e a exibição de previsões on-line com base no modelo implantado.
Na última parte do tutorial, veremos o código de treinamento usado neste modelo e faremos uma verificação de compatibilidade dele com o AI Platform. Para saber mais sobre como criar modelos de machine learning no Keras de maneira mais generalizada, leia os tutoriais do Keras do TensorFlow (em inglês).
Conjunto de dados
Neste tutorial, usamos o conjunto de dados de renda do Censo dos Estados Unidos fornecido pelo repositório de machine learning da UC Irvine (ambos em inglês). Esse conjunto de dados contém informações sobre pessoas de um banco de dados do censo de 1994, inclusive idade, escolaridade, estado civil, profissão e se ganham mais de US$ 50.000 por ano.
Objetivo
A meta é treinar uma rede neural profunda (DNN, na sigla em inglês) usando Keras, que prevê se uma pessoa ganha mais de US$ 50.000 por ano (rótulo de destino) com base em outras informações do censo sobre a pessoa (atributos).
O foco deste tutorial é usar esse modelo com o AI Platform, mais do que a criação do modelo em si. No entanto, é sempre importante pensar em problemas em potencial e consequências não intencionais durante a criação dos sistemas de machine learning. Consulte o exercício do curso intensivo de machine learning sobre imparcialidade para saber mais sobre as fontes de viés no conjunto de dados do censo, bem como a imparcialidade do machine learning em geral.
Custos
Neste tutorial, usamos componentes faturáveis do Google Cloud:
- AI Platform Training
- AI Platform Prediction
- Cloud Storage
Saiba mais sobre os preços do AI Platform Training, 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:
- 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:
- Git
- Python 3
- virtualenv
- O SDK Google Cloud
No guia do Google Cloud sobre Como configurar um ambiente de desenvolvimento do Python, apresentamos instruções detalhadas para atender a esses requisitos. Veja a seguir um conjunto condensado de instruções:
Instale o virtualenv e crie um ambiente virtual que use o Python 3.
Ative esse ambiente.
Conclua as etapas na seção a seguir para instalar o SDK Google Cloud.
Configurar seu projeto do Google Cloud
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the AI Platform Training & Prediction and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the AI Platform Training & Prediction and Compute Engine APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
Autenticar a conta do GCP
Para configurar a autenticação, crie uma chave da conta de serviço e defina uma variável de ambiente para o caminho do arquivo dessa chave.
-
Crie uma conta de serviço:
-
No Console do Google Cloud, acesse a página Criar conta de serviço.
- No campo Nome da conta de serviço, insira um nome.
- Opcional: no campo Descrição da conta de serviço, digite uma descrição.
- Clique em Criar.
- Clique no campo Selecionar um papel. Em Todos os papéis, selecione AI Platform > Administrador do AI Platform.
- Clique em Adicionar outro papel.
-
Clique no campo Selecionar um papel. Em Todos os papéis, selecione Armazenamento > Administrador de objetos do Storage.
-
Clique em Concluído para criar a conta de serviço.
Não feche a janela do navegador. Você vai usá-la na próxima etapa.
-
-
Crie uma chave da conta de serviço para autenticação:
- No console do Google Cloud, clique no endereço de e-mail da conta de serviço que você criou.
- Clique em Chaves.
- Clique em Adicionar chave e, depois, em Criar nova chave.
- Clique em Criar. O download de um arquivo de chave JSON é feito no seu computador.
- Clique em Fechar.
-
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
Ao enviar um job de treinamento usando o SDK do Cloud, você faz upload de um pacote do Python que contém o código de treinamento para um bucket do Cloud Storage. O AI Platform executa o código desse pacote. Neste tutorial, o AI Platform também salva o modelo treinado resultante do job no mesmo bucket. Em seguida, crie uma versão de modelo do AI Platform com base nessa saída para exibir predições on-line.
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 em que o AI Platform Training e o AI Platform Prediction estejam disponíveis e crie outra variável de ambiente. Exemplo:
REGION="us-central1"
Crie o bucket do Cloud Storage nessa região e, posteriormente, use a mesma região no treinamento e na previsão. Execute o comando a seguir para criar o bucket, caso ele ainda não exista:
gsutil mb -l $REGION gs://$BUCKET_NAME
Guia de início rápido para treinamento no AI Platform
Nesta seção do tutorial, você verá como enviar um job de treinamento para o AI Platform. Esse job executa um código de amostra que usa o Keras para treinar uma rede neural profunda com base nos dados do censo dos Estados Unidos. Ele exibe o modelo treinado como um diretório SavedModel do TensorFlow (em inglês) no bucket do Cloud Storage.
Receber o código de treinamento e as dependências
Primeiro, faça o download do código de treinamento e altere o diretório de trabalho:
# Clone the repository of AI Platform samples
git clone --depth 1 https://github.com/GoogleCloudPlatform/cloudml-samples
# Set the working directory to the sample code directory
cd cloudml-samples/census/tf-keras
O código de treinamento é estruturado como um pacote Python no subdiretório trainer/
:
# `ls` shows the working directory's contents. The `p` flag adds trailing
# slashes to subdirectory names. The `R` flag lists subdirectories recursively.
ls -pR
.: README.md requirements.txt trainer/ ./trainer: __init__.py model.py task.py util.py
Em seguida, instale as dependências do Python necessárias para treinar o modelo localmente:
pip install -r requirements.txt
Quando você gera o job de treinamento no AI Platform, as dependências são pré-instaladas com base na versão do ambiente de execução escolhida.
Treinar o modelo localmente
Antes do treinamento no AI Platform, treine o job localmente para verificar se a estrutura do arquivo e o empacotamento estão corretos.
Para um job complexo ou que exija muitos recursos, convém treinar localmente em uma pequena amostra do conjunto de dados para verificar o código. Em seguida, gere o job no AI Platform para treinamento em todo o conjunto de dados.
Essa amostra gera um job relativamente rápido em um conjunto de dados pequeno. Dessa maneira, o treinamento local e o job do AI Platform geram o mesmo código nos mesmos dados.
Gere o seguinte comando para treinar um modelo localmente:
# This is similar to `python -m trainer.task --job-dir local-training-output`
# but it better replicates the AI Platform environment, especially
# for distributed training (not applicable here).
gcloud ai-platform local train \
--package-path trainer \
--module-name trainer.task \
--job-dir local-training-output
Observe o progresso do treinamento no shell. Ao final, o aplicativo de treinamento exporta o modelo treinado e imprime uma mensagem semelhante a esta:
Model exported to: local-training-output/keras_export/1553709223
Treinar o modelo usando o AI Platform
Em seguida, envie um job de treinamento para o AI Platform. Isso gera o módulo de treinamento na nuvem e exporta o modelo treinado para o Cloud Storage.
Primeiro, atribua um nome ao job de treinamento e escolha um diretório no bucket do Cloud Storage para salvar arquivos intermediários e de saída. Defina-os como variáveis de ambiente. Exemplo:
JOB_NAME="my_first_keras_job"
JOB_DIR="gs://$BUCKET_NAME/keras-job-dir"
Execute o comando a seguir para empacotar o diretório trainer/
, carregá-lo para o --job-dir
especificado e instruir o AI Platform para executar o módulo trainer.task
desse pacote.
A sinalização --stream-logs
permite visualizar os registros de treinamento no shell. Também é possível ver os registros e outros detalhes dos jobs no Console do Google Cloud.
gcloud ai-platform jobs submit training $JOB_NAME \
--package-path trainer/ \
--module-name trainer.task \
--region $REGION \
--python-version 3.7 \
--runtime-version 1.15 \
--job-dir $JOB_DIR \
--stream-logs
Isso pode demorar mais do que o treinamento local, mas é possível observar o progresso do treinamento no shell de maneira semelhante. Ao final, o job de treinamento exporta o modelo treinado para o bucket do Cloud Storage e imprime uma mensagem como esta:
INFO 2019-03-27 17:57:11 +0000 master-replica-0 Model exported to: gs://your-bucket-name/keras-job-dir/keras_export/1553709421 INFO 2019-03-27 17:57:11 +0000 master-replica-0 Module completed; cleaning up. INFO 2019-03-27 17:57:11 +0000 master-replica-0 Clean up finished. INFO 2019-03-27 17:57:11 +0000 master-replica-0 Task completed successfully.
Ajuste de hiperparâmetros
Opcionalmente, é possível executar o ajuste de hiperparâmetros usando o arquivo de configuração hptuning_config.yaml
incluído. Esse arquivo instrui o AI Platform a ajustar o tamanho do lote e a taxa de aprendizado para o treinamento em várias tentativas para maximizar a precisão.
Neste exemplo, o código de treinamento usa um callback
TensorBoard,
que cria os Summary
Event
do TensorFlow
durante o treinamento (ambos os links em inglês). O AI Platform usa esses eventos para rastrear a métrica que você quer otimizar. Saiba mais sobre o ajuste de hiperparâmetros no treinamento do AI Platform.
gcloud ai-platform jobs submit training ${JOB_NAME}_hpt \
--config hptuning_config.yaml \
--package-path trainer/ \
--module-name trainer.task \
--region $REGION \
--python-version 3.7 \
--runtime-version 1.15 \
--job-dir $JOB_DIR \
--stream-logs
Guia de início rápido para previsões on-line no AI Platform
Nesta seção, você verá como usar o AI Platform e o modelo treinado da seção anterior para prever a faixa de renda de uma pessoa com base em outras informações do censo sobre ela.
Criar recursos de modelo e versão no AI Platform
Para exibir previsões on-line usando o modelo treinado e exportado no guia de início rápido para treinamento, crie um recurso de modelo no AI Platform e um recurso de versão dentro dele. O recurso de versão é o que realmente usa o modelo treinado para exibir previsões. Essa estrutura permite ajustar e treinar o modelo muitas vezes e organizar todas as versões juntas no AI Platform. Saiba mais sobre modelos e versões.
Primeiro, nomeie e crie o recurso de modelo:
MODEL_NAME="my_first_keras_model"
gcloud ai-platform models create $MODEL_NAME \
--regions $REGION
Created ml engine model [projects/your-project-id/models/my_first_keras_model].
Em seguida, crie a versão do modelo. O job de treinamento do guia de início rápido para treinamento (em inglês) exportou um diretório SavedModel do TensorFlow (em inglês) com carimbo de data/hora para o bucket do Cloud Storage. O AI Platform usa esse diretório para criar uma versão de modelo. Saiba mais sobre SavedModel e AI Platform.
É possível encontrar o caminho para esse diretório nos registros do job de treinamento. Procure uma linha como esta:
Model exported to: gs://your-bucket-name/keras-job-dir/keras_export/1545439782
Execute o seguinte comando para identificar o diretório SavedModel e o use para criar um recurso de versão de modelo:
MODEL_VERSION="v1"
# Get a list of directories in the `keras_export` parent directory. Then pick
# the directory with the latest timestamp, in case you've trained multiple
# times.
SAVED_MODEL_PATH=$(gsutil ls $JOB_DIR/keras_export | head -n 1)
# Create model version based on that SavedModel directory
gcloud ai-platform versions create $MODEL_VERSION \
--model $MODEL_NAME \
--region $REGION \
--runtime-version 1.15 \
--python-version 3.7 \
--framework tensorflow \
--origin $SAVED_MODEL_PATH
Preparar entrada para previsão
Para receber previsões válidas e úteis, pré-processe a entrada para previsão da mesma maneira que os dados de treinamento foram pré-processados. Em um sistema de produção, convém criar um pipeline de pré-processamento que possa ser usado de maneira idêntica no momento do treinamento e da previsão.
Neste exercício, use o código de carregamento de dados do pacote de treinamento para selecionar uma amostra aleatória dos dados de avaliação. Esses dados estão no formato usado para avaliar a acurácia após cada período de treinamento. Dessa maneira, eles podem ser usados para enviar previsões de teste sem pré-processamento adicional.
Abra o interpretador Python (python
) no diretório de trabalho atual para executar os próximos snippets de código:
from trainer import util
_, _, eval_x, eval_y = util.load_data()
prediction_input = eval_x.sample(20)
prediction_targets = eval_y[prediction_input.index]
prediction_input
age | workclass | education_num | marital_status | occupation | relationship | race | capital_gain | capital_loss | hours_per_week | native_country | |
---|---|---|---|---|---|---|---|---|---|---|---|
1979 | 0.901213 | 1 | 1.525542 | 2 | 9 | 0 | 4 | -0.144792 | -0.217132 | -0.437544 | 38 |
2430 | -0.922154 | 3 | -0.419265 | 4 | 2 | 3 | 4 | -0.144792 | -0.217132 | -0.034039 | 38 |
4214 | -1.213893 | 3 | -0.030304 | 4 | 10 | 1 | 4 | -0.144792 | -0.217132 | 1.579979 | 38 |
10389 | -0.630415 | 3 | 0.358658 | 4 | 0 | 3 | 4 | -0.144792 | -0.217132 | -0.679647 | 38 |
14525 | -1.505632 | 3 | -1.586149 | 4 | 7 | 3 | 0 | -0.144792 | -0.217132 | -0.034039 | 38 |
15040 | -0.119873 | 5 | 0.358658 | 2 | 2 | 0 | 4 | -0.144792 | -0.217132 | -0.841048 | 38 |
8409 | 0.244801 | 3 | 1.525542 | 2 | 9 | 0 | 4 | -0.144792 | -0.217132 | 1.176475 | 6 |
10628 | 0.098931 | 1 | 1.525542 | 2 | 9 | 0 | 4 | 0.886847 | -0.217132 | -0.034039 | 38 |
10942 | 0.390670 | 5 | -0.030304 | 2 | 4 | 0 | 4 | -0.144792 | -0.217132 | 4.727315 | 38 |
5129 | 1.120017 | 3 | 1.136580 | 2 | 12 | 0 | 4 | -0.144792 | -0.217132 | -0.034039 | 38 |
2096 | -1.286827 | 3 | -0.030304 | 4 | 11 | 3 | 4 | -0.144792 | -0.217132 | -1.648058 | 38 |
12463 | -0.703350 | 3 | -0.419265 | 2 | 7 | 5 | 4 | -0.144792 | 4.502280 | -0.437544 | 38 |
8528 | 0.536539 | 3 | 1.525542 | 4 | 3 | 4 | 4 | -0.144792 | -0.217132 | -0.034039 | 38 |
7093 | -1.359762 | 3 | -0.419265 | 4 | 6 | 3 | 2 | -0.144792 | -0.217132 | -0.034039 | 38 |
12565 | 0.536539 | 3 | 1.136580 | 0 | 11 | 2 | 2 | -0.144792 | -0.217132 | -0.034039 | 38 |
5655 | 1.338821 | 3 | -0.419265 | 2 | 2 | 0 | 4 | -0.144792 | -0.217132 | -0.034039 | 38 |
2322 | 0.682409 | 3 | 1.136580 | 0 | 12 | 3 | 4 | -0.144792 | -0.217132 | -0.034039 | 38 |
12652 | 0.025997 | 3 | 1.136580 | 2 | 11 | 0 | 4 | -0.144792 | -0.217132 | 0.369465 | 38 |
4755 | -0.411611 | 3 | -0.419265 | 2 | 11 | 0 | 4 | -0.144792 | -0.217132 | 1.176475 | 38 |
4413 | 0.390670 | 6 | 1.136580 | 4 | 4 | 1 | 4 | -0.144792 | -0.217132 | -0.034039 | 38 |
Os campos categóricos, como occupation
, já foram convertidos em números inteiros (com o mesmo mapeamento usado no treinamento). Campos numéricos, como age
, foram dimensionados para um
z-score.
Alguns campos foram eliminados dos dados originais. Compare a entrada de previsão com os dados brutos para os mesmos exemplos:
import pandas as pd
_, eval_file_path = util.download(util.DATA_DIR)
raw_eval_data = pd.read_csv(eval_file_path,
names=util._CSV_COLUMNS,
na_values='?')
raw_eval_data.iloc[prediction_input.index]
age | workclass | fnlwgt | education | education_num | marital_status | occupation | relationship | race | gender | capital_gain | capital_loss | hours_per_week | native_country | income_bracket | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1979 | 51 | Local-gov | 99064 | Masters | 14 | Married-civ-spouse | Prof-specialty | Husband | White | Male | 0 | 0 | 35 | United-States | <=50K |
2430 | 26 | Private | 197967 | HS-grad | 9 | Never-married | Craft-repair | Own-child | White | Male | 0 | 0 | 40 | United-States | <=50K |
4214 | 22 | Private | 221694 | Some-college | 10 | Never-married | Protective-serv | Not-in-family | White | Male | 0 | 0 | 60 | United-States | <=50K |
10389 | 30 | Private | 96480 | Assoc-voc | 11 | Never-married | Adm-clerical | Own-child | White | Female | 0 | 0 | 32 | United-States | <=50K |
14525 | 18 | Private | 146225 | 10th | 6 | Never-married | Other-service | Own-child | Amer-Indian-Eskimo | Female | 0 | 0 | 40 | United-States | <=50K |
15040 | 37 | Self-emp-not-inc | 50096 | Assoc-voc | 11 | Married-civ-spouse | Craft-repair | Husband | White | Male | 0 | 0 | 30 | United-States | <=50K |
8409 | 42 | Private | 102988 | Masters | 14 | Married-civ-spouse | Prof-specialty | Husband | White | Male | 0 | 0 | 55 | Ecuador | >50K |
10628 | 40 | Local-gov | 284086 | Masters | 14 | Married-civ-spouse | Prof-specialty | Husband | White | Male | 7688 | 0 | 40 | United-States | >50K |
10942 | 44 | Self-emp-not-inc | 52505 | Some-college | 10 | Married-civ-spouse | Farming-fishing | Husband | White | Male | 0 | 0 | 99 | United-States | <=50K |
5129 | 54 | Private | 106728 | Bachelors | 13 | Married-civ-spouse | Tech-support | Husband | White | Male | 0 | 0 | 40 | United-States | <=50K |
2096 | 21 | Private | 190916 | Some-college | 10 | Never-married | Sales | Own-child | White | Female | 0 | 0 | 20 | United-States | <=50K |
12463 | 29 | Private | 197565 | HS-grad | 9 | Married-civ-spouse | Other-service | Wife | White | Female | 0 | 1902 | 35 | United-States | >50K |
8528 | 46 | Private | 193188 | Masters | 14 | Never-married | Exec-managerial | Unmarried | White | Male | 0 | 0 | 40 | United-States | <=50K |
7093 | 20 | Private | 273147 | HS-grad | 9 | Never-married | Machine-op-inspct | Own-child | Black | Male | 0 | 0 | 40 | United-States | <=50K |
12565 | 46 | Private | 203653 | Bachelors | 13 | Divorced | Sales | Other-relative | Black | Male | 0 | 0 | 40 | United-States | <=50K |
5655 | 57 | Private | 174662 | HS-grad | 9 | Married-civ-spouse | Craft-repair | Husband | White | Male | 0 | 0 | 40 | United-States | <=50K |
2322 | 48 | Private | 232149 | Bachelors | 13 | Divorced | Tech-support | Own-child | White | Female | 0 | 0 | 40 | United-States | <=50K |
12652 | 39 | Private | 82521 | Bachelors | 13 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 0 | 45 | United-States | >50K |
4755 | 33 | Private | 330715 | HS-grad | 9 | Married-civ-spouse | Sales | Husband | White | Male | 0 | 0 | 55 | United-States | <=50K |
4413 | 44 | State-gov | 128586 | Bachelors | 13 | Never-married | Farming-fishing | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
Exporte a entrada de previsão para um arquivo JSON delimitado por nova linha:
import json
with open('prediction_input.json', 'w') as json_file:
for row in prediction_input.values.tolist():
json.dump(row, json_file)
json_file.write('\n')
Saia do interpretador Python (exit()
). No shell, examine prediction_input.json
:
cat prediction_input.json
[0.9012127751273994, 1.0, 1.525541514460902, 2.0, 9.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.43754385253479555, 38.0] [-0.9221541171760282, 3.0, -0.4192650914017433, 4.0, 2.0, 3.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [-1.2138928199445767, 3.0, -0.030303770229214273, 4.0, 10.0, 1.0, 4.0, -0.14479173735784842, -0.21713186390175285, 1.5799792247041626, 38.0] [-0.6304154144074798, 3.0, 0.35865755094331475, 4.0, 0.0, 3.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.6796466218034705, 38.0] [-1.5056315227131252, 3.0, -1.5861490549193304, 4.0, 7.0, 3.0, 0.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [-0.11987268456252011, 5.0, 0.35865755094331475, 2.0, 2.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.8410484679825871, 38.0] [0.24480069389816542, 3.0, 1.525541514460902, 2.0, 9.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, 1.176474609256371, 6.0] [0.0989313425138912, 1.0, 1.525541514460902, 2.0, 9.0, 0.0, 4.0, 0.8868473744801746, -0.21713186390175285, -0.03403923708700391, 38.0] [0.39067004528243965, 5.0, -0.030303770229214273, 2.0, 4.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, 4.7273152251969375, 38.0] [1.1200168022038106, 3.0, 1.1365801932883728, 2.0, 12.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [-1.2868274956367138, 3.0, -0.030303770229214273, 4.0, 11.0, 3.0, 4.0, -0.14479173735784842, -0.21713186390175285, -1.6480576988781703, 38.0] [-0.7033500900996169, 3.0, -0.4192650914017433, 2.0, 7.0, 5.0, 4.0, -0.14479173735784842, 4.5022796885373735, -0.43754385253479555, 38.0] [0.5365393966667138, 3.0, 1.525541514460902, 4.0, 3.0, 4.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [-1.3597621713288508, 3.0, -0.4192650914017433, 4.0, 6.0, 3.0, 2.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [0.5365393966667138, 3.0, 1.1365801932883728, 0.0, 11.0, 2.0, 2.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [1.338820829280222, 3.0, -0.4192650914017433, 2.0, 2.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [0.6824087480509881, 3.0, 1.1365801932883728, 0.0, 12.0, 3.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0] [0.0259966668217541, 3.0, 1.1365801932883728, 2.0, 11.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, 0.3694653783607877, 38.0] [-0.4116113873310685, 3.0, -0.4192650914017433, 2.0, 11.0, 0.0, 4.0, -0.14479173735784842, -0.21713186390175285, 1.176474609256371, 38.0] [0.39067004528243965, 6.0, 1.1365801932883728, 4.0, 4.0, 1.0, 4.0, -0.14479173735784842, -0.21713186390175285, -0.03403923708700391, 38.0]
A ferramenta de linha de comando gcloud
aceita JSON delimitado por nova linha para previsão on-line, e esse modelo específico de Keras espera uma lista fixa de números para cada exemplo de entrada.
O AI Platform requer um formato diferente quando você faz solicitações de previsão on-line para a API REST sem usar a ferramenta gcloud
. A maneira como você estrutura o modelo também pode alterar como é preciso formatar dados para previsão.
Saiba mais sobre como formatar dados para previsão on-line.
Enviar a solicitação de previsão on-line
Use gcloud
para enviar sua solicitação de previsão on-line:
gcloud ai-platform predict \
--model $MODEL_NAME \
--region $REGION \
--version $MODEL_VERSION \
--json-instances prediction_input.json
DENSE_4 [0.6854287385940552] [0.011786997318267822] [0.037236183881759644] [0.016223609447479248] [0.0012015104293823242] [0.23621389269828796] [0.6174039244651794] [0.9822691679000854] [0.3815768361091614] [0.6715215444564819] [0.001094043254852295] [0.43077391386032104] [0.22132840752601624] [0.004075437784194946] [0.22736871242523193] [0.4111979305744171] [0.27328649163246155] [0.6981356143951416] [0.3309604525566101] [0.20807647705078125]
Como a última camada do modelo usa uma função sigmoide na ativação, as saídas entre 0 e 0,5 representam previsões negativas ("<=50K") e as saídas entre 0,5 e 1 representam as positivas (">50K").
Como desenvolver o modelo Keras do zero
A esta altura, você já treinou um modelo de machine learning no AI Platform, implantou o modelo treinado como um recurso de versão no AI Platform e recebeu previsões on-line da implantação. Na próxima seção, mostraremos como recriar o código do Keras usado para treinar o modelo. Ela abrange as seguintes partes do desenvolvimento de um modelo de machine learning a ser usado com o AI Platform:
- Fazer o download e pré-processar dados
- Projetar e treinar o modelo
- Visualizar o treinamento e exportar o modelo treinado
Nesta seção, apresentamos uma visão mais detalhada das tarefas concluídas nas partes anteriores. Para saber mais sobre como usar tf.keras
, leia o guia do TensorFlow para Keras.
Para saber mais sobre como estruturar o código como um pacote de treinamento para o
AI Platform, leia Como empacotar um aplicativo de treinamento
e consulte o código de treinamento completo,
estruturado como um pacote do Python.
Importar bibliotecas e definir constantes
Primeiro, importe as bibliotecas do Python obrigatórias para treinamento:
import os
from six.moves import urllib
import tempfile
import numpy as np
import pandas as pd
import tensorflow as tf
# Examine software versions
print(__import__('sys').version)
print(tf.__version__)
print(tf.keras.__version__)
Em seguida, defina algumas constantes úteis:
- Informações para fazer o download dos dados de treinamento e avaliação
- Informações obrigatórias para o Pandas interpretar dados e converter campos categóricos em atributos numéricos
- Hiperparâmetros de treinamento, como taxa de aprendizado e tamanho do lote
### For downloading data ###
# Storage directory
DATA_DIR = os.path.join(tempfile.gettempdir(), 'census_data')
# Download options.
DATA_URL = 'https://storage.googleapis.com/cloud-samples-data/ai-platform' \
'/census/data'
TRAINING_FILE = 'adult.data.csv'
EVAL_FILE = 'adult.test.csv'
TRAINING_URL = '%s/%s' % (DATA_URL, TRAINING_FILE)
EVAL_URL = '%s/%s' % (DATA_URL, EVAL_FILE)
### For interpreting data ###
# These are the features in the dataset.
# Dataset information: https://archive.ics.uci.edu/ml/datasets/census+income
_CSV_COLUMNS = [
'age', 'workclass', 'fnlwgt', 'education', 'education_num',
'marital_status', 'occupation', 'relationship', 'race', 'gender',
'capital_gain', 'capital_loss', 'hours_per_week', 'native_country',
'income_bracket'
]
_CATEGORICAL_TYPES = {
'workclass': pd.api.types.CategoricalDtype(categories=[
'Federal-gov', 'Local-gov', 'Never-worked', 'Private', 'Self-emp-inc',
'Self-emp-not-inc', 'State-gov', 'Without-pay'
]),
'marital_status': pd.api.types.CategoricalDtype(categories=[
'Divorced', 'Married-AF-spouse', 'Married-civ-spouse',
'Married-spouse-absent', 'Never-married', 'Separated', 'Widowed'
]),
'occupation': pd.api.types.CategoricalDtype([
'Adm-clerical', 'Armed-Forces', 'Craft-repair', 'Exec-managerial',
'Farming-fishing', 'Handlers-cleaners', 'Machine-op-inspct',
'Other-service', 'Priv-house-serv', 'Prof-specialty', 'Protective-serv',
'Sales', 'Tech-support', 'Transport-moving'
]),
'relationship': pd.api.types.CategoricalDtype(categories=[
'Husband', 'Not-in-family', 'Other-relative', 'Own-child', 'Unmarried',
'Wife'
]),
'race': pd.api.types.CategoricalDtype(categories=[
'Amer-Indian-Eskimo', 'Asian-Pac-Islander', 'Black', 'Other', 'White'
]),
'native_country': pd.api.types.CategoricalDtype(categories=[
'Cambodia', 'Canada', 'China', 'Columbia', 'Cuba', 'Dominican-Republic',
'Ecuador', 'El-Salvador', 'England', 'France', 'Germany', 'Greece',
'Guatemala', 'Haiti', 'Holand-Netherlands', 'Honduras', 'Hong', 'Hungary',
'India', 'Iran', 'Ireland', 'Italy', 'Jamaica', 'Japan', 'Laos', 'Mexico',
'Nicaragua', 'Outlying-US(Guam-USVI-etc)', 'Peru', 'Philippines', 'Poland',
'Portugal', 'Puerto-Rico', 'Scotland', 'South', 'Taiwan', 'Thailand',
'Trinadad&Tobago', 'United-States', 'Vietnam', 'Yugoslavia'
]),
'income_bracket': pd.api.types.CategoricalDtype(categories=[
'<=50K', '>50K'
])
}
# This is the label (target) we want to predict.
_LABEL_COLUMN = 'income_bracket'
### Hyperparameters for training ###
# This the training batch size
BATCH_SIZE = 128
# This is the number of epochs (passes over the full training data)
NUM_EPOCHS = 20
# Define learning rate.
LEARNING_RATE = .01
Fazer o download e pré-processar dados
Fazer o download dos dados
Em seguida, defina funções para fazer download de dados de treinamento e avaliação. Essas funções também corrigem pequenas irregularidades na formatação dos dados.
def _download_and_clean_file(filename, url):
"""Downloads data from url, and makes changes to match the CSV format.
The CSVs may use spaces after the comma delimters (non-standard) or include
rows which do not represent well-formed examples. This function strips out
some of these problems.
Args:
filename: filename to save url to
url: URL of resource to download
"""
temp_file, _ = urllib.request.urlretrieve(url)
with tf.gfile.Open(temp_file, 'r') as temp_file_object:
with tf.gfile.Open(filename, 'w') as file_object:
for line in temp_file_object:
line = line.strip()
line = line.replace(', ', ',')
if not line or ',' not in line:
continue
if line[-1] == '.':
line = line[:-1]
line += '\n'
file_object.write(line)
tf.gfile.Remove(temp_file)
def download(data_dir):
"""Downloads census data if it is not already present.
Args:
data_dir: directory where we will access/save the census data
"""
tf.gfile.MakeDirs(data_dir)
training_file_path = os.path.join(data_dir, TRAINING_FILE)
if not tf.gfile.Exists(training_file_path):
_download_and_clean_file(training_file_path, TRAINING_URL)
eval_file_path = os.path.join(data_dir, EVAL_FILE)
if not tf.gfile.Exists(eval_file_path):
_download_and_clean_file(eval_file_path, EVAL_URL)
return training_file_path, eval_file_path
Use essas funções para fazer download dos dados de treinamento e verificar se você tem arquivos CSV de treinamento e avaliação:
training_file_path, eval_file_path = download(DATA_DIR)
Em seguida, carregue esses arquivos usando o Pandas e examine os dados:
# This census data uses the value '?' for fields (column) that are missing data.
# We use na_values to find ? and set it to NaN values.
# https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html
train_df = pd.read_csv(training_file_path, names=_CSV_COLUMNS, na_values='?')
eval_df = pd.read_csv(eval_file_path, names=_CSV_COLUMNS, na_values='?')
Na tabela a seguir, mostramos um trecho dos dados (train_df.head()
) antes do pré-processamento:
age | workclass | fnlwgt | education | education_num | marital_status | occupation | relationship | race | gender | capital_gain | capital_loss | hours_per_week | native_country | income_bracket | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 39 | State-gov | 77516 | Bachelors | 13 | Never-married | Adm-clerical | Not-in-family | White | Male | 2174 | 0 | 40 | United-States | <=50K |
1 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
2 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
3 | 53 | Private | 234721 | Dia 11 | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
4 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
Pré-processar os dados
O primeiro passo do pré-processamento remove determinados atributos dos dados e converte os atributos categóricos em valores numéricos a serem usados com o Keras.
Saiba mais sobre engenharia de atributos e viés nos dados.
UNUSED_COLUMNS = ['fnlwgt', 'education', 'gender']
def preprocess(dataframe):
"""Converts categorical features to numeric. Removes unused columns.
Args:
dataframe: Pandas dataframe with raw data
Returns:
Dataframe with preprocessed data
"""
dataframe = dataframe.drop(columns=UNUSED_COLUMNS)
# Convert integer valued (numeric) columns to floating point
numeric_columns = dataframe.select_dtypes(['int64']).columns
dataframe[numeric_columns] = dataframe[numeric_columns].astype('float32')
# Convert categorical columns to numeric
cat_columns = dataframe.select_dtypes(['object']).columns
dataframe[cat_columns] = dataframe[cat_columns].apply(lambda x: x.astype(
_CATEGORICAL_TYPES[x.name]))
dataframe[cat_columns] = dataframe[cat_columns].apply(lambda x: x.cat.codes)
return dataframe
prepped_train_df = preprocess(train_df)
prepped_eval_df = preprocess(eval_df)
Veja na tabela a seguir (prepped_train_df.head()
) como o pré-processamento alterou os dados. Observe, em especial, que income_bracket
, o rótulo que você está treinando para prever, mudou de <=50K
e >50K
para 0
e 1
:
age | workclass | education_num | marital_status | occupation | relationship | race | capital_gain | capital_loss | hours_per_week | native_country | income_bracket | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 39.0 | 6 | 13.0 | 4 | 0 | 1 | 4 | 2174.0 | 0.0 | 40.0 | 38 | 0 |
1 | 50.0 | 5 | 13.0 | 2 | 3 | 0 | 4 | 0.0 | 0.0 | 13.0 | 38 | 0 |
2 | 38.0 | 3 | 9.0 | 0 | 5 | 1 | 4 | 0.0 | 0.0 | 40.0 | 38 | 0 |
3 | 53.0 | 3 | 7.0 | 2 | 5 | 0 | 2 | 0.0 | 0.0 | 40.0 | 38 | 0 |
4 | 28.0 | 3 | 13.0 | 2 | 9 | 5 | 2 | 0.0 | 0.0 | 40.0 | 4 | 0 |
Em seguida, separe os dados em atributos ("x") e rótulos ("y") e remodele as matrizes de rótulos em um formato a ser usado com tf.data.Dataset
posteriormente:
# Split train and test data with labels.
# The pop() method will extract (copy) and remove the label column from the dataframe
train_x, train_y = prepped_train_df, prepped_train_df.pop(_LABEL_COLUMN)
eval_x, eval_y = prepped_eval_df, prepped_eval_df.pop(_LABEL_COLUMN)
# Reshape label columns for use with tf.data.Dataset
train_y = np.asarray(train_y).astype('float32').reshape((-1, 1))
eval_y = np.asarray(eval_y).astype('float32').reshape((-1, 1))
É 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.
Em um sistema de produção, convém salvar as médias e os desvios padrão do conjunto de treinamento e usá-los para realizar uma transformação idêntica em dados de teste no momento da previsão. Para facilitar este exercício, combine temporariamente os dados de treinamento e avaliação para dimensionar todos eles:
def standardize(dataframe):
"""Scales numerical columns using their means and standard deviation to get
z-scores: the mean of each numerical column becomes 0, and the standard
deviation becomes 1. This can help the model converge during training.
Args:
dataframe: Pandas dataframe
Returns:
Input dataframe with the numerical columns scaled to z-scores
"""
dtypes = list(zip(dataframe.dtypes.index, map(str, dataframe.dtypes)))
# Normalize numeric columns.
for column, dtype in dtypes:
if dtype == 'float32':
dataframe[column] -= dataframe[column].mean()
dataframe[column] /= dataframe[column].std()
return dataframe
# Join train_x and eval_x to normalize on overall means and standard
# deviations. Then separate them again.
all_x = pd.concat([train_x, eval_x], keys=['train', 'eval'])
all_x = standardize(all_x)
train_x, eval_x = all_x.xs('train'), all_x.xs('eval')
Na próxima tabela (train_x.head()
), mostramos a aparência dos dados totalmente pré-processados:
age | workclass | education_num | marital_status | occupation | relationship | race | capital_gain | capital_loss | hours_per_week | native_country | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0.025997 | 6 | 1.136580 | 4 | 0 | 1 | 4 | 0.146933 | -0.217132 | -0.034039 | 38 |
1 | 0.828278 | 5 | 1.136580 | 2 | 3 | 0 | 4 | -0.144792 | -0.217132 | -2.212964 | 38 |
2 | -0.046938 | 3 | -0.419265 | 0 | 5 | 1 | 4 | -0.144792 | -0.217132 | -0.034039 | 38 |
3 | 1.047082 | 3 | -1.197188 | 2 | 5 | 0 | 2 | -0.144792 | -0.217132 | -0.034039 | 38 |
4 | -0.776285 | 3 | 1.136580 | 2 | 9 | 5 | 2 | -0.144792 | -0.217132 | -0.034039 | 4 |
Projetar e treinar o modelo
Criar conjuntos de dados de treinamento e validação
Crie uma função de entrada para converter atributos e rótulos em um
tf.data.Dataset
para treinamento ou avaliação:
def input_fn(features, labels, shuffle, num_epochs, batch_size):
"""Generates an input function to be used for model training.
Args:
features: numpy array of features used for training or inference
labels: numpy array of labels for each example
shuffle: boolean for whether to shuffle the data or not (set True for
training, False for evaluation)
num_epochs: number of epochs to provide the data for
batch_size: batch size for training
Returns:
A tf.data.Dataset that can provide data to the Keras model for training or
evaluation
"""
if labels is None:
inputs = features
else:
inputs = (features, labels)
dataset = tf.data.Dataset.from_tensor_slices(inputs)
if shuffle:
dataset = dataset.shuffle(buffer_size=len(features))
# We call repeat after shuffling, rather than before, to prevent separate
# epochs from blending together.
dataset = dataset.repeat(num_epochs)
dataset = dataset.batch(batch_size)
return dataset
Em seguida, crie esses conjuntos de dados de treinamento e avaliação. Use os hiperparâmetros NUM_EPOCHS
e BATCH_SIZE
definidos anteriormente para determinar como o conjunto de dados de treinamento fornece exemplos ao modelo durante o treinamento. Configure o conjunto de dados de validação a fim de apresentar todos os exemplos em um só lote, para um único passo de validação ao final de cada período de treinamento.
# Pass a numpy array by using DataFrame.values
training_dataset = input_fn(features=train_x.values,
labels=train_y,
shuffle=True,
num_epochs=NUM_EPOCHS,
batch_size=BATCH_SIZE)
num_eval_examples = eval_x.shape[0]
# Pass a numpy array by using DataFrame.values
validation_dataset = input_fn(features=eval_x.values,
labels=eval_y,
shuffle=False,
num_epochs=NUM_EPOCHS,
batch_size=num_eval_examples)
Projetar um modelo do Keras
Projete a rede neural usando a API Keras Sequential.
Essa rede neural profunda (DNN, na sigla em inglês) tem várias camadas ocultas, e a última camada usa uma função de ativação sigmoide para produzir um valor entre 0 e 1:
- A camada de entrada tem 100 unidades que usam a função de ativação ReLU.
- A camada oculta tem 75 unidades que usam a função de ativação ReLU.
- A camada oculta tem 50 unidades que usam a função de ativação ReLU.
- A camada oculta tem 25 unidades que usam a função de ativação ReLU.
- A camada de saída tem uma unidade que usa uma função de ativação sigmoide.
- O otimizador usa a função de perda de entropia cruzada binária, apropriada para um problema de classificação binária como este.
Sinta-se à vontade para alterar essas camadas a fim de tentar melhorar o modelo:
def create_keras_model(input_dim, learning_rate):
"""Creates Keras Model for Binary Classification.
Args:
input_dim: How many features the input has
learning_rate: Learning rate for training
Returns:
The compiled Keras model (still needs to be trained)
"""
Dense = tf.keras.layers.Dense
model = tf.keras.Sequential(
[
Dense(100, activation=tf.nn.relu, kernel_initializer='uniform',
input_shape=(input_dim,)),
Dense(75, activation=tf.nn.relu),
Dense(50, activation=tf.nn.relu),
Dense(25, activation=tf.nn.relu),
Dense(1, activation=tf.nn.sigmoid)
])
# Custom Optimizer:
# https://www.tensorflow.org/api_docs/python/tf/train/RMSPropOptimizer
optimizer = tf.keras.optimizers.RMSprop(
lr=learning_rate)
# Compile Keras model
model.compile(
loss='binary_crossentropy', optimizer=optimizer, metrics=['accuracy'])
return model
Em seguida, crie o objeto de modelo do Keras:
num_train_examples, input_dim = train_x.shape
print('Number of features: {}'.format(input_dim))
print('Number of examples: {}'.format(num_train_examples))
keras_model = create_keras_model(
input_dim=input_dim,
learning_rate=LEARNING_RATE)
Examinar o modelo com keras_model.summary()
retornará algo como:
Number of features: 11 Number of examples: 32561 WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version. Instructions for updating: Colocations handled automatically by placer. _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense (Dense) (None, 100) 1200 _________________________________________________________________ dense_1 (Dense) (None, 75) 7575 _________________________________________________________________ dense_2 (Dense) (None, 50) 3800 _________________________________________________________________ dense_3 (Dense) (None, 25) 1275 _________________________________________________________________ dense_4 (Dense) (None, 1) 26 ================================================================= Total params: 13,876 Trainable params: 13,876 Non-trainable params: 0 _________________________________________________________________
Treine e avalie o modelo
Defina um decaimento da taxa de aprendizado para incentivar os parâmetros do modelo a fazer mudanças menores à medida que o treinamento avança:
# Setup Learning Rate decay.
lr_decay_cb = tf.keras.callbacks.LearningRateScheduler(
lambda epoch: LEARNING_RATE + 0.02 * (0.5 ** (1 + epoch)),
verbose=True)
# Setup TensorBoard callback.
JOB_DIR = os.getenv('JOB_DIR')
tensorboard_cb = tf.keras.callbacks.TensorBoard(
os.path.join(JOB_DIR, 'keras_tensorboard'),
histogram_freq=1)
Por fim, treine o modelo. Insira o steps_per_epoch
apropriado para o modelo treinar em todo o conjunto de dados de treinamento (com exemplos de BATCH_SIZE
por etapa) durante cada período. E instrua o modelo a calcular a acurácia da validação com um grande lote de validação ao final de cada período.
history = keras_model.fit(training_dataset,
epochs=NUM_EPOCHS,
steps_per_epoch=int(num_train_examples/BATCH_SIZE),
validation_data=validation_dataset,
validation_steps=1,
callbacks=[lr_decay_cb, tensorboard_cb],
verbose=1)
O progresso do treinamento pode ser semelhante a este:
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version. Instructions for updating: Use tf.cast instead. Epoch 00001: LearningRateScheduler reducing learning rate to 0.02. Epoch 1/20 254/254 [==============================] - 1s 5ms/step - loss: 0.6986 - acc: 0.7893 - val_loss: 0.3894 - val_acc: 0.8329 Epoch 00002: LearningRateScheduler reducing learning rate to 0.015. Epoch 2/20 254/254 [==============================] - 1s 4ms/step - loss: 0.3574 - acc: 0.8335 - val_loss: 0.3861 - val_acc: 0.8131 ... Epoch 00019: LearningRateScheduler reducing learning rate to 0.010000038146972657. Epoch 19/20 254/254 [==============================] - 1s 4ms/step - loss: 0.3239 - acc: 0.8512 - val_loss: 0.3334 - val_acc: 0.8496 Epoch 00020: LearningRateScheduler reducing learning rate to 0.010000019073486329. Epoch 20/20 254/254 [==============================] - 1s 4ms/step - loss: 0.3279 - acc: 0.8504 - val_loss: 0.3174 - val_acc: 0.8523
Visualizar o treinamento e exportar o modelo treinado
Visualizar o treinamento
Importe matplotlib
para visualizar como foi o aprendizado do modelo durante o período de treinamento.
Se necessário, primeiro instale-o com pip install matplotlib
.
from matplotlib import pyplot as plt
Crie uma representação gráfica da perda do modelo (entropia cruzada binária) e da acurácia, medidas ao final de cada período de treinamento:
# Visualize History for Loss.
plt.title('Keras model loss')
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['training', 'validation'], loc='upper right')
plt.show()
# Visualize History for Accuracy.
plt.title('Keras model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.legend(['training', 'validation'], loc='lower right')
plt.show()
Com o passar do tempo, a perda diminui e a acurácia aumenta. Mas elas convergem para um nível estável? Há grandes diferenças entre as métricas de treinamento e validação (um sinal de overfitting)?
Saiba mais sobre como melhorar o modelo de machine learning. Em seguida, sinta-se à vontade para ajustar hiperparâmetros ou a arquitetura do modelo e treinar novamente.
Exportar o modelo para exibição
Use tf.contrib.saved_model.save_keras_model (link em inglês) para exportar um diretório SavedModel do TensorFlow. Esse é o formato exigido pelo AI Platform quando você cria um recurso de versão de modelo.
Como nem todos os otimizadores podem ser exportados para o formato SavedModel, é possível que você veja avisos durante o processo de exportação. Desde que você exporte com êxito um gráfico de exibição, o AI Platform pode usar o SavedModel para exibir predições.
# Export the model to a local SavedModel directory
export_path = tf.contrib.saved_model.save_keras_model(keras_model, 'keras_export')
print("Model exported to: ", export_path)
WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0. For more information, please see: * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md * https://github.com/tensorflow/addons If you depend on functionality not listed there, please file an issue. WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.RMSprop object at 0x7fc198c4e400>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved. Consider using a TensorFlow optimizer from `tf.train`. WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/network.py:1436: update_checkpoint_state (from tensorflow.python.training.checkpoint_management) is deprecated and will be removed in a future version. Instructions for updating: Use tf.train.CheckpointManager to manage checkpoints rather than manually editing the Checkpoint proto. WARNING:tensorflow:Model was compiled with an optimizer, but the optimizer is not from `tf.train` (e.g. `tf.train.AdagradOptimizer`). Only the serving graph was exported. The train and evaluate graphs were not added to the SavedModel. WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/saved_model/signature_def_utils_impl.py:205: build_tensor_info (from tensorflow.python.saved_model.utils_impl) is deprecated and will be removed in a future version. Instructions for updating: This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.utils.build_tensor_info or tf.compat.v1.saved_model.build_tensor_info. INFO:tensorflow:Signatures INCLUDED in export for Classify: None INFO:tensorflow:Signatures INCLUDED in export for Regress: None INFO:tensorflow:Signatures INCLUDED in export for Predict: ['serving_default'] INFO:tensorflow:Signatures INCLUDED in export for Train: None INFO:tensorflow:Signatures INCLUDED in export for Eval: None INFO:tensorflow:No assets to save. INFO:tensorflow:No assets to write. INFO:tensorflow:SavedModel written to: keras_export/1553710367/saved_model.pb Model exported to: b'keras_export/1553710367'
Convém exportar um diretório SavedModel para o sistema de arquivos local ou para o Cloud Storage, desde que você tenha as permissões necessárias. No seu ambiente atual, você concedeu acesso ao Cloud Storage por meio da autenticação da sua conta do Google Cloud e da configuração da variável de ambiente GOOGLE_APPLICATION_CREDENTIALS
. Os jobs de treinamento do AI Platform também podem ser exportados diretamente para o Cloud Storage, porque as contas de serviço do AI Platform têm acesso aos buckets do Cloud Storage no próprio projeto.
Tente exportar diretamente para o Cloud Storage:
JOB_DIR = os.getenv('JOB_DIR')
# Export the model to a SavedModel directory in Cloud Storage
export_path = tf.contrib.saved_model.save_keras_model(keras_model, JOB_DIR + '/keras_export')
print("Model exported to: ", export_path)
WARNING:tensorflow:This model was compiled with a Keras optimizer (<tensorflow.python.keras.optimizers.RMSprop object at 0x7fc198c4e400>) but is being saved in TensorFlow format with `save_weights`. The model's weights will be saved, but unlike with TensorFlow optimizers in the TensorFlow format the optimizer's state will not be saved. Consider using a TensorFlow optimizer from `tf.train`. WARNING:tensorflow:Model was compiled with an optimizer, but the optimizer is not from `tf.train` (e.g. `tf.train.AdagradOptimizer`). Only the serving graph was exported. The train and evaluate graphs were not added to the SavedModel. INFO:tensorflow:Signatures INCLUDED in export for Classify: None INFO:tensorflow:Signatures INCLUDED in export for Regress: None INFO:tensorflow:Signatures INCLUDED in export for Predict: ['serving_default'] INFO:tensorflow:Signatures INCLUDED in export for Train: None INFO:tensorflow:Signatures INCLUDED in export for Eval: None INFO:tensorflow:No assets to save. INFO:tensorflow:No assets to write. INFO:tensorflow:SavedModel written to: gs://your-bucket-name/keras-job-dir/keras_export/1553710379/saved_model.pb Model exported to: b'gs://your-bucket-name/keras-job-dir/keras_export/1553710379'
Já é possível implantar esse modelo para o AI Platform e exibir predições. Para isso, siga os passos do guia de início rápido para predição.
Limpar
Para limpar todos os recursos do Google Cloud usados neste projeto, exclua o projeto do Google Cloud usado no tutorial.
Também é possível limpar recursos individuais com os comandos a seguir:
# Delete model version resource
gcloud ai-platform versions delete $MODEL_VERSION --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 $JOB_DIR
# If training job is still running, cancel it
gcloud ai-platform jobs cancel $JOB_NAME --quiet
Se o bucket do Cloud Storage não contiver nenhum outro objeto e você quiser excluí-lo, execute gsutil rm -r gs://$BUCKET_NAME
.
A seguir
- Confira o código de treinamento completo (link em inglês) usado neste guia, que estrutura o código para aceitar hiperparâmetros personalizados como sinalizações de linha de comando.
- Leia mais sobre como empacotar código para um job de treinamento do AI Platform.
- Leia sobre como implantar um modelo para exibir previsões.