TF1.x -> Visão geral da migração TF2

O TensorFlow 2 é fundamentalmente diferente do TF1.x de várias maneiras. Você ainda pode executar o código TF1.x não modificado ( exceto contrib ) em instalações binárias do TF2 da seguinte forma:

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

No entanto, isso não está executando comportamentos e APIs do TF2 e pode não funcionar conforme o esperado com código escrito para TF2. Se você não estiver executando com os comportamentos do TF2 ativos, você está efetivamente executando o TF1.x sobre uma instalação do TF2. Leia o guia de comportamento TF1 vs TF2 para obter mais detalhes sobre como o TF2 é diferente do TF1.x.

Este guia fornece uma visão geral do processo de migração do código TF1.x para TF2. Isso permite que você aproveite melhorias de recursos novas e futuras e também torne seu código mais simples, com melhor desempenho e mais fácil de manter.

Se você estiver usando APIs de alto nível do tf.keras e treinando exclusivamente com model.fit , seu código deverá ser mais ou menos totalmente compatível com TF2, exceto pelas seguintes advertências:

Processo de migração TF2

Antes de migrar, aprenda sobre o comportamento e as diferenças de API entre TF1.x e TF2 lendo o guia .

  1. Execute o script automatizado para converter parte do uso da API TF1.x em tf.compat.v1 .
  2. Remova os símbolos tf.contrib antigos (verifique TF Addons e TF-Slim ).
  3. Faça com que os passes de encaminhamento do modelo TF1.x sejam executados no TF2 com a execução antecipada habilitada.
  4. Atualize seu código TF1.x para loops de treinamento e salvamento/carregamento de modelos para equivalentes TF2.
  5. (Opcional) Migre suas APIs tf.compat.v1 compatíveis com TF2 para APIs TF2 idiomáticas.

As seções a seguir expandem as etapas descritas acima.

Execute o script de conversão de símbolo

Isso executa uma passagem inicial para reescrever seus símbolos de código para execução em binários TF 2.x, mas não tornará seu código idiomático para TF 2.x nem tornará seu código automaticamente compatível com comportamentos do TF2.

Seu código provavelmente ainda usará endpoints tf.compat.v1 para acessar espaços reservados, sessões, coleções e outras funcionalidades do estilo TF1.x.

Leia o guia para saber mais sobre as práticas recomendadas para usar o script de conversão de símbolos.

Remover o uso de tf.contrib

O módulo tf.contrib foi desativado e vários de seus submódulos foram integrados à API principal do TF2. Os outros submódulos agora são desmembrados em outros projetos como TF IO e TF Addons .

Uma grande quantidade de código TF1.x antigo usa a biblioteca Slim , que foi empacotada com TF1.x como tf.contrib.layers . Ao migrar seu código Slim para TF2, altere os usos da API Slim para apontar para o pacote tf-slim pip . Em seguida, leia o guia de mapeamento de modelo para aprender como converter o código Slim.

Alternativamente, se você usar modelos pré-treinados Slim, você pode considerar experimentar os modelos pré-treinados de Keras em tf.keras.applications ou TF2 SavedModel s do TF Hub exportados do código Slim original.

Faça com que os passes de encaminhamento do modelo TF1.x sejam executados com os comportamentos do TF2 habilitados

Acompanhe variáveis ​​e perdas

TF2 não oferece suporte a coleções globais.

A execução rápida no TF2 não oferece suporte a APIs baseadas em coleção tf.Graph . Isso afeta como você constrói e rastreia variáveis.

Para o novo código TF2, você usaria tf.Variable em vez de v1.get_variable e usaria objetos Python para coletar e rastrear variáveis ​​em vez de tf.compat.v1.variable_scope . Normalmente, isso seria um dos seguintes:

Agregue listas de variáveis ​​(como tf.Graph.get_collection(tf.GraphKeys.VARIABLES) ) com os atributos .variables e .trainable_variables dos objetos Layer , Module ou Model .

As classes Layer e Model implementam diversas outras propriedades que eliminam a necessidade de coleções globais. Sua propriedade .losses pode substituir o uso da coleção tf.GraphKeys.LOSSES .

Leia o guia de mapeamento de modelo para saber mais sobre como usar os calços de modelagem de código TF2 para incorporar seu código existente baseado em get_variable e variable_scope dentro de Layers , Models e Modules . Isso permitirá que você execute passes avançados com execução antecipada habilitada sem grandes reescritas.

