¿Cómo funciona tf.app.run ()?

148

¿Cómo tf.app.run()funciona la demostración de traducción de Tensorflow?

En tensorflow/models/rnn/translate/translate.py, hay una llamada a tf.app.run(). ¿Cómo se está manejando?

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

Respuestas:

134
if __name__ == "__main__":

significa que el archivo actual se ejecuta bajo un shell en lugar de importarse como un módulo.

tf.app.run()

Como puedes ver a través del archivo 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 a romper línea por línea:

flags_passthrough = f._parse_flags(args=args)

Esto asegura que el argumento que pasa a través de la línea de comando es válido, por ejemplo python my_model.py --data_dir='...' --max_iteration=10000, en realidad, esta característica se implementa en base al argparsemódulo estándar de Python .

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

El primero mainen el lado derecho de =es el primer argumento de la función actual run(main=None, argv=None) . Mientras que sys.modules['__main__']significa el archivo actual en ejecución (por ejemplo my_model.py).

Entonces hay dos casos:

  1. No tienes una mainfunción en my_model.pyEntonces tienes que llamartf.app.run(my_main_running_function)

  2. tienes una mainfunción en my_model.py. (Este es principalmente el caso).

Última línea:

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

garantiza que se llame a su función main(argv)o my_main_running_function(argv)con argumentos analizados correctamente.

lei du
fuente
67
Una pieza faltante del rompecabezas para usuarios principiantes de Tensorflow: Tensorflow tiene algún mecanismo de manejo de banderas de línea de comando incorporado. Puede definir sus indicadores como tf.flags.DEFINE_integer('batch_size', 128, 'Number of images to process in a batch.')y luego, si lo usa tf.app.run(), configurará las cosas para que pueda acceder globalmente a los valores pasados ​​de los indicadores que definió, como tf.flags.FLAGS.batch_sizedesde donde lo necesite en su código.
isarandi
1
Esta es la mejor respuesta de los tres (actuales) en mi opinión. Explica el "Cómo funciona tf.app.run ()", mientras que las otras dos respuestas solo dicen lo que hace.
Thomas Fauskanger
Parece que las banderas son manejadas por las abseilcuales TF debe haber absorbido abseil.io/docs/python/guides/flags
CpILL
75

Es solo un contenedor muy rápido que maneja el análisis de banderas y luego se envía a su propio main. Mira el código .

dga
fuente
12
¿Qué significa "maneja el análisis de la bandera"? ¿Quizás podría agregar un enlace para informar a los principiantes lo que eso significa?
Pinocho
44
Analiza los argumentos de la línea de comandos suministrados al programa utilizando el paquete flags. (que utiliza la biblioteca estándar 'argparse' debajo de las cubiertas, con algunos contenedores). Está vinculado desde el código al que lo hice en mi respuesta.
dga
1
En app.py, ¿qué significa main = main or sys.modules['__main__'].mainy qué sys.exit(main(sys.argv[:1] + flags_passthrough))significa?
HAcKnRoCk
3
esto me parece extraño, ¿por qué envolver la función principal en todo eso si puedes llamarlo directamente main()?
Charlie Parker el
2
hAcKnRoCk: si no hay main en el archivo, en su lugar usa lo que esté en sys.modules [' main '] .main. El sys.exit significa ejecutar el comando principal que se encuentra usando los args y cualquier indicador que haya pasado, y salir con el valor de retorno de main. @CharlieParker: para compatibilidad con las bibliotecas de aplicaciones Python existentes de Google, como gflags y google-apputils. Ver, por ejemplo, github.com/google/google-apputils
dga
8

No hay nada especial en tf.app. Esto es solo un script de punto de entrada genérico , que

Ejecuta el programa con una función opcional 'main' y una lista 'argv'.

No tiene nada que ver con las redes neuronales y solo llama a la función principal, pasando por cualquier argumento.

Salvador Dalí
fuente
5

En términos simples, el trabajo de tf.app.run()es establecer primero las banderas globales para su uso posterior como:

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

y luego ejecuta tu función principal personalizada con un conjunto de argumentos.

Por ejemplo, en la base de código NMT de TensorFlow , el primer punto de entrada para la ejecución del programa de capacitación / inferencia comienza en este punto (ver el código a continuación)

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)

Después de analizar los argumentos usando argparse, tf.app.run()ejecuta la función "main" que se define 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)

Entonces, después de configurar las banderas para uso global, tf.app.run()simplemente ejecuta esa mainfunción que le pasa argvcomo parámetros.

PD: Supongo que, como dice la respuesta de Salvador Dalí , es solo una buena práctica de ingeniería de software, aunque no estoy seguro de si TensorFlow realiza alguna ejecución optimizada de la mainfunción de la que se realizó utilizando CPython normal.

kmario23
fuente
2

El código de Google depende en gran medida de que las banderas globales estén accediendo en bibliotecas / binarios / scripts de python, por lo que tf.app.run () analiza esas banderas para crear un estado global en la variable FLAGs (o algo similar) y luego llama a python main ( ) como debería.

Si no tenían esta llamada a tf.app.run (), los usuarios podrían olvidarse de analizar los FLAG, lo que llevaría a que estas bibliotecas / binarios / scripts no tuvieran acceso a los FLAG que necesitan.

Mudit Jain
fuente
1

2.0 Respuesta Compatible : Si desea utilizar tf.app.run()en Tensorflow 2.0, debemos utilizar el comando,

tf.compat.v1.app.run()o puede usar tf_upgrade_v2para convertir 1.xcódigo a 2.0.

Soporte Tensorflow
fuente