3

In TensorFlow, I found that I can do the following,

from tensorflow.core import framework
from google.protobuf import json_format
graph_def = framework.graph_pb2.GraphDef()
node_def = framework.node_def_pb2.NodeDef()
graph_def.node.extend([node_def])
print json_format.MessageToJson(graph_def)

Which prints

{
  "node": [
    {}
  ]
}

Now, my node is not actually set to an Operation. I can't figure out how to make node_def be an operation. I can construct OpDefs via,

from tensorflow.python.ops import gen_array_ops
const_op_def = gen_array_ops._InitOpDefLibrary()._ops['Const'].op_def

Which is of class <class 'tensorflow.core.framework.op_def_pb2.OpDef'>

I would like to make my NodeDef register as this OpDef.

EDIT:

>>> print json_format.MessageToJson(gen_array_ops._InitOpDefLibrary()._ops['Const'].op_def)
{
  "outputArg": [
    {
      "typeAttr": "dtype", 
      "name": "output"
    }
  ], 
  "name": "Const", 
  "attr": [
    {
      "type": "tensor", 
      "name": "value"
    }, 
    {
      "type": "type", 
      "name": "dtype"
    }
  ]
}
  • Operation is a Python object, and OpDef is a protobuf. GraphDef is a protobuf containing NodeDef messages, while Graph is a Python object containing Operation objects, you can't mix the two – Yaroslav Bulatov Feb 10 '17 at 21:42
  • Why does `json_format.MessageToJson(gen_array_ops._InitOpDefLibrary()._ops['Const'].op_def)` work? –  Feb 10 '17 at 21:55
  • well, it prints something that looks sane, although I'm not familiar with json – Yaroslav Bulatov Feb 10 '17 at 23:51
  • I meant that as evidence that the .op_def is a Protobuf Message. The MessageToJson would error out otherwise. –  Feb 10 '17 at 23:53
  • I guess I'm confused by your question, `Operation` is an object you get when you do something like `tf.get_default_graph().get_operations()[0]` – Yaroslav Bulatov Feb 11 '17 at 00:05
  • if you want to create `OpDef` instead of `NodeDef`, you would do `framework.op_def_pb2.OpDef()` instead of `framework.node_def_pb2.NodeDef()` – Yaroslav Bulatov Feb 11 '17 at 00:07
  • see `tensorflow/core/framework/node_def.proto` and `tensorflow/core/framework/op_def.proto` for their definitions – Yaroslav Bulatov Feb 11 '17 at 00:08
  • Yeah. I do that in beginning of this question. The problem is nesting the OpDef under the NodeDef like it is in GraphDef protobuf. –  Feb 11 '17 at 00:14
  • There are no opdef's inside GraphDef, the graphdef is defined in [graph.proto](https://github.com/tensorflow/tensorflow/blob/754048a0453a04a761e112ae5d99c149eb9910dd/tensorflow/core/framework/graph.proto) – Yaroslav Bulatov Feb 11 '17 at 01:22
  • Could you figure out how to register an own operation? – user3085931 Apr 05 '18 at 07:50
  • @user3085931I believe so, but that doesn't mean I remember how at the moment. [This past self-answer](https://stackoverflow.com/a/44337811/3002273) might be of help. What I believe I did is dump out the graph for existing operations as JSON and then modify them and use Protobuf to reload them into a TF graph. If you figure it out, maybe you could answer this question. –  Apr 05 '18 at 16:37

1 Answers1

0

I believe you are looking for a way to set message fields inside of the GraphDef and NodeDef protos. How to modify ProtoBuf objects in Python is detailed here

jsimsa
  • 315
  • 2
  • 6