提交 4c52f7af authored 作者: Christof Angermueller's avatar Christof Angermueller

Add test case to compare files and fix Travis complaints

上级 f2ff5a87
......@@ -37,3 +37,5 @@ Theano.suo
.ipynb_checkpoints
.pydevproject
doc/library/d3viz/GSoC/
theano/d3viz/tests/data/test_d3viz/*/d3viz/
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -35,7 +35,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"`d3viz` extends Theano’s [printing module](http://deeplearning.net/software/theano/library/printing.html) to interactively visualize compute graphs. Instead of creating a static picture, it creates an HTML file, which can be opened with any web-browser. `d3viz` allows\n",
"`d3viz` extends Theano’s [printing module](http://deeplearning.net/software/theano/library/printing.html) to interactively visualize compute graphs. Instead of creating a static picture, it creates an HTML file, which can be opened with current web-browsers. `d3viz` allows\n",
"\n",
"* to zoom to different regions and to move graphs via drag and drop,\n",
"* to position nodes both manually and automatically,\n",
......
......@@ -29,8 +29,8 @@ Overview
``d3viz`` extends Theano’s `printing
module <http://deeplearning.net/software/theano/library/printing.html>`__
to interactively visualize compute graphs. Instead of creating a static
picture, it creates an HTML file, which can be opened with any
web-browser. ``d3viz`` allows
picture, it creates an HTML file, which can be opened with current
web-browsers. ``d3viz`` allows
- to zoom to different regions and to move graphs via drag and drop,
- to position nodes both manually and automatically,
......@@ -166,7 +166,7 @@ language <http://www.graphviz.org/>`__, using the
`pydot <https://pypi.python.org/pypi/pydot>`__ package, and defines a
front-end based on the `d3.js <http://d3js.org/>`__ library to visualize
it. However, any other Graphviz front-end can be used, which allows to
export graps to different formats.
export graphs to different formats.
.. code:: python
......
from d3viz import *
from theano.d3viz.d3viz import d3viz, d3write
......@@ -26,7 +26,7 @@ def escape_quotes(s):
return s
def d3viz(fct, outfile, copy_deps=True, *args, **kwargs):
def d3viz(fct, outfile, copy_deps=True, *args, **kwargs):
"""Create HTML file with dynamic visualizing of a Theano function graph.
:param fct: A compiled Theano function, variable, apply or a list of
......
......@@ -5,8 +5,8 @@ Author: Christof Angermueller <cangermueller@gmail.com>
import numpy as np
import logging
import re
import os.path as pt
from functools import reduce
try:
import pydot as pd
......@@ -121,7 +121,7 @@ class PyDotFormatter(object):
nparams['label'] = apply_label(node)
nparams['profile'] = apply_profile(node, profile)
nparams['node_type'] = 'apply'
nparams['apply_op'] = apply_op(node)
nparams['apply_op'] = nparams['label']
nparams['shape'] = self.shapes['apply']
use_color = None
......@@ -175,7 +175,7 @@ class PyDotFormatter(object):
**edge_params)
graph.add_edge(pdedge)
# Loop over ouput nodes
# Loop over output nodes
for id, var in enumerate(node.outputs):
var_id = self.__node_id(var)
......@@ -201,7 +201,7 @@ class PyDotFormatter(object):
graph.add_edge(pd.Edge(__node_id, var_id,
label=vparams['dtype']))
# Create sub-groph for OpFromGraph nodes
# Create sub-graph for OpFromGraph nodes
if isinstance(node.op, builders.OpFromGraph):
subgraph = pd.Cluster(__node_id)
gf = PyDotFormatter()
......@@ -277,14 +277,6 @@ def apply_label(node):
return node.op.__class__.__name__
def apply_op(node):
"""Return apply operation."""
name = str(node.op).replace(':', '_')
name = re.sub('^<', '', name)
name = re.sub('>$', '', name)
return name
def apply_profile(node, profile):
"""Return apply profiling informaton."""
if not profile or profile.fct_call_time == 0:
......
......@@ -35,18 +35,14 @@
var profileColors = ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15"];
var pad = 10;
var isEditNode = false; // true if node is edited
var menuItems = [
var menuItems = [
{
title: 'Edit',
action: function(elm, d, i) {
editNode(elm, d);
}
action: function(elm, d, i) { editNode(elm, d); }
},
{
title: 'Release',
action: function(elm, d, i) {
releaseNode(d);
}
action: function(elm, d, i) { releaseNode(d); }
}
];
......
#!/usr/bin/env python
"""Creates reference files for testing d3viz module.
Used in tests/test_d3viz.py.
Author: Christof Angermueller <cangermueller@gmail.com>
"""
import theano as th
import theano.d3viz as d3v
from theano.d3viz.tests import models
model = models.Mlp()
f = th.function(model.inputs, model.outputs)
d3v.d3viz(f, 'mlp/index.html')
model = models.Ofg()
f = th.function(model.inputs, model.outputs)
d3v.d3viz(f, 'ofg/index.html')
model = models.OfgNested()
f = th.function(model.inputs, model.outputs)
d3v.d3viz(f, 'ofg_nested/index.html')
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="d3viz/css/d3viz.css"/>
<link rel="stylesheet" href="d3viz/css/d3-context-menu.css"/>
<script type="text/javascript" src="d3viz/js/d3viz.js"></script>
<script type="text/javascript" src="d3viz/js/d3.v3.min.js"></script>
<script type="text/javascript" src="d3viz/js/dagre-d3.js"></script>
<script type="text/javascript" src="d3viz/js/graphlib-dot.js"></script>
<script type="text/javascript" src="d3viz/js/d3-context-menu.js"></script>
</head>
<body>
<div id='menu' class='menuBar'>
<input name="resetNodes"
type="button"
value="Reset nodes"
onclick="resetNodes()"/>
<input name="releaseNodes"
type="button"
value="Release nodes"
onclick="releaseNodes()"/>
</div>
<script type="text/javascript">
// Backend graph in DOT format
var dotGraph = graphlibDot.read("digraph G { graph [bb=\"0,0,272,476\"]; node [label=\"\N\"]; n1 [apply_op=DimShuffle, height=0.5, label=DimShuffle, node_type=apply, pos=\"219,370\", shape=ellipse, width=1.4763]; n8 [apply_op=Elemwise, fillcolor=\"#FFAABB\", height=0.5, label=Elemwise, node_type=apply, pos=\"170,282\", shape=ellipse, style=filled, type=colored, width=1.2888]; n1 -> n8 [label=\"1 dmatrix\", lp=\"225.5,326\", pos=\"e,179.49,299.66 209.32,352.01 202.23,339.56 192.48,322.45 184.47,308.39\"]; n2 [dtype=dvector, fillcolor=YellowGreen, height=0.5, label=dvector, node_type=shared_input, pos=\"219,458\", shape=box, style=filled, width=0.80556]; n2 -> n1 [color=dodgerblue, label=dvector, lp=\"240,414\", pos=\"e,219,388.08 219,439.6 219,427.75 219,411.82 219,398.29\"]; n4 [apply_op=Dot22, height=0.5, label=Dot22, node_type=apply, pos=\"114,370\", shape=ellipse, width=0.92774]; n4 -> n8 [color=red, label=\"0 dmatrix\", lp=\"158.5,326\", pos=\"e,148.95,298.37 117.35,351.95 119.93,341.54 124.24,328.3 131,318 133.92,313.55 137.54,309.31 141.39,305.41\"]; n5 [dtype=dmatrix, fillcolor=limegreen, height=0.5, label=x, node_type=input, pos=\"50,458\", shape=box, style=filled, width=0.75]; n5 -> n4 [label=\"0 dmatrix\", lp=\"88.5,414\", pos=\"e,89.174,382.09 50.492,439.64 51.537,429.12 54.251,415.87 61,406 66.011,398.67 73.111,392.49 80.491,387.46\"]; n6 [dtype=dmatrix, fillcolor=YellowGreen, height=0.5, label=dmatrix, node_type=shared_input, pos=\"128,458\", shape=box, style=filled, width=0.83333]; n6 -> n4 [label=\"1 dmatrix\", lp=\"149.5,414\", pos=\"e,116.78,388.08 125.17,439.6 123.24,427.75 120.64,411.82 118.44,398.29\"]; n10 [apply_op=Dot22, height=0.5, label=Dot22, node_type=apply, pos=\"118,194\", shape=ellipse, width=0.92774]; n8 -> n10 [label=\"0 dmatrix\", lp=\"175.5,238\", pos=\"e,127.82,211.24 159.97,264.42 152.37,251.85 141.8,234.35 133.16,220.07\"]; n13 [apply_op=SoftmaxWithBias, height=0.5, label=SoftmaxWithBias, node_type=apply, pos=\"76,106\", shape=ellipse, width=2.1117]; n10 -> n13 [label=\"0 dmatrix\", lp=\"128.5,150\", pos=\"e,84.361,124.12 109.9,176.42 103.94,164.2 95.704,147.35 88.845,133.3\"]; n11 [dtype=dmatrix, fillcolor=YellowGreen, height=0.5, label=dmatrix, node_type=shared_input, pos=\"75,282\", shape=box, style=filled, width=0.83333]; n11 -> n10 [label=\"1 dmatrix\", lp=\"111.5,238\", pos=\"e,100.16,209.41 75.526,263.66 76.44,253.4 78.677,240.41 84,230 86.398,225.31 89.636,220.84 93.164,216.75\"]; n15 [dtype=dmatrix, fillcolor=dodgerblue, height=0.5, label=dmatrix, node_type=output, pos=\"76,18\", shape=box, style=filled, width=0.83333]; n13 -> n15 [label=dmatrix, lp=\"98,62\", pos=\"e,76,36.084 76,87.597 76,75.746 76,59.817 76,46.292\"]; n14 [dtype=dvector, fillcolor=YellowGreen, height=0.5, label=dvector, node_type=shared_input, pos=\"37,194\", shape=box, style=filled, width=0.80556]; n14 -> n13 [label=\"1 dvector\", lp=\"66.5,150\", pos=\"e,53.961,123.42 34.978,175.72 34.504,165.47 35.203,152.48 40,142 41.795,138.08 44.242,134.36 47.022,130.92\"];}");
// Frontend graph for visualization
var graph = {};
var forceLayout;
var isProfiled = false; // true if profiling information available
var useProfileColors = false;
var fixOnInit = true; // fix nodes on initialization
var maxProfilePer = 0;
var profileColors = ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15"];
var pad = 10;
var isEditNode = false; // true if node is edited
var menuItems = [
{
title: 'Edit',
action: function(elm, d, i) { editNode(elm, d); }
},
{
title: 'Release',
action: function(elm, d, i) { releaseNode(d); }
}
];
// Create main panel
d3.select('body').select('svg').remove();
var svg = d3.select('body').append('svg')
.attr('width', '100%')
.attr('height', '95%');
var pane = svg.append('g');
// Zoom behaviour
var zoom = d3.behavior.zoom()
.scaleExtent([0.2, 8])
.on('zoom', function(d) {
var trans = d3.event.translate;
trans[0] += 300;
trans[1] += 100;
pane.attr('transform', 'translate(' + trans + ') scale(' + d3.event.scale + ')');
});
svg.call(zoom);
zoom.event(svg);
svg.on("dblclick.zoom", null);
// Edges
var edgeDiv = d3.select('body').append('div')
.attr('class', 'edgeTooltip')
.style('opacity', 0.0);
// Div for node details
var nodeInfo = d3.select('body').append('div')
.attr('class', 'nodeInfo')
.style('opacity', 0.0);
// Definition head of edges
var markerData = [
{'id': 'n', 'color': 'black'},
{'id': 'r', 'color': 'red'},
{'id': 'b', 'color': 'dodgerblue'}];
svg.append("defs").selectAll('marker').data(markerData).enter().append("marker")
.attr("id", function(d) { return 'edgeArrow_' + d.id;})
.attr("markerWidth", 4)
.attr("markerHeight", 4)
.attr("refX", 2)
.attr("refY", 2)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,0 L4,2 L0,4 Z")
.attr('fill', function(d) { return d.color;});
// Initialize graph
processDotGraph(dotGraph);
graph = frontEndGraph(dotGraph);
drawGraph();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="d3viz/css/d3viz.css"/>
<link rel="stylesheet" href="d3viz/css/d3-context-menu.css"/>
<script type="text/javascript" src="d3viz/js/d3viz.js"></script>
<script type="text/javascript" src="d3viz/js/d3.v3.min.js"></script>
<script type="text/javascript" src="d3viz/js/dagre-d3.js"></script>
<script type="text/javascript" src="d3viz/js/graphlib-dot.js"></script>
<script type="text/javascript" src="d3viz/js/d3-context-menu.js"></script>
</head>
<body>
<div id='menu' class='menuBar'>
<input name="resetNodes"
type="button"
value="Reset nodes"
onclick="resetNodes()"/>
<input name="releaseNodes"
type="button"
value="Release nodes"
onclick="releaseNodes()"/>
</div>
<script type="text/javascript">
// Backend graph in DOT format
var dotGraph = graphlibDot.read("digraph G { graph [bb=\"0,0,877.01,316\"]; node [label=\"\N\"]; subgraph cluster_n1 { graph [bb=\"413.01,80,637.01,308\"]; n11 [apply_op=Elemwise, fillcolor=\"#FFAABB\", height=0.5, label=Elemwise, node_type=apply, pos=\"510.01,194\", shape=ellipse, style=filled, type=colored, width=1.2888]; n15 [dtype=fscalar, fillcolor=dodgerblue, height=0.5, label=fscalar, node_type=output, pos=\"510.01,106\", shape=box, style=filled, width=0.75]; n11 -> n15 [label=fscalar, lp=\"529.01,150\", pos=\"e,510.01,124.08 510.01,175.6 510.01,163.75 510.01,147.82 510.01,134.29\"]; n12 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=z, node_type=input, pos=\"592.01,282\", shape=box, style=filled, width=0.75]; n12 -> n11 [label=\"0 fscalar\", lp=\"596.01,238\", pos=\"e,534.12,209.56 583.05,263.78 577.09,253.31 568.62,240.07 559.01,230 554.11,224.87 548.36,220 542.56,215.61\"]; n13 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=x, node_type=input, pos=\"520.01,282\", shape=box, style=filled, width=0.75]; n13 -> n11 [label=\"1 fscalar\", lp=\"535.01,238\", pos=\"e,509.36,212.08 514.71,263.71 513.23,258.11 511.8,251.84 511.01,246 509.95,238.28 509.51,229.84 509.37,222.09\"]; n14 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=y, node_type=input, pos=\"448.01,282\", shape=box, style=filled, width=0.75]; n14 -> n11 [label=\"2 fscalar\", lp=\"482.01,238\", pos=\"e,481.77,208.39 448.14,263.68 448.97,253.17 451.42,239.92 458.01,230 462.06,223.89 467.58,218.57 473.52,214.05\"]; } subgraph cluster_n7 { graph [bb=\"645.01,80,869.01,308\"]; n71 [apply_op=Elemwise, fillcolor=\"#FFAABB\", height=0.5, label=Elemwise, node_type=apply, pos=\"742.01,194\", shape=ellipse, style=filled, type=colored, width=1.2888]; n75 [dtype=fscalar, fillcolor=dodgerblue, height=0.5, label=fscalar, node_type=output, pos=\"742.01,106\", shape=box, style=filled, width=0.75]; n71 -> n75 [label=fscalar, lp=\"761.01,150\", pos=\"e,742.01,124.08 742.01,175.6 742.01,163.75 742.01,147.82 742.01,134.29\"]; n72 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=z, node_type=input, pos=\"824.01,282\", shape=box, style=filled, width=0.75]; n72 -> n71 [label=\"0 fscalar\", lp=\"828.01,238\", pos=\"e,766.12,209.56 815.05,263.78 809.09,253.31 800.62,240.07 791.01,230 786.11,224.87 780.36,220 774.56,215.61\"]; n73 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=x, node_type=input, pos=\"752.01,282\", shape=box, style=filled, width=0.75]; n73 -> n71 [label=\"1 fscalar\", lp=\"767.01,238\", pos=\"e,741.36,212.08 746.71,263.71 745.23,258.11 743.8,251.84 743.01,246 741.95,238.28 741.51,229.84 741.37,222.09\"]; n74 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=y, node_type=input, pos=\"680.01,282\", shape=box, style=filled, width=0.75]; n74 -> n71 [label=\"2 fscalar\", lp=\"714.01,238\", pos=\"e,713.77,208.39 680.14,263.68 680.97,253.17 683.42,239.92 690.01,230 694.06,223.89 699.58,218.57 705.52,214.05\"]; } n1 [apply_op=OpFromGraph, height=0.5, label=OpFromGraph, node_type=apply, pos=\"217.01,194\", shape=ellipse, subg=cluster_n1, subg_map_inputs=\"[[\'n2\', \'n13\'], [\'n3\', \'n14\'], [\'n4\', \'n12\']]\", subg_map_outputs=\"[[\'n15\', \'n6\']]\", width=1.7826]; n6 [apply_op=Elemwise, fillcolor=\"#FFAABB\", height=0.5, label=Elemwise, node_type=apply, pos=\"153.01,106\", shape=ellipse, style=filled, type=colored, width=1.2888]; n1 -> n6 [label=\"1 fscalar\", lp=\"215.01,150\", pos=\"e,165.19,123.37 204.36,176.01 194.95,163.36 181.96,145.9 171.4,131.71\"]; n2 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=z, node_type=input, pos=\"55.007,282\", shape=box, style=filled, width=0.75]; n2 -> n1 [label=\"0 fscalar\", lp=\"175.01,238\", pos=\"e,188.78,210.26 82.101,266.93 94.312,260.57 108.9,252.94 122.01,246 141.17,235.85 162.43,224.45 179.98,215\"]; n7 [apply_op=OpFromGraph, height=0.5, label=OpFromGraph, node_type=apply, pos=\"70.007,194\", shape=ellipse, subg=cluster_n7, subg_map_inputs=\"[[\'n4\', \'n73\'], [\'n3\', \'n74\'], [\'n2\', \'n72\']]\", subg_map_outputs=\"[[\'n75\', \'n6\']]\", width=1.7826]; n2 -> n7 [label=\"2 fscalar\", lp=\"27.007,238\", pos=\"e,28.697,207.85 27.721,268.8 10.72,259.37 -6.2971,245.36 3.007,230 7.1667,223.13 13.164,217.55 19.883,213.03\"]; n3 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=y, node_type=input, pos=\"304.01,282\", shape=box, style=filled, width=0.75]; n3 -> n1 [label=\"1 fscalar\", lp=\"363.01,238\", pos=\"e,279.27,198.73 325,263.94 334.94,253.78 343.06,240.79 335.01,230 323.95,215.19 306.9,206.39 289.16,201.24\"]; n3 -> n7 [label=\"1 fscalar\", lp=\"304.01,238\", pos=\"e,116.87,206.31 294.23,263.96 286.68,252.44 275.15,237.94 261.01,230 215.13,204.25 195.68,221.9 144.01,212 138.37,210.92 132.5,209.72 \126.66,208.46\"]; n4 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=x, node_type=input, pos=\"197.01,282\", shape=box, style=filled, width=0.75]; n4 -> n1 [label=\"2 fscalar\", lp=\"233.01,238\", pos=\"e,213.03,212.08 201.05,263.6 203.84,251.63 207.59,235.5 210.75,221.89\"]; n4 -> n7 [label=\"0 fscalar\", lp=\"98.007,238\", pos=\"e,66.731,212.43 169.97,281.61 141.33,280.65 97.14,274.26 74.007,246 68.707,239.52 66.766,230.91 66.43,222.6\"]; n7 -> n6 [color=red, label=\"0 fscalar\", lp=\"143.01,150\", pos=\"e,137.33,123.24 86.01,176.42 98.606,163.37 116.32,145.01 130.37,130.46\"]; n9 [dtype=fscalar, fillcolor=dodgerblue, height=0.5, label=fscalar, node_type=output, pos=\"153.01,18\", shape=box, style=filled, width=0.75]; n6 -> n9 [label=fscalar, lp=\"172.01,62\", pos=\"e,153.01,36.084 153.01,87.597 153.01,75.746 153.01,59.817 153.01,46.292\"];}");
// Frontend graph for visualization
var graph = {};
var forceLayout;
var isProfiled = false; // true if profiling information available
var useProfileColors = false;
var fixOnInit = true; // fix nodes on initialization
var maxProfilePer = 0;
var profileColors = ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15"];
var pad = 10;
var isEditNode = false; // true if node is edited
var menuItems = [
{
title: 'Edit',
action: function(elm, d, i) { editNode(elm, d); }
},
{
title: 'Release',
action: function(elm, d, i) { releaseNode(d); }
}
];
// Create main panel
d3.select('body').select('svg').remove();
var svg = d3.select('body').append('svg')
.attr('width', '100%')
.attr('height', '95%');
var pane = svg.append('g');
// Zoom behaviour
var zoom = d3.behavior.zoom()
.scaleExtent([0.2, 8])
.on('zoom', function(d) {
var trans = d3.event.translate;
trans[0] += 300;
trans[1] += 100;
pane.attr('transform', 'translate(' + trans + ') scale(' + d3.event.scale + ')');
});
svg.call(zoom);
zoom.event(svg);
svg.on("dblclick.zoom", null);
// Edges
var edgeDiv = d3.select('body').append('div')
.attr('class', 'edgeTooltip')
.style('opacity', 0.0);
// Div for node details
var nodeInfo = d3.select('body').append('div')
.attr('class', 'nodeInfo')
.style('opacity', 0.0);
// Definition head of edges
var markerData = [
{'id': 'n', 'color': 'black'},
{'id': 'r', 'color': 'red'},
{'id': 'b', 'color': 'dodgerblue'}];
svg.append("defs").selectAll('marker').data(markerData).enter().append("marker")
.attr("id", function(d) { return 'edgeArrow_' + d.id;})
.attr("markerWidth", 4)
.attr("markerHeight", 4)
.attr("refX", 2)
.attr("refY", 2)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,0 L4,2 L0,4 Z")
.attr('fill', function(d) { return d.color;});
// Initialize graph
processDotGraph(dotGraph);
graph = frontEndGraph(dotGraph);
drawGraph();
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="d3viz/css/d3viz.css"/>
<link rel="stylesheet" href="d3viz/css/d3-context-menu.css"/>
<script type="text/javascript" src="d3viz/js/d3viz.js"></script>
<script type="text/javascript" src="d3viz/js/d3.v3.min.js"></script>
<script type="text/javascript" src="d3viz/js/dagre-d3.js"></script>
<script type="text/javascript" src="d3viz/js/graphlib-dot.js"></script>
<script type="text/javascript" src="d3viz/js/d3-context-menu.js"></script>
</head>
<body>
<div id='menu' class='menuBar'>
<input name="resetNodes"
type="button"
value="Reset nodes"
onclick="resetNodes()"/>
<input name="releaseNodes"
type="button"
value="Release nodes"
onclick="releaseNodes()"/>
</div>
<script type="text/javascript">
// Backend graph in DOT format
var dotGraph = graphlibDot.read("digraph G { graph [bb=\"0,0,636,340\"]; node [label=\"\N\"]; subgraph cluster_n1 { graph [bb=\"251,8,628,332\"]; subgraph cluster_n11 { graph [bb=\"467,96,620,324\"]; n111 [apply_op=Elemwise, fillcolor=\"#FFAABB\", height=0.5, label=Elemwise, node_type=apply, pos=\"544,210\", shape=ellipse, style=filled, type=colored, width=1.2888]; n114 [dtype=fscalar, fillcolor=dodgerblue, height=0.5, label=fscalar, node_type=output, pos=\"544,122\", shape=box, style=filled, width=0.75]; n111 -> n114 [label=fscalar, lp=\"563,166\", pos=\"e,544,140.08 544,191.6 544,179.75 544,163.82 544,150.29\"]; n112 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=x, node_type=input, pos=\"574,298\", shape=box, style=filled, width=0.75]; n112 -> n111 [label=\"0 fscalar\", lp=\"586,254\", pos=\"e,549.96,228.08 567.93,279.6 563.75,267.63 558.13,251.5 553.38,237.89\"]; n113 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=y, node_type=input, pos=\"502,298\", shape=box, style=filled, width=0.75]; n113 -> n111 [label=\"1 fscalar\", lp=\"529,254\", pos=\"e,521.37,226.05 499.83,279.65 499.3,269.38 499.99,256.39 505,246 507.26,241.31 510.46,236.96 514.07,233.04\"]; } n11 [apply_op=OpFromGraph, height=0.5, label=OpFromGraph, node_type=apply, pos=\"395,210\", shape=ellipse, subg=cluster_n11, subg_map_inputs=\"[[\'n12\', \'n112\'], [\'n13\', \'n113\']]\", subg_map_outputs=\"[[\'n114\', \'n15\']]\", width=1.7826]; n15 [apply_op=Elemwise, fillcolor=\"#FFAABB\", height=0.5, label=Elemwise, node_type=apply, pos=\"345,122\", shape=ellipse, style=filled, type=colored, width=1.2888]; n11 -> n15 [color=red, label=\"0 fscalar\", lp=\"399,166\", pos=\"e,354.69,139.66 385.12,192.01 377.88,179.56 367.94,162.45 359.76,148.39\"]; n12 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=x, node_type=input, pos=\"404,298\", shape=box, style=filled, width=0.75]; n12 -> n11 [label=\"0 fscalar\", lp=\"425,254\", pos=\"e,396.79,228.08 402.18,279.6 400.94,267.75 399.27,251.82 397.86,238.29\"]; n13 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=y, node_type=input, pos=\"332,298\", shape=box, style=filled, width=0.75]; n13 -> n11 [label=\"1 fscalar\", lp=\"371,254\", pos=\"e,367.62,226.31 334.21,279.71 336.22,269.21 339.99,255.96 347,246 350.46,241.08 354.83,236.59 359.53,232.59\"]; n17 [dtype=fscalar, fillcolor=dodgerblue, height=0.5, label=fscalar, node_type=output, pos=\"345,34\", shape=box, style=filled, width=0.75]; n15 -> n17 [label=fscalar, lp=\"364,78\", pos=\"e,345,52.084 345,103.6 345,91.746 345,75.817 345,62.292\"]; n16 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=z, node_type=input, pos=\"286,210\", shape=box, style=filled, width=0.75]; n16 -> n15 [label=\"1 fscalar\", lp=\"338,166\", pos=\"e,329.38,139.11 294.18,191.9 299.34,181.72 306.44,168.74 314,158 316.65,154.24 319.64,150.43 322.7,146.78\"]; } n1 [apply_op=OpFromGraph, height=0.5, label=OpFromGraph, node_type=apply, pos=\"136,210\", shape=ellipse, subg=cluster_n1, subg_map_inputs=\"[[\'n2\', \'n12\'], [\'n3\', \'n13\'], [\'n4\', \'n16\']]\", subg_map_outputs=\"[[\'n17\', \'n6\']]\", width=1.7826]; n6 [apply_op=Elemwise, fillcolor=\"#FFAABB\", height=0.5, label=Elemwise, node_type=apply, pos=\"46,122\", shape=ellipse, style=filled, type=colored, width=1.2888]; n1 -> n6 [color=red, label=\"0 fscalar\", lp=\"124,166\", pos=\"e,62.691,138.95 118.65,192.42 104.9,179.28 85.538,160.78 70.258,146.18\"]; n2 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=x, node_type=input, pos=\"123,298\", shape=box, style=filled, width=0.75]; n2 -> n1 [label=\"0 fscalar\", lp=\"149,254\", pos=\"e,129.59,228.22 122.55,279.88 122.56,269.92 123.06,257.17 125,246 125.46,243.33 126.08,240.57 126.78,237.84\"]; n3 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=y, node_type=input, pos=\"195,298\", shape=box, style=filled, width=0.75]; n3 -> n1 [label=\"1 fscalar\", lp=\"207,254\", pos=\"e,155.98,227.13 189.48,279.56 185.74,269.26 180.18,256.27 173,246 170.17,241.96 166.82,238.01 163.3,234.32\"]; n4 [dtype=fscalar, fillcolor=limegreen, height=0.5, label=z, node_type=input, pos=\"29,298\", shape=box, style=filled, width=0.75]; n4 -> n1 [label=\"2 fscalar\", lp=\"96,254\", pos=\"e,103.61,225.73 40.803,279.98 48.767,269.34 59.985,255.82 72,246 78.91,240.35 86.866,235.16 94.768,230.6\"]; n4 -> n6 [label=\"1 fscalar\", lp=\"39,210\", pos=\"e,36.126,139.61 23.104,279.76 16.772,258.84 8.4483,222.57 15,192 18.224,176.96 24.988,161.23 31.378,148.6\"]; n7 [dtype=fscalar, fillcolor=dodgerblue, height=0.5, label=fscalar, node_type=output, pos=\"46,34\", shape=box, style=filled, width=0.75]; n6 -> n7 [label=fscalar, lp=\"65,78\", pos=\"e,46,52.084 46,103.6 46,91.746 46,75.817 46,62.292\"];}");
// Frontend graph for visualization
var graph = {};
var forceLayout;
var isProfiled = false; // true if profiling information available
var useProfileColors = false;
var fixOnInit = true; // fix nodes on initialization
var maxProfilePer = 0;
var profileColors = ["#fff5f0","#fee0d2","#fcbba1","#fc9272","#fb6a4a","#ef3b2c","#cb181d","#a50f15"];
var pad = 10;
var isEditNode = false; // true if node is edited
var menuItems = [
{
title: 'Edit',
action: function(elm, d, i) { editNode(elm, d); }
},
{
title: 'Release',
action: function(elm, d, i) { releaseNode(d); }
}
];
// Create main panel
d3.select('body').select('svg').remove();
var svg = d3.select('body').append('svg')
.attr('width', '100%')
.attr('height', '95%');
var pane = svg.append('g');
// Zoom behaviour
var zoom = d3.behavior.zoom()
.scaleExtent([0.2, 8])
.on('zoom', function(d) {
var trans = d3.event.translate;
trans[0] += 300;
trans[1] += 100;
pane.attr('transform', 'translate(' + trans + ') scale(' + d3.event.scale + ')');
});
svg.call(zoom);
zoom.event(svg);
svg.on("dblclick.zoom", null);
// Edges
var edgeDiv = d3.select('body').append('div')
.attr('class', 'edgeTooltip')
.style('opacity', 0.0);
// Div for node details
var nodeInfo = d3.select('body').append('div')
.attr('class', 'nodeInfo')
.style('opacity', 0.0);
// Definition head of edges
var markerData = [
{'id': 'n', 'color': 'black'},
{'id': 'r', 'color': 'red'},
{'id': 'b', 'color': 'dodgerblue'}];
svg.append("defs").selectAll('marker').data(markerData).enter().append("marker")
.attr("id", function(d) { return 'edgeArrow_' + d.id;})
.attr("markerWidth", 4)
.attr("markerHeight", 4)
.attr("refX", 2)
.attr("refY", 2)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,0 L4,2 L0,4 Z")
.attr('fill', function(d) { return d.color;});
// Initialize graph
processDotGraph(dotGraph);
graph = frontEndGraph(dotGraph);
drawGraph();
</script>
</body>
</html>
......@@ -7,9 +7,11 @@ import theano.tensor as T
class Mlp(object):
def __init__(self, nfeatures=100, noutputs=10, nhiddens=50, rng=None):
if rng is None:
rng = 0
if isinstance(rng, int):
rng = np.random.RandomState(rng)
self.rng = rng
if self.rng is None:
self.rng = np.random.RandomState(0)
self.nfeatures = nfeatures
self.noutputs = noutputs
self.nhiddens = nhiddens
......
import numpy as np
import os.path as pt
from tempfile import mkstemp
import tempfile
import unittest
import filecmp
import sys
import theano as th
import theano.d3viz as d3v
......@@ -12,19 +14,25 @@ class TestD3Viz(unittest.TestCase):
def setUp(self):
self.rng = np.random.RandomState(0)
self.data_dir = pt.join('data', 'test_d3viz')
def check(self, f):
_, html_file = mkstemp('.html')
def check(self, f, reference=None, verbose=False):
tmp_dir = tempfile.mkdtemp()
html_file = pt.join(tmp_dir, 'index.html')
if verbose:
print(html_file)
d3v.d3viz(f, html_file)
assert pt.getsize(html_file) > 0
if reference:
assert filecmp.cmp(html_file, reference)
def test_mlp(self):
m = models.Mlp(rng=self.rng)
m = models.Mlp()
f = th.function(m.inputs, m.outputs)
self.check(f)
self.check(f, pt.join(self.data_dir, 'mlp', 'index.html'))
def test_mlp_profiled(self):
m = models.Mlp(rng=self.rng)
m = models.Mlp()
f = th.function(m.inputs, m.outputs, profile=True)
x_val = self.rng.normal(0, 1, (1000, m.nfeatures))
f(x_val)
......@@ -33,9 +41,9 @@ class TestD3Viz(unittest.TestCase):
def test_ofg(self):
m = models.Ofg()
f = th.function(m.inputs, m.outputs)
self.check(f)
self.check(f, pt.join(self.data_dir, 'ofg', 'index.html'))
def test_ofg_nested(self):
m = models.OfgNested()
f = th.function(m.inputs, m.outputs)
self.check(f)
self.check(f, pt.join(self.data_dir, 'ofg_nested', 'index.html'))
......@@ -14,7 +14,7 @@ class TestPyDotFormatter(unittest.TestCase):
def node_counts(self, graph):
node_types = [node.get_attributes()['node_type']
for node in graph.get_nodes()]
a, b = np.unique(node_types, return_counts=True)
a, b = np.unique(node_types, return_counts=True)
nc = dict(zip(a, b))
return nc
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论