3

I have existing model that is stored in .pb, I want to add some constant tensor (initially I have data in numpy array) to some tensor in graph via Add op, how can it be done?

As I understand each node in graph is tensorflow.core.framework.node_def_pb2.NodeDef, so I need create one node for Add op and one node for const tensor?

These are related questions:

TensorFlow Manual Construction of GraphDef

How to get weights from .pb model in Tensorflow

mrgloom
  • 20,061
  • 36
  • 171
  • 301

1 Answers1

6

EDIT: The answer below is just to add a disconnected constant to a graph, if you want to add a new adding operation then it would be something like this:

import tensorflow as tf

constant_value = ...
with tf.Graph().as_default():
    gd = tf.GraphDef()
    with open('my_graph.pb', 'rb') as f:
        gd.MergeFromString(f.read())
    my_tensor = tf.import_graph_def(gd, name='', return_elements='SomeOperation:0')
    tf.add(my_tensor, constant_value, name='NewOperation')
    tf.train.write_graph(tf.get_default_graph(), '.',
                         'my_modified_graph.pb', as_text=False)

Note however this just adds new operations, it does not modify the value of the original tensor. I'm not sure which one of these is what you wanted.


The most practical way is to import the graph, add the constant and save it again:

import tensorflow as tf

new_constant = ...
with tf.Graph().as_default():
    gd = tf.GraphDef()
    with open('my_graph.pb', 'rb') as f:
        gd.MergeFromString(f.read())
    tf.import_graph_def(gd, name='')
    tf.constant(new_constant, name='NewConstant')
    tf.train.write_graph(tf.get_default_graph(), '.',
                         'my_graph_with_constant.pb', as_text=False)

If for some reason you don't want to import the graph, you can manually build the node object like this:

import numpy as np
import tensorflow as tf
from tensorflow.core.framework.tensor_pb2 import TensorProto
from tensorflow.core.framework.tensor_shape_pb2 import TensorShapeProto

# New constant to add
my_value = np.array([[1, 2, 3], [4, 5,6]], dtype=np.int32)
# Make graph node
tensor_content = my_value.tobytes()
dt = tf.as_dtype(my_value.dtype).as_datatype_enum
tensor_shape = TensorShapeProto(dim=[TensorShapeProto.Dim(size=s) for s in my_value.shape])
tensor_proto = TensorProto(tensor_content=tensor_content,
                           tensor_shape=tensor_shape,
                           dtype=dt)
node = tf.NodeDef(name='MyConstant', op='Const',
                  attr={'value': tf.AttrValue(tensor=tensor_proto),
                        'dtype': tf.AttrValue(type=dt)})
# Read existing graph
gd = tf.GraphDef()
with open('my_graph.pb', 'rb') as f:
    gd.MergeFromString(f.read())
# Add new node
gd.node.extend([node])
# Save modified graph
tf.train.write_graph(tf.get_default_graph(), '.',
                     'my_graph_with_constant.pb', as_text=False)

Note this case is relatively easy because the node is not connected to any other node.

jdehesa
  • 58,456
  • 7
  • 77
  • 121
  • Actually I don't see `NewConstant` in new saved `.pb` maybe because it's don't connected to main graph? And I need to add const tensor to some existing tensor. – mrgloom May 24 '19 at 16:28
  • @mrgloom Ah wait I didn't understand that right, I thought you just wanted to have the constant in the graph. – jdehesa May 24 '19 at 16:43
  • @mrgloom Okay I edited for the addition. However, as I point out, I'm not sure if what you want is to introduce a new addition operation (what I posted) or actually modify the existing value of a tensor (a bit more complicated). – jdehesa May 24 '19 at 16:47
  • One problem is seems when I call `tf.import_graph_def` 2 times to add 2 constants, it creates copy of graph each time(so I have 2 graphs in .pb each with one constant added), second problem is that `Pack` operation is added before added `Add` operation which is not desired effect. – mrgloom May 27 '19 at 01:21