2-2 Three Types of Graph

There are three types of graph: static, dynamic, and Autograph.

TensorFlow 1.X used static graph, which firstly creating the graph by various operators and then open a Session to execute the graph.

For TensorFlow 2.X, dynamic graph is used. The operator will be added to the invisible default graph and executed instantaneously after its usage; there is no need to create a Session.

Using dynamic graph (i.e. Eager Execution) is convenient for debugging, as it improves performance of TensorFlow code just as original Python code, with possibilities of log output and flow control, etc.

The drawback of dynamic graph is a relatively lower execution efficiency comparing to static graph. This is because multiple times of communication between the Python thread and the C++ thread of TensorFlow Kernel is required for dynamic graph, while the static graph is executed almost all on the TensorFlow kernel using C++ code with higher efficiency. What’s more, the static graph optimizes the computation, reducing the steps that are not relevant to the result.

It is possible to use the decorator @tf.function to construct code by converting normal Python function to TensorFlow graph. Executing this function is identical to executing Session in TensorFlow 1.X. This method, which uses decorator @tf.function to create static graph, is called Autograph.

1. Introduction to Graph

The graph consists of nodes and edges.

The node represent operator, while the edge represents the dependencies between the operators.

The solid edge (line) represents the dependency with data (tensor) transmission.

The dotted edge (line) represents the dependency of control, i.e. the order of execution.

2-2 Three Types of Graph - 图1

2. The Static Graph

In TensorFlow 1.X, the static graph is impelmented in two steps: defining the graph and executing it in Session.

Example of Static Graph in TensorFlow 1.X

  1. import tensorflow as tf
  2. #Defining the graph
  3. g = tf.Graph()
  4. with g.as_default():
  5. #The object of the placeholder will be designated during the execution of the Session
  6. x = tf.placeholder(name='x', shape=[], dtype=tf.string)
  7. y = tf.placeholder(name='y', shape=[], dtype=tf.string)
  8. z = tf.string_join([x,y],name = 'join',separator=' ')
  9. #Executing the graph
  10. with tf.Session(graph = g) as sess:
  11. print(sess.run(fetches = z,feed_dict = {x:"hello",y:"world"}))

The Static Graph in TensorFlow2.0 as a memorial

In order to be compatible to the old versions, TensorFlow 2.X supports the TensorFlow 1.X styled static graph in the sub-module tf.compat.v1.

This is just for memorial and we do NOT recommend this way.

  1. import tensorflow as tf
  2. g = tf.compat.v1.Graph()
  3. with g.as_default():
  4. x = tf.compat.v1.placeholder(name='x', shape=[], dtype=tf.string)
  5. y = tf.compat.v1.placeholder(name='y', shape=[], dtype=tf.string)
  6. z = tf.strings.join([x,y],name = "join",separator = " ")
  7. with tf.compat.v1.Session(graph = g) as sess:
  8. # fetches is similar to the returning value from a function, while the placeholders in feed_dict is the input argument list to this function
  9. result = sess.run(fetches = z,feed_dict = {x:"hello",y:"world"})
  10. print(result)
  1. b'hello world'

3. The Dynamic Graph

TensorFlow 2.X uses the dynamic graph and Autograph.

In TensorFlow 1.X, the static graph is impelmented in two steps: defining the graph and executing it in Session.

However, the definition and execution is no more distinguishable for dynamic graph. It executes immediatly after definition and that’s the reason why it is called “Eager Excution”.

  1. # The construction of the graph takes place at every operator, and the graph execution is immediately following each construction.
  2. x = tf.constant("hello")
  3. y = tf.constant("world")
  4. z = tf.strings.join([x,y],separator=" ")
  5. tf.print(z)
  1. hello world
  1. # The input/output of the dynamic graph could be packaged as a function
  2. def strjoin(x,y):
  3. z = tf.strings.join([x,y],separator = " ")
  4. tf.print(z)
  5. return z
  6. result = strjoin(tf.constant("hello"),tf.constant("world"))
  7. print(result)
  1. hello world
  2. tf.Tensor(b'hello world', shape=(), dtype=string)

4. Autograph in TensorFlow 2.X

The dynamic graph has a relatively lower efficiency in execution.

We can use the decorator @tf.function to convert the original Python functions into the static graph as TensorFlow 1.X。

In TensorFlow 1.X, the static graph is impelmented in two steps: defining the graph and executing it in Session.

In TensorFlow 2.X, the two steps for Autographs are: defining the function with a decorator ‘@tf.function’ and calling this function.

The is no need to use Session, so the syntax is as smooth as that of original Python.

In reality, we will debug with the dynamic graph, and shift to Autograph using decorator @tf.function for the code requires higher efficiency of execution.

There are certain rules of implementing @tf.function, which will be introduced in the following chapters.

  1. import tensorflow as tf
  2. # Use Autograph to construct the static graph
  3. @tf.function
  4. def strjoin(x,y):
  5. z = tf.strings.join([x,y],separator = " ")
  6. tf.print(z)
  7. return z
  8. result = strjoin(tf.constant("hello"),tf.constant("world"))
  9. print(result)
  1. hello world
  2. tf.Tensor(b'hello world', shape=(), dtype=string)
  1. import datetime
  2. # Create logdir
  3. import os
  4. stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
  5. logdir = os.path.join('data', 'autograph', stamp)
  6. ## We recommend using pathlib under Python3
  7. # from pathlib import Path
  8. # stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
  9. # logdir = str(Path('../data/autograph/' + stamp))
  10. writer = tf.summary.create_file_writer(logdir)
  11. # Start tracing on Autograph
  12. tf.summary.trace_on(graph=True, profiler=True)
  13. # Execute Autograph
  14. result = strjoin("hello","world")
  15. # Write the graph info into the log
  16. with writer.as_default():
  17. tf.summary.trace_export(
  18. name="autograph",
  19. step=0,
  20. profiler_outdir=logdir)
  1. # Magic command to launch tensorboard in jupyter
  2. %load_ext tensorboard
  1. # Launch tensorboard
  2. %tensorboard --logdir ../data/autograph/

2-2 Three Types of Graph - 图2

Please leave comments in the WeChat official account “Python与算法之美” (Elegance of Python and Algorithms) if you want to communicate with the author about the content. The author will try best to reply given the limited time available.

You are also welcomed to join the group chat with the other readers through replying 加群 (join group) in the WeChat official account.

image.png