35 votes

Comment fonctionnent les séances d'entraînement surveillées ?

J'essaie de comprendre la différence entre le fait d'utiliser tf.Session et tf.train.MonitoredTrainingSession et où je pourrais préférer l'un plutôt que l'autre. Il semble que lorsque j'utilise ce dernier, je peux éviter de nombreuses "corvées" telles que l'initialisation des variables, le démarrage des files d'attente ou la configuration des auteurs de fichiers pour les opérations sommaires. D'autre part, avec une session de formation surveillée, je ne peux pas spécifier explicitement le graphe de calcul que je veux utiliser. Tout cela me semble plutôt mystérieux. Y a-t-il une philosophie sous-jacente à la création de ces classes que je ne comprends pas ?

0 votes

Je pense que la réponse de Nicolas devrait vous couvrir à peu près, non ?

36voto

pfm Points 3526

Je ne peux pas donner d'indications sur la façon dont ces classes ont été créées, mais voici quelques éléments qui me semblent pertinents sur la façon dont vous pourriez les utiliser.

El tf.Session est un objet de bas niveau dans l'API TensorFlow python alors que, comme vous l'avez dit, l tf.train.MonitoredTrainingSession est doté d'un grand nombre de fonctionnalités pratiques, particulièrement utiles dans la plupart des cas courants.

Avant de décrire certains des avantages de tf.train.MonitoredTrainingSession Laissez-moi répondre à la question sur le graphique utilisé par la session. Vous pouvez spécifier le tf.Graph utilisé par le MonitoredTrainingSession en utilisant un gestionnaire de contexte with your_graph.as_default() :

from __future__ import print_function
import tensorflow as tf

def example():
    g1 = tf.Graph()
    with g1.as_default():
        # Define operations and tensors in `g`.
        c1 = tf.constant(42)
        assert c1.graph is g1

    g2 = tf.Graph()
    with g2.as_default():
        # Define operations and tensors in `g`.
        c2 = tf.constant(3.14)
        assert c2.graph is g2

    # MonitoredTrainingSession example
    with g1.as_default():
        with tf.train.MonitoredTrainingSession() as sess:
            print(c1.eval(session=sess))
            # Next line raises
            # ValueError: Cannot use the given session to evaluate tensor:
            # the tensor's graph is different from the session's graph.
            try:
                print(c2.eval(session=sess))
            except ValueError as e:
                print(e)

    # Session example
    with tf.Session(graph=g2) as sess:
        print(c2.eval(session=sess))
        # Next line raises
        # ValueError: Cannot use the given session to evaluate tensor:
        # the tensor's graph is different from the session's graph.
        try:
            print(c1.eval(session=sess))
        except ValueError as e:
            print(e)

if __name__ == '__main__':
    example()

Donc, comme vous l'avez dit, les avantages d'utiliser MonitoredTrainingSession cet objet s'occupe de

  • initialisation des variables,
  • le coureur de la file d'attente de départ ainsi que
  • la mise en place des écrivains de fichiers,

mais il a aussi l'avantage de rendre votre code facile à distribuer car il fonctionne aussi différemment selon que vous avez spécifié le processus en cours d'exécution comme maître ou non.

Par exemple, vous pourriez exécuter quelque chose comme :

def run_my_model(train_op, session_args):
    with tf.train.MonitoredTrainingSession(**session_args) as sess:
        sess.run(train_op)

que vous appelleriez d'une manière non distribuée :

run_my_model(train_op, {})`

ou de manière distribuée (voir le document distribué pour plus d'informations sur les entrées) :

run_my_model(train_op, {"master": server.target,
                        "is_chief": (FLAGS.task_index == 0)})

D'un autre côté, l'avantage d'utiliser les données brutes de la tf.Session est que, vous n'avez pas les avantages supplémentaires de tf.train.MonitoredTrainingSession ce qui peut être utile si vous ne prévoyez pas de les utiliser ou si vous voulez avoir plus de contrôle (par exemple sur la façon dont les files d'attente sont lancées).

EDIT (selon le commentaire) : Pour l'initialisation de l'opération, il faudrait faire quelque chose comme (cf. document officiel :

# Define your graph and your ops
init_op = tf.global_variables_initializer()
with tf.Session() as sess:
    sess.run(init_p)
    sess.run(your_graph_ops,...)

Pour le QueueRunner, je vous renvoie au document document officiel où vous trouverez des exemples plus complets.

EDIT2 :

Le principal concept à comprendre pour se faire une idée de la manière dont les tf.train.MonitoredTrainingSession œuvre est le _WrappedSession classe :

Ce wrapper est utilisé comme classe de base pour divers wrappers de session qui fournissent des fonctionnalités supplémentaires telles que la surveillance, la coordination.., et la récupération.

El tf.train.MonitoredTrainingSession œuvres (à partir de version 1.1 ) de cette façon :

  • Il vérifie d'abord s'il s'agit d'un chef ou d'un ouvrier (cf. document distribué pour la question lexicale).

  • Il commence les crochets qui ont été fournis (par exemple, StopAtStepHook ne ferait que récupérer le global_step à ce stade.

  • Il crée une session qui est un Chief (ou Worker ) enveloppée dans une _HookedSession enveloppé dans un _CoordinatedSession enveloppé dans un _RecoverableSession .
    Le site Chief / Worker sont chargées de l'exécution des opérations d'initialisation fournies par le système de gestion de l'information. Scaffold .

      scaffold: A `Scaffold` used for gathering or building supportive ops. If
    not specified a default one is created. It's used to finalize the graph.
  • El chief s'occupe également de toutes les parties relatives aux points de contrôle : par exemple, la restauration à partir de points de contrôle à l'aide de la fonction Saver de la Scaffold .

  • El _HookedSession est essentiellement là pour décorer le run : elle appelle la méthode _call_hook_before_run et after_run le cas échéant.

  • Lors de la création, le _CoordinatedSession construit un Coordinator qui démarre les files d'attente et sera responsable de leur fermeture.

  • El _RecoverableSession permettra de s'assurer qu'il y a une nouvelle tentative en cas de tf.errors.AbortedError .

En conclusion, le tf.train.MonitoredTrainingSession évite une grande quantité de code passe-partout tout en étant facilement extensible grâce au mécanisme des crochets.

0 votes

Merci - pourriez-vous donner un peu de (pseudo ?) code sur la façon dont nous pourrions remplacer le code de MonitoredTrainingSession en utilisant une simple Session ? C'est assez compliqué - par exemple, apparemment une MTS finalisera le graphique (par défaut) : github.com/tensorflow/tensorflow/blob/

0 votes

Merci - tf.initialize_all_variables() est déprécié, ils sont dépréciés très rapidement. Ce qui m'intéresse, ce sont les "actions sous le capot" - il faut parcourir le code comme dans github.com/tensorflow/tensorflow/blob/ - ici le graphique (quel graphique...) est finalisé par exemple. MTS fait donc beaucoup de choses - et comme nous l'avons discuté dans ma question précédente, cela peut conduire à de mauvaises surprises. Il serait intéressant d'avoir un récapitulatif de la série d'opérations effectuées - je ne peux pas upvote plus cependant.

0 votes

J'ai ajouté quelques descriptions sur la façon dont le MTS fonctionne en interne, j'espère que cela sera utile. (J'ai aussi modifié l'initialisateur pour tf.global_variables_initializer() . Merci de l'avoir repéré).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X