Um tutorial oficial sobre @tf.function
diz:
Para obter o máximo desempenho e tornar seu modelo implantável em qualquer lugar, use tf.function para criar gráficos de seus programas. Graças ao AutoGraph, uma quantidade surpreendente de código Python funciona apenas com o tf.function, mas ainda há algumas armadilhas com as quais desconfiar.
Os principais tópicos e recomendações são:
- Não confie nos efeitos colaterais do Python, como mutação de objeto ou anexos à lista.
- O tf.function funciona melhor com operações TensorFlow, em vez de operações NumPy ou primitivas Python.
- Em caso de dúvida, use o idioma for x no y.
Ele menciona apenas como implementar @tf.function
funções anotadas, mas não quando usá-las.
Existe uma heurística sobre como decidir se devo pelo menos tentar anotar uma função tf.function
? Parece que não há razões para não fazê-lo, a menos que eu tenha preguiça de remover efeitos colaterais ou mudar algumas coisas como range()
-> tf.range()
. Mas se eu estiver disposto a fazer isso ...
Existe alguma razão para não usar @tf.function
para todas as funções?
fonte
tensorflow0.1
,tensorflow0.2
,tensorflow0.3
,tensorflow0.4
,tensorflow0.5
e assim por diante, bem como uma tag para cada um destestf
módulos e classes , em seguida. Além disso, por que não adicionar uma tag para cada um dos módulos padrão do Python e suas funções e classes?tf.function
guia diz "Decore funções no nível do módulo e métodos de classes no nível do módulo, e evite decorar funções ou métodos locais". Parece que me lembro de palavras mais explícitas, como "não decoro todas as funções, usotf.function
em funções de nível superior, como um loop de treinamento", mas posso me lembrar errado (ou talvez tenha sido removido). OTOH, essa discussão tem informações interessantes dos desenvolvedores; no final, parece bom usá-lo em qualquer função para tensores / vars.@tf.function
funções anotadas do AFAIK também compilam as funções que eles chamam de gráficos. Portanto, você só precisa anotar o ponto de entrada no módulo que é coerente com o que você descreve. Mas também não faria mal anotar manualmente funções mais baixas na pilha de chamadas.tf.function
for chamado várias vezes, não poderá impedir a "duplicação de código" no gráfico, e é por isso que o uso generalizado parece recomendável.Respostas:
TLDR: Depende da sua função e se você está em produção ou desenvolvimento. Não use
tf.function
se você deseja poder depurar sua função facilmente ou se ela se enquadra nas limitações do AutoGraph ou da compatibilidade de código tf.v1. Eu recomendo assistir as palestras do Inside TensorFlow sobre AutoGraph e Funções, não Sessões .A seguir, detalharei os motivos, todos extraídos de informações disponibilizadas on-line pelo Google.
Em geral, o
tf.function
decorador faz com que uma função seja compilada como uma chamada que executa um gráfico TensorFlow. Isto implica:Há informações detalhadas disponíveis sobre as idéias de design por trás disso.
Benefícios de decorar uma função com
tf.function
Benefícios gerais
Para funções com código Python / Uso do AutoGraph via
tf.function
decoraçãoSe você deseja usar o AutoGraph,
tf.function
é altamente recomendável usar diretamente o AutoGraph. Os motivos para isso incluem: Dependências de controle automático, são necessárias para algumas APIs, mais cache e auxiliares de exceção (Origem) .Desvantagens de decorar uma função com
tf.function
Desvantagens gerais
Para funções com código Python / Uso do AutoGraph via
tf.function
decoraçãoInformações detalhadas sobre as limitações do AutoGraph estão disponíveis.
Para funções com código tf.v1
tf.function
, mas isso está sujeito a alterações à medida que o código tf.v1 é eliminado gradualmente (Origem)Para funções com código tf.v2
Exemplos de limitações
Criando variáveis mais de uma vez
Não é permitido criar variáveis mais de uma vez, como
v
no exemplo a seguir:No código a seguir, isso é atenuado, garantindo que ele
self.v
seja criado apenas uma vez:Efeitos colaterais ocultos não capturados pelo AutoGraph
Alterações como
self.a
neste exemplo não podem ser ocultadas, o que leva a um erro, pois a análise de função cruzada ainda não foi realizada (ainda) (origem) :Mudanças à vista de todos não são um problema:
Exemplo de limitação devido ao fluxo de controle de TF
Esta instrução if leva a um erro porque o valor para else precisa ser definido para o fluxo de controle TF:
fonte
@tf.function
para produção, mas apenas para desenvolvimento, não é uma solução viável. Primeiro, no aprendizado de máquina (pelo menos na pesquisa), o treinamento durante o estágio de desenvolvimento também cria o produto final (o modelo treinado). Em segundo lugar, os decoradores são uma mudança significativa. Não posso simplesmente colocá-los em "após o desenvolvimento" e ter certeza de que o código se comporta da mesma maneira. Isso significa que eu tenho que desenvolver e testar com eles já lá.tf.function
se apropriado.O tf.function é útil na criação e no uso de gráficos computacionais, eles devem ser usados no treinamento e na implantação, no entanto, não é necessário para a maioria das suas funções.
Digamos que estamos construindo uma camada especial que fará parte de um modelo maior. Não gostaríamos de ter o decorador tf.function acima da função que constrói essa camada, porque é apenas uma definição da aparência da camada.
Por outro lado, digamos que vamos fazer uma previsão ou continuar nosso treinamento usando alguma função. Gostaríamos de ter o decorador tf.function porque, na verdade, estamos usando o gráfico computacional para obter algum valor.
Um ótimo exemplo seria construir um modelo de codificador-decodificador. NÃO coloque o decorador em torno da função, crie o codificador ou decodificador ou qualquer camada, que é apenas uma definição do que ele fará. Coloque o decorador em torno do método "treinar" ou "prever", porque eles realmente vão usar o gráfico computacional para computação.
fonte
tf.range()
. AFAIK estes não podem ser convertidos automaticamente. Então, eu precisaria escrever minhas camadas personalizadas com o gráfico automático em mente desde o início. Portanto, não posso apenas decorar a função de chamada (previsão).