Adaptando-se a outras mudanças de comportamento

Se o guia de mapeamento do modelo por si só for insuficiente para fazer seu modelo avançar executando outras mudanças de comportamento que podem ser mais detalhadas, consulte o guia sobre comportamentos TF1.x vs TF2 para aprender sobre as outras mudanças de comportamento e como você pode se adaptar a elas . Verifique também o guia de criação de novas camadas e modelos por meio de subclasses para obter detalhes.

Validando seus resultados

Consulte o guia de validação de modelo para obter ferramentas fáceis e orientações sobre como você pode validar (numericamente) se seu modelo está se comportando corretamente quando a execução antecipada está habilitada. Você pode achar isso especialmente útil quando combinado com o guia de mapeamento de modelo .

Atualizar treinamento, avaliação e código de importação/exportação

Os loops de treinamento TF1.x construídos com tf.estimator.Estimator estilo v1.Session e outras abordagens baseadas em coleções não são compatíveis com os novos comportamentos do TF2. É importante que você migre todo o seu código de treinamento TF1.x, pois combiná-lo com o código TF2 pode causar comportamentos inesperados.

Você pode escolher entre várias estratégias para fazer isso.

A abordagem de mais alto nível é usar tf.keras . As funções de alto nível no Keras gerenciam muitos detalhes de baixo nível que podem ser fáceis de perder se você escrever seu próprio ciclo de treinamento. Por exemplo, eles coletam automaticamente as perdas de regularização e definem o argumento training=True ao chamar o modelo.

Consulte o guia de migração do Estimator para saber como você pode migrar o código do tf.estimator.Estimator para usar loops de treinamento vanilla e personalizados tf.keras .

Loops de treinamento personalizados oferecem controle mais preciso sobre seu modelo, como rastrear os pesos de camadas individuais. Leia o guia sobre como criar loops de treinamento do zero para aprender como usar tf.GradientTape para recuperar pesos de modelo e usá-los para atualizar o modelo.

Converter otimizadores TF1.x em otimizadores Keras

Os otimizadores em tf.compat.v1.train , como o otimizador Adam e o otimizador de gradiente descendente , têm equivalentes em tf.keras.optimizers .

A tabela abaixo resume como você pode converter esses otimizadores legados em seus equivalentes Keras. Você pode substituir diretamente a versão TF1.x pela versão TF2, a menos que etapas adicionais (como atualizar a taxa de aprendizado padrão ) sejam necessárias.

Observe que a conversão de seus otimizadores pode tornar os pontos de verificação antigos incompatíveis .

TF1.x TF2 Etapas adicionais
`tf.v1.train.GradientDescentOptimizer` tf.keras.optimizers.SGD Nenhum
`tf.v1.train.MomentumOptimizer` tf.keras.optimizers.SGD Incluir o argumento `momentum`
`tf.v1.train.AdamOptimizer` tf.keras.optimizers.Adam Renomeie os argumentos `beta1` e `beta2` para `beta_1` e `beta_2`
`tf.v1.train.RMSPropOptimizer` tf.keras.optimizers.RMSprop Renomeie o argumento `decay` para `rho`
`tf.v1.train.AdadeltaOptimizer` tf.keras.optimizers.Adadelta Nenhum
`tf.v1.train.AdagradOptimizer` tf.keras.optimizers.Adagrad Nenhum
`tf.v1.train.FtrlOptimizer` tf.keras.optimizers.Ftrl Remova os argumentos `accum_name` e `linear_name`
`tf.contrib.AdamaxOptimizer` tf.keras.optimizers.Adamax Renomeie os argumentos `beta1` e `beta2` para `beta_1` e `beta_2`
`tf.contrib.Nadam` tf.keras.optimizers.Nadam Renomeie os argumentos `beta1` e `beta2` para `beta_1` e `beta_2`

Atualizar pipelines de entrada de dados

Existem muitas maneiras de alimentar dados para um modelo tf.keras . Eles aceitarão geradores Python e matrizes Numpy como entrada.

A maneira recomendada de alimentar um modelo com dados é usar o pacote tf.data , que contém uma coleção de classes de alto desempenho para manipulação de dados. Os conjuntos de dataset pertencentes ao tf.data são eficientes, expressivos e integram-se bem com o TF2.

Eles podem ser passados ​​diretamente para o método tf.keras.Model.fit .

