web-dev-qa-db-fra.com

Dans Tensorflow, obtenez les noms de tous les tenseurs dans un graphique

Je crée des réseaux neuronaux avec Tensorflow et skflow; Pour une raison quelconque, je souhaite obtenir les valeurs de certains tenseurs internes pour une entrée donnée. J'utilise donc myClassifier.get_layer_value(input, "tensorName"), myClassifier étant un skflow.estimators.TensorFlowEstimator

Cependant, il m'est difficile de trouver la syntaxe correcte du nom du tenseur, même si je connais son nom (et je suis confus entre opération et tenseurs), j'utilise donc tenseur pour tracer le graphique et rechercher le nom.

Existe-t-il un moyen de dénombrer tous les tenseurs dans un graphique sans utiliser tensorboard?

72
P. Camilleri

Tu peux faire

[n.name for n in tf.get_default_graph().as_graph_def().node]

De même, si vous prototypez dans un bloc-notes IPython, vous pouvez afficher le graphique directement dans le bloc-notes, voir Fonction show_graph dans Deep Dream d'Alexander bloc-notes

137
Yaroslav Bulatov

Il existe un moyen de le faire légèrement plus rapidement que dans la réponse de Yaroslav en utilisant get_operations . Voici un exemple rapide:

import tensorflow as tf

a = tf.constant(1.3, name='const_a')
b = tf.Variable(3.1, name='variable_b')
c = tf.add(a, b, name='addition')
d = tf.multiply(c, a, name='multiply')

for op in tf.get_default_graph().get_operations():
    print(str(op.name))
19
Salvador Dali

tf.all_variables() peut vous obtenir les informations que vous souhaitez.

En outre, this commit est effectué aujourd'hui dans TensorFlow Learn, qui fournit une fonction get_variable_names dans l’estimateur que vous pouvez utiliser pour extraire facilement tous les noms de variables. 

9
Yuan Tang

La réponse acceptée ne vous donne qu'une liste de chaînes avec les noms. Je préfère une approche différente, qui vous donne un accès (presque) direct aux tenseurs:

graph = tf.get_default_graph()
list_of_tuples = [op.values() for op in graph.get_operations()]

list_of_tuples contient maintenant chaque tenseur, chacun dans un tuple. Vous pouvez également l'adapter pour obtenir directement les tenseurs:

graph = tf.get_default_graph()
list_of_tuples = [op.values()[0] for op in graph.get_operations()]
5
Pepe

Je pense que cela ira aussi:

print(tf.contrib.graph_editor.get_tensors(tf.get_default_graph()))

Mais comparé aux réponses de Salvado et de Yaroslav, je ne sais pas laquelle est la meilleure.

3
Lu Howyou

Les réponses précédentes sont bonnes, j'aimerais juste partager une fonction utilitaire que j'ai écrite pour sélectionner les tenseurs à partir d'un graphique:

def get_graph_op(graph, and_conds=None, op='and', or_conds=None):
    """Selects nodes' names in the graph if:
    - The name contains all items in and_conds
    - OR/AND depending on op
    - The name contains any item in or_conds

    Condition starting with a "!" are negated.
    Returns all ops if no optional arguments is given.

    Args:
        graph (tf.Graph): The graph containing sought tensors
        and_conds (list(str)), optional): Defaults to None.
            "and" conditions
        op (str, optional): Defaults to 'and'. 
            How to link the and_conds and or_conds:
            with an 'and' or an 'or'
        or_conds (list(str), optional): Defaults to None.
            "or conditions"

    Returns:
        list(str): list of relevant tensor names
    """
    assert op in {'and', 'or'}

    if and_conds is None:
        and_conds = ['']
    if or_conds is None:
        or_conds = ['']

    node_names = [n.name for n in graph.as_graph_def().node]

    ands = {
        n for n in node_names
        if all(
            cond in n if '!' not in cond
            else cond[1:] not in n
            for cond in and_conds
        )}

    ors = {
        n for n in node_names
        if any(
            cond in n if '!' not in cond
            else cond[1:] not in n
            for cond in or_conds
        )}

    if op == 'and':
        return [
            n for n in node_names
            if n in ands.intersection(ors)
        ]
    Elif op == 'or':
        return [
            n for n in node_names
            if n in ands.union(ors)
        ]

Donc, si vous avez un graphique avec ops:

['model/classifier/dense/kernel',
'model/classifier/dense/kernel/Assign',
'model/classifier/dense/kernel/read',
'model/classifier/dense/bias',
'model/classifier/dense/bias/Assign',
'model/classifier/dense/bias/read',
'model/classifier/dense/MatMul',
'model/classifier/dense/BiasAdd',
'model/classifier/ArgMax/dimension',
'model/classifier/ArgMax']

Puis courir 

get_graph_op(tf.get_default_graph(), ['dense', '!kernel'], 'or', ['Assign'])

résultats:

['model/classifier/dense/kernel/Assign',
'model/classifier/dense/bias',
'model/classifier/dense/bias/Assign',
'model/classifier/dense/bias/read',
'model/classifier/dense/MatMul',
'model/classifier/dense/BiasAdd']
3
ted

Je vais essayer de résumer les réponses:

Pour obtenir tous les nœuds:

all_nodes = [n for n in tf.get_default_graph().as_graph_def().node]

Ceux-ci ont le type tensorflow.core.framework.node_def_pb2.NodeDef

Pour obtenir tous les ops:

all_ops = tf.get_default_graph().get_operations()

Ceux-ci ont le type tensorflow.python.framework.ops.Operation

Pour obtenir toutes les variables:

all_vars = tf.global_variables()

Ceux-ci ont le type tensorflow.python.ops.resource_variable_ops.ResourceVariable

Et enfin, pour répondre à la question, obtenir tous les tenseurs:

all_tensors = [tensor for op in tf.get_default_graph().get_operations() for tensor in op.values()]

Ceux-ci ont le type tensorflow.python.framework.ops.Tensor

1
Szabolcs

Comme le PO a demandé la liste des tenseurs au lieu de la liste des opérations/nœuds, le code devrait être légèrement différent:

graph = tf.get_default_graph()    
tensors_per_node = [node.values() for node in graph.get_operations()]
tensor_names = [tensor.name for tensors in tensors_per_node for tensor in tensors]
0
gebbissimo

Cela a fonctionné pour moi:

for n in tf.get_default_graph().as_graph_def().node:
    print('\n',n)
0
Akshaya Natarajan