【问题标题】:How can I list all Tensorflow variables a node depends on?如何列出节点依赖的所有 Tensorflow 变量?
【发布时间】:2017-07-04 13:33:04
【问题描述】:

如何列出节点依赖的所有 Tensorflow 变量/常量/占位符?

示例 1(常量的添加):

import tensorflow as tf

a = tf.constant(1, name = 'a')
b = tf.constant(3, name = 'b')
c = tf.constant(9, name = 'c')
d = tf.add(a, b, name='d')
e = tf.add(d, c, name='e')

sess = tf.Session()
print(sess.run([d, e]))

我想要一个函数list_dependencies() 比如:

  • list_dependencies(d) 返回['a', 'b']
  • list_dependencies(e) 返回['a', 'b', 'c']

示例 2(占位符和权重矩阵之间的矩阵相乘,然后加上偏置向量):

tf.set_random_seed(1)
input_size  = 5
output_size = 3
input       = tf.placeholder(tf.float32, shape=[1, input_size], name='input')
W           = tf.get_variable(
                "W",
                shape=[input_size, output_size],
                initializer=tf.contrib.layers.xavier_initializer())
b           = tf.get_variable(
                "b",
                shape=[output_size],
                initializer=tf.constant_initializer(2))
output      = tf.matmul(input, W, name="output")
output_bias = tf.nn.xw_plus_b(input, W, b, name="output_bias")

sess = tf.Session()
sess.run(tf.global_variables_initializer())
print(sess.run([output,output_bias], feed_dict={input: [[2]*input_size]}))

我想要一个函数list_dependencies() 比如:

  • list_dependencies(output) 返回['W', 'input']
  • list_dependencies(output_bias) 返回['W', 'b', 'input']

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    这是我为此使用的实用程序(来自https://github.com/yaroslavvb/stuff/blob/master/linearize/linearize.py

    # computation flows from parents to children
    
    def parents(op):
      return set(input.op for input in op.inputs)
    
    def children(op):
      return set(op for out in op.outputs for op in out.consumers())
    
    def get_graph():
      """Creates dictionary {node: {child1, child2, ..},..} for current
      TensorFlow graph. Result is compatible with networkx/toposort"""
    
      ops = tf.get_default_graph().get_operations()
      return {op: children(op) for op in ops}
    
    
    def print_tf_graph(graph):
      """Prints tensorflow graph in dictionary form."""
      for node in graph:
        for child in graph[node]:
          print("%s -> %s" % (node.name, child.name))
    

    这些函数适用于操作。要获得产生张量 t 的操作,请使用 t.op。要获取 op op 生成的张量,请使用 op.outputs

    【讨论】:

    • graph_util 或通过 contrib 贡献它可能是个好主意。
    • 这个解决方案似乎会返回图中的所有子操作,而不仅仅是特定节点的操作。
    • 为什么 tensorflow 一定是个坏人......就像 windows 一样,它浪费了大量的人力时间
    【解决方案2】:

    Yaroslav Bulatov's answer 很好,我将添加一个使用 Yaroslav 的 get_graph()children() 方法的绘图函数:

    import matplotlib.pyplot as plt
    import networkx as nx
    def plot_graph(G):
        '''Plot a DAG using NetworkX'''        
        def mapping(node):
            return node.name
        G = nx.DiGraph(G)
        nx.relabel_nodes(G, mapping, copy=False)
        nx.draw(G, cmap = plt.get_cmap('jet'), with_labels = True)
        plt.show()
    
    plot_graph(get_graph())
    

    从问题中绘制示例 1:

    import matplotlib.pyplot as plt
    import networkx as nx
    import tensorflow as tf
    
    def children(op):
      return set(op for out in op.outputs for op in out.consumers())
    
    def get_graph():
      """Creates dictionary {node: {child1, child2, ..},..} for current
      TensorFlow graph. Result is compatible with networkx/toposort"""
      print('get_graph')
      ops = tf.get_default_graph().get_operations()
      return {op: children(op) for op in ops}
    
    def plot_graph(G):
        '''Plot a DAG using NetworkX'''        
        def mapping(node):
            return node.name
        G = nx.DiGraph(G)
        nx.relabel_nodes(G, mapping, copy=False)
        nx.draw(G, cmap = plt.get_cmap('jet'), with_labels = True)
        plt.show()
    
    a = tf.constant(1, name = 'a')
    b = tf.constant(3, name = 'b')
    c = tf.constant(9, name = 'c')
    d = tf.add(a, b, name='d')
    e = tf.add(d, c, name='e')
    
    sess = tf.Session()
    print(sess.run([d, e]))
    plot_graph(get_graph())
    

    输出:

    从问题中绘制示例 2:

    如果您使用 Microsoft Windows,您可能会遇到此问题:Python Error (ValueError: _getfullpathname: embedded null character),在这种情况下,您需要按照链接说明修补 matplotlib。

    【讨论】:

    【解决方案3】:

    在某些情况下,您可能希望找到与“输出”张量相关的所有“输入”变量,例如图的损失。为此,以下代码片段可能有用(受上述代码启发):

    def findVars(atensor):
        allinputs=atensor.op.inputs
        if len(allinputs)==0:
            if atensor.op.type == 'VariableV2' or atensor.op.type == 'Variable':
                return set([atensor.op])
        a=set()
        for t in allinputs:
            a=a | findVars(t)
        return a
    

    这可用于调试以找出图中缺少连接的位置。

    【讨论】:

      【解决方案4】:

      这些都是很好的答案,我将添加一个简单的方法,以一种不太容易阅读的格式生成依赖项,但对于快速调试很有用。

      tf.get_default_graph().as_graph_def()
      

      将图形中的操作生成为如下所示的简单字典的打印。每个 OP 都可以通过名称及其属性和输入轻松发现,从而允许您遵循依赖关系。

      import tensorflow as tf
      
      a = tf.placeholder(tf.float32, name='placeholder_1')
      b = tf.placeholder(tf.float32, name='placeholder_2')
      c = a + b
      
      tf.get_default_graph().as_graph_def()
      
      Out[14]: 
      node {
        name: "placeholder_1"
        op: "Placeholder"
        attr {
          key: "dtype"
          value {
            type: DT_FLOAT
          }
        }
        attr {
          key: "shape"
          value {
            shape {
              unknown_rank: true
            }
          }
        }
      }
      node {
        name: "placeholder_2"
        op: "Placeholder"
        attr {
          key: "dtype"
          value {
            type: DT_FLOAT
          }
        }
        attr {
          key: "shape"
          value {
            shape {
              unknown_rank: true
            }
          }
        }
      }
      node {
        name: "add"
        op: "Add"
        input: "placeholder_1"
        input: "placeholder_2"
        attr {
          key: "T"
          value {
            type: DT_FLOAT
          }
        }
      }
      versions {
        producer: 27
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        相关资源
        最近更新 更多