How to access values ​​in protoses in TensorFlow?

I see from the tutorial that we can do this:

for node in tf.get_default_graph().as_graph_def().node: print node

When executed on an arbitrary network, we get many key value pairs. For example:

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
  }
}

      

How do I access all of these values ​​and put them in Python lists? Specifically, how can we get the "strides" attribute and convert all 1s to [1, 1, 1, 1]?

+1


source to share


1 answer


TL; DR: Below is the code you can use:

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]

The trick is to understand what protobufs . Skip the above tutorial .

First of all, there is a statement:

for node in graph_def.node

Each node is a NodeDef object defined in tensorflow / core / frames/node_def.proto. These are fundamental building blocks of TensorFlow plots, with each one defining a single one as well as its input connections. Here are the NodeDef members and what they mean.

Note the following in node_def.proto:

  • It will import attr_value.proto.
  • There are attributes such as name, op, input, device, attr. In particular, there is in front of the entrance repeated

    . For now, we can ignore this.

This works exactly the same as a Python class and so we can call node.name, node.op, node.input, node.device, node.attr, etc.



Now we would like to access the content in node.attr. Looking at the tutorial again, it points out:

It is a key / value store containing all the attributes of a node. These are constant properties of nodes, things that do not change with such as the size of filters for convolutions or constant ops values. Because there can be so many different types of attribute values, from strings, to integers, to arrays of tensor values, there is a separate protobuf file that defines the data structure that contains them in the tensorflow / core / structure / attr_value.proto.

Each attribute has a unique name string and the expected attributes are specified when the operation is defined. If the attribute is not present in node, but has a default value, the definition is specified in the operation, which is used by default when creating a graph.

You can access all of these members by calling node.name, node.op, etc. in Python. The list of nodes stored in GraphDef is a complete definition of the model's architecture.

Since this is a key store, we can call n.attr.keys()

to see a list of the keys that this attribute has. We can go further to make a call, perhaps n.attr['strides']

to access the steps, if such a key is available. When we try to print this, we get this:

list {
  i: 1
  i: 2
  i: 2
  i: 1
}

      

And this is where it starts to get confused because we might try to do it list(n.attr['strides'])

or something. If we look at attr_value.proto we can understand what's going on. We see that it is oneof value

and in this case it is a ListValue list

, so we can call n.attr['strides'].list

. And if we print this, we get this:

i: 1
i: 1
i: 1
i: 1

      

We could try to do the following: [a for a in n.attr['strides'].list]

or [a.i for a in n.attr['strides'].list]

. However, nothing works. Here repeated

is an important term for understanding. This basically means that there is an int64 list and you need to access it with an attribute i

. Execution [int(a) for a in n.attr['strides'].list.i]

then gives us what we want, a Python list that we can use:

[1, 1, 1, 1]

      

+1


source







All Articles