d3viz – d3viz: Interactive visualization of Theano compute graphs

Guide

Requirements

d3viz requires the pydotpackage. pydot-ng fork is bettermaintained, and it works both in Python 2.x and 3.x. Install it with pip:

  1. pip install pydot-ng

Like Theano’s printing module, d3vizrequires graphviz binary to be available.

Overview

d3viz extends Theano’s printingmoduleto interactively visualize compute graphs. Instead of creating a staticpicture, it creates an HTML file, which can be opened with currentweb-browsers. d3viz allows

  • to zoom to different regions and to move graphs via drag and drop,
  • to position nodes both manually and automatically,
  • to retrieve additional information about nodes and edges such astheir data type or definition in the source code,
  • to edit node labels,
  • to visualizing profiling information, and
  • to explore nested graphs such as OpFromGraph nodes.

Note

This userguide is also avaible asIPython notebook.

As an example, consider the following multilayer perceptron with onehidden layer and a softmax output layer.

  1. import theano as th
  2. import theano.tensor as T
  3. import numpy as np
  4.  
  5. ninputs = 1000
  6. nfeatures = 100
  7. noutputs = 10
  8. nhiddens = 50
  9.  
  10. rng = np.random.RandomState(0)
  11. x = T.dmatrix('x')
  12. wh = th.shared(rng.normal(0, 1, (nfeatures, nhiddens)), borrow=True)
  13. bh = th.shared(np.zeros(nhiddens), borrow=True)
  14. h = T.nnet.sigmoid(T.dot(x, wh) + bh)
  15.  
  16. wy = th.shared(rng.normal(0, 1, (nhiddens, noutputs)))
  17. by = th.shared(np.zeros(noutputs), borrow=True)
  18. y = T.nnet.softmax(T.dot(h, wy) + by)
  19.  
  20. predict = th.function([x], y)

The function predict outputs the probability of 10 classes. You canvisualize it with theano.printing.pydotprint() as follows:

  1. from theano.printing import pydotprint
  2. import os
  3.  
  4. if not os.path.exists('examples'):
  5. os.makedirs('examples')
  6. pydotprint(predict, 'examples/mlp.png')
  1. The output file is available at examples/mlp.png
  1. from IPython.display import Image
  2. Image('./examples/mlp.png', width='80%')

../../_images/index_10_0.png To visualize it interactively, import theano.d3viz.d3viz.d3viz() fromthe the theano.d3viz.d3viz module, which can be called as before:

  1. import theano.d3viz as d3v
  2. d3v.d3viz(predict, 'examples/mlp.html')

Open visualization!

When you open the output file mlp.html in your web-browser, you willsee an interactive visualization of the compute graph. You can move thewhole graph or single nodes via drag and drop, and zoom via the mousewheel. When you move the mouse cursor over a node, a window will pop upthat displays detailed information about the node, such as its data typeor definition in the source code. When you left-click on a node andselect Edit, you can change the predefined node label. If you aredealing with a complex graph with many nodes, the default node layoutmay not be perfect. In this case, you can press the Release nodebutton in the top-left corner to automatically arrange nodes. To resetnodes to their default position, press the Reset nodes button.

You can also display the interactive graph inline inIPython using IPython.display.IFrame:

  1. from IPython.display import IFrame
  2. d3v.d3viz(predict, 'examples/mlp.html')
  3. IFrame('examples/mlp.html', width=700, height=500)

Currently if you use display.IFrame you still have to create a file,and this file can’t be outside notebooks root (e.g. usually it can’t bein /tmp/).

Profiling

Theano allows functionprofilingvia the profile=True flag. After at least one function call, thecompute time of each node can be printed in text form withdebugprint. However, analyzing complex graphs in this way can becumbersome.

d3viz can visualize the same timing information graphically, andhence help to spot bottlenecks in the compute graph more easily! Tobegin with, we will redefine the predict function, this time byusing profile=True flag. Afterwards, we capture the runtime onrandom data:

  1. predict_profiled = th.function([x], y, profile=True)
  2.  
  3. x_val = rng.normal(0, 1, (ninputs, nfeatures))
  4. y_val = predict_profiled(x_val)
  1. d3v.d3viz(predict_profiled, 'examples/mlp2.html')

Open visualization!

When you open the HTML file in your browser, you will find an additionalToggle profile colors button in the menu bar. By clicking on it,nodes will be colored by their compute time, where red corresponds to ahigh compute time. You can read out the exact timing information of anode by moving the cursor over it.

Different output formats

Internally, d3viz represents a compute graph in the Graphviz DOTlanguage, using thepydot package, and defines afront-end based on the d3.js library to visualizeit. However, any other Graphviz front-end can be used, which allows toexport graphs to different formats.

  1. formatter = d3v.formatting.PyDotFormatter()
  2. pydot_graph = formatter(predict_profiled)
  3.  
  4. pydot_graph.write_png('examples/mlp2.png');
  5. pydot_graph.write_png('examples/mlp2.pdf');
  1. Image('./examples/mlp2.png')

