No Tensorflow, obtenha os nomes de todos os Tensores em um gráfico

118

Estou criando redes neurais com Tensorflowe skflow; por alguma razão, quero obter os valores de alguns tensores internos para uma determinada entrada, então estou usando myClassifier.get_layer_value(input, "tensorName"), myClassifiersendo a skflow.estimators.TensorFlowEstimator.

Porém, acho difícil encontrar a sintaxe correta do nome do tensor, mesmo sabendo seu nome (e estou ficando confuso entre operação e tensores), então estou usando o tensorboard para plotar o gráfico e procurar o nome.

Existe uma maneira de enumerar todos os tensores em um gráfico sem usar tensorboard?

P. Camilleri
fonte

Respostas:

189

Você pode fazer

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

Além disso, se você estiver prototipando em um notebook IPython, poderá mostrar o gráfico diretamente no notebook, consulte a show_graphfunção no bloco de notas Deep Dream de Alexander

Yaroslav Bulatov
fonte
2
Você pode filtrar isso por exemplo, variáveis ​​adicionando if "Variable" in n.opno final da compreensão.
Radu de
Existe uma maneira de obter um nó específico se você souber o nome?
Rocket Pingu
Para ler mais sobre nós de gráfico: tensorflow.org/extend/tool_developers/#nodes
Ivan Talalaev
3
O comando acima fornece os nomes de todas as operações / nós. Para obter os nomes de todos os tensores, faça: tensors_per_node = [node.values ​​() para o nó em graph.get_operations ()] tensor_names = [tensor.name para tensores em tensors_per_node para tensores em tensores]
gebbissimo
25

Existe uma maneira de fazer isso um pouco mais rápido do que na resposta de Yaroslav usando get_operations . Aqui está um exemplo 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í
fonte
1
Você não pode obter tensores usando tf.get_operations(). A única operação que você pode obter.
Soulduck de
14

Vou tentar resumir as respostas:

Para obter todos os nós (tipo tensorflow.core.framework.node_def_pb2.NodeDef):

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

Para obter todas as operações (tipo tensorflow.python.framework.ops.Operation):

all_ops = tf.get_default_graph().get_operations()

Para obter todas as variáveis (tipo tensorflow.python.ops.resource_variable_ops.ResourceVariable):

all_vars = tf.global_variables()

Para obter todos os 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
fonte
11

tf.all_variables() pode obter as informações que você deseja.

Além disso, este commit feito hoje no TensorFlow Learn que fornece uma função get_variable_namesno estimador que você pode usar para recuperar todos os nomes de variáveis ​​facilmente.

Yuan Tang
fonte
Esta função está obsoleta
CAFEBABE
8
... e seu sucessor étf.global_variables()
bluenote10
11
isso busca apenas variáveis, não tensores.
Rajarshee Mitra
No Tensorflow 1.9.0 mostra issoall_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02
stackoverYC
5

Acho que isso também servirá:

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

Mas, em comparação com as respostas de Salvado e Yaroslav, não sei qual é a melhor.

Lu Howyou
fonte
Este trabalhou com um gráfico importado de um arquivo frozen_inference_graph.pb usado na API de detecção de objeto tensorflow. Obrigado
simo23
4

A resposta aceita apenas fornece uma lista de strings com os nomes. Eu prefiro uma abordagem diferente, que dá a você acesso (quase) direto aos tensores:

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

list_of_tuplesagora contém todos os tensores, cada um dentro de uma tupla. Você também pode adaptá-lo para obter os tensores diretamente:

graph = tf.get_default_graph()
list_of_tuples = [op.values()[0] for op in graph.get_operations()]
Picard
fonte
Esta é a maneira de buscar os tensores de saída reais dos ops, não apenas os ops.
Szabolcs
4

Uma vez que o OP pediu a lista dos tensores em vez da lista de operações / nós, o código deve ser um pouco 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
fonte
3

As respostas anteriores são boas, gostaria apenas de compartilhar uma função de utilidade que escrevi para selecionar tensores de um 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)
        ]

Então, se você tiver um gráfico com 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']

Então correndo

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

retorna:

['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
fonte
0

Isso funcionou para mim:

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