Fazer previsões com modelos PyTorch no formato ONNX

Informações gerais

O Open Neural Network Exchange (ONNX) fornece um formato uniforme projetado para representar qualquer framework de machine learning. O suporte do BigQuery ML para ONNX permite que você:

  • Treine um modelo usando seu framework favorito.
  • Converta o modelo no formato de modelo ONNX. Para mais informações, consulte Como converter para o formato ONNX.
  • Importe o modelo ONNX para o BigQuery e faça previsões usando o BigQuery ML.

Neste tutorial, mostramos como importar modelos ONNX treinados com PyTorch em um conjunto de dados do BigQuery e usá-los para fazer previsões a partir de uma consulta SQL. Importe modelos do ONNX usando estas interfaces:

Para mais informações sobre como importar modelos ONNX para o BigQuery, incluindo requisitos de formato e armazenamento, consulte A instrução CREATE MODEL para importar modelos ONNX.

Objetivos

Com este tutorial, você vai:

  • Crie e treine modelos com o PyTorch.
  • Converta os modelos para o formato ONNX usando torch.onnx.
  • Importe os modelos ONNX para o BigQuery e faça previsões.

Criar um modelo de visão PyTorch para classificação de imagens

Importe um resnet18 pré-treinado do PyTorch que aceita dados de imagem decodificados retornados pelas funções do BigQuery ML ML.DECODE_IMAGE e ML.RESIZE_IMAGE.

import torch
import torch.nn as nn

# Define model input format to match the output format of
# ML.DECODE_IMAGE function: [height, width, channels]
dummy_input = torch.randn(1, 224, 224, 3, device="cpu")

# Load a pretrained pytorch model for image classification
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet18', pretrained=True)

