En Tensorflow, obtenga los nombres de todos los tensores en un gráfico

118

Estoy creando redes neuronales con Tensorflowy skflow; por alguna razón, quiero obtener los valores de algunos tensores internos para una entrada determinada, por lo que estoy usando myClassifier.get_layer_value(input, "tensorName"), myClassifiersiendo a skflow.estimators.TensorFlowEstimator.

Sin embargo, me resulta difícil encontrar la sintaxis correcta del nombre del tensor, incluso sabiendo su nombre (y me estoy confundiendo entre operación y tensores), así que estoy usando tensorboard para trazar el gráfico y buscar el nombre.

¿Hay alguna forma de enumerar todos los tensores en un gráfico sin usar tensorboard?

P. Camilleri
fuente

Respuestas:

189

Tu puedes hacer

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

Además, si está creando un prototipo en un cuaderno IPython, puede mostrar el gráfico directamente en el cuaderno, consulte la show_graphfunción en el cuaderno Deep Dream de Alexander.

Yaroslav Bulatov
fuente
2
Puede filtrar esto para, por ejemplo, variables añadiendo if "Variable" in n.opal final de la comprensión.
Radu
¿Hay alguna forma de obtener un nodo específico si conoce el nombre?
Rocket Pingu
Para leer más sobre los nodos de gráficos: tensorflow.org/extend/tool_developers/#nodes
Ivan Talalaev
3
El comando anterior produce los nombres de todas las operaciones / nodos. Para obtener los nombres de todos los tensores, haga lo siguiente: 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
25

Hay una manera de hacerlo un poco más rápido que en la respuesta de Yaroslav usando get_operations . Aquí hay un ejemplo rápido:

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))
Salvador Dalí
fuente
1
No puede usar Tensores tf.get_operations(). Única operación que puedes conseguir.
Soulduck
14

Intentaré resumir las respuestas:

Para obtener todos los nodos (tipo tensorflow.core.framework.node_def_pb2.NodeDef):

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

Para obtener todas las operaciones (tipo tensorflow.python.framework.ops.Operation):

all_ops = tf.get_default_graph().get_operations()

Para obtener todas las variables (tipo tensorflow.python.ops.resource_variable_ops.ResourceVariable):

all_vars = tf.global_variables()

Para obtener todos los tensores (tipo tensorflow.python.framework.ops.Tensor) :

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

tf.all_variables() puede conseguirle la información que desee.

Además, esta confirmación realizada hoy en TensorFlow Learn que proporciona una función get_variable_namesen el estimador que puede usar para recuperar todos los nombres de variables fácilmente.

Yuan Tang
fuente
Esta función está obsoleta
CAFEBABE
8
... y su sucesor estf.global_variables()
bluenote10
11
esto solo obtiene variables, no tensores.
Rajarshee Mitra
En Tensorflow 1.9.0 muestra esoall_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02
StackoverYC
5

Creo que esto también servirá:

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

Pero comparado con las respuestas de Salvado y Yaroslav, no sé cuál es mejor.

Lu Howyou
fuente
Este funcionó con un gráfico importado de un archivo frozen_inference_graph.pb utilizado en la API de detección de objetos de tensorflow. Gracias
simo23
4

La respuesta aceptada solo le brinda una lista de cadenas con los nombres. Prefiero un enfoque diferente, que le da (casi) acceso directo a los tensores:

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

list_of_tuplesahora contiene cada tensor, cada uno dentro de una tupla. También puedes adaptarlo para obtener los tensores directamente:

graph = tf.get_default_graph()
list_of_tuples = [op.values()[0] for op in graph.get_operations()]
Picard
fuente
Esta es la forma de obtener los tensores de salida reales de las operaciones, no solo las operaciones.
Szabolcs
4

Dado que el OP solicitó la lista de tensores en lugar de la lista de operaciones / nodos, el código debería ser ligeramente diferente:

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]
gebbissimo
fuente
3

Las respuestas anteriores son buenas, solo me gustaría compartir una función de utilidad que escribí para seleccionar Tensores de un gráfico:

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)
        ]

Entonces, si tiene un gráfico con operaciones:

['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']

Entonces corriendo

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

devoluciones:

['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']
ted
fuente
0

Esto funcionó para mí:

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