For my project, I need to convert a directed graph into a tensorflow implementation of the graph as if it was a neural network. In tensorflow version 1, I could just define all of my inputs as placeholders and then just generate the dataflow graph for the outputs using a breadthfirst search of the graph. Then I would just feed in my inputs using a feed_dict. However, in TensorFlow v2.0 they have decided to do away with placeholders entirely.
How would I make a tf.function for each graph that takes in a variable amount of inputs and returns a variable amount of outputs without using a placeholder?
I want to generate a tf.function like this that works for an arbitrary acyclic directed graph so that I can take advantage of tensorflow GPU support to run the graph feed forward a few thousand times in a row after I have generated it.
Edit for code example:
My graph is defined as a dictionary. Each key represents a node and has a corresponding value of another dictionary specifying incoming and outgoing links with weights.
{
"A": {
"incoming": [("B", 2), ("C", -1)],
"outgoing": [("D", 3)]
}
}
I have omitted the entries for B,C, and D for brevity. Here is how I would construct the code I want in tensorflow v1.0 where inputs is just a list of key values that are strictly inputs to the graph
def construct_graph(graph_dict, inputs, outputs):
queue = inputs[:]
make_dict = {}
for key, val in graph_dict.items():
if key in inputs:
make_dict[key] = tf.placeholder(tf.float32, name=key)
else:
make_dict[key] = None
# Breadth-First search of graph starting from inputs
while len(queue) != 0:
cur = graph_dict[queue[0]]
for outg in cur["outgoing"]:
if make_dict[outg[0]]: # If discovered node, do add/multiply operation
make_dict[outg[0]] = tf.add(make_dict[outg[0]], tf.multiply(outg[1], make_dict[queue[0]]))
else: # If undiscovered node, input is just coming in multiplied and add outgoing to queue
make_dict[outg[0]] = tf.multiply(make_dict[queue[0]], outg[1])
for outgo in graph_dict[outg[0]]["outgoing"]:
queue.append(outgo[0])
queue.pop(0)
# Returns one data graph for each output
return [make_dict[x] for x in outputs]
I would then be able to run the outputs many times as they are simply graphs with placeholders that I would provide a feed_dict for.
Obviously, this is not the intended way in TensorFlow v2.0 as they seem to strongly discourage the use of placeholders in this new version.
The point is that I only have to do this preprocessing for a graph once, as it returns a datagraph which is independent of the graph_dict definition.
tf.function
?inputs
andoutputs
?graph_dict
,inputs
andoutputs
, would be much helpful.