../../_images/index_24_0.png Here, we used the theano.d3viz.formatting.PyDotFormatter class toconvert the compute graph into a pydot graph, and created aPNG and PDFfile. You can find all output formats supported by Graphviz here.

OpFromGraph nodes

AnOpFromGraphnode defines a new operation, which can be called with different inputsat different places in the compute graph. Each OpFromGraph nodedefines a nested graph, which will be visualized accordingly byd3viz.

  1. x, y, z = T.scalars('xyz')
  2. e = T.nnet.sigmoid((x + y + z)**2)
  3. op = th.OpFromGraph([x, y, z], [e])
  4.  
  5. e2 = op(x, y, z) + op(z, y, x)
  6. f = th.function([x, y, z], e2)
  1. d3v.d3viz(f, 'examples/ofg.html')

Open visualization!

In this example, an operation with three inputs is defined, which isused to build a function that calls this operations twice, each timewith different input arguments.

In the d3viz visualization, you will find two OpFromGraph nodes,which correspond to the two OpFromGraph calls. When you double click onone of them, the nested graph appears with the correct mapping of itsinput arguments. You can move it around by drag and drop in the shadedarea, and close it again by double-click.

An OpFromGraph operation can be composed of further OpFromGraphoperations, which will be visualized as nested graphs as you can see inthe following example.

  1. x, y, z = T.scalars('xyz')
  2. e = x * y
  3. op = th.OpFromGraph([x, y], [e])
  4. e2 = op(x, y) + z
  5. op2 = th.OpFromGraph([x, y, z], [e2])
  6. e3 = op2(x, y, z) + z
  7. f = th.function([x, y, z], [e3])
  1. d3v.d3viz(f, 'examples/ofg2.html')

Open visualization!

Feedback

If you have any problems or great ideas on how to improve d3viz,please let me know!

References

d3viz module

Dynamic visualization of Theano graphs.

Author: Christof Angermueller <cangermueller@gmail.com>

  • theano.d3viz.d3viz.d3viz(fct, outfile, copy_deps=True, *args, **kwargs)[source]
  • Create HTML file with dynamic visualizing of a Theano function graph.

In the HTML file, the whole graph or single nodes can be moved by drag anddrop. Zooming is possible via the mouse wheel. Detailed information aboutnodes and edges are displayed via mouse-over events. Node labels can beedited by selecting Edit from the context menu.

Input nodes are colored in green, output nodes in blue. Apply nodes areellipses, and colored depending on the type of operation they perform. Redellipses are transfers from/to the GPU (ops with names GpuFromHost,HostFromGpu).

Edges are black by default. If a node returns a view of aninput, the input edge will be blue. If it returns a destroyed input, theedge will be red.

Parameters:

  • fct (theano.compile.function_module.Function) – A compiled Theano function, variable, apply or a list of variables.
  • outfile (str) – Path to output HTML file.
  • copy_deps (bool, optional) – Copy javascript and CSS dependencies to output directory.

Notes

This function accepts extra parameters which will be forwarded totheano.d3viz.formatting.PyDotFormatter.

  • theano.d3viz.d3viz.d3write(fct, path, *args, **kwargs)[source]
  • Convert Theano graph to pydot graph and write to dot file.

Parameters:

Notes

This function accepts extra parameters which will be forwarded totheano.d3viz.formatting.PyDotFormatter.

  • theano.d3viz.d3viz.replacepatterns(_x, replace)[source]
  • Replace replace in string x.

Parameters:

  • s (str) – String on which function is applied
  • replace (dict) – key, value pairs where key is a regular expression and value astring by which key is replaced
  • theano.d3viz.d3viz.safejson(_obj)[source]
  • Encode obj to JSON so that it can be embedded safely inside HTML.

Parameters:obj (object) – object to serialize

PyDotFormatter

  • class theano.d3viz.formatting.PyDotFormatter(compact=True)[source]
  • Create pydot graph object from Theano function.

Parameters:compact (bool) – if True, will remove intermediate variables without name.

  • node_colors[source]
  • dict – Color table of node types.

  • apply_colors[source]

  • dict – Color table of apply nodes.

  • shapes[source]

  • dict – Shape table of node types.

  • call(fct, graph=None)[source]

  • Create pydot graph from function.

Parameters:

  1. - **fct** ([_theano.compile.function_module.Function_](http://deeplearning.net/software/theano_versions/0.9.X/library/compile/function.html#theano.compile.function_module.Function)) – A compiled Theano function, variable, apply or a list of variables.
  2. - **graph** (_pydot.Dot_) _pydot_ graph to which nodes are added. Creates new one ifundefined.Returns:

Pydot graph of fct Return type: pydot.Dot