model.fit(dataset, epochs=5)

Eles podem ser iterados diretamente no Python padrão:

for example_batch, label_batch in dataset:
    break

Se você ainda estiver usando tf.queue , agora eles serão suportados apenas como estruturas de dados, não como pipelines de entrada.

Você também deve migrar todo o código de pré-processamento de recursos que usa tf.feature_columns . Leia o guia de migração para obter mais detalhes.

Salvando e carregando modelos

TF2 usa pontos de verificação baseados em objetos. Leia o guia de migração de pontos de verificação para saber mais sobre a migração de pontos de verificação TF1.x baseados em nomes. Leia também o guia de pontos de verificação nos documentos principais do TensorFlow.

Não há preocupações significativas de compatibilidade para modelos salvos. Leia o guia SavedModel para obter mais informações sobre a migração SavedModel s em TF1.x para TF2. Em geral,

  • TF1.x save_models funcionam no TF2.
  • Os modelos salvos do TF2 funcionam no TF1.x se todas as operações forem suportadas.

Consulte também a seção GraphDef no guia de migração SavedModel para obter mais informações sobre como trabalhar com objetos Graph.pb e Graph.pbtxt .

(Opcional) Migrar símbolos tf.compat.v1

O módulo tf.compat.v1 contém a API TF1.x completa, com sua semântica original.

Mesmo depois de seguir as etapas acima e obter um código totalmente compatível com todos os comportamentos do TF2, é provável que haja muitas menções a APIs compat.v1 que sejam compatíveis com o TF2. Você deve evitar usar essas APIs compat.v1 herdadas para qualquer novo código que você escrever, embora elas continuem funcionando para o seu código já escrito.

No entanto, você pode optar por migrar os usos existentes para APIs TF2 não herdadas. As docstrings de símbolos compat.v1 individuais geralmente explicam como migrá-los para APIs TF2 não herdadas. Além disso, a seção do guia de mapeamento de modelo sobre migração incremental para APIs idiomáticas do TF2 também pode ajudar com isso.

Recursos e leitura adicional

Conforme mencionado anteriormente, é uma boa prática migrar todo o seu código TF1.x para TF2. Leia os guias na seção Migrar para TF2 do guia do TensorFlow para saber mais.

,

O TensorFlow 2 é fundamentalmente diferente do TF1.x de várias maneiras. Você ainda pode executar o código TF1.x não modificado ( exceto contrib ) em instalações binárias do TF2 da seguinte forma:

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()

No entanto, isso não está executando comportamentos e APIs do TF2 e pode não funcionar conforme o esperado com código escrito para TF2. Se você não estiver executando com os comportamentos do TF2 ativos, você está efetivamente executando o TF1.x sobre uma instalação do TF2. Leia o guia de comportamento TF1 vs TF2 para obter mais detalhes sobre como o TF2 é diferente do TF1.x.

Este guia fornece uma visão geral do processo de migração do código TF1.x para TF2. Isso permite que você aproveite melhorias de recursos novas e futuras e também torne seu código mais simples, com melhor desempenho e mais fácil de manter.

Se você estiver usando APIs de alto nível do tf.keras e treinando exclusivamente com model.fit , seu código deverá ser mais ou menos totalmente compatível com TF2, exceto pelas seguintes advertências:

Processo de migração TF2

Antes de migrar, aprenda sobre o comportamento e as diferenças de API entre TF1.x e TF2 lendo o guia .

  1. Execute o script automatizado para converter parte do uso da API TF1.x em tf.compat.v1 .
  2. Remova os símbolos tf.contrib antigos (verifique TF Addons e TF-Slim ).
  3. Faça com que os passes de encaminhamento do modelo TF1.x sejam executados no TF2 com a execução antecipada habilitada.
  4. Atualize seu código TF1.x para loops de treinamento e salvamento/carregamento de modelos para equivalentes TF2.
  5. (Opcional) Migre suas APIs tf.compat.v1 compatíveis com TF2 para APIs TF2 idiomáticas.

As seções a seguir expandem as etapas descritas acima.

Execute o script de conversão de símbolo

Isso executa uma passagem inicial para reescrever seus símbolos de código para execução em binários TF 2.x, mas não tornará seu código idiomático para TF 2.x nem tornará seu código automaticamente compatível com comportamentos do TF2.

Seu código provavelmente ainda usará endpoints tf.compat.v1 para acessar espaços reservados, sessões, coleções e outras funcionalidades do estilo TF1.x.