# Reshape input format from [batch_size, height, width, channels]
# to [batch_size, channels, height, width]
class ReshapeLayer(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
        x = x.permute(0, 3, 1, 2)  # reorder dimensions
        return x

class ArgMaxLayer(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self, x):
       return torch.argmax(x, dim=1)

final_model = nn.Sequential(
    ReshapeLayer(),
    model,
    nn.Softmax(),
    ArgMaxLayer()
)

Converter o modelo no formato ONNX e salvar

Use torch.onnx para exportar o modelo de visão PyTorch para um arquivo ONNX chamado resnet18.onnx.

torch.onnx.export(final_model,            # model being run
                  dummy_input,            # model input
                  "resnet18.onnx",        # where to save the model
                  opset_version=10,       # the ONNX version to export the model to
                  input_names = ['input'],         # the model's input names
                  output_names = ['class_label'])  # the model's output names

Faça o upload do modelo ONNX para o Cloud Storage.

Crie um bucket do Cloud Storage para armazenar o arquivo de modelo ONNX e, em seguida, faça upload do arquivo de modelo ONNX salvo no bucket do Cloud Storage. Para mais informações, consulte Fazer upload de objetos de um sistema de arquivos.

Importar o modelo ONNX para o BigQuery

Esta etapa pressupõe que você fez upload do modelo ONNX para o bucket do Cloud Storage. Um modelo de exemplo é armazenado em gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx.

Console

  1. No console do Google Cloud, acesse a página do BigQuery.

    Acesse a página do BigQuery

  2. No editor de consultas, insira uma instrução CREATE MODEL como a seguinte.

     CREATE OR REPLACE MODEL `mydataset.mymodel`
      OPTIONS (MODEL_TYPE='ONNX',
       MODEL_PATH='gs://bucket/path/to/onnx_model/*')
    

    Exemplo:

     CREATE OR REPLACE MODEL `example_dataset.imported_onnx_model`
      OPTIONS (MODEL_TYPE='ONNX',
       MODEL_PATH='gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx')
    

    A consulta anterior importa o modelo ONNX localizado em gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx como um modelo do BigQuery chamado imported_onnx_model.

  3. Agora, seu novo modelo aparecerá no painel Recursos. À medida que você expande cada um dos conjuntos de dados em um projeto, os modelos são listados junto a outros recursos do BigQuery nos conjuntos de dados. Os modelos são indicados pelo ícone do modelo: ícone do modelo.

  4. Se você selecionar o novo modelo no painel Recursos, as informações sobre o modelo serão exibidas abaixo do Editor de consultas.

    informações do modelo onnx

bq

Para importar um modelo ONNX do Cloud Storage, execute uma consulta em lote inserindo um comando como este:

bq query \
--use_legacy_sql=false \
"CREATE MODEL
  `mydataset.mymodel`
OPTIONS
  (MODEL_TYPE='ONNX',
   MODEL_PATH='gs://bucket/path/to/onnx_model/*')"

Exemplo:

bq query --use_legacy_sql=false \
"CREATE OR REPLACE MODEL
  `example_dataset.imported_onnx_model`
OPTIONS
  (MODEL_TYPE='ONNX',
   MODEL_PATH='gs://cloud-samples-data/bigquery/ml/onnx/resnet18.onnx')"

Depois de importar o modelo, ele deve aparecer na saída de bq ls [dataset_name]:

$ bq ls example_dataset

       tableId          Type    Labels   Time Partitioning
 --------------------- ------- -------- -------------------
  imported_onnx_model   MODEL

API

Insira um novo job e preencha a propriedade jobs#configuration.query como no corpo da solicitação a seguir:

{
  "query": "CREATE MODEL `project_id:mydataset.mymodel` OPTIONS(MODEL_TYPE='ONNX' MODEL_PATH='gs://bucket/path/to/onnx_model/*')"
}

Criar uma tabela de objetos no BigQuery para acessar dados de imagem

Para acessar dados não estruturados no BigQuery, você precisa criar uma tabela de objetos. Consulte Criar tabelas de objetos para instruções detalhadas.

Crie uma tabela de objetos chamada goldfish_image_table em uma imagem dourada, armazenada em gs://mybucket/goldfish.jpg.

CREATE EXTERNAL TABLE `example_dataset.goldfish_image_table`
WITH CONNECTION `us.my-connection`
OPTIONS(
  object_metadata = 'SIMPLE',
  uris = ['gs://mybucket/goldfish.jpg'],
  max_staleness = INTERVAL 1 DAY,
  metadata_cache_mode = 'AUTOMATIC');

Fazer previsões com o modelo ONNX importado

Console

  1. No console do Google Cloud, acesse a página do BigQuery.

    Acesse a página do BigQuery

  2. No Editor de consultas, insira uma consulta usando ML.PREDICT (em inglês) da seguinte maneira.

     SELECT
       class_label
     FROM
       ML.PREDICT(MODEL example_dataset.imported_onnx_model,
         (
         SELECT
           ML.RESIZE_IMAGE(ML.DECODE_IMAGE(DATA),
             224,
             224,
             FALSE) AS input
         FROM
           example_dataset.goldfish_image_table) )
     

    A consulta anterior usa o modelo chamado imported_onnx_model no conjunto de dados example_dataset no projeto atual para fazer previsões a partir de dados de imagem na tabela de objetos de entrada goldfish_image_table. A função ML.DECODE_IMAGE é necessária para decodificar os dados da imagem para que ela possa ser interpretada por ML.PREDICT. Além disso, a função ML.RESIZE_IMAGE é chamada para redimensionar a imagem para se ajustar ao tamanho da entrada do modelo (224*224). Para mais informações sobre como executar a inferência em tabelas de objetos de imagem, consulte Executar inferência em tabelas de objetos de imagem.

    Essa consulta gera o rótulo de classe previsto da imagem de entrada com base no dicionário de rótulos do ImageNet.

    Resultados da consulta

bq

Para fazer previsões a partir de dados de entrada na tabela input_data, insira um comando como este a seguir, usando o modelo importado my_model do ONNX:

bq query \
--use_legacy_sql=false \
'SELECT *
 FROM ML.PREDICT(
   MODEL `my_project.my_dataset.my_model`,
   (SELECT * FROM input_data))'

API

Insira um novo job e preencha a propriedade jobs#configuration.query como no corpo da solicitação a seguir:

{
  "query": "SELECT * FROM ML.PREDICT(MODEL `my_project.my_dataset.my_model`, (SELECT * FROM input_data))"
}

A seguir