diff options
Diffstat (limited to 'code')
| -rw-r--r-- | code/weightvis.js | 11 | ||||
| -rw-r--r-- | code/weightviswrapper.js | 45 |
2 files changed, 45 insertions, 11 deletions
diff --git a/code/weightvis.js b/code/weightvis.js index f61ec39..2ef33e1 100644 --- a/code/weightvis.js +++ b/code/weightvis.js @@ -30,7 +30,9 @@ var linkHighlightColor = pDeepPurple[5], linkHighlightColorAlt = pPink[5], nodeColor = pDeepPurple[4], - nodeHighlightColor = accentColor + nodeColorAlt = pPink[4], + nodeHighlightColor = accentColor, + nodeHighlightColorAlt = pPinkA[3] ; /* network construction */ @@ -63,6 +65,7 @@ var Network = (function() { this.nodes.push({ id: layer.toString() + "_" + node.toString(), layer: layer, + node: node, fixed: true }); } @@ -507,12 +510,14 @@ var NetVisualizer = (function() { function activation(x) { return 1 / (1 + Math.exp(-x)); } var weights = this.data[this.layout.data.batches-1][this.layout.data.epochs-1]; var lastLayerOut = inputs; + var activations = [inputs]; var hasBias = false; if (this.layout.net[0].isBias) { for (bias=0; bias<inputs.length; bias++) { lastLayerOut[bias] += weights[0][0][bias]; } hasBias = true; + activations.push(lastLayerOut); } for (layer=hasBias?1:0; layer<this.layout.net.layers-1; layer++) { // manual vector matrix multiplication @@ -525,9 +530,9 @@ var NetVisualizer = (function() { thisLayerOut[tar] = activation(thisLayerOut[tar]); } lastLayerOut = thisLayerOut; - //console.log("layer out", layer, lastLayerOut); + activations.push(lastLayerOut); } - return lastLayerOut; + return activations; }; return NetVisualizer; diff --git a/code/weightviswrapper.js b/code/weightviswrapper.js index 1b3a91a..22bbe63 100644 --- a/code/weightviswrapper.js +++ b/code/weightviswrapper.js @@ -7,6 +7,7 @@ var WeightVisWrapper = (function() { this.container = d3.select("body").append("div").remove(); this.svgContainer = this.container.append("div"); this.controlContainer = this.container.append("div"); + this.controlBarAttached = false; this.svg = this.svgContainer.append("svg"); this.netVisualizer = new NetVisualizer(this.svg); this.resizeHooks = []; @@ -62,7 +63,7 @@ var WeightVisWrapper = (function() { WeightVisWrapper.prototype.mock = function(shape, callback) { var self = this; - this.controlContainer.style("display", "none"); + this.hideControlBar; this.netVisualizer.mock(shape, function() { self.loaded(callback); }); }; @@ -94,8 +95,8 @@ var WeightVisWrapper = (function() { self.slider.node().MaterialSlider.change(0); // wrap at right end } }); - this.slider.attr("max", this.netVisualizer.getSteps() - 1); - this.slider.node().addEventListener("input", function() { self.netVisualizer.showStep(self.value); }); + this.slider.attr("max", this.steps()-1); + this.slider.node().addEventListener("input", function() { self.jumpTo(self.value); }); this.button.node().addEventListener("click", function toggle() { if (self.button.attr("data-pressed") != "true") { var step = self.slider.node().value; @@ -139,15 +140,22 @@ var WeightVisWrapper = (function() { el.appendChild(this.spinner.node().cloneNode(true)); }; - WeightVisWrapper.prototype.openIn = function(el) { + WeightVisWrapper.prototype.openIn = function(el, withControlbar) { d3.select(el).select(".spinner").remove(); el.appendChild(this.svgContainer.node()); - el.appendChild(this.controlContainer.node()); + if (withControlbar) { + el.appendChild(this.controlContainer.node()); + this.controlBarAttached = true; + } else { + this.controlBarAttached = false; + } this.reposition(); }; WeightVisWrapper.prototype.remove = function(el) { - this.svgContainer.node().parentNode.removeChild(this.controlContainer.node()); + if (this.controlBarAttached) { + this.svgContainer.node().parentNode.removeChild(this.controlContainer.node()); + } this.svgContainer.node().parentNode.appendChild(this.spinner.node().cloneNode(true)); this.svgContainer.node().parentNode.removeChild(this.svgContainer.node()); this.netVisualizer.stopAnimation(); @@ -169,9 +177,30 @@ var WeightVisWrapper = (function() { this.button.select(".pause").style("display", ""); }; + WeightVisWrapper.prototype.jumpTo = function(step) { + this.netVisualizer.showStep(step); + }; + + WeightVisWrapper.prototype.steps = function() { + return this.netVisualizer.getSteps(); + }; + + WeightVisWrapper.prototype.calculate = function(inputs) { + // returns the final layer's outputs + return this.netVisualizer.activate(inputs).pop(); + }; + WeightVisWrapper.prototype.activate = function(inputs) { - // TODO visualize this :) - return this.netVisualizer.activate(inputs); + // TODO this should be in weightvis.js + // …this is rather a hack, I got lazy… + var activations = this.netVisualizer.activate(inputs); + var flatActivations = [].concat.apply([], activations); + var max = d3.max(flatActivations, Math.abs), + min = d3.min(flatActivations, Math.abs); + var node = this.svg.selectAll(".node"); + node + .attr("r", function(d) { return 2 * d.r * (Math.abs(activations[d.layer][d.node]) - min) / (max-min); }) + .style("fill", function(d) { return activations[d.layer][d.node]>0?nodeColor:nodeColorAlt; }); }; return WeightVisWrapper; |
