Perguntas frequentes sobre análise de modelo Tensorflow

Em geral

Um EvalSavedModel ainda é necessário?

Anteriormente, o TFMA exigia que todas as métricas fossem armazenadas em um gráfico tensorflow usando um EvalSavedModel especial. Agora, as métricas podem ser calculadas fora do gráfico TF usando implementações beam.CombineFn .

Algumas das principais diferenças são:

  • Um EvalSavedModel requer uma exportação especial do treinador, enquanto um modelo de serviço pode ser usado sem nenhuma alteração necessária no código de treinamento.
  • Quando um EvalSavedModel é usado, todas as métricas adicionadas no momento do treinamento ficam automaticamente disponíveis no momento da avaliação. Sem um EvalSavedModel essas métricas devem ser adicionadas novamente.
    • A exceção a essa regra é que, se um modelo keras for usado, as métricas também poderão ser adicionadas automaticamente porque o keras salva as informações da métrica ao lado do modelo salvo.

O TFMA pode trabalhar com métricas in-graph e métricas externas?

O TFMA permite que uma abordagem híbrida seja usada onde algumas métricas podem ser calculadas no gráfico, enquanto outras podem ser calculadas fora. Se você atualmente possui um EvalSavedModel , pode continuar a usá-lo.

Existem dois casos:

  1. Use o TFMA EvalSavedModel para extração de recursos e cálculos de métricas, mas também adicione métricas adicionais baseadas em combinador. Nesse caso, você obteria todas as métricas no gráfico do EvalSavedModel junto com quaisquer métricas adicionais do combinador que talvez não tivessem suporte anteriormente.
  2. Use o TFMA EvalSavedModel para extração de recursos/previsões, mas use métricas baseadas em combinador para todos os cálculos de métricas. Este modo é útil se houver transformações de recursos presentes no EvalSavedModel que você gostaria de usar para fatiar, mas prefere realizar todos os cálculos de métricas fora do gráfico.

Configurar

Quais tipos de modelo são suportados?

O TFMA suporta modelos keras, modelos baseados em APIs genéricas de assinatura TF2, bem como modelos baseados em estimador TF (embora, dependendo do caso de uso, os modelos baseados em estimador possam exigir que um EvalSavedModel seja usado).

Consulte o guia get_started para obter a lista completa de tipos de modelo suportados e quaisquer restrições.

Como configuro o TFMA para trabalhar com um modelo nativo baseado em keras?

Veja a seguir um exemplo de configuração para um modelo keras com base nas seguintes suposições:

  • O modelo salvo é para veiculação e usa o nome de assinatura serving_default (isso pode ser alterado usando model_specs[0].signature_name ).
  • Métricas incorporadas de model.compile(...) devem ser avaliadas (isso pode ser desabilitado via options.include_default_metric dentro do tfma.EvalConfig ).
from google.protobuf import text_format

config = text_format.Parse("""
  model_specs {
    label_key: "<label-key>"
    example_weight_key: "<example-weight-key>"
  }
  metrics_specs {
    # Add metrics here. For example:
    #  metrics { class_name: "ConfusionMatrixPlot" }
    #  metrics { class_name: "CalibrationPlot" }
  }
  slicing_specs {}
""", tfma.EvalConfig())

Consulte métricas para obter mais informações sobre outros tipos de métricas que podem ser configuradas.

Como configuro o TFMA para trabalhar com um modelo genérico baseado em assinaturas TF2?

A seguir está um exemplo de configuração para um modelo TF2 genérico. Abaixo, signature_name é o nome da assinatura específica que deve ser usada para avaliação.

from google.protobuf import text_format

config = text_format.Parse("""
  model_specs {
    signature_name: "<signature-name>"
    label_key: "<label-key>"
    example_weight_key: "<example-weight-key>"
  }
  metrics_specs {
    # Add metrics here. For example:
    #  metrics { class_name: "BinaryCrossentropy" }
    #  metrics { class_name: "ConfusionMatrixPlot" }
    #  metrics { class_name: "CalibrationPlot" }
  }
  slicing_specs {}
""", tfma.EvalConfig())

