diff options
Diffstat (limited to 'code')
| -rw-r--r-- | code/bostonset.js | 100 | ||||
| -rw-r--r-- | code/weightvis.js | 30 | ||||
| -rw-r--r-- | code/weightviswrapper.js | 5 |
3 files changed, 133 insertions, 2 deletions
diff --git a/code/bostonset.js b/code/bostonset.js new file mode 100644 index 0000000..50b9d38 --- /dev/null +++ b/code/bostonset.js @@ -0,0 +1,100 @@ +var Bostonset = (function() { + var attrs = + ["crim", "zn", "indus", "chas", "nox", "rm", "age", "dis", "rad", "tax", "ptratio", "black", "lstat", "medv"]; + + function Bostonset() { + this.data = []; + // fixed constants exported from training data + this.dataScaler = new MinMaxScaler(); + this.dataScaler.setScales([[0.00632, 0.0, 0.46, 0.0, 0.385, 3.561, 2.9, 1.1296, 1.0, 187.0, 12.6, 0.32, 1.73], [88.9762, 100.0, 27.74, 1.0, 0.871, 8.78, 100.0, 12.1265, 24.0, 711.0, 22.0, 396.9, 37.97]]); + this.targetScaler = new MinMaxScaler(); + this.targetScaler.setScales([5.0, 50.0]); + } + + Bostonset.prototype.load = function(url) { + var self = this; + d3.csv(url).get(function(e, data) { + if (e) console.log(e); + data.forEach(function (el) { + var arr = []; + for (c=0; c<attrs.length; c++) { + arr.push(parseFloat(el[attrs[c]])); + } + self.data.push(arr); + }); + }); + }; + + Bostonset.prototype.length = function() { + return this.data.length; + }; + + Bostonset.prototype.rawInputs = function(row) { + return this.data[row].slice(0, -1); // leave out MEDV + }; + + Bostonset.prototype.inputs = function(row) { + return this.dataScaler.scale(this.rawInputs(row)); + }; + + Bostonset.prototype.asOutput = function(num) { + return this.targetScaler.unscale(num); + }; + + Bostonset.prototype.expectedOutput = function(row) { + return this.data[row][attrs.length-1]; + }; + + return Bostonset; +})(); + +// TODO abstract for generic shapes? +var MinMaxScaler = (function() { + function MinMaxScaler() { + } + + MinMaxScaler.prototype.fit = function(arr) { + this.setScales(d3.extent(arr)); + }; + + MinMaxScaler.prototype.setScales = function(fits) { + this.min = fits[0]; + this.max = fits[1]; + }; + + MinMaxScaler.prototype.scale = function(data) { + data = this._arrayDivide(this._arraySubtract(data, this.min), this._arraySubtract(this.max, this.min)); + return data; + }; + + MinMaxScaler.prototype.unscale = function(data) { + data = this._arrayAdd(this._arrayMultiply(data, this._arraySubtract(this.max, this.min)), this.min); + return data; + }; + + MinMaxScaler.prototype._arraySubtract = function(one, two) { + if (one.constructor !== Array) return one - two; + for (i=0; i<one.length; one[i]-=two[i++]); + return one; + }; + + MinMaxScaler.prototype._arrayAdd = function(one, two) { + if (one.constructor !== Array) return one + two; + for (i=0; i<one.length; one[i]+=two[i++]); + return one; + }; + + MinMaxScaler.prototype._arrayMultiply = function(one, two) { + if (one.constructor !== Array) return one * two; + for (i=0; i<one.length; one[i]*=two[i++]); + return one; + }; + + MinMaxScaler.prototype._arrayDivide = function(one, two) { + if (one.constructor !== Array) return one / two; + for (i=0; i<one.length; one[i]/=two[i++]); + return one; + }; + + return MinMaxScaler; +})(); diff --git a/code/weightvis.js b/code/weightvis.js index 64d398c..e3cec42 100644 --- a/code/weightvis.js +++ b/code/weightvis.js @@ -33,9 +33,9 @@ var nodeHighlightColor = accentColor ; - /* network construction */ +// TODO make multiple bias layers at positions > 0 possible? var Network = (function() { function Network(layout) { this.layout = layout; @@ -499,9 +499,35 @@ var NetVisualizer = (function() { me.attr("data-highlight", "true"); } }); - this.reposition(); }; + NetVisualizer.prototype.activate = function(inputs) { + // assumes the sigmoid function is used as activation + function activation(x) { return 0.5 + x / Math.sqrt(1 + 4 * x * x); } + var weights = this.data[this.layout.data.batches-1][this.layout.data.epochs-1]; + var lastLayerOut = 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; + } + for (layer=hasBias?1:0; layer<this.layout.net.layers-1; layer++) { + // manual vector matrix multiplication + var thisLayerOut = []; + for (tar=0; tar<this.layout.net[layer+1].size; tar++) { + thisLayerOut[tar] = 0; + for (src=0; src<this.layout.net[layer].size; src++) { + thisLayerOut[tar] += weights[layer][src][tar] * lastLayerOut[src]; + } + thisLayerOut[tar] = activation(thisLayerOut[tar]); + } + lastLayerOut = thisLayerOut; + } + return lastLayerOut; + }; + return NetVisualizer; })(); diff --git a/code/weightviswrapper.js b/code/weightviswrapper.js index c1586d1..1b3a91a 100644 --- a/code/weightviswrapper.js +++ b/code/weightviswrapper.js @@ -169,6 +169,11 @@ var WeightVisWrapper = (function() { this.button.select(".pause").style("display", ""); }; + WeightVisWrapper.prototype.activate = function(inputs) { + // TODO visualize this :) + return this.netVisualizer.activate(inputs); + }; + return WeightVisWrapper; })(); |
