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

¿Cómo funciona tf.app.run() en Tensorflow traduce la demo?

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

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

 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 garantiza que el argumento que pase a través de la línea de comando sea válido, por ejemplo, python my_model.py --data_dir='...' --max_iteration=10000 En realidad, esta función se implementa en base al módulo argparse estándar de python.

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

El primer main en 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 en ejecución actual (por ejemplo, my_model.py ).

Así que hay dos casos:

  1. No tienes una función main en my_model.py Luego tienes que llamar a tf.app.run(my_main_running_function)

  2. tienes una función main en my_model.py . (Esto es principalmente el caso.)

Última línea:

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

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

Es solo un envoltorio muy rápido que maneja el análisis de la bandera y luego se envía a su propio main. Ver el codigo

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

Ejecuta el progtwig con una función ‘principal’ y una lista ‘argv’ opcionales.

No tiene nada que ver con las redes neuronales y simplemente llama a la función principal, y le pasa cualquier argumento.

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

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

y luego ejecute su función principal personalizada con un conjunto de argumentos.

Por ejemplo, en la base de código TensorFlow NMT , el primer punto de entrada para la ejecución del progtwig para entrenamiento / inferencia comienza en este punto (consulte 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 , con 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 los indicadores para uso global, tf.app.run() simplemente ejecuta esa función main que le pasas con argv como sus parámetros.

PD: Como dice la respuesta de Salvador Dalí , es solo una buena práctica de ingeniería de software, supongo, aunque no estoy seguro de si TensorFlow realiza una ejecución optimizada de la función main que la que se ejecutó usando el CPython normal.

El código de Google depende mucho de los indicadores globales que se acceden en las bibliotecas / archivos binarios / scripts de python, por lo que tf.app.run () analiza esos indicadores para crear un estado global en FLAG (o algo similar) variable y luego llama python main ( ) como debería.

Si no tenían esta llamada a tf.app.run (), entonces los usuarios podrían olvidarse de hacer un análisis de FLAG, lo que lleva a que estas bibliotecas / binarios / scripts no tengan acceso a los FLAG que necesitan.