Consulte métricas para obter mais informações sobre outros tipos de métricas que podem ser configuradas.

Como configuro o TFMA para trabalhar com um modelo baseado em estimador?

Neste caso, há três opções.

Opção 1: usar o modelo de veiculação

Se esta opção for usada, quaisquer métricas adicionadas durante o treinamento NÃO serão incluídas na avaliação.

Veja a seguir um exemplo de configuração assumindo que serving_default é o nome da assinatura usada:

from google.protobuf import text_format

config = text_format.Parse("""
  model_specs {
    label_key: "<label-key>"
    example_weight_key: "<example-weight-key>"
  }
  metrics_specs {
    # Add metrics here.
  }
  slicing_specs {}
""", tfma.EvalConfig())

Consulte métricas para obter mais informações sobre outros tipos de métricas que podem ser configuradas.

Opção 2: use EvalSavedModel junto com métricas adicionais baseadas em combinador

Nesse caso, use EvalSavedModel para extração e avaliação de recurso/predição e também adicione métricas adicionais baseadas em combinador.

Segue um exemplo de configuração:

from google.protobuf import text_format

config = text_format.Parse("""
  model_specs {
    signature_name: "eval"
  }
  metrics_specs {
    # Add metrics here.
  }
  slicing_specs {}
""", tfma.EvalConfig())

Consulte métricas para obter mais informações sobre outros tipos de métricas que podem ser configuradas e EvalSavedModel para obter mais informações sobre como configurar o EvalSavedModel.

Opção 3: use o modelo EvalSavedModel apenas para extração de recurso/previsão

Semelhante à opção (2), mas use apenas EvalSavedModel para extração de recursos/previsões. Essa opção é útil se apenas métricas externas forem desejadas, mas houver transformações de recursos que você gostaria de fatiar. Semelhante à opção (1), quaisquer métricas adicionadas durante o treinamento NÃO serão incluídas na avaliação.

Neste caso, a configuração é a mesma acima, apenas include_default_metrics está desabilitado.

from google.protobuf import text_format

config = text_format.Parse("""
  model_specs {
    signature_name: "eval"
  }
  metrics_specs {
    # Add metrics here.
  }
  slicing_specs {}
  options {
    include_default_metrics { value: false }
  }
""", tfma.EvalConfig())

Consulte métricas para obter mais informações sobre outros tipos de métricas que podem ser configuradas e EvalSavedModel para obter mais informações sobre como configurar o EvalSavedModel.

Como configuro o TFMA para trabalhar com um modelo baseado em modelo para estimador keras?

A configuração do keras model_to_estimator é semelhante à configuração do estimador. No entanto, existem algumas diferenças específicas de como o modelo para o estimador funciona. Em particular, o model-to-esimtator devolve os seus resultados na forma de um dict onde a chave dictéo nome da última camada de saída no modelo keras associado (se não for fornecido nenhum nome, o keras iráescolher um nome predefinido para si como dense_1 ou output_1 ). Do ponto de vista do TFMA, esse comportamento é semelhante ao que seria produzido para um modelo de várias saídas, embora o modelo para o estimador possa ser apenas para um único modelo. Para levar em conta essa diferença, uma etapa adicional é necessária para configurar o nome de saída. No entanto, as mesmas três opções se aplicam como estimador.

Veja a seguir um exemplo das alterações necessárias para uma configuração baseada em estimador:

from google.protobuf import text_format

config = text_format.Parse("""
  ... as for estimator ...
  metrics_specs {
    output_names: ["<keras-output-layer>"]
    # Add metrics here.
  }
  ... as for estimator ...
""", tfma.EvalConfig())

Como configuro o TFMA para trabalhar com previsões pré-calculadas (ou seja, independentemente do modelo)? ( TFRecord e tf.Example )

Para configurar o TFMA para trabalhar com previsões pré-calculadas, o tfma.PredictExtractor padrão deve ser desabilitado e o tfma.InputExtractor deve ser configurado para analisar as previsões junto com os outros recursos de entrada. Isso é feito configurando um tfma.ModelSpec com o nome da chave de recurso usada para as previsões ao lado dos rótulos e pesos.