Leia o guia para saber mais sobre as práticas recomendadas para usar o script de conversão de símbolos.

Remover o uso de tf.contrib

O módulo tf.contrib foi desativado e vários de seus submódulos foram integrados à API principal do TF2. Os outros submódulos agora são desmembrados em outros projetos como TF IO e TF Addons .

Uma grande quantidade de código TF1.x antigo usa a biblioteca Slim , que foi empacotada com TF1.x como tf.contrib.layers . Ao migrar seu código Slim para TF2, altere os usos da API Slim para apontar para o pacote tf-slim pip . Em seguida, leia o guia de mapeamento de modelo para aprender como converter o código Slim.

Alternativamente, se você usar modelos pré-treinados Slim, você pode considerar experimentar os modelos pré-treinados de Keras em tf.keras.applications ou TF2 SavedModel s do TF Hub exportados do código Slim original.

Faça com que os passes de encaminhamento do modelo TF1.x sejam executados com os comportamentos do TF2 habilitados

Acompanhe variáveis ​​e perdas

TF2 não oferece suporte a coleções globais.

A execução rápida no TF2 não oferece suporte a APIs baseadas em coleção tf.Graph . Isso afeta como você constrói e rastreia variáveis.

Para o novo código TF2, você usaria tf.Variable em vez de v1.get_variable e usaria objetos Python para coletar e rastrear variáveis ​​em vez de tf.compat.v1.variable_scope . Normalmente, isso seria um dos seguintes:

Agregue listas de variáveis ​​(como tf.Graph.get_collection(tf.GraphKeys.VARIABLES) ) com os atributos .variables e .trainable_variables dos objetos Layer , Module ou Model .

As classes Layer e Model implementam diversas outras propriedades que eliminam a necessidade de coleções globais. Sua propriedade .losses pode substituir o uso da coleção tf.GraphKeys.LOSSES .

Leia o guia de mapeamento de modelo para saber mais sobre como usar os calços de modelagem de código TF2 para incorporar seu código existente baseado em get_variable e variable_scope dentro de Layers , Models e Modules . Isso permitirá que você execute passes avançados com execução antecipada habilitada sem grandes reescritas.

Adaptando-se a outras mudanças de comportamento

Se o guia de mapeamento do modelo por si só for insuficiente para fazer seu modelo avançar executando outras mudanças de comportamento que podem ser mais detalhadas, consulte o guia sobre comportamentos TF1.x vs TF2 para aprender sobre as outras mudanças de comportamento e como você pode se adaptar a elas . Verifique também o guia de criação de novas camadas e modelos por meio de subclasses para obter detalhes.

Validando seus resultados

Consulte o guia de validação de modelo para obter ferramentas fáceis e orientações sobre como você pode validar (numericamente) se seu modelo está se comportando corretamente quando a execução antecipada está habilitada. Você pode achar isso especialmente útil quando combinado com o guia de mapeamento de modelo .

Atualizar treinamento, avaliação e código de importação/exportação

Os loops de treinamento TF1.x construídos com tf.estimator.Estimator estilo v1.Session e outras abordagens baseadas em coleções não são compatíveis com os novos comportamentos do TF2. É importante que você migre todo o seu código de treinamento TF1.x, pois combiná-lo com o código TF2 pode causar comportamentos inesperados.

Você pode escolher entre várias estratégias para fazer isso.

A abordagem de mais alto nível é usar tf.keras . As funções de alto nível no Keras gerenciam muitos detalhes de baixo nível que podem ser fáceis de perder se você escrever seu próprio ciclo de treinamento. Por exemplo, eles coletam automaticamente as perdas de regularização e definem o argumento training=True ao chamar o modelo.

Consulte o guia de migração do Estimator para saber como você pode migrar o código do tf.estimator.Estimator para usar loops de treinamento vanilla e personalizados tf.keras .

Loops de treinamento personalizados oferecem controle mais preciso sobre seu modelo, como rastrear os pesos de camadas individuais. Leia o guia sobre como criar loops de treinamento do zero para aprender como usar tf.GradientTape para recuperar pesos de modelo e usá-los para atualizar o modelo.

Converter otimizadores TF1.x em otimizadores Keras

Os otimizadores em tf.compat.v1.train , como o otimizador Adam e o otimizador de gradiente descendente , têm equivalentes em tf.keras.optimizers .

