summaryrefslogtreecommitdiff
path: root/code
diff options
context:
space:
mode:
Diffstat (limited to 'code')
-rw-r--r--code/weightvis.js87
1 files changed, 58 insertions, 29 deletions
diff --git a/code/weightvis.js b/code/weightvis.js
index 3512373..757fa2b 100644
--- a/code/weightvis.js
+++ b/code/weightvis.js
@@ -112,7 +112,7 @@ var Network = (function() {
}
};
- Network.prototype.updateWeights = function(weights, epochLayout) {
+ Network.prototype.updateWeights = function(weights, epochLayout) { // TODO negative weights!?!
var cnt = 0;
for (layer=0; layer<weights.length; layer++) {
for (layer2=0; layer2<weights[layer].length; layer2++) {
@@ -212,12 +212,14 @@ var Animator = (function() {
function Animator(layout, time, step) {
this.layout = layout;
this.step = step;
- this.batch = this.epoch = 0;
this.frameDuration = time / (this.layout.data.batches * this.layout.data.epochs / this.step);
}
- Animator.prototype.start = function(callback) {
+ Animator.prototype.start = function(bat, ep, callback, finishedCb) {
var self = this;
+ this.epoch = ep;
+ this.batch = bat;
+ this.finishedCb = finishedCb;
wrapper = function() {
callback(self.batch, self.epoch, self.frameDuration);
self.animate();
@@ -225,14 +227,18 @@ var Animator = (function() {
this.pid = setInterval(wrapper, this.frameDuration);
};
+ Animator.prototype.stop = function() {
+ if (this.finishedCb) this.finishedCb();
+ clearInterval(this.pid);
+ };
+
Animator.prototype.animate = function() {
this.epoch += this.step;
if (this.epoch >= this.layout.data.epochs) {
this.epoch = 0;
if (++this.batch>= this.layout.data.batches) {
this.batch = 0;
- clearInterval(this.pid); // suicide
- console.log("finished");
+ this.stop();
}
}
};
@@ -249,11 +255,16 @@ var Visualizer = (function() {
function Visualizer(svg) {
this.loader = new Loader();
this.svg = svg;
+ this.stepHooks = [];
+ this.stopHooks = [];
}
Visualizer.prototype.getSteps = function() {
return this.layout.data.batches * this.layout.data.epochs;
};
+ Visualizer.prototype.getDatashape = function() {
+ return this.layout.data;
+ };
Visualizer.prototype.load = function(url, callback) {
var self = this;
@@ -266,14 +277,30 @@ var Visualizer = (function() {
this.loader.load("data/log.json", wrapper);
};
- Visualizer.prototype.animate = function(animationTime, resolution) {
+ Visualizer.prototype.stopAnimation = function() {
+ this.animator.stop();
+ };
+
+ Visualizer.prototype.animate = function(animationTime, resolution, step) {
// animationTime in seconds per frame
// resolution in epochs per frame
var self = this;
- this.domLink = this.svg.selectAll(".link");
-
+ var batch = Math.floor(step / this.layout.data.epochs),
+ epoch = step % this.layout.data.epochs;
this.animator = new Animator(this.layout, animationTime * 1000, resolution);
- this.animator.start(function(batch, epoch){self.show(batch, epoch);});
+ this.animator.start(batch, epoch, function(cbatch, cepoch) {
+ self.show(cbatch, cepoch);
+ }, function() {
+ self.stopHooks.forEach(function(hook){ hook(); });
+ });
+ };
+
+ Visualizer.prototype.hookStepper = function(hook) {
+ this.stepHooks.push(hook);
+ };
+
+ Visualizer.prototype.hookStop = function(hook) {
+ this.stopHooks.push(hook);
};
Visualizer.prototype.showStep = function(step) {
@@ -283,6 +310,7 @@ var Visualizer = (function() {
};
Visualizer.prototype.show = function(batch, epoch, transitionDuration) {
+ var self = this;
this.network.updateWeights(this.data[batch][epoch], this.layout.layers[batch][epoch]);
if (transitionDuration) {
// 10% extra time per frame for the code execution
@@ -291,6 +319,25 @@ var Visualizer = (function() {
.duration(transitionDuration / 1.1);
}
this.domLink.style("stroke-width", function(d) { return d.weight * _weightScaler; });
+ this.stepHooks.forEach(function(hook){ hook(batch * self.layout.data.epochs + epoch); });
+ };
+
+ Visualizer.prototype.reposition = function() {
+ var width = parseInt(this.svg.style("width")) || 800,
+ height = parseInt(this.svg.style("height")) || 600;
+ var node = this.svg.selectAll(".node");
+
+ this.network.resize({"width": width, "height": height});
+
+ node
+ .attr("cx", function(d) { return d.x; })
+ .attr("cy", function(d) { return d.y; })
+ .attr("r", function(d) { return d.r; });
+ this.domLink
+ .attr("x1", function(d) { return d.source.x; })
+ .attr("y1", function(d) { return d.source.y; })
+ .attr("x2", function(d) { return d.target.x; })
+ .attr("y2", function(d) { return d.target.y; });
};
Visualizer.prototype._setup = function() {
@@ -304,25 +351,7 @@ var Visualizer = (function() {
this.network.resize({"width": width, "height": height});
this.network.updateWeights(this.data[0][0], this.layout.layers[0][0]);
- function reposition() {
- width = parseInt(self.svg.style("width")) || 800;
- height = parseInt(self.svg.style("height")) || 600;
-
- self.network.resize({"width": width, "height": height});
-
- node
- .attr("cx", function(d) { return d.x; })
- .attr("cy", function(d) { return d.y; })
- .attr("r", function(d) { return d.r; });
- link
- .attr("x1", function(d) { return d.source.x; })
- .attr("y1", function(d) { return d.source.y; })
- .attr("x2", function(d) { return d.target.x; })
- .attr("y2", function(d) { return d.target.y; });
- }
- window.addEventListener("resize", reposition, true);
-
- var link = this.svg.selectAll(".link")
+ this.domLink = this.svg.selectAll(".link")
.data(this.network.links)
.enter().append("line")
.attr("class", function(d) { return "link source-" + d.source.id + " target-" + d.target.id; })
@@ -381,7 +410,7 @@ var Visualizer = (function() {
}
});
- reposition();
+ this.reposition();
};
return Visualizer;