Segue um exemplo de configuração:

from google.protobuf import text_format

config = text_format.Parse("""
  model_specs {
    prediction_key: "<prediction-key>"
    label_key: "<label-key>"
    example_weight_key: "<example-weight-key>"
  }
  metrics_specs {
    # Add metrics here.
  }
  slicing_specs {}
""", tfma.EvalConfig())

Consulte as métricas para obter mais informações sobre as métricas que podem ser configuradas.

Observe que embora um tfma.ModelSpec esteja sendo configurado, um modelo não está realmente sendo usado (ou seja, não há tfma.EvalSharedModel ). A chamada para executar a análise do modelo pode ter a seguinte aparência:

eval_result = tfma.run_model_analysis(
    eval_config=eval_config,
    # This assumes your data is a TFRecords file containing records in the
    # tf.train.Example format.
    data_location="/path/to/file/containing/tfrecords",
    output_path="/path/for/metrics_for_slice_proto")

Como configuro o TFMA para trabalhar com previsões pré-calculadas (ou seja, independentemente do modelo)? ( pd.DataFrame )

Para conjuntos de dados pequenos que podem caber na memória, uma alternativa para um TFRecord é um pandas.DataFrame s. O TFMA pode operar em pandas.DataFrame s usando a API tfma.analyze_raw_data . Para obter uma explicação de tfma.MetricsSpec e tfma.SlicingSpec , consulte o guia de configuração . Consulte as métricas para obter mais informações sobre as métricas que podem ser configuradas.

Segue um exemplo de configuração:

# Run in a Jupyter Notebook.

df_data = ...  # your pd.DataFrame

eval_config = text_format.Parse("""
  model_specs {
    label_key: 'label'
    prediction_key: 'prediction'
  }
  metrics_specs {
    metrics { class_name: "AUC" }
    metrics { class_name: "ConfusionMatrixPlot" }
  }
  slicing_specs {}
  slicing_specs {
    feature_keys: 'language'
  }
""", config.EvalConfig())

eval_result = tfma.analyze_raw_data(df_data, eval_config)

tfma.view.render_slicing_metrics(eval_result)

Métricas

Que tipos de métricas são compatíveis?

O TFMA suporta uma ampla variedade de métricas, incluindo:

As métricas de modelos de várias saídas são suportadas?

Sim. Consulte o guia de métricas para obter mais detalhes.

As métricas de vários modelos são suportadas?

Sim. Consulte o guia de métricas para obter mais detalhes.

As configurações de métrica (nome etc.) podem ser personalizadas?

Sim. As configurações de métricas podem ser personalizadas (por exemplo, definindo limites específicos, etc.) adicionando config à configuração da métrica. Veja o guia de métricas tem mais detalhes.

As métricas personalizadas são suportadas?

Sim. Ou escrevendo uma implementação customizada de tf.keras.metrics.Metric ou escrevendo uma implementação customizada de beam.CombineFn . O guia de métricas tem mais detalhes.

Que tipos de métricas não são compatíveis?

Contanto que sua métrica possa ser calculada usando um beam.CombineFn , não há restrições sobre os tipos de métricas que podem ser calculadas com base em tfma.metrics.Metric . Se estiver trabalhando com uma métrica derivada de tf.keras.metrics.Metric , os seguintes critérios devem ser atendidos:

  • Deve ser possível calcular estatísticas suficientes para a métrica em cada exemplo de forma independente, depois combinar essas estatísticas suficientes adicionando-as em todos os exemplos e determinar o valor da métrica apenas a partir dessas estatísticas suficientes.
  • Por exemplo, para precisão, as estatísticas suficientes são "total correto" e "total de exemplos". É possível calcular esses dois números para exemplos individuais e somá-los para um grupo de exemplos para obter os valores corretos para esses exemplos. A precisão final pode ser calculada usando "total correto / total de exemplos".

Complementos

