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:
- pip install pydot-ng
Like Theano’s printing module, d3viz
requires 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.
- import theano as th
- import theano.tensor as T
- import numpy as np
- ninputs = 1000
- nfeatures = 100
- noutputs = 10
- nhiddens = 50
- rng = np.random.RandomState(0)
- x = T.dmatrix('x')
- wh = th.shared(rng.normal(0, 1, (nfeatures, nhiddens)), borrow=True)
- bh = th.shared(np.zeros(nhiddens), borrow=True)
- h = T.nnet.sigmoid(T.dot(x, wh) + bh)
- wy = th.shared(rng.normal(0, 1, (nhiddens, noutputs)))
- by = th.shared(np.zeros(noutputs), borrow=True)
- y = T.nnet.softmax(T.dot(h, wy) + by)
- predict = th.function([x], y)
The function predict
outputs the probability of 10 classes. You canvisualize it with theano.printing.pydotprint()
as follows:
- from theano.printing import pydotprint
- import os
- if not os.path.exists('examples'):
- os.makedirs('examples')
- pydotprint(predict, 'examples/mlp.png')
- The output file is available at examples/mlp.png
- from IPython.display import Image
- Image('./examples/mlp.png', width='80%')
To visualize it interactively, import theano.d3viz.d3viz.d3viz()
fromthe the theano.d3viz.d3viz
module, which can be called as before:
- import theano.d3viz as d3v
- d3v.d3viz(predict, 'examples/mlp.html')
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 node
button 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
:
- from IPython.display import IFrame
- d3v.d3viz(predict, 'examples/mlp.html')
- 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:
- predict_profiled = th.function([x], y, profile=True)
- x_val = rng.normal(0, 1, (ninputs, nfeatures))
- y_val = predict_profiled(x_val)
- d3v.d3viz(predict_profiled, 'examples/mlp2.html')
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.
- formatter = d3v.formatting.PyDotFormatter()
- pydot_graph = formatter(predict_profiled)
- pydot_graph.write_png('examples/mlp2.png');
- pydot_graph.write_png('examples/mlp2.pdf');
- Image('./examples/mlp2.png')
Here, we used the theano.d3viz.formatting.PyDotFormatter
class toconvert the compute graph into a pydot
graph, and created aPNG
and PDF
file. 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
.
- x, y, z = T.scalars('xyz')
- e = T.nnet.sigmoid((x + y + z)**2)
- op = th.OpFromGraph([x, y, z], [e])
- e2 = op(x, y, z) + op(z, y, x)
- f = th.function([x, y, z], e2)
- d3v.d3viz(f, 'examples/ofg.html')
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.
- x, y, z = T.scalars('xyz')
- e = x * y
- op = th.OpFromGraph([x, y], [e])
- e2 = op(x, y) + z
- op2 = th.OpFromGraph([x, y, z], [e2])
- e3 = op2(x, y, z) + z
- f = th.function([x, y, z], [e3])
- d3v.d3viz(f, 'examples/ofg2.html')
Feedback
If you have any problems or great ideas on how to improve d3viz
,please let me know!
- Christof Angermueller
- cangermueller@gmail.com
- https://cangermueller.com
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:
- fct (theano.compile.function_module.Function) – A compiled Theano function, variable, apply or a list of variables.
- path (str) – Path to output file
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:
- **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.
- **graph** (_pydot.Dot_) – _pydot_ graph to which nodes are added. Creates new one ifundefined.Returns:
Pydot graph of fct Return type: pydot.Dot