Comment tf.app.run()
fonctionne-t-il dans la démo de traduction de Tensorflow?
Dans tensorflow/models/rnn/translate/translate.py
, il existe un appel à tf.app.run()
. Comment est-il géré?
if __== "__main__":
tf.app.run()
if __== "__main__":
signifie que le fichier en cours est exécuté sous un shell au lieu d'être importé en tant que module.
tf.app.run()
Comme vous pouvez le voir à travers le fichier 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))
Brisons ligne par ligne:
flags_passthrough = f._parse_flags(args=args)
Cela garantit que l'argument que vous transmettez via la ligne de commande est valide, par exemple. python my_model.py --data_dir='...' --max_iteration=10000
En fait, cette fonctionnalité est implémentée sur la base du module python standard argparse
.
main = main or sys.modules['__main__'].main
Le premier main
dans le côté droit de =
est le premier argument de la fonction actuelle run(main=None, argv=None)
. Alors que sys.modules['__main__']
signifie le fichier en cours d’exécution (par exemple my_model.py
).
Donc, il y a deux cas:
Vous n'avez pas de fonction main
dans my_model.py
Ensuite, vous devez appeler tf.app.run(my_main_running_function)
vous avez une fonction main
dans my_model.py
. (C'est principalement le cas.)
Dernière ligne:
sys.exit(main(sys.argv[:1] + flags_passthrough))
assure que votre fonction main(argv)
ou my_main_running_function(argv)
est appelée correctement avec les arguments analysés.
C'est juste un très rapide wrapper qui gère l'analyse des indicateurs, puis les envoie à votre propre tâche principale. Voir le code .
Il n'y a rien de spécial dans tf.app
. Ceci est juste un script de point d'entrée générique , qui
Exécute le programme avec une fonction optionnelle 'main' et une liste 'argv'.
Cela n'a rien à voir avec les réseaux de neurones et appelle simplement la fonction principale, en lui transmettant tous les arguments.
En termes simples, le travail de tf.app.run()
consiste à premier définir les indicateurs globaux pour une utilisation ultérieure, comme:
from tensorflow.python.platform import flags
f = flags.FLAGS
puis exécutez votre fonction custom main avec un ensemble d'arguments.
Par exemple in TensorFlow NMT codebase, le tout premier point d'entrée pour l'exécution du programme d'apprentissage/d'inférence commence à ce point (voir le code ci-dessous)
if __== "__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)
Après avoir analysé les arguments avec argparse
, avec tf.app.run()
, vous exécutez la fonction "main" qui est définie comme suit:
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)
Ainsi, après avoir défini les indicateurs pour une utilisation globale, tf.app.run()
exécute simplement la fonction main
que vous lui transmettez avec argv
comme ses paramètres.
PS: Comme réponse de Salvador Dali , il s'agit simplement d'une bonne pratique d'ingénierie logicielle, même si je ne suis pas sûr que TensorFlow exécute une exécution optimisée de la fonction main
par rapport à celle qui a été exécutée. en utilisant CPython normal.
Le code de Google dépend en grande partie du nombre d'indicateurs globaux accessibles dans les bibliothèques/binaires/scripts python. Tf.app.run () analyse donc ces indicateurs pour créer un état global dans une variable FLAG (ou quelque chose de similaire), puis appelle python main () comme il se doit.
S'ils n'avaient pas cet appel à tf.app.run (), alors les utilisateurs pourraient oublier d'analyser les FLAG, ce qui empêcherait ces bibliothèques/binaires/scripts d'accéder aux FLAG dont ils ont besoin.