Posso usar o TFMA para avaliar a imparcialidade ou o viés em meu modelo?

O TFMA inclui um complemento FairnessIndicators que fornece métricas pós-exportação para avaliar os efeitos de viés não intencional em modelos de classificação.

Costumização

E se eu precisar de mais personalização?

O TFMA é muito flexível e permite que você personalize quase todas as partes do pipeline usando Extractors , Evaluators e/ou Writers personalizados. Essas abstrações são discutidas com mais detalhes no documento de arquitetura .

Solução de problemas, depuração e obtenção de ajuda

Por que as métricas MultiClassConfusionMatrix não correspondem às métricas binarizadas do ConfusionMatrix

Na verdade, são cálculos diferentes. A binarização realiza uma comparação para cada ID de classe de forma independente (ou seja, a previsão para cada classe é comparada separadamente com os limites fornecidos). Neste caso, é possível que duas ou mais classes todas indiquem que corresponderam à previsão porque seu valor previsto foi maior que o limite (isso será ainda mais aparente em limites mais baixos). No caso da matriz de confusão multiclasse, ainda há apenas um valor predito verdadeiro e ele corresponde ao valor real ou não. O limite só é usado para forçar uma previsão a não corresponder a nenhuma classe se for menor que o limite. Quanto maior o limite, mais difícil para a previsão de uma classe binarizada corresponder. Da mesma forma, quanto menor o limite, mais fácil é para as previsões de uma classe binarizada corresponderem. Isso significa que em limites > 0,5 os valores binarizados e os valores da matriz multiclasse estarão mais alinhados e em limites < 0,5 estarão mais distantes.

Por exemplo, digamos que temos 10 classes onde a classe 2 foi prevista com uma probabilidade de 0,8, mas a classe real foi a classe 1 que teve uma probabilidade de 0,15. Se você binarizar na classe 1 e usar um limite de 0,1, então a classe 1 será considerada correta (0,15 > 0,1) então será contada como um TP, porém, para o caso multiclasse, a classe 2 será considerada correta (0,8 > 0.1) e como a classe 1 foi a real, isso será contado como um FN. Como em limiares mais baixos mais valores serão considerados positivos, em geral haverá contagens de TP e FP mais altas para a matriz de confusão binarizada do que para a matriz de confusão multiclasse, e TN e FN igualmente mais baixos.

Veja a seguir um exemplo de diferenças observadas entre MultiClassConfusionMatrixAtThresholds e as contagens correspondentes da binarização de uma das classes.

MultiClassConfusionMatrixAtThresholds vs Binarized

Por que minhas métricas de precisão@1 e recall@1 têm o mesmo valor?

Em um valor k superior de 1, precisão e recall são a mesma coisa. A precisão é igual a TP / (TP + FP) e o recall é igual a TP / (TP + FN) . A previsão superior é sempre positiva e corresponderá ou não ao rótulo. Em outras palavras, com N exemplos, TP + FP = N . No entanto, se o rótulo não corresponder à previsão superior, isso também implica que uma previsão não superior k foi correspondida e com top k definido como 1, todas as previsões não superiores 1 serão 0. Isso implica que FN deve ser (N - TP) ou N = TP + FN . O resultado final é precision@1 = TP / N = recall@1 . Observe que isso só se aplica quando há um único rótulo por exemplo, não para vários rótulos.

Por que minhas métricas mean_label e mean_prediction são sempre 0,5?

Isso provavelmente é causado porque as métricas estão configuradas para um problema de classificação binária, mas o modelo está gerando probabilidades para ambas as classes em vez de apenas uma. Isso é comum quando a API de classificação do tensorflow é usada. A solução é escolher a classe na qual você gostaria que as previsões fossem baseadas e então binarizar nessa classe. Por exemplo:

eval_config = text_format.Parse("""
  ...
  metrics_specs {
    binarize { class_ids: { values: [0] } }
    metrics { class_name: "MeanLabel" }
    metrics { class_name: "MeanPrediction" }
    ...
  }
  ...
""", config.EvalConfig())

Como interpretar o MultiLabelConfusionMatrixPlot?