A tabela abaixo resume como você pode converter esses otimizadores legados em seus equivalentes Keras. Você pode substituir diretamente a versão TF1.x pela versão TF2, a menos que etapas adicionais (como atualizar a taxa de aprendizado padrão ) sejam necessárias.

Observe que a conversão de seus otimizadores pode tornar os pontos de verificação antigos incompatíveis .

TF1.x TF2 Etapas adicionais
`tf.v1.train.GradientDescentOptimizer` tf.keras.optimizers.SGD Nenhum
`tf.v1.train.MomentumOptimizer` tf.keras.optimizers.SGD Incluir o argumento `momentum`
`tf.v1.train.AdamOptimizer` tf.keras.optimizers.Adam Renomeie os argumentos `beta1` e `beta2` para `beta_1` e `beta_2`
`tf.v1.train.RMSPropOptimizer` tf.keras.optimizers.RMSprop Renomeie o argumento `decay` para `rho`
`tf.v1.train.AdadeltaOptimizer` tf.keras.optimizers.Adadelta Nenhum
`tf.v1.train.AdagradOptimizer` tf.keras.optimizers.Adagrad Nenhum
`tf.v1.train.FtrlOptimizer` tf.keras.optimizers.Ftrl Remova os argumentos `accum_name` e `linear_name`
`tf.contrib.AdamaxOptimizer` tf.keras.optimizers.Adamax Renomeie os argumentos `beta1` e `beta2` para `beta_1` e `beta_2`
`tf.contrib.Nadam` tf.keras.optimizers.Nadam Renomeie os argumentos `beta1` e `beta2` para `beta_1` e `beta_2`

Atualizar pipelines de entrada de dados

Existem muitas maneiras de alimentar dados para um modelo tf.keras . Eles aceitarão geradores Python e matrizes Numpy como entrada.

A maneira recomendada de alimentar um modelo com dados é usar o pacote tf.data , que contém uma coleção de classes de alto desempenho para manipulação de dados. Os conjuntos de dataset pertencentes ao tf.data são eficientes, expressivos e integram-se bem com o TF2.

Eles podem ser passados ​​diretamente para o método tf.keras.Model.fit .

model.fit(dataset, epochs=5)

Eles podem ser iterados diretamente no Python padrão:

for example_batch, label_batch in dataset:
    break

Se você ainda estiver usando tf.queue , agora eles serão suportados apenas como estruturas de dados, não como pipelines de entrada.

Você também deve migrar todo o código de pré-processamento de recursos que usa tf.feature_columns . Leia o guia de migração para obter mais detalhes.

Salvando e carregando modelos

TF2 usa pontos de verificação baseados em objetos. Leia o guia de migração de pontos de verificação para saber mais sobre a migração de pontos de verificação TF1.x baseados em nome. Leia também o guia de pontos de verificação nos documentos principais do TensorFlow.

Não há preocupações significativas de compatibilidade para modelos salvos. Leia o guia SavedModel para obter mais informações sobre a migração SavedModel s em TF1.x para TF2. Em geral,

  • TF1.x save_models funcionam no TF2.
  • Os modelos salvos do TF2 funcionam no TF1.x se todas as operações forem suportadas.

Consulte também a seção GraphDef no guia de migração SavedModel para obter mais informações sobre como trabalhar com objetos Graph.pb e Graph.pbtxt .

(Opcional) Migrar símbolos tf.compat.v1

O módulo tf.compat.v1 contém a API TF1.x completa, com sua semântica original.

Mesmo depois de seguir as etapas acima e obter um código totalmente compatível com todos os comportamentos do TF2, é provável que haja muitas menções a APIs compat.v1 que sejam compatíveis com o TF2. Você deve evitar usar essas APIs compat.v1 herdadas para qualquer novo código que você escrever, embora elas continuem funcionando para o seu código já escrito.

No entanto, você pode optar por migrar os usos existentes para APIs TF2 não herdadas. As docstrings de símbolos compat.v1 individuais geralmente explicam como migrá-los para APIs TF2 não herdadas. Além disso, a seção do guia de mapeamento de modelo sobre migração incremental para APIs idiomáticas do TF2 também pode ajudar com isso.

Recursos e leitura adicional

Conforme mencionado anteriormente, é uma boa prática migrar todo o seu código TF1.x para TF2. Leia os guias na seção Migrar para TF2 do guia do TensorFlow para saber mais.