Como o tf.app.run () funciona?

148

Como tf.app.run()funciona a demonstração de tradução do Tensorflow?

Em tensorflow/models/rnn/translate/translate.py, há uma chamada para tf.app.run(). Como está sendo tratado?

if __name__ == "__main__":
    tf.app.run() 
Anurag Ranjan
fonte

Respostas:

134
if __name__ == "__main__":

significa que o arquivo atual é executado em um shell em vez de importado como um módulo.

tf.app.run()

Como você pode ver através do arquivo app.py

def run(main=None, argv=None):
  """Runs the program with an optional 'main' function and 'argv' list."""
  f = flags.FLAGS

  # Extract the args from the optional `argv` list.
  args = argv[1:] if argv else None

  # Parse the known flags from that list, or from the command
  # line otherwise.
  # pylint: disable=protected-access
  flags_passthrough = f._parse_flags(args=args)
  # pylint: enable=protected-access

  main = main or sys.modules['__main__'].main

  # Call the main function, passing through any arguments
  # to the final program.
  sys.exit(main(sys.argv[:1] + flags_passthrough))

Vamos quebrar linha por linha:

flags_passthrough = f._parse_flags(args=args)

Isso garante que o argumento que você passa pela linha de comando seja válido; por exemplo python my_model.py --data_dir='...' --max_iteration=10000, esse recurso é implementado com base no argparsemódulo padrão python .

main = main or sys.modules['__main__'].main

O primeiro mainno lado direito de =é o primeiro argumento da função atual run(main=None, argv=None) . Enquanto sys.modules['__main__']significa atual arquivo em execução (por exemplo my_model.py).

Portanto, existem dois casos:

  1. Você não tem uma mainfunção em my_model.pyEntão você tem que chamartf.app.run(my_main_running_function)

  2. você tem uma mainfunção my_model.py. (Este é principalmente o caso.)

Última linha:

sys.exit(main(sys.argv[:1] + flags_passthrough))

garante que sua função main(argv)ou my_main_running_function(argv)seja chamada com argumentos analisados ​​corretamente.

lei du
fonte
67
Uma peça que falta no quebra-cabeça para usuários iniciantes do Tensorflow: O Tensorflow possui algum mecanismo interno de manipulação de sinalizadores de linha de comando. Você pode definir seus sinalizadores como tf.flags.DEFINE_integer('batch_size', 128, 'Number of images to process in a batch.')e, se usá- tf.app.run()lo, configurará as coisas para que você possa acessar globalmente os valores passados ​​dos sinalizadores que você definiu, como tf.flags.FLAGS.batch_sizede onde você precisar no seu código.
Isarandi 28/05
1
Esta é a melhor resposta dos três (atuais) na minha opinião. Ele explica "Como funciona o tf.app.run ()", enquanto as outras duas respostas apenas dizem o que fazem.
Thomas Fauskanger
Looks como as bandeiras são tratados pelo abseilqual TF deve ter absorvido abseil.io/docs/python/guides/flags
CpILL
75

É apenas um invólucro muito rápido que lida com a análise de sinalizadores e depois despacha para o seu próprio main. Veja o código .

dga
fonte
12
o que significa "manipula a análise de sinalizadores"? Talvez você possa adicionar um link para informar aos iniciantes o que isso significa?
Pinóquio
4
Ele analisa os argumentos da linha de comando fornecidos ao programa usando o pacote flags. (que usa a biblioteca 'argparse' padrão sob as capas, com alguns invólucros). Está vinculado ao código ao qual vinculei minha resposta.
dga
1
No app.py, o que significa main = main or sys.modules['__main__'].maine o que sys.exit(main(sys.argv[:1] + flags_passthrough))significa?
HAcKnRoCk
3
isso me parece estranho, por que agrupar a função principal em tudo isso, se você pode chamá-lo diretamente main()?
Charlie Parker
2
hAcKnRoCk: se não houver main no arquivo, ele usará o que estiver em sys.modules [' main '] .main. O sys.exit significa executar o comando principal encontrado com os argumentos e quaisquer sinalizadores passados ​​e sair com o valor de retorno de main. @CharlieParker - para compatibilidade com as bibliotecas de aplicativos python existentes do Google, como gflags e google-apputils. Veja, por exemplo, github.com/google/google-apputils
dga
8

Não há nada de especial tf.app. Este é apenas um script de ponto de entrada genérico , que

Executa o programa com uma função opcional 'main' e uma lista 'argv'.

Não tem nada a ver com redes neurais e apenas chama a função principal, passando por quaisquer argumentos a ela.

Salvador Dalí
fonte
5

Em termos simples, o trabalho de tf.app.run()é primeiro definir os sinalizadores globais para uso posterior, como:

from tensorflow.python.platform import flags
f = flags.FLAGS

e, em seguida, execute sua função principal personalizada com um conjunto de argumentos.

Por exemplo, na base de código TensorFlow NMT , o primeiro ponto de entrada para a execução do programa para treinamento / inferência começa neste ponto (veja o código abaixo)

if __name__ == "__main__":
  nmt_parser = argparse.ArgumentParser()
  add_arguments(nmt_parser)
  FLAGS, unparsed = nmt_parser.parse_known_args()
  tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)

Após analisar os argumentos usando argparse, tf.app.run()você executa a função "main", definida como:

def main(unused_argv):
  default_hparams = create_hparams(FLAGS)
  train_fn = train.train
  inference_fn = inference.inference
  run_main(FLAGS, default_hparams, train_fn, inference_fn)

Portanto, depois de definir os sinalizadores para uso global, tf.app.run()basta executar a mainfunção que você passar para ela argvcomo seus parâmetros.

PS: Como a resposta de Salvador Dali diz, acho que é apenas uma boa prática de engenharia de software, embora não tenha certeza se o TensorFlow executa uma execução otimizada da mainfunção do que aquela executada usando o CPython normal.

kmario23
fonte
2

O código do Google depende muito do acesso de sinalizadores globais nos scripts libraries / binaries / python e, portanto, tf.app.run () analisa esses sinalizadores para criar um estado global na variável FLAGs (ou algo semelhante) e depois chama python main ( ) Como deveria.

Se eles não tiverem essa chamada para tf.app.run (), os usuários poderão esquecer de analisar FLAGs, fazendo com que essas bibliotecas / binários / scripts não tenham acesso aos FLAGs necessários.

Mudit Jain
fonte
1

2.0 compatível Resposta : Se você quiser usar tf.app.run()em Tensorflow 2.0, devemos usar o comando,

tf.compat.v1.app.run()ou você pode usar tf_upgrade_v2para converter o 1.xcódigo em 2.0.

Suporte ao Tensorflow
fonte