如何在TensorFlow中访问protos中的值?

如何在TensorFlow中访问protos中的值?,tensorflow,Tensorflow,我从中看出,我们可以做到这一点: 对于tf.get_default_graph().as_graph_def()中的节点。节点: 打印节点 在任意网络上执行时,我们会得到许多键值对。例如: name: "conv2d_2/convolution" op: "Conv2D" input: "max_pooling2d/MaxPool" input: "conv2d_1/kernel/read" device: "/device:GPU:0" attr { key: "T" value

我从中看出,我们可以做到这一点:


对于tf.get_default_graph().as_graph_def()中的节点。节点:
打印节点

在任意网络上执行时,我们会得到许多键值对。例如:

name: "conv2d_2/convolution"
op: "Conv2D"
input: "max_pooling2d/MaxPool"
input: "conv2d_1/kernel/read"
device: "/device:GPU:0"
attr {
  key: "T"
  value {
    type: DT_FLOAT
  }
}
attr {
  key: "data_format"
  value {
    s: "NHWC"
  }
}
attr {
  key: "padding"
  value {
    s: "SAME"
  }
}
attr {
  key: "strides"
  value {
    list {
      i: 1
      i: 1
      i: 1
      i: 1
    }
  }
}
attr {
  key: "use_cudnn_on_gpu"
  value {
    b: true
  }
}

如何访问所有这些值并将它们放入Python列表中?具体来说,我们如何获得“步幅”属性并将其中的所有1转换为[1,1,1,1]?

TLDR:下面的代码是您可能想要使用的:

for n in tf.get_default_graph().as_graph_def().node:
    if 'strides' in n.attr.keys():
        print n.name, [int(a) for a in n.attr['strides'].list.i]
    if 'shape' in n.attr.keys():
        print n.name, [int(a.size) for a in n.attr['shape'].shape.dim]
做这件事的诀窍是要了解你在做什么。让我们看一下上面提到的

首先,有一个声明:

每个节点都是在中定义的NodeDef对象 tensorflow/core/framework/node_def.proto。这些是最基本的 TensorFlow图的构建块,每个块定义一个 操作及其输入连接。这是一个组织的成员 诺迪夫,还有他们的意思

请注意节点_def.proto中的以下内容:

  • 它导入attr_value.proto
  • 有名称、操作、输入、设备、属性等属性。具体来说,在输入前面有一个重复的项。我们现在可以忽略这一点
这与Python类的工作方式完全相同,因此我们可以调用node.name、node.op、node.input、node.device、node.attr等

我们现在想要访问的是node.attr中的内容。如果我们再次参考教程,它将指定:

这是保存节点所有属性的键/值存储。这些 是节点的永久属性,是在任何时候都不会改变的东西 运行时,例如卷积过滤器的大小,或 经常行动。因为可以有很多不同类型的 属性值,从字符串到整数,再到张量值数组, 有一个单独的protobuf文件定义了 在tensorflow/core/framework/attr_value.proto中保存它们

每个属性都有一个唯一的名称字符串和预期的属性 在定义操作时列出。如果属性不是 存在于节点中,但在操作中列出了默认值 定义,该默认值在创建图形时使用

通过调用node.name、node.op、, 等等,在Python中。GraphDef中存储的节点列表已满 模型架构的定义

由于这是一个键值存储,我们可以调用
n.attr.keys()
,查看此属性具有的键列表。我们可以进一步调用
n.attr['strips']
来访问步幅,如果这样的键可用的话。当我们尝试打印此文件时,会得到以下结果:

list {
  i: 1
  i: 2
  i: 2
  i: 1
}
i: 1
i: 1
i: 1
i: 1
这就是它开始变得混乱的地方,因为我们可能会尝试做
list(n.attr['strips'])
或类似的事情。如果我们查看attr_value.proto,我们就可以了解发生了什么。我们看到它是
oneofvalue
,在本例中它是一个
ListValue列表
,因此我们可以调用
n.attr['strips'].list
。如果我们把它打印出来,我们会得到以下结果:

list {
  i: 1
  i: 2
  i: 2
  i: 1
}
i: 1
i: 1
i: 1
i: 1
接下来我们可能会尝试这样做:
[a代表n.attr['strips'].list]
[a.i代表n.attr['strips'].list]
。然而,一切都不起作用。在这里,
重复
是一个需要理解的重要术语。这基本上意味着有一个int64列表,您必须使用
i
属性访问它。对n.attr['strips'].list.i中的a执行
[int(a)]
之后,我们就可以使用Python列表了:

[1, 1, 1, 1]