Dado um rótulo específico, o MultiLabelConfusionMatrixPlot (e o MultiLabelConfusionMatrix associado) podem ser usados ​​para comparar os resultados de outros rótulos e suas previsões quando o rótulo escolhido era realmente verdadeiro. Por exemplo, digamos que temos três classes bird , plane e superman -homem e estamos classificando imagens para indicar se elas contêm uma ou mais dessas classes. O MultiLabelConfusionMatrix calculará o produto cartesiano de cada classe real em relação a cada outra classe (chamada de classe prevista). Observe que, embora o emparelhamento seja (actual, predicted) , a classe predicted não implica necessariamente em uma previsão positiva, ela apenas representa a coluna prevista na matriz real x prevista. Por exemplo, digamos que calculamos as seguintes matrizes:

   (bird, bird)         ->    { tp: 6, fp: 0, fn: 2, tn: 0}
   (bird, plane)        ->    { tp: 2, fp: 2, fn: 2, tn: 2}
   (bird, superman)     ->    { tp: 1, fp: 1, fn: 4, tn: 2}
   (plane, bird)        ->    { tp: 3, fp: 1, fn: 1, tn: 3}
   (plane, plane)       ->    { tp: 4, fp: 0, fn: 4, tn: 0}
   (plane, superman)    ->    { tp: 1, fp: 3, fn: 3, tn: 1}
   (superman, bird)     ->    { tp: 3, fp: 2, fn: 2, tn: 2}
   (superman, plane)    ->    { tp: 2, fp: 3, fn: 2, tn: 2}
   (superman, superman) ->    { tp: 4, fp: 0, fn: 5, tn: 0}

   num_examples: 20

O MultiLabelConfusionMatrixPlot tem três maneiras de exibir esses dados. Em todos os casos, a maneira de ler a tabela é linha por linha da perspectiva da classe real.

1) Contagem total de previsão

Neste caso, para uma determinada linha (ou seja, classe real) quais foram as contagens de TP + FP para as outras classes. Para as contagens acima, nossa exibição seria a seguinte:

Ave prevista Plano previsto super-homem previsto
pássaro real 6 4 2
Avião real 4 4 4
super-homem real 5 5 4

Quando as imagens realmente continham um bird , previmos corretamente 6 deles. Ao mesmo tempo, também previmos plane (correta ou incorretamente) 4 vezes e superman -homem (correta ou incorretamente) 2 vezes.

2) Contagem de previsão incorreta

Neste caso, para uma determinada linha (ou seja, classe real), quais foram as contagens de FP para as outras classes. Para as contagens acima, nossa exibição seria a seguinte:

Ave prevista Plano previsto super-homem previsto
pássaro real 0 2 1
Avião real 1 0 3
super-homem real 2 3 0

Quando as imagens realmente continham um bird , previmos incorretamente o plane 2 vezes e o superman -homem 1 vezes.

3) Contagem de falsos negativos

Neste caso, para uma determinada linha (ou seja, classe real), quais foram as contagens de FN para as outras classes. Para as contagens acima, nossa exibição seria a seguinte:

Ave prevista Plano previsto super-homem previsto
pássaro real 2 2 4
Avião real 1 4 3
super-homem real 2 2 5

Quando as imagens realmente continham um bird , falhamos em prever 2 vezes. Ao mesmo tempo, falhamos em prever o plane 2 vezes e o superman -homem 4 vezes.

Por que recebo um erro sobre a chave de previsão não encontrada?

Alguns modelos produzem suas previsões na forma de um dicionário. Por exemplo, um estimador de TF para problemas de classificação binária gera um dicionário contendo probabilities , class_ids , etc. Na maioria dos casos, o TFMA tem padrões para encontrar nomes de chaves comumente usados, como predictions , probabilities , etc. No entanto, se seu modelo for muito personalizado, pode chaves de saída sob nomes não conhecidos pelo TFMA. Nesses casos, uma configuração prediciton_key deve ser adicionada ao tfma.ModelSpec para identificar o nome da chave sob a qual a saída está armazenada.