diff --git a/browser.js b/browser.js index 7678e7c03..943e891ed 100644 --- a/browser.js +++ b/browser.js @@ -930,7 +930,7 @@ var NeuralNetwork = function () { Object.assign(this, this.constructor.defaults, options); this.hiddenSizes = options.hiddenLayers; this.trainOpts = {}; - this.updateTrainingOptions(Object.assign({}, this.constructor.trainDefaults, options)); + this._updateTrainingOptions(Object.assign({}, this.constructor.trainDefaults, options)); this.sizes = null; this.outputLayer = null; @@ -1183,38 +1183,15 @@ var NeuralNetwork = function () { */ }, { - key: 'updateTrainingOptions', - value: function updateTrainingOptions(opts) { - if (opts.iterations) { - this.trainOpts.iterations = opts.iterations; - } - if (opts.errorThresh) { - this.trainOpts.errorThresh = opts.errorThresh; - } - if (opts.log) { - this._setLogMethod(opts.log); - } - if (opts.logPeriod) { - this.trainOpts.logPeriod = opts.logPeriod; - } - if (opts.learningRate) { - this.trainOpts.learningRate = opts.learningRate; - } - if (opts.momentum) { - this.trainOpts.momentum = opts.momentum; - } - if (opts.callback) { - this.trainOpts.callback = opts.callback; - } - if (opts.callbackPeriod) { - this.trainOpts.callbackPeriod = opts.callbackPeriod; - } - if (opts.timeout) { - this.trainOpts.timeout = opts.timeout; - } - if (opts.activation) { - this.activation = opts.activation; - } + key: '_updateTrainingOptions', + value: function _updateTrainingOptions(opts) { + var _this2 = this; + + Object.keys(NeuralNetwork.trainDefaults).forEach(function (opt) { + return _this2.trainOpts[opt] = opts[opt] || _this2.trainOpts[opt]; + }); + this._setLogMethod(opts.log || this.trainOpts.log); + this.activation = opts.activation || this.activation; } /** @@ -1226,35 +1203,13 @@ var NeuralNetwork = function () { }, { key: '_getTrainOptsJSON', value: function _getTrainOptsJSON() { - var results = {}; - if (this.trainOpts.iterations) { - results.iterations = this.trainOpts.iterations; - } - if (this.trainOpts.errorThresh) { - results.errorThresh = this.trainOpts.errorThresh; - } - if (this.trainOpts.logPeriod) { - results.logPeriod = this.trainOpts.logPeriod; - } - if (this.trainOpts.learningRate) { - results.learningRate = this.trainOpts.learningRate; - } - if (this.trainOpts.momentum) { - results.momentum = this.trainOpts.momentum; - } - if (this.trainOpts.callback) { - results.callback = this.trainOpts.callback; - } - if (this.trainOpts.callbackPeriod) { - results.callbackPeriod = this.trainOpts.callbackPeriod; - } - if (this.trainOpts.timeout) { - results.timeout = this.trainOpts.timeout; - } - if (this.trainOpts.log) { - results.log = true; - } - return results; + var _this3 = this; + + return Object.keys(NeuralNetwork.trainDefaults).reduce(function (opts, opt) { + if (_this3.trainOpts[opt]) opts[opt] = _this3.trainOpts[opt]; + if (opt === 'log') opts.log = typeof opts.log === 'function'; + return opts; + }, {}); } /** @@ -1387,7 +1342,7 @@ var NeuralNetwork = function () { }, { key: 'trainAsync', value: function trainAsync(data) { - var _this2 = this; + var _this4 = this; var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -1403,10 +1358,10 @@ var NeuralNetwork = function () { return new Promise(function (resolve, reject) { try { - var thawedTrain = new _thaw2.default(new Array(_this2.trainOpts.iterations), { + var thawedTrain = new _thaw2.default(new Array(_this4.trainOpts.iterations), { delay: true, each: function each() { - return _this2._trainingTick(data, status, endTime) || thawedTrain.stop(); + return _this4._trainingTick(data, status, endTime) || thawedTrain.stop(); }, done: function done() { return resolve(status); @@ -1584,7 +1539,7 @@ var NeuralNetwork = function () { }, { key: '_formatData', value: function _formatData(data) { - var _this3 = this; + var _this5 = this; if (!Array.isArray(data)) { // turn stream datum into array @@ -1601,7 +1556,7 @@ var NeuralNetwork = function () { })); } data = data.map(function (datum) { - var array = _lookup2.default.toArray(_this3.inputLookup, datum.input); + var array = _lookup2.default.toArray(_this5.inputLookup, datum.input); return Object.assign({}, datum, { input: array }); }, this); } @@ -1613,7 +1568,7 @@ var NeuralNetwork = function () { })); } data = data.map(function (datum) { - var array = _lookup2.default.toArray(_this3.outputLookup, datum.output); + var array = _lookup2.default.toArray(_this5.outputLookup, datum.output); return Object.assign({}, datum, { output: array }); }, this); } @@ -1634,7 +1589,7 @@ var NeuralNetwork = function () { }, { key: 'test', value: function test(data) { - var _this4 = this; + var _this6 = this; data = this._formatData(data); @@ -1653,13 +1608,13 @@ var NeuralNetwork = function () { var sum = 0; var _loop = function _loop(i) { - var output = _this4.runInput(data[i].input); + var output = _this6.runInput(data[i].input); var target = data[i].output; var actual = void 0, expected = void 0; if (isBinary) { - actual = output[0] > _this4.binaryThresh ? 1 : 0; + actual = output[0] > _this6.binaryThresh ? 1 : 0; expected = target[0]; } else { actual = output.indexOf((0, _max2.default)(output)); @@ -1828,7 +1783,7 @@ var NeuralNetwork = function () { } } } - this.updateTrainingOptions(json.trainOpts); + this._updateTrainingOptions(json.trainOpts); this.setActivation(); return this; } @@ -1906,7 +1861,7 @@ var NeuralNetwork = function () { }, { key: 'isRunnable', get: function get() { - var _this5 = this; + var _this7 = this; if (!this.runInput) { console.error('Activation function has not been initialized, did you run train()?'); @@ -1914,7 +1869,7 @@ var NeuralNetwork = function () { } var checkFns = ['sizes', 'outputLayer', 'biases', 'weights', 'outputs', 'deltas', 'changes', 'errors'].filter(function (c) { - return _this5[c] === null; + return _this7[c] === null; }); if (checkFns.length > 0) { diff --git a/browser.min.js b/browser.min.js index 152aa03d9..1c09f49ae 100644 --- a/browser.min.js +++ b/browser.min.js @@ -116,7 +116,7 @@ "use strict";function _interopRequireDefault(t){return t&&t.__esModule?t:{default:t}}function _toConsumableArray(t){if(Array.isArray(t)){for(var e=0,r=Array(t.length);e0?t:0}function calcDeltasLeakyRelu(t,e){return e>0?t:.01*t}function calcDeltasTanh(t,e){return(1-e*e)*t}function calcError(t,e){for(var r=0,a=0;a0&&void 0!==arguments[0]?arguments[0]:{};_classCallCheck(this,e);var r=_possibleConstructorReturn(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t));return r.forwardPropagate=[],r.backwardPropagate=[],r.changesPropagate=[],r.biasesPropagate=[],r.gpu=new _gpu2.default({mode:t.mode}),r}return _inherits(e,t),_createClass(e,[{key:"initialize",value:function(t){_get(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"initialize",this).call(this,t),this.buildRunInput(),this.buildCalculateDeltas(),this.buildGetChanges(),this.buildChangeBiases(),this.buildGetMSE()}},{key:"setActivation",value:function(){}},{key:"trainPattern",value:function(t,e,r){return r=r||this.learningRate,this.runInput(t),this.calculateDeltas(e),this.getChanges(r),this.changeBiases(r),this.getMSE(this.errors[this.outputLayer])[0]}},{key:"buildRunInput",value:function(){var t=null;switch(this.activation){case"sigmoid":t=weightedSumSigmoid;break;case"relu":t=weightedSumRelu;break;case"leaky-relu":t=weightedSumLeakyRelu;break;case"tanh":t=weightedSumTanh;break;default:throw new Error("unknown activation "+this.activation)}for(var e=1;e<=this.outputLayer;e++)this.forwardPropagate[e]=this.gpu.createKernel(t,{output:[this.sizes[e]],outputToTexture:!0,constants:{size:this.sizes[e-1]}})}},{key:"runInput",value:function(t){var e=void 0;this.outputs[0]=t;for(var r=1;r<=this.outputLayer;r++)this.outputs[r]=this.forwardPropagate[r](this.weights[r],this.biases[r],t),e=t=this.outputs[r];return e}},{key:"buildCalculateDeltas",value:function(){var t=null;switch(this.activation){case"sigmoid":t=calcDeltasSigmoid;break;case"relu":t=calcDeltasRelu;break;case"leaky-relu":t=calcDeltasLeakyRelu;break;case"tanh":t=calcDeltasTanh;break;default:throw new Error("unknown activation "+this.activation)}for(var e=this.outputLayer;e>0;e--)e===this.outputLayer?this.backwardPropagate[e]=this.gpu.createKernelMap({error:_gpu2.default.alias("calcErrorOutput",calcErrorOutput),deltas:_gpu2.default.alias("calcDeltas",t)},function(e,r){var a=e[this.thread.x];return t(calcErrorOutput(a,r),a)},{output:[this.sizes[e]],outputToTexture:!0}):this.backwardPropagate[e]=this.gpu.createKernelMap({error:_gpu2.default.alias("calcError",calcError),deltas:_gpu2.default.alias("calcDeltas",t)},function(e,r,a){var u=r[this.thread.x];return t(calcError(e,a),u)},{output:[this.sizes[e]],outputToTexture:!0,constants:{size:this.deltas[e+1].length}})}},{key:"calculateDeltas",value:function(t,e){for(var r=this.outputLayer;r>0;r--){var a=void 0;a=r===this.outputLayer?this.backwardPropagate[r](this.outputs[r],t):this.backwardPropagate[r](this.weights[r+1],this.outputs[r],this.deltas[r+1]),this.deltas[r]=a.deltas,this.errors[r]=a.error}}},{key:"buildGetChanges",value:function(){for(var t=1;t<=this.outputLayer;t++)this.changesPropagate[t]=this.gpu.createKernelMap({weights:_gpu2.default.alias("addWeights",addWeights),changes:_gpu2.default.alias("calcChanges",calcChanges)},function(t,e,r,a,u,i){return addWeights(calcChanges(a,e,t,u,i),r)},{output:[this.sizes[t-1],this.sizes[t]],outputToTexture:!0,constants:{size:this.outputs[t-1].length}})}},{key:"getChanges",value:function(t){for(var e=1;e<=this.outputLayer;e++){var r=this.changesPropagate[e](this.outputs[e-1],this.deltas[e],this.weights[e],this.changes[e],t,this.momentum);this.changes[e]=r.changes,this.weights[e]=r.weights}}},{key:"buildChangeBiases",value:function(){for(var t=1;t<=this.outputLayer;t++)this.biasesPropagate[t]=this.gpu.createKernel(addBiases,{output:[this.sizes[t]],outputToTexture:!0})}},{key:"changeBiases",value:function(t){for(var e=1;e<=this.outputLayer;e++)this.biases[e]=this.biasesPropagate[e](this.biases[e],this.deltas[e],t)}},{key:"buildGetMSE",value:function(){this.getMSE=this.gpu.createKernel(mse,{output:[1],constants:{size:this.outputLayer}})}},{key:"run",value:function(t){if(!this.isRunnable)return null;this.inputLookup&&(t=_lookup2.default.toArray(this.inputLookup,t));var e=[].concat(_toConsumableArray(this.runInput(t).toArray(this.gpu)));return this.outputLookup&&(e=_lookup2.default.toHash(this.outputLookup,e)),e}},{key:"formatData",value:function(t){var e=this;if(!Array.isArray(t)){var r=[];r.push(t),t=r}var a=t[0].input;return Array.isArray(a)||a instanceof Float32Array||(this.inputLookup||(this.inputLookup=_lookup2.default.buildLookup(t.map(function(t){return t.input}))),t=t.map(function(t){var r=_lookup2.default.toArray(e.inputLookup,t.input);return Object.assign({},t,{input:r})},this)),Array.isArray(t[0].output)||(this.outputLookup||(this.outputLookup=_lookup2.default.buildLookup(t.map(function(t){return t.output}))),t=t.map(function(t){var r=_lookup2.default.toArray(e.outputLookup,t.output);return Object.assign({},t,{output:r})},this)),t}},{key:"toFunction",value:function(){throw new Error("not implemented on NeuralNetworkGPU")}}]),e}(_neuralNetwork2.default);exports.default=NeuralNetworkGPU; },{"./lookup":3,"./neural-network":5,"gpu.js":75}],5:[function(require,module,exports){ -"use strict";function _interopRequireDefault(t){return t&&t.__esModule?t:{default:t}}function _toConsumableArray(t){if(Array.isArray(t)){for(var i=0,e=Array(t.length);i0&&void 0!==arguments[0]?arguments[0]:{};_classCallCheck(this,t),Object.assign(this,this.constructor.defaults,i),this.hiddenSizes=i.hiddenLayers,this.trainOpts={},this.updateTrainingOptions(Object.assign({},this.constructor.trainDefaults,i)),this.sizes=null,this.outputLayer=null,this.biases=null,this.weights=null,this.outputs=null,this.deltas=null,this.changes=null,this.errors=null,this.constructor.prototype.hasOwnProperty("runInput")||(this.runInput=null),this.constructor.prototype.hasOwnProperty("calculateDeltas")||(this.calculateDeltas=null)}return _createClass(t,null,[{key:"trainDefaults",get:function(){return{iterations:2e4,errorThresh:.005,log:!1,logPeriod:10,learningRate:.3,momentum:.1,callback:null,callbackPeriod:10,timeout:1/0}}},{key:"defaults",get:function(){return{binaryThresh:.5,hiddenLayers:[3],activation:"sigmoid"}}}]),_createClass(t,[{key:"_initialize",value:function(){if(!this.sizes)throw new Error("Sizes must be set before initializing");this.outputLayer=this.sizes.length-1,this.biases=[],this.weights=[],this.outputs=[],this.deltas=[],this.changes=[],this.errors=[];for(var t=0;t<=this.outputLayer;t++){var i=this.sizes[t];if(this.deltas[t]=(0,_zeros2.default)(i),this.errors[t]=(0,_zeros2.default)(i),this.outputs[t]=(0,_zeros2.default)(i),t>0){this.biases[t]=(0,_randos2.default)(i),this.weights[t]=new Array(i),this.changes[t]=new Array(i);for(var e=0;e=this.trainOpts.iterations||i.error<=this.trainOpts.errorThresh||Date.now()>=e)&&(i.iterations++,i.error=this._calculateTrainingError(t),this.trainOpts.log&&i.iterations%this.trainOpts.logPeriod==0&&this.trainOpts.log("iterations: "+i.iterations+", training error: "+i.error),this.trainOpts.callback&&i.iterations%this.trainOpts.callbackPeriod==0&&this.trainOpts.callback(Object.assign(i)),!0)}},{key:"_prepTraining",value:function(t,i){this.updateTrainingOptions(i),t=this._formatData(t);var e=Date.now()+this.trainOpts.timeout,r={error:1,iterations:0};return this._verifyIsInitialized(t),{data:t,status:r,endTime:e}}},{key:"train",value:function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=void 0,r=void 0,s=this._prepTraining(t,i);for(t=s.data,e=s.status,r=s.endTime;this._trainingTick(t,e,r););return e}},{key:"trainAsync",value:function(t){var i=this,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=void 0,s=void 0,a=this._prepTraining(t,e);return t=a.data,r=a.status,s=a.endTime,new Promise(function(e,a){try{var n=new _thaw2.default(new Array(i.trainOpts.iterations),{delay:!0,each:function(){return i._trainingTick(t,r,s)||n.stop()},done:function(){return e(r)}});n.tick()}catch(t){a({trainError:t,status:r})}})}},{key:"_trainPattern",value:function(t,i){return this.runInput(t),this.calculateDeltas(i),this._adjustWeights(),(0,_mse2.default)(this.errors[this.outputLayer])}},{key:"_calculateDeltasSigmoid",value:function(t){for(var i=this.outputLayer;i>=0;i--)for(var e=0;e=0;i--)for(var e=0;e0?s:0}}},{key:"_calculateDeltasLeakyRelu",value:function(t){for(var i=this.outputLayer;i>=0;i--)for(var e=0;e0?s:.01*s}}},{key:"_calculateDeltasTanh",value:function(t){for(var i=this.outputLayer;i>=0;i--)for(var e=0;ei.binaryThresh?1:0,f=p[0]):(c=l.indexOf((0,_max2.default)(l)),f=p.indexOf((0,_max2.default)(p))),c!==f){var v=t[h];Object.assign(v,{actual:c,expected:f}),u.push(v)}e&&(0===c&&0===f?n++:1===c&&1===f?a++:0===c&&1===f?s++:1===c&&0===f&&r++);var g=l.map(function(t,i){return p[i]-t});o+=(0,_mse2.default)(g)}(h);var l=o/t.length,p={error:l,misclasses:u};return e&&Object.assign(p,{trueNeg:n,truePos:a,falseNeg:s,falsePos:r,total:t.length,precision:a/(a+r),recall:a/(a+s),accuracy:(n+a)/t.length}),p}},{key:"toJSON",value:function(){for(var t=[],i=0;i<=this.outputLayer;i++){t[i]={};var e=void 0;e=0===i&&this.inputLookup?Object.keys(this.inputLookup):i===this.outputLayer&&this.outputLookup?Object.keys(this.outputLookup):(0,_range2.default)(0,this.sizes[i]);for(var r=0;r0){t[i][s].bias=this.biases[i][r],t[i][s].weights={};for(var a in t[i-1]){var n=a;1===i&&this.inputLookup&&(n=this.inputLookup[a]),t[i][s].weights[a]=this.weights[i][r][n]}}}}return{sizes:this.sizes,layers:t,outputLookup:!!this.outputLookup,inputLookup:!!this.inputLookup,activation:this.activation,trainOpts:this._getTrainOptsJSON()}}},{key:"fromJSON",value:function(t){this.sizes=t.sizes,this._initialize();for(var i=0;i<=this.outputLayer;i++){var e=t.layers[i];if(0!==i||e[0]&&!t.inputLookup?i!==this.outputLayer||e[0]&&!t.outputLookup||(this.outputLookup=_lookup2.default.lookupFromHash(e)):this.inputLookup=_lookup2.default.lookupFromHash(e),i>0){var r=Object.keys(e);this.sizes[i]=r.length;for(var s in r){var a=r[s];this.biases[i][s]=e[a].bias,this.weights[i][s]=(0,_toArray2.default)(e[a].weights)}}}return this.updateTrainingOptions(t.trainOpts),this.setActivation(),this}},{key:"toFunction",value:function(){function t(e,r,s){if(0===r)return"string"==typeof s?"input['"+s+"']":"input["+s+"]";var a=e[r],n=a[s],u=[n.bias];for(var o in n.weights)n.weights[o]<0?u.push(n.weights[o]+"*("+t(e,r-1,o)+")"):u.push("+"+n.weights[o]+"*("+t(e,r-1,o)+")");switch(i){case"sigmoid":return"1/(1+1/Math.exp("+u.join("")+"))";case"relu":return"var sum = "+u.join("")+";(sum < 0 ? 0 : sum);";case"leaky-relu":return"var sum = "+u.join("")+";(sum < 0 ? 0 : 0.01 * sum);";case"tanh":return"Math.tanh("+u.join("")+");";default:throw new Error("unknown activation type "+i)}}var i=this.activation,e=this.toJSON().layers,r=[],s=void 0;for(var a in e[e.length-1])r.push(t(e,e.length-1,a));return s=this.outputLookup?"{"+Object.keys(this.outputLookup).map(function(t,i){return"'"+t+"':"+r[i]})+"}":"["+r.join(",")+"]",new Function("input","return "+s)}},{key:"createTrainStream",value:function(t){return t=t||{},t.neuralNetwork=this,this.setActivation(),this.trainStream=new _trainStream2.default(t),this.trainStream}},{key:"isRunnable",get:function(){var t=this;if(!this.runInput)return console.error("Activation function has not been initialized, did you run train()?"),!1;var i=["sizes","outputLayer","biases","weights","outputs","deltas","changes","errors"].filter(function(i){return null===t[i]});return!(i.length>0)||(console.error("Some settings have not been initialized correctly, did you run train()? Found issues with: "+i.join(", ")),!1)}}]),t}();exports.default=NeuralNetwork; +"use strict";function _interopRequireDefault(t){return t&&t.__esModule?t:{default:t}}function _toConsumableArray(t){if(Array.isArray(t)){for(var i=0,e=Array(t.length);i0&&void 0!==arguments[0]?arguments[0]:{};_classCallCheck(this,t),Object.assign(this,this.constructor.defaults,i),this.hiddenSizes=i.hiddenLayers,this.trainOpts={},this._updateTrainingOptions(Object.assign({},this.constructor.trainDefaults,i)),this.sizes=null,this.outputLayer=null,this.biases=null,this.weights=null,this.outputs=null,this.deltas=null,this.changes=null,this.errors=null,this.constructor.prototype.hasOwnProperty("runInput")||(this.runInput=null),this.constructor.prototype.hasOwnProperty("calculateDeltas")||(this.calculateDeltas=null)}return _createClass(t,null,[{key:"trainDefaults",get:function(){return{iterations:2e4,errorThresh:.005,log:!1,logPeriod:10,learningRate:.3,momentum:.1,callback:null,callbackPeriod:10,timeout:1/0}}},{key:"defaults",get:function(){return{binaryThresh:.5,hiddenLayers:[3],activation:"sigmoid"}}}]),_createClass(t,[{key:"_initialize",value:function(){if(!this.sizes)throw new Error("Sizes must be set before initializing");this.outputLayer=this.sizes.length-1,this.biases=[],this.weights=[],this.outputs=[],this.deltas=[],this.changes=[],this.errors=[];for(var t=0;t<=this.outputLayer;t++){var i=this.sizes[t];if(this.deltas[t]=(0,_zeros2.default)(i),this.errors[t]=(0,_zeros2.default)(i),this.outputs[t]=(0,_zeros2.default)(i),t>0){this.biases[t]=(0,_randos2.default)(i),this.weights[t]=new Array(i),this.changes[t]=new Array(i);for(var e=0;e=this.trainOpts.iterations||i.error<=this.trainOpts.errorThresh||Date.now()>=e)&&(i.iterations++,i.error=this._calculateTrainingError(t),this.trainOpts.log&&i.iterations%this.trainOpts.logPeriod==0&&this.trainOpts.log("iterations: "+i.iterations+", training error: "+i.error),this.trainOpts.callback&&i.iterations%this.trainOpts.callbackPeriod==0&&this.trainOpts.callback(Object.assign(i)),!0)}},{key:"_prepTraining",value:function(t,i){this.updateTrainingOptions(i),t=this._formatData(t);var e=Date.now()+this.trainOpts.timeout,s={error:1,iterations:0};return this._verifyIsInitialized(t),{data:t,status:s,endTime:e}}},{key:"train",value:function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=void 0,s=void 0,r=this._prepTraining(t,i);for(t=r.data,e=r.status,s=r.endTime;this._trainingTick(t,e,s););return e}},{key:"trainAsync",value:function(t){var i=this,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s=void 0,r=void 0,a=this._prepTraining(t,e);return t=a.data,s=a.status,r=a.endTime,new Promise(function(e,a){try{var u=new _thaw2.default(new Array(i.trainOpts.iterations),{delay:!0,each:function(){return i._trainingTick(t,s,r)||u.stop()},done:function(){return e(s)}});u.tick()}catch(t){a({trainError:t,status:s})}})}},{key:"_trainPattern",value:function(t,i){return this.runInput(t),this.calculateDeltas(i),this._adjustWeights(),(0,_mse2.default)(this.errors[this.outputLayer])}},{key:"_calculateDeltasSigmoid",value:function(t){for(var i=this.outputLayer;i>=0;i--)for(var e=0;e=0;i--)for(var e=0;e0?r:0}}},{key:"_calculateDeltasLeakyRelu",value:function(t){for(var i=this.outputLayer;i>=0;i--)for(var e=0;e0?r:.01*r}}},{key:"_calculateDeltasTanh",value:function(t){for(var i=this.outputLayer;i>=0;i--)for(var e=0;ei.binaryThresh?1:0,f=p[0]):(c=l.indexOf((0,_max2.default)(l)),f=p.indexOf((0,_max2.default)(p))),c!==f){var v=t[h];Object.assign(v,{actual:c,expected:f}),n.push(v)}e&&(0===c&&0===f?u++:1===c&&1===f?a++:0===c&&1===f?r++:1===c&&0===f&&s++);var g=l.map(function(t,i){return p[i]-t});o+=(0,_mse2.default)(g)}(h);var l=o/t.length,p={error:l,misclasses:n};return e&&Object.assign(p,{trueNeg:u,truePos:a,falseNeg:r,falsePos:s,total:t.length,precision:a/(a+s),recall:a/(a+r),accuracy:(u+a)/t.length}),p}},{key:"toJSON",value:function(){for(var t=[],i=0;i<=this.outputLayer;i++){t[i]={};var e=void 0;e=0===i&&this.inputLookup?Object.keys(this.inputLookup):i===this.outputLayer&&this.outputLookup?Object.keys(this.outputLookup):(0,_range2.default)(0,this.sizes[i]);for(var s=0;s0){t[i][r].bias=this.biases[i][s],t[i][r].weights={};for(var a in t[i-1]){var u=a;1===i&&this.inputLookup&&(u=this.inputLookup[a]),t[i][r].weights[a]=this.weights[i][s][u]}}}}return{sizes:this.sizes,layers:t,outputLookup:!!this.outputLookup,inputLookup:!!this.inputLookup,activation:this.activation,trainOpts:this._getTrainOptsJSON()}}},{key:"fromJSON",value:function(t){this.sizes=t.sizes,this._initialize();for(var i=0;i<=this.outputLayer;i++){var e=t.layers[i];if(0!==i||e[0]&&!t.inputLookup?i!==this.outputLayer||e[0]&&!t.outputLookup||(this.outputLookup=_lookup2.default.lookupFromHash(e)):this.inputLookup=_lookup2.default.lookupFromHash(e),i>0){var s=Object.keys(e);this.sizes[i]=s.length;for(var r in s){var a=s[r];this.biases[i][r]=e[a].bias,this.weights[i][r]=(0,_toArray2.default)(e[a].weights)}}}return this._updateTrainingOptions(t.trainOpts),this.setActivation(),this}},{key:"toFunction",value:function(){function t(e,s,r){if(0===s)return"string"==typeof r?"input['"+r+"']":"input["+r+"]";var a=e[s],u=a[r],n=[u.bias];for(var o in u.weights)u.weights[o]<0?n.push(u.weights[o]+"*("+t(e,s-1,o)+")"):n.push("+"+u.weights[o]+"*("+t(e,s-1,o)+")");switch(i){case"sigmoid":return"1/(1+1/Math.exp("+n.join("")+"))";case"relu":return"var sum = "+n.join("")+";(sum < 0 ? 0 : sum);";case"leaky-relu":return"var sum = "+n.join("")+";(sum < 0 ? 0 : 0.01 * sum);";case"tanh":return"Math.tanh("+n.join("")+");";default:throw new Error("unknown activation type "+i)}}var i=this.activation,e=this.toJSON().layers,s=[],r=void 0;for(var a in e[e.length-1])s.push(t(e,e.length-1,a));return r=this.outputLookup?"{"+Object.keys(this.outputLookup).map(function(t,i){return"'"+t+"':"+s[i]})+"}":"["+s.join(",")+"]",new Function("input","return "+r)}},{key:"createTrainStream",value:function(t){return t=t||{},t.neuralNetwork=this,this.setActivation(),this.trainStream=new _trainStream2.default(t),this.trainStream}},{key:"isRunnable",get:function(){var t=this;if(!this.runInput)return console.error("Activation function has not been initialized, did you run train()?"),!1;var i=["sizes","outputLayer","biases","weights","outputs","deltas","changes","errors"].filter(function(i){return null===t[i]});return!(i.length>0)||(console.error("Some settings have not been initialized correctly, did you run train()? Found issues with: "+i.join(", ")),!1)}}]),t}();exports.default=NeuralNetwork; },{"./lookup":3,"./train-stream":33,"./utilities/max":35,"./utilities/mse":36,"./utilities/randos":40,"./utilities/range":41,"./utilities/to-array":42,"./utilities/zeros":43,"thaw.js":100}],6:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r1)for(var r=1;r0?("string"==typeof t||i.objectMode||Object.getPrototypeOf(t)===Buffer.prototype||(t=_uint8ArrayToBuffer(t)),n?i.endEmitted?e.emit("error",new Error("stream.unshift() after end event")):addChunk(e,i,t,!0):i.ended?e.emit("error",new Error("stream.push() after EOF")):(i.reading=!1,i.decoder&&!r?(t=i.decoder.write(t),i.objectMode||0!==t.length?addChunk(e,i,t,!1):maybeReadMore(e,i)):addChunk(e,i,t,!1))):n||(i.reading=!1)}return needMoreData(i)}function addChunk(e,t,r,n){t.flowing&&0===t.length&&!t.sync?(e.emit("data",r),e.read(0)):(t.length+=t.objectMode?1:r.length,n?t.buffer.unshift(r):t.buffer.push(r),t.needReadable&&emitReadable(e)),maybeReadMore(e,t)}function chunkInvalid(e,t){var r;return _isUint8Array(t)||"string"==typeof t||void 0===t||e.objectMode||(r=new TypeError("Invalid non-string/buffer chunk")),r}function needMoreData(e){return!e.ended&&(e.needReadable||e.length=MAX_HWM?e=MAX_HWM:(e--,e|=e>>>1,e|=e>>>2,e|=e>>>4,e|=e>>>8,e|=e>>>16,e++),e}function howMuchToRead(e,t){return e<=0||0===t.length&&t.ended?0:t.objectMode?1:e!==e?t.flowing&&t.length?t.buffer.head.data.length:t.length:(e>t.highWaterMark&&(t.highWaterMark=computeNewHighWaterMark(e)),e<=t.length?e:t.ended?t.length:(t.needReadable=!0,0))}function onEofChunk(e,t){if(!t.ended){if(t.decoder){var r=t.decoder.end();r&&r.length&&(t.buffer.push(r),t.length+=t.objectMode?1:r.length)}t.ended=!0,emitReadable(e)}}function emitReadable(e){var t=e._readableState;t.needReadable=!1,t.emittedReadable||(debug("emitReadable",t.flowing),t.emittedReadable=!0,t.sync?processNextTick(emitReadable_,e):emitReadable_(e))}function emitReadable_(e){debug("emit readable"),e.emit("readable"),flow(e)}function maybeReadMore(e,t){t.readingMore||(t.readingMore=!0,processNextTick(maybeReadMore_,e,t))}function maybeReadMore_(e,t){for(var r=t.length;!t.reading&&!t.flowing&&!t.ended&&t.length=t.length?(r=t.decoder?t.buffer.join(""):1===t.buffer.length?t.buffer.head.data:t.buffer.concat(t.length),t.buffer.clear()):r=fromListPartial(e,t.buffer,t.decoder),r}function fromListPartial(e,t,r){var n;return ei.length?i.length:e;if(d===i.length?a+=i:a+=i.slice(0,e),0===(e-=d)){d===i.length?(++n,r.next?t.head=r.next:t.head=t.tail=null):(t.head=r,r.data=i.slice(d));break}++n}return t.length-=n,a}function copyFromBuffer(e,t){var r=Buffer.allocUnsafe(e),n=t.head,a=1;for(n.data.copy(r),e-=n.data.length;n=n.next;){var i=n.data,d=e>i.length?i.length:e;if(i.copy(r,r.length-e,0,d),0===(e-=d)){d===i.length?(++a,n.next?t.head=n.next:t.head=t.tail=null):(t.head=n,n.data=i.slice(d));break}++a}return t.length-=a,r}function endReadable(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');t.endEmitted||(t.ended=!0,processNextTick(endReadableNT,t,e))}function endReadableNT(e,t){e.endEmitted||0!==e.length||(e.endEmitted=!0,t.readable=!1,t.emit("end"))}function forEach(e,t){for(var r=0,n=e.length;r=t.highWaterMark||t.ended))return debug("read: emitReadable",t.length,t.ended),0===t.length&&t.ended?endReadable(this):emitReadable(this),null;if(0===(e=howMuchToRead(e,t))&&t.ended)return 0===t.length&&endReadable(this),null;var n=t.needReadable;debug("need readable",n),(0===t.length||t.length-e0?fromList(e,t):null,null===a?(t.needReadable=!0,e=0):t.length-=e,0===t.length&&(t.ended||(t.needReadable=!0),r!==e&&t.ended&&endReadable(this)),null!==a&&this.emit("data",a),a},Readable.prototype._read=function(e){this.emit("error",new Error("_read() is not implemented"))},Readable.prototype.pipe=function(e,t){function r(e,t){debug("onunpipe"),e===l&&t&&!1===t.hasUnpiped&&(t.hasUnpiped=!0,a())}function n(){debug("onend"),e.end()}function a(){debug("cleanup"),e.removeListener("close",o),e.removeListener("finish",u),e.removeListener("drain",c),e.removeListener("error",d),e.removeListener("unpipe",r),l.removeListener("end",n),l.removeListener("end",s),l.removeListener("data",i),b=!0,!h.awaitDrain||e._writableState&&!e._writableState.needDrain||c()}function i(t){debug("ondata"),g=!1,!1!==e.write(t)||g||((1===h.pipesCount&&h.pipes===e||h.pipesCount>1&&-1!==indexOf(h.pipes,e))&&!b&&(debug("false write response, pause",l._readableState.awaitDrain),l._readableState.awaitDrain++,g=!0),l.pause())}function d(t){debug("onerror",t),s(),e.removeListener("error",d),0===EElistenerCount(e,"error")&&e.emit("error",t)}function o(){e.removeListener("finish",u),s()}function u(){debug("onfinish"),e.removeListener("close",o),s()}function s(){debug("unpipe"),l.unpipe(e)}var l=this,h=this._readableState;switch(h.pipesCount){case 0:h.pipes=e;break;case 1:h.pipes=[h.pipes,e];break;default:h.pipes.push(e)}h.pipesCount+=1,debug("pipe count=%d opts=%j",h.pipesCount,t);var f=(!t||!1!==t.end)&&e!==process.stdout&&e!==process.stderr,p=f?n:s;h.endEmitted?processNextTick(p):l.once("end",p),e.on("unpipe",r);var c=pipeOnDrain(l);e.on("drain",c);var b=!1,g=!1;return l.on("data",i),prependListener(e,"error",d),e.once("close",o),e.once("finish",u),e.emit("pipe",l),h.flowing||(debug("pipe resume"),l.resume()),e},Readable.prototype.unpipe=function(e){var t=this._readableState,r={hasUnpiped:!1};if(0===t.pipesCount)return this;if(1===t.pipesCount)return e&&e!==t.pipes?this:(e||(e=t.pipes),t.pipes=null,t.pipesCount=0,t.flowing=!1,e&&e.emit("unpipe",this,r),this);if(!e){var n=t.pipes,a=t.pipesCount;t.pipes=null,t.pipesCount=0,t.flowing=!1;for(var i=0;i-1?setImmediate:processNextTick,Duplex;Writable.WritableState=WritableState;var util=require("core-util-is");util.inherits=require("inherits");var internalUtil={deprecate:require("util-deprecate")},Stream=require("./internal/streams/stream"),Buffer=require("safe-buffer").Buffer,OurUint8Array=global.Uint8Array||function(){},destroyImpl=require("./internal/streams/destroy");util.inherits(Writable,Stream),WritableState.prototype.getBuffer=function(){for(var e=this.bufferedRequest,t=[];e;)t.push(e),e=e.next;return t},function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:internalUtil.deprecate(function(){return this.getBuffer()},"_writableState.buffer is deprecated. Use _writableState.getBuffer instead.","DEP0003")})}catch(e){}}();var realHasInstance;"function"==typeof Symbol&&Symbol.hasInstance&&"function"==typeof Function.prototype[Symbol.hasInstance]?(realHasInstance=Function.prototype[Symbol.hasInstance],Object.defineProperty(Writable,Symbol.hasInstance,{value:function(e){return!!realHasInstance.call(this,e)||e&&e._writableState instanceof WritableState}})):realHasInstance=function(e){return e instanceof this},Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))},Writable.prototype.write=function(e,t,r){var i=this._writableState,n=!1,o=_isUint8Array(e)&&!i.objectMode;return o&&!Buffer.isBuffer(e)&&(e=_uint8ArrayToBuffer(e)),"function"==typeof t&&(r=t,t=null),o?t="buffer":t||(t=i.defaultEncoding),"function"!=typeof r&&(r=nop),i.ended?writeAfterEnd(this,r):(o||validChunk(this,i,e,r))&&(i.pendingcb++,n=writeOrBuffer(this,i,o,e,t,r)),n},Writable.prototype.cork=function(){this._writableState.corked++},Writable.prototype.uncork=function(){var e=this._writableState;e.corked&&(e.corked--,e.writing||e.corked||e.finished||e.bufferProcessing||!e.bufferedRequest||clearBuffer(this,e))},Writable.prototype.setDefaultEncoding=function(e){if("string"==typeof e&&(e=e.toLowerCase()),!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);return this._writableState.defaultEncoding=e,this},Writable.prototype._write=function(e,t,r){r(new Error("_write() is not implemented"))},Writable.prototype._writev=null,Writable.prototype.end=function(e,t,r){var i=this._writableState;"function"==typeof e?(r=e,e=null,t=null):"function"==typeof t&&(r=t,t=null),null!==e&&void 0!==e&&this.write(e,t),i.corked&&(i.corked=1,this.uncork()),i.ending||i.finished||endWritable(this,i,r)},Object.defineProperty(Writable.prototype,"destroyed",{get:function(){return void 0!==this._writableState&&this._writableState.destroyed},set:function(e){this._writableState&&(this._writableState.destroyed=e)}}),Writable.prototype.destroy=destroyImpl.destroy,Writable.prototype._undestroy=destroyImpl.undestroy,Writable.prototype._destroy=function(e,t){this.end(),t(e)}; + }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./_stream_duplex":84,"./internal/streams/destroy":90,"./internal/streams/stream":91,"_process":82,"core-util-is":48,"inherits":78,"process-nextick-args":81,"safe-buffer":97,"util-deprecate":102}],89:[function(require,module,exports){ "use strict";function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function copyBuffer(t,e,h){t.copy(e,h)}var Buffer=require("safe-buffer").Buffer;module.exports=function(){function t(){_classCallCheck(this,t),this.head=null,this.tail=null,this.length=0}return t.prototype.push=function(t){var e={data:t,next:null};this.length>0?this.tail.next=e:this.head=e,this.tail=e,++this.length},t.prototype.unshift=function(t){var e={data:t,next:this.head};0===this.length&&(this.tail=e),this.head=e,++this.length},t.prototype.shift=function(){if(0!==this.length){var t=this.head.data;return 1===this.length?this.head=this.tail=null:this.head=this.head.next,--this.length,t}},t.prototype.clear=function(){this.head=this.tail=null,this.length=0},t.prototype.join=function(t){if(0===this.length)return"";for(var e=this.head,h=""+e.data;e=e.next;)h+=t+e.data;return h},t.prototype.concat=function(t){if(0===this.length)return Buffer.alloc(0);if(1===this.length)return this.head.data;for(var e=Buffer.allocUnsafe(t>>>0),h=this.head,n=0;h;)copyBuffer(h.data,e,n),n+=h.data.length,h=h.next;return e},t}(); @@ -377,7 +377,6 @@ module.exports=require("./lib/_stream_duplex.js"); },{"process-nextick-args":81}],91:[function(require,module,exports){ module.exports=require("events").EventEmitter; - },{"events":49}],92:[function(require,module,exports){ "use strict";function _normalizeEncoding(t){if(!t)return"utf8";for(var e;;)switch(t){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return t;default:if(e)return;t=(""+t).toLowerCase(),e=!0}}function normalizeEncoding(t){var e=_normalizeEncoding(t);if("string"!=typeof e&&(Buffer.isEncoding===isEncoding||!isEncoding(t)))throw new Error("Unknown encoding: "+t);return e||t}function StringDecoder(t){this.encoding=normalizeEncoding(t);var e;switch(this.encoding){case"utf16le":this.text=utf16Text,this.end=utf16End,e=4;break;case"utf8":this.fillLast=utf8FillLast,e=4;break;case"base64":this.text=base64Text,this.end=base64End,e=3;break;default:return this.write=simpleWrite,void(this.end=simpleEnd)}this.lastNeed=0,this.lastTotal=0,this.lastChar=Buffer.allocUnsafe(e)}function utf8CheckByte(t){return t<=127?0:t>>5==6?2:t>>4==14?3:t>>3==30?4:-1}function utf8CheckIncomplete(t,e,s){var i=e.length-1;if(i=0?(a>0&&(t.lastNeed=a-1),a):--i=0?(a>0&&(t.lastNeed=a-2),a):--i=0?(a>0&&(2===a?a=0:t.lastNeed=a-3),a):0)}function utf8CheckExtraBytes(t,e,s){if(128!=(192&e[0]))return t.lastNeed=0,"�".repeat(s);if(t.lastNeed>1&&e.length>1){if(128!=(192&e[1]))return t.lastNeed=1,"�".repeat(s+1);if(t.lastNeed>2&&e.length>2&&128!=(192&e[2]))return t.lastNeed=2,"�".repeat(s+2)}}function utf8FillLast(t){var e=this.lastTotal-this.lastNeed,s=utf8CheckExtraBytes(this,t,e);return void 0!==s?s:this.lastNeed<=t.length?(t.copy(this.lastChar,e,0,this.lastNeed),this.lastChar.toString(this.encoding,0,this.lastTotal)):(t.copy(this.lastChar,e,0,t.length),void(this.lastNeed-=t.length))}function utf8Text(t,e){var s=utf8CheckIncomplete(this,t,e);if(!this.lastNeed)return t.toString("utf8",e);this.lastTotal=s;var i=t.length-(s-this.lastNeed);return t.copy(this.lastChar,0,i),t.toString("utf8",e,i)}function utf8End(t){var e=t&&t.length?this.write(t):"";return this.lastNeed?e+"�".repeat(this.lastTotal-this.lastNeed):e}function utf16Text(t,e){if((t.length-e)%2==0){var s=t.toString("utf16le",e);if(s){var i=s.charCodeAt(s.length-1);if(i>=55296&&i<=56319)return this.lastNeed=2,this.lastTotal=4,this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1],s.slice(0,-1)}return s}return this.lastNeed=1,this.lastTotal=2,this.lastChar[0]=t[t.length-1],t.toString("utf16le",e,t.length-1)}function utf16End(t){var e=t&&t.length?this.write(t):"";if(this.lastNeed){var s=this.lastTotal-this.lastNeed;return e+this.lastChar.toString("utf16le",0,s)}return e}function base64Text(t,e){var s=(t.length-e)%3;return 0===s?t.toString("base64",e):(this.lastNeed=3-s,this.lastTotal=3,1===s?this.lastChar[0]=t[t.length-1]:(this.lastChar[0]=t[t.length-2],this.lastChar[1]=t[t.length-1]),t.toString("base64",e,t.length-s))}function base64End(t){var e=t&&t.length?this.write(t):"";return this.lastNeed?e+this.lastChar.toString("base64",0,3-this.lastNeed):e}function simpleWrite(t){return t.toString(this.encoding)}function simpleEnd(t){return t&&t.length?this.write(t):""}var Buffer=require("safe-buffer").Buffer,isEncoding=Buffer.isEncoding||function(t){switch((t=""+t)&&t.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return!0;default:return!1}};exports.StringDecoder=StringDecoder,StringDecoder.prototype.write=function(t){if(0===t.length)return"";var e,s;if(this.lastNeed){if(void 0===(e=this.fillLast(t)))return"";s=this.lastNeed,this.lastNeed=0}else s=0;return s 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -560,10 +515,10 @@ var NeuralNetwork = function () { return new Promise(function (resolve, reject) { try { - var thawedTrain = new _thaw2.default(new Array(_this2.trainOpts.iterations), { + var thawedTrain = new _thaw2.default(new Array(_this4.trainOpts.iterations), { delay: true, each: function each() { - return _this2._trainingTick(data, status, endTime) || thawedTrain.stop(); + return _this4._trainingTick(data, status, endTime) || thawedTrain.stop(); }, done: function done() { return resolve(status); @@ -741,7 +696,7 @@ var NeuralNetwork = function () { }, { key: '_formatData', value: function _formatData(data) { - var _this3 = this; + var _this5 = this; if (!Array.isArray(data)) { // turn stream datum into array @@ -758,7 +713,7 @@ var NeuralNetwork = function () { })); } data = data.map(function (datum) { - var array = _lookup2.default.toArray(_this3.inputLookup, datum.input); + var array = _lookup2.default.toArray(_this5.inputLookup, datum.input); return Object.assign({}, datum, { input: array }); }, this); } @@ -770,7 +725,7 @@ var NeuralNetwork = function () { })); } data = data.map(function (datum) { - var array = _lookup2.default.toArray(_this3.outputLookup, datum.output); + var array = _lookup2.default.toArray(_this5.outputLookup, datum.output); return Object.assign({}, datum, { output: array }); }, this); } @@ -791,7 +746,7 @@ var NeuralNetwork = function () { }, { key: 'test', value: function test(data) { - var _this4 = this; + var _this6 = this; data = this._formatData(data); @@ -810,13 +765,13 @@ var NeuralNetwork = function () { var sum = 0; var _loop = function _loop(i) { - var output = _this4.runInput(data[i].input); + var output = _this6.runInput(data[i].input); var target = data[i].output; var actual = void 0, expected = void 0; if (isBinary) { - actual = output[0] > _this4.binaryThresh ? 1 : 0; + actual = output[0] > _this6.binaryThresh ? 1 : 0; expected = target[0]; } else { actual = output.indexOf((0, _max2.default)(output)); @@ -985,7 +940,7 @@ var NeuralNetwork = function () { } } } - this.updateTrainingOptions(json.trainOpts); + this._updateTrainingOptions(json.trainOpts); this.setActivation(); return this; } @@ -1063,7 +1018,7 @@ var NeuralNetwork = function () { }, { key: 'isRunnable', get: function get() { - var _this5 = this; + var _this7 = this; if (!this.runInput) { console.error('Activation function has not been initialized, did you run train()?'); @@ -1071,7 +1026,7 @@ var NeuralNetwork = function () { } var checkFns = ['sizes', 'outputLayer', 'biases', 'weights', 'outputs', 'deltas', 'changes', 'errors'].filter(function (c) { - return _this5[c] === null; + return _this7[c] === null; }); if (checkFns.length > 0) { diff --git a/dist/neural-network.js.map b/dist/neural-network.js.map index 481162d26..59f34dc8b 100644 --- a/dist/neural-network.js.map +++ b/dist/neural-network.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/neural-network.js"],"names":["NeuralNetwork","iterations","errorThresh","log","logPeriod","learningRate","momentum","callback","callbackPeriod","timeout","Infinity","binaryThresh","hiddenLayers","activation","options","Object","assign","constructor","defaults","hiddenSizes","trainOpts","updateTrainingOptions","trainDefaults","sizes","outputLayer","biases","weights","outputs","deltas","changes","errors","prototype","hasOwnProperty","runInput","calculateDeltas","Error","length","layer","size","Array","node","prevSize","setActivation","_runInputSigmoid","_calculateDeltasSigmoid","_runInputRelu","_calculateDeltasRelu","_runInputLeakyRelu","_calculateDeltasLeakyRelu","_runInputTanh","_calculateDeltasTanh","input","isRunnable","inputLookup","toArray","output","outputLookup","toHash","sum","k","Math","exp","tanh","data","push","max","floor","forEach","_initialize","opts","_setLogMethod","results","console","i","_trainPattern","status","endTime","error","Date","now","_calculateTrainingError","_formatData","_verifyIsInitialized","_prepTraining","_trainingTick","Promise","resolve","reject","thawedTrain","delay","each","stop","done","tick","trainError","target","_adjustWeights","incoming","delta","change","isArray","tmp","datum","Float32Array","buildLookup","map","value","array","isBinary","falsePos","falseNeg","truePos","trueNeg","misclasses","actual","expected","indexOf","misclass","stats","total","precision","recall","accuracy","layers","nodes","keys","j","bias","index","_getTrainOptsJSON","json","lookupFromHash","nodeHandle","layerNumber","nodeKey","result","w","join","toJSON","layersAsMath","key","Function","neuralNetwork","trainStream","checkFns","filter","c"],"mappings":"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","file":"neural-network.js","sourcesContent":["import lookup from './lookup';\nimport TrainStream from './train-stream';\nimport max from './utilities/max';\nimport mse from './utilities/mse';\nimport randos from './utilities/randos';\nimport range from './utilities/range';\nimport toArray from './utilities/to-array';\nimport zeros from './utilities/zeros';\nimport Thaw from 'thaw.js';\n\n/**\n * @param {object} options\n * @constructor\n */\nexport default class NeuralNetwork {\n static get trainDefaults() {\n return {\n iterations: 20000, // the maximum times to iterate the training data\n errorThresh: 0.005, // the acceptable error percentage from training data\n log: false, // true to use console.log, when a function is supplied it is used\n logPeriod: 10, // iterations between logging out\n learningRate: 0.3, // multiply's against the input and the delta then adds to momentum\n momentum: 0.1, // multiply's against the specified \"change\" then adds to learning rate for change\n callback: null, // a periodic call back that can be triggered while training\n callbackPeriod: 10, // the number of iterations through the training data between callback calls\n timeout: Infinity // the max number of milliseconds to train for\n };\n }\n\n static get defaults() {\n return {\n binaryThresh: 0.5, // ¯\\_(ツ)_/¯\n hiddenLayers: [3], // array of ints for the sizes of the hidden layers in the network\n activation: 'sigmoid' // Supported activation types ['sigmoid', 'relu', 'leaky-relu', 'tanh']\n };\n }\n\n constructor(options = {}) {\n Object.assign(this, this.constructor.defaults, options);\n this.hiddenSizes = options.hiddenLayers;\n this.trainOpts = {};\n this.updateTrainingOptions(Object.assign({}, this.constructor.trainDefaults, options));\n\n this.sizes = null;\n this.outputLayer = null;\n this.biases = null; // weights for bias nodes\n this.weights = null;\n this.outputs = null;\n\n // state for training\n this.deltas = null;\n this.changes = null; // for momentum\n this.errors = null;\n\n if (!this.constructor.prototype.hasOwnProperty('runInput')) {\n this.runInput = null;\n }\n if (!this.constructor.prototype.hasOwnProperty('calculateDeltas')) {\n this.calculateDeltas = null;\n }\n }\n\n /**\n *\n * Expects this.sizes to have been set\n */\n _initialize() {\n if (!this.sizes) throw new Error ('Sizes must be set before initializing')\n\n this.outputLayer = this.sizes.length - 1;\n this.biases = []; // weights for bias nodes\n this.weights = [];\n this.outputs = [];\n\n // state for training\n this.deltas = [];\n this.changes = []; // for momentum\n this.errors = [];\n\n for (let layer = 0; layer <= this.outputLayer; layer++) {\n let size = this.sizes[layer];\n this.deltas[layer] = zeros(size);\n this.errors[layer] = zeros(size);\n this.outputs[layer] = zeros(size);\n\n if (layer > 0) {\n this.biases[layer] = randos(size);\n this.weights[layer] = new Array(size);\n this.changes[layer] = new Array(size);\n\n for (let node = 0; node < size; node++) {\n let prevSize = this.sizes[layer - 1];\n this.weights[layer][node] = randos(prevSize);\n this.changes[layer][node] = zeros(prevSize);\n }\n }\n }\n\n this.setActivation();\n }\n\n /**\n *\n * @param supported input: ['sigmoid', 'relu', 'leaky-relu', 'tanh']\n */\n setActivation(activation) {\n this.activation = (activation) ? activation : this.activation;\n switch (this.activation) {\n case 'sigmoid':\n this.runInput = this.runInput || this._runInputSigmoid;\n this.calculateDeltas = this.calculateDeltas || this._calculateDeltasSigmoid;\n break;\n case 'relu':\n this.runInput = this.runInput || this._runInputRelu;\n this.calculateDeltas = this.calculateDeltas || this._calculateDeltasRelu;\n break;\n case 'leaky-relu':\n this.runInput = this.runInput || this._runInputLeakyRelu;\n this.calculateDeltas = this.calculateDeltas || this._calculateDeltasLeakyRelu;\n break;\n case 'tanh':\n this.runInput = this.runInput || this._runInputTanh;\n this.calculateDeltas = this.calculateDeltas || this._calculateDeltasTanh;\n break;\n default:\n throw new Error('unknown activation ' + this.activation + ', The activation should be one of [\\'sigmoid\\', \\'relu\\', \\'leaky-relu\\', \\'tanh\\']');\n }\n }\n\n /**\n *\n * @returns boolean\n */\n get isRunnable(){\n if(!this.runInput){\n console.error('Activation function has not been initialized, did you run train()?');\n return false;\n }\n\n const checkFns = [\n 'sizes',\n 'outputLayer',\n 'biases',\n 'weights',\n 'outputs',\n 'deltas',\n 'changes',\n 'errors',\n ].filter(c => this[c] === null);\n\n if(checkFns.length > 0){\n console.error(`Some settings have not been initialized correctly, did you run train()? Found issues with: ${checkFns.join(', ')}`);\n return false;\n }\n return true;\n }\n\n\n /**\n *\n * @param input\n * @returns {*}\n */\n run(input) {\n if (!this.isRunnable) return null;\n if (this.inputLookup) {\n input = lookup.toArray(this.inputLookup, input);\n }\n\n let output = [...this.runInput(input)];\n\n if (this.outputLookup) {\n output = lookup.toHash(this.outputLookup, output);\n }\n return output;\n }\n\n /**\n * trains via sigmoid\n * @param input\n * @returns {*}\n */\n _runInputSigmoid(input) {\n this.outputs[0] = input; // set output state of input layer\n\n let output = null;\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let weights = this.weights[layer][node];\n\n let sum = this.biases[layer][node];\n for (let k = 0; k < weights.length; k++) {\n sum += weights[k] * input[k];\n }\n //sigmoid\n this.outputs[layer][node] = 1 / (1 + Math.exp(-sum));\n }\n output = input = this.outputs[layer];\n }\n return output;\n }\n\n _runInputRelu(input) {\n this.outputs[0] = input; // set output state of input layer\n\n let output = null;\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let weights = this.weights[layer][node];\n\n let sum = this.biases[layer][node];\n for (let k = 0; k < weights.length; k++) {\n sum += weights[k] * input[k];\n }\n //relu\n this.outputs[layer][node] = (sum < 0 ? 0 : sum);\n }\n output = input = this.outputs[layer];\n }\n return output;\n }\n\n _runInputLeakyRelu(input) {\n this.outputs[0] = input; // set output state of input layer\n\n let output = null;\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let weights = this.weights[layer][node];\n\n let sum = this.biases[layer][node];\n for (let k = 0; k < weights.length; k++) {\n sum += weights[k] * input[k];\n }\n //leaky relu\n this.outputs[layer][node] = (sum < 0 ? 0 : 0.01 * sum);\n }\n output = input = this.outputs[layer];\n }\n return output;\n }\n\n _runInputTanh(input) {\n this.outputs[0] = input; // set output state of input layer\n\n let output = null;\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let weights = this.weights[layer][node];\n\n let sum = this.biases[layer][node];\n for (let k = 0; k < weights.length; k++) {\n sum += weights[k] * input[k];\n }\n //tanh\n this.outputs[layer][node] = Math.tanh(sum);\n }\n output = input = this.outputs[layer];\n }\n return output;\n }\n\n /**\n *\n * @param data\n * Verifies network sizes are initilaized\n * If they are not it will initialize them based off the data set.\n */\n _verifyIsInitialized(data) {\n if (this.sizes) return;\n\n this.sizes = [];\n this.sizes.push(data[0].input.length);\n if (!this.hiddenSizes) {\n this.sizes.push(Math.max(3, Math.floor(data[0].input.length / 2)));\n } else {\n this.hiddenSizes.forEach(size => {\n this.sizes.push(size);\n });\n }\n this.sizes.push(data[0].output.length)\n\n this._initialize();\n }\n\n /**\n *\n * @param options\n * Supports all `trainDefaults` properties\n * also supports:\n * learningRate: (number),\n * momentum: (number),\n * activation: ['sigmoid', 'relu', 'leaky-relu', 'tanh']\n */\n updateTrainingOptions(opts) {\n if (opts.iterations) { this.trainOpts.iterations = opts.iterations; }\n if (opts.errorThresh) { this.trainOpts.errorThresh = opts.errorThresh; }\n if (opts.log) { this._setLogMethod(opts.log); }\n if (opts.logPeriod) { this.trainOpts.logPeriod = opts.logPeriod; }\n if (opts.learningRate) { this.trainOpts.learningRate = opts.learningRate; }\n if (opts.momentum) { this.trainOpts.momentum = opts.momentum; }\n if (opts.callback) { this.trainOpts.callback = opts.callback; }\n if (opts.callbackPeriod) { this.trainOpts.callbackPeriod = opts.callbackPeriod; }\n if (opts.timeout) { this.trainOpts.timeout = opts.timeout; }\n if (opts.activation) { this.activation = opts.activation; }\n }\n\n /**\n *\n * Gets JSON of trainOpts object\n * NOTE: Activation is stored directly on JSON object and not in the training options\n */\n _getTrainOptsJSON() {\n let results = {}\n if (this.trainOpts.iterations) { results.iterations = this.trainOpts.iterations; }\n if (this.trainOpts.errorThresh) { results.errorThresh = this.trainOpts.errorThresh; }\n if (this.trainOpts.logPeriod) { results.logPeriod = this.trainOpts.logPeriod; }\n if (this.trainOpts.learningRate) { results.learningRate = this.trainOpts.learningRate; }\n if (this.trainOpts.momentum) { results.momentum = this.trainOpts.momentum; }\n if (this.trainOpts.callback) { results.callback = this.trainOpts.callback; }\n if (this.trainOpts.callbackPeriod) { results.callbackPeriod = this.trainOpts.callbackPeriod; }\n if (this.trainOpts.timeout) { results.timeout = this.trainOpts.timeout; }\n if (this.trainOpts.log) { results.log = true; }\n return results;\n }\n\n /**\n *\n * @param log\n * if a method is passed in method is used\n * if false passed in nothing is logged\n * @returns error\n */\n _setLogMethod(log) {\n if (typeof log === 'function'){\n this.trainOpts.log = log;\n } else if (log) {\n this.trainOpts.log = console.log;\n } else {\n this.trainOpts.log = false;\n }\n }\n\n /**\n *\n * @param data\n * @param learning Rate\n * @returns error\n */\n _calculateTrainingError(data) {\n let sum = 0;\n for (let i = 0; i < data.length; ++i) {\n sum += this._trainPattern(data[i].input, data[i].output);\n }\n return sum / data.length;\n }\n\n /**\n *\n * @param status { iterations: number, error: number}\n * @param options\n */\n _trainingTick(data, status, endTime) {\n if (status.iterations >= this.trainOpts.iterations || status.error <= this.trainOpts.errorThresh || Date.now() >= endTime) {\n return false;\n }\n\n status.iterations++;\n status.error = this._calculateTrainingError(data);\n\n if (this.trainOpts.log && (status.iterations % this.trainOpts.logPeriod === 0)) {\n this.trainOpts.log(`iterations: ${status.iterations}, training error: ${status.error}`);\n }\n\n if (this.trainOpts.callback && (status.iterations % this.trainOpts.callbackPeriod === 0)) {\n this.trainOpts.callback(Object.assign(status));\n }\n return true;\n }\n\n /**\n *\n * @param data\n * @param options\n * @private\n * @return {{runTrainingTick: function, status: {error: number, iterations: number}}}\n */\n _prepTraining(data, options) {\n this.updateTrainingOptions(options);\n data = this._formatData(data);\n const endTime = Date.now() + this.trainOpts.timeout;\n\n const status = {\n error: 1,\n iterations: 0\n };\n\n this._verifyIsInitialized(data);\n\n return {\n data,\n status,\n endTime\n }\n }\n\n /**\n *\n * @param data\n * @param options\n * @returns {{error: number, iterations: number}}\n */\n train(data, options = {}) {\n let status, endTime;\n ({ data, status, endTime } = this._prepTraining(data, options));\n\n while (this._trainingTick(data, status, endTime));\n return status;\n }\n\n /**\n *\n * @param data\n * @param options\n * @returns {Promise}\n * @resolves {{error: number, iterations: number}}\n * @rejects {{trainError: string, status: {error: number, iterations: number}}\n */\n trainAsync(data, options = {}) {\n let status, endTime;\n ({ data, status, endTime } = this._prepTraining(data, options));\n\n return new Promise((resolve, reject) => {\n try {\n const thawedTrain = new Thaw(new Array(this.trainOpts.iterations), {\n delay: true,\n each: () => this._trainingTick(data, status, endTime) || thawedTrain.stop(),\n done: () => resolve(status)\n });\n thawedTrain.tick();\n } catch (trainError) {\n reject({trainError, status});\n }\n });\n }\n\n /**\n *\n * @param input\n * @param target\n */\n _trainPattern(input, target) {\n\n // forward propagate\n this.runInput(input);\n\n // back propagate\n this.calculateDeltas(target);\n this._adjustWeights();\n\n let error = mse(this.errors[this.outputLayer]);\n return error;\n }\n\n /**\n *\n * @param target\n */\n _calculateDeltasSigmoid(target) {\n for (let layer = this.outputLayer; layer >= 0; layer--) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let output = this.outputs[layer][node];\n\n let error = 0;\n if (layer === this.outputLayer) {\n error = target[node] - output;\n }\n else {\n let deltas = this.deltas[layer + 1];\n for (let k = 0; k < deltas.length; k++) {\n error += deltas[k] * this.weights[layer + 1][k][node];\n }\n }\n this.errors[layer][node] = error;\n this.deltas[layer][node] = error * output * (1 - output);\n }\n }\n }\n\n /**\n *\n * @param target\n */\n _calculateDeltasRelu(target) {\n for (let layer = this.outputLayer; layer >= 0; layer--) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let output = this.outputs[layer][node];\n\n let error = 0;\n if (layer === this.outputLayer) {\n error = target[node] - output;\n }\n else {\n let deltas = this.deltas[layer + 1];\n for (let k = 0; k < deltas.length; k++) {\n error += deltas[k] * this.weights[layer + 1][k][node];\n }\n }\n this.errors[layer][node] = error;\n this.deltas[layer][node] = output > 0 ? error : 0;\n }\n }\n }\n\n /**\n *\n * @param target\n */\n _calculateDeltasLeakyRelu(target) {\n for (let layer = this.outputLayer; layer >= 0; layer--) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let output = this.outputs[layer][node];\n\n let error = 0;\n if (layer === this.outputLayer) {\n error = target[node] - output;\n }\n else {\n let deltas = this.deltas[layer + 1];\n for (let k = 0; k < deltas.length; k++) {\n error += deltas[k] * this.weights[layer + 1][k][node];\n }\n }\n this.errors[layer][node] = error;\n this.deltas[layer][node] = output > 0 ? error : 0.01 * error;\n }\n }\n }\n\n /**\n *\n * @param target\n */\n _calculateDeltasTanh(target) {\n for (let layer = this.outputLayer; layer >= 0; layer--) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let output = this.outputs[layer][node];\n\n let error = 0;\n if (layer === this.outputLayer) {\n error = target[node] - output;\n }\n else {\n let deltas = this.deltas[layer + 1];\n for (let k = 0; k < deltas.length; k++) {\n error += deltas[k] * this.weights[layer + 1][k][node];\n }\n }\n this.errors[layer][node] = error;\n this.deltas[layer][node] = (1 - output * output) * error;\n }\n }\n }\n\n /**\n *\n * Changes weights of networks\n */\n _adjustWeights() {\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n let incoming = this.outputs[layer - 1];\n\n for (let node = 0; node < this.sizes[layer]; node++) {\n let delta = this.deltas[layer][node];\n\n for (let k = 0; k < incoming.length; k++) {\n let change = this.changes[layer][node][k];\n\n change = (this.trainOpts.learningRate * delta * incoming[k])\n + (this.trainOpts.momentum * change);\n\n this.changes[layer][node][k] = change;\n this.weights[layer][node][k] += change;\n }\n this.biases[layer][node] += this.trainOpts.learningRate * delta;\n }\n }\n }\n\n /**\n *\n * @param data\n * @returns {*}\n */\n _formatData(data) {\n if (!Array.isArray(data)) { // turn stream datum into array\n let tmp = [];\n tmp.push(data);\n data = tmp;\n }\n // turn sparse hash input into arrays with 0s as filler\n let datum = data[0].input;\n if (!Array.isArray(datum) && !(datum instanceof Float32Array)) {\n if (!this.inputLookup) {\n this.inputLookup = lookup.buildLookup(data.map(value => value['input']));\n }\n data = data.map(datum => {\n let array = lookup.toArray(this.inputLookup, datum.input);\n return Object.assign({}, datum, { input: array });\n }, this);\n }\n\n if (!Array.isArray(data[0].output)) {\n if (!this.outputLookup) {\n this.outputLookup = lookup.buildLookup(data.map(value => value['output']));\n }\n data = data.map(datum => {\n let array = lookup.toArray(this.outputLookup, datum.output);\n return Object.assign({}, datum, { output: array });\n }, this);\n }\n return data;\n }\n\n /**\n *\n * @param data\n * @returns {\n * {\n * error: number,\n * misclasses: Array\n * }\n * }\n */\n test(data) {\n data = this._formatData(data);\n\n // for binary classification problems with one output node\n let isBinary = data[0].output.length === 1;\n let falsePos = 0;\n let falseNeg = 0;\n let truePos = 0;\n let trueNeg = 0;\n\n // for classification problems\n let misclasses = [];\n\n // run each pattern through the trained network and collect\n // error and misclassification statistics\n let sum = 0;\n for (let i = 0; i < data.length; i++) {\n let output = this.runInput(data[i].input);\n let target = data[i].output;\n\n let actual, expected;\n if (isBinary) {\n actual = output[0] > this.binaryThresh ? 1 : 0;\n expected = target[0];\n }\n else {\n actual = output.indexOf(max(output));\n expected = target.indexOf(max(target));\n }\n\n if (actual !== expected) {\n let misclass = data[i];\n Object.assign(misclass, {\n actual: actual,\n expected: expected\n });\n misclasses.push(misclass);\n }\n\n if (isBinary) {\n if (actual === 0 && expected === 0) {\n trueNeg++;\n } else if (actual === 1 && expected === 1) {\n truePos++;\n } else if (actual === 0 && expected === 1) {\n falseNeg++;\n } else if (actual === 1 && expected === 0) {\n falsePos++;\n }\n }\n\n let errors = output.map((value, i) => {\n return target[i] - value;\n });\n sum += mse(errors);\n }\n let error = sum / data.length;\n\n let stats = {\n error: error,\n misclasses: misclasses\n };\n\n if (isBinary) {\n Object.assign(stats, {\n trueNeg: trueNeg,\n truePos: truePos,\n falseNeg: falseNeg,\n falsePos: falsePos,\n total: data.length,\n precision: truePos / (truePos + falsePos),\n recall: truePos / (truePos + falseNeg),\n accuracy: (trueNeg + truePos) / data.length\n });\n }\n return stats;\n }\n\n /**\n *\n * @returns\n * {\n * layers: [\n * {\n * x: {},\n * y: {}\n * },\n * {\n * '0': {\n * bias: -0.98771313,\n * weights: {\n * x: 0.8374838,\n * y: 1.245858\n * },\n * '1': {\n * bias: 3.48192004,\n * weights: {\n * x: 1.7825821,\n * y: -2.67899\n * }\n * }\n * },\n * {\n * f: {\n * bias: 0.27205739,\n * weights: {\n * '0': 1.3161821,\n * '1': 2.00436\n * }\n * }\n * }\n * ]\n * }\n */\n toJSON() {\n let layers = [];\n for (let layer = 0; layer <= this.outputLayer; layer++) {\n layers[layer] = {};\n\n let nodes;\n // turn any internal arrays back into hashes for readable json\n if (layer === 0 && this.inputLookup) {\n nodes = Object.keys(this.inputLookup);\n }\n else if (layer === this.outputLayer && this.outputLookup) {\n nodes = Object.keys(this.outputLookup);\n }\n else {\n nodes = range(0, this.sizes[layer]);\n }\n\n for (let j = 0; j < nodes.length; j++) {\n let node = nodes[j];\n layers[layer][node] = {};\n\n if (layer > 0) {\n layers[layer][node].bias = this.biases[layer][j];\n layers[layer][node].weights = {};\n for (let k in layers[layer - 1]) {\n let index = k;\n if (layer === 1 && this.inputLookup) {\n index = this.inputLookup[k];\n }\n layers[layer][node].weights[k] = this.weights[layer][j][index];\n }\n }\n }\n }\n return {\n sizes: this.sizes,\n layers,\n outputLookup:!!this.outputLookup,\n inputLookup:!!this.inputLookup,\n activation: this.activation,\n trainOpts: this._getTrainOptsJSON()\n };\n }\n\n /**\n *\n * @param json\n * @returns {NeuralNetwork}\n */\n fromJSON (json) {\n this.sizes = json.sizes\n this._initialize();\n\n for (let i = 0; i <= this.outputLayer; i++) {\n let layer = json.layers[i];\n if (i === 0 && (!layer[0] || json.inputLookup)) {\n this.inputLookup = lookup.lookupFromHash(layer);\n }\n else if (i === this.outputLayer && (!layer[0] || json.outputLookup)) {\n this.outputLookup = lookup.lookupFromHash(layer);\n }\n if (i > 0) {\n const nodes = Object.keys(layer);\n this.sizes[i] = nodes.length;\n for (let j in nodes) {\n const node = nodes[j];\n this.biases[i][j] = layer[node].bias;\n this.weights[i][j] = toArray(layer[node].weights);\n }\n }\n }\n this.updateTrainingOptions(json.trainOpts)\n this.setActivation();\n return this;\n }\n\n /**\n *\n * @returns {Function}\n */\n toFunction() {\n const activation = this.activation;\n function nodeHandle(layers, layerNumber, nodeKey) {\n if (layerNumber === 0) {\n return (typeof nodeKey === 'string'\n ? `input['${nodeKey}']`\n : `input[${nodeKey}]`);\n }\n\n const layer = layers[layerNumber];\n const node = layer[nodeKey];\n let result = [node.bias];\n for (let w in node.weights) {\n if (node.weights[w] < 0) {\n result.push(`${node.weights[w]}*(${nodeHandle(layers, layerNumber - 1, w)})`);\n } else {\n result.push(`+${node.weights[w]}*(${nodeHandle(layers, layerNumber - 1, w)})`);\n }\n }\n\n switch (activation) {\n case 'sigmoid':\n return `1/(1+1/Math.exp(${result.join('')}))`;\n case 'relu':\n return `var sum = ${result.join('')};(sum < 0 ? 0 : sum);`;\n case 'leaky-relu':\n return `var sum = ${result.join('')};(sum < 0 ? 0 : 0.01 * sum);`;\n case 'tanh':\n return `Math.tanh(${result.join('')});`;\n default:\n throw new Error('unknown activation type ' + activation);\n }\n }\n\n const layers = this.toJSON().layers;\n const layersAsMath = [];\n let result;\n for (let i in layers[layers.length - 1]) {\n layersAsMath.push(nodeHandle(layers, layers.length - 1, i));\n }\n if (this.outputLookup) {\n result = `{${\n Object.keys(this.outputLookup)\n .map((key, i) => `'${key}':${layersAsMath[i]}`)\n }}`;\n } else {\n result = `[${layersAsMath.join(',')}]`;\n }\n return new Function('input', `return ${result}`);\n }\n\n /**\n * This will create a TrainStream (WriteStream) for us to send the training data to.\n * @param opts training options\n * @returns {TrainStream|*}\n */\n createTrainStream(opts) {\n opts = opts || {};\n opts.neuralNetwork = this;\n this.setActivation();\n this.trainStream = new TrainStream(opts);\n return this.trainStream;\n }\n}"]} \ No newline at end of file +{"version":3,"sources":["../src/neural-network.js"],"names":["NeuralNetwork","iterations","errorThresh","log","logPeriod","learningRate","momentum","callback","callbackPeriod","timeout","Infinity","binaryThresh","hiddenLayers","activation","options","Object","assign","constructor","defaults","hiddenSizes","trainOpts","_updateTrainingOptions","trainDefaults","sizes","outputLayer","biases","weights","outputs","deltas","changes","errors","prototype","hasOwnProperty","runInput","calculateDeltas","Error","length","layer","size","Array","node","prevSize","setActivation","_runInputSigmoid","_calculateDeltasSigmoid","_runInputRelu","_calculateDeltasRelu","_runInputLeakyRelu","_calculateDeltasLeakyRelu","_runInputTanh","_calculateDeltasTanh","input","isRunnable","inputLookup","toArray","output","outputLookup","toHash","sum","k","Math","exp","tanh","data","push","max","floor","forEach","_initialize","opts","keys","opt","_setLogMethod","reduce","console","i","_trainPattern","status","endTime","error","Date","now","_calculateTrainingError","updateTrainingOptions","_formatData","_verifyIsInitialized","_prepTraining","_trainingTick","Promise","resolve","reject","thawedTrain","delay","each","stop","done","tick","trainError","target","_adjustWeights","incoming","delta","change","isArray","tmp","datum","Float32Array","buildLookup","map","value","array","isBinary","falsePos","falseNeg","truePos","trueNeg","misclasses","actual","expected","indexOf","misclass","stats","total","precision","recall","accuracy","layers","nodes","j","bias","index","_getTrainOptsJSON","json","lookupFromHash","nodeHandle","layerNumber","nodeKey","result","w","join","toJSON","layersAsMath","key","Function","neuralNetwork","trainStream","checkFns","filter","c"],"mappings":"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","file":"neural-network.js","sourcesContent":["import lookup from './lookup';\nimport TrainStream from './train-stream';\nimport max from './utilities/max';\nimport mse from './utilities/mse';\nimport randos from './utilities/randos';\nimport range from './utilities/range';\nimport toArray from './utilities/to-array';\nimport zeros from './utilities/zeros';\nimport Thaw from 'thaw.js';\n\n/**\n * @param {object} options\n * @constructor\n */\nexport default class NeuralNetwork {\n static get trainDefaults() {\n return {\n iterations: 20000, // the maximum times to iterate the training data\n errorThresh: 0.005, // the acceptable error percentage from training data\n log: false, // true to use console.log, when a function is supplied it is used\n logPeriod: 10, // iterations between logging out\n learningRate: 0.3, // multiply's against the input and the delta then adds to momentum\n momentum: 0.1, // multiply's against the specified \"change\" then adds to learning rate for change\n callback: null, // a periodic call back that can be triggered while training\n callbackPeriod: 10, // the number of iterations through the training data between callback calls\n timeout: Infinity // the max number of milliseconds to train for\n };\n }\n\n static get defaults() {\n return {\n binaryThresh: 0.5, // ¯\\_(ツ)_/¯\n hiddenLayers: [3], // array of ints for the sizes of the hidden layers in the network\n activation: 'sigmoid' // Supported activation types ['sigmoid', 'relu', 'leaky-relu', 'tanh']\n };\n }\n\n constructor(options = {}) {\n Object.assign(this, this.constructor.defaults, options);\n this.hiddenSizes = options.hiddenLayers;\n this.trainOpts = {};\n this._updateTrainingOptions(Object.assign({}, this.constructor.trainDefaults, options));\n\n this.sizes = null;\n this.outputLayer = null;\n this.biases = null; // weights for bias nodes\n this.weights = null;\n this.outputs = null;\n\n // state for training\n this.deltas = null;\n this.changes = null; // for momentum\n this.errors = null;\n\n if (!this.constructor.prototype.hasOwnProperty('runInput')) {\n this.runInput = null;\n }\n if (!this.constructor.prototype.hasOwnProperty('calculateDeltas')) {\n this.calculateDeltas = null;\n }\n }\n\n /**\n *\n * Expects this.sizes to have been set\n */\n _initialize() {\n if (!this.sizes) throw new Error ('Sizes must be set before initializing')\n\n this.outputLayer = this.sizes.length - 1;\n this.biases = []; // weights for bias nodes\n this.weights = [];\n this.outputs = [];\n\n // state for training\n this.deltas = [];\n this.changes = []; // for momentum\n this.errors = [];\n\n for (let layer = 0; layer <= this.outputLayer; layer++) {\n let size = this.sizes[layer];\n this.deltas[layer] = zeros(size);\n this.errors[layer] = zeros(size);\n this.outputs[layer] = zeros(size);\n\n if (layer > 0) {\n this.biases[layer] = randos(size);\n this.weights[layer] = new Array(size);\n this.changes[layer] = new Array(size);\n\n for (let node = 0; node < size; node++) {\n let prevSize = this.sizes[layer - 1];\n this.weights[layer][node] = randos(prevSize);\n this.changes[layer][node] = zeros(prevSize);\n }\n }\n }\n\n this.setActivation();\n }\n\n /**\n *\n * @param supported input: ['sigmoid', 'relu', 'leaky-relu', 'tanh']\n */\n setActivation(activation) {\n this.activation = (activation) ? activation : this.activation;\n switch (this.activation) {\n case 'sigmoid':\n this.runInput = this.runInput || this._runInputSigmoid;\n this.calculateDeltas = this.calculateDeltas || this._calculateDeltasSigmoid;\n break;\n case 'relu':\n this.runInput = this.runInput || this._runInputRelu;\n this.calculateDeltas = this.calculateDeltas || this._calculateDeltasRelu;\n break;\n case 'leaky-relu':\n this.runInput = this.runInput || this._runInputLeakyRelu;\n this.calculateDeltas = this.calculateDeltas || this._calculateDeltasLeakyRelu;\n break;\n case 'tanh':\n this.runInput = this.runInput || this._runInputTanh;\n this.calculateDeltas = this.calculateDeltas || this._calculateDeltasTanh;\n break;\n default:\n throw new Error('unknown activation ' + this.activation + ', The activation should be one of [\\'sigmoid\\', \\'relu\\', \\'leaky-relu\\', \\'tanh\\']');\n }\n }\n\n /**\n *\n * @returns boolean\n */\n get isRunnable(){\n if(!this.runInput){\n console.error('Activation function has not been initialized, did you run train()?');\n return false;\n }\n\n const checkFns = [\n 'sizes',\n 'outputLayer',\n 'biases',\n 'weights',\n 'outputs',\n 'deltas',\n 'changes',\n 'errors',\n ].filter(c => this[c] === null);\n\n if(checkFns.length > 0){\n console.error(`Some settings have not been initialized correctly, did you run train()? Found issues with: ${checkFns.join(', ')}`);\n return false;\n }\n return true;\n }\n\n\n /**\n *\n * @param input\n * @returns {*}\n */\n run(input) {\n if (!this.isRunnable) return null;\n if (this.inputLookup) {\n input = lookup.toArray(this.inputLookup, input);\n }\n\n let output = [...this.runInput(input)];\n\n if (this.outputLookup) {\n output = lookup.toHash(this.outputLookup, output);\n }\n return output;\n }\n\n /**\n * trains via sigmoid\n * @param input\n * @returns {*}\n */\n _runInputSigmoid(input) {\n this.outputs[0] = input; // set output state of input layer\n\n let output = null;\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let weights = this.weights[layer][node];\n\n let sum = this.biases[layer][node];\n for (let k = 0; k < weights.length; k++) {\n sum += weights[k] * input[k];\n }\n //sigmoid\n this.outputs[layer][node] = 1 / (1 + Math.exp(-sum));\n }\n output = input = this.outputs[layer];\n }\n return output;\n }\n\n _runInputRelu(input) {\n this.outputs[0] = input; // set output state of input layer\n\n let output = null;\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let weights = this.weights[layer][node];\n\n let sum = this.biases[layer][node];\n for (let k = 0; k < weights.length; k++) {\n sum += weights[k] * input[k];\n }\n //relu\n this.outputs[layer][node] = (sum < 0 ? 0 : sum);\n }\n output = input = this.outputs[layer];\n }\n return output;\n }\n\n _runInputLeakyRelu(input) {\n this.outputs[0] = input; // set output state of input layer\n\n let output = null;\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let weights = this.weights[layer][node];\n\n let sum = this.biases[layer][node];\n for (let k = 0; k < weights.length; k++) {\n sum += weights[k] * input[k];\n }\n //leaky relu\n this.outputs[layer][node] = (sum < 0 ? 0 : 0.01 * sum);\n }\n output = input = this.outputs[layer];\n }\n return output;\n }\n\n _runInputTanh(input) {\n this.outputs[0] = input; // set output state of input layer\n\n let output = null;\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let weights = this.weights[layer][node];\n\n let sum = this.biases[layer][node];\n for (let k = 0; k < weights.length; k++) {\n sum += weights[k] * input[k];\n }\n //tanh\n this.outputs[layer][node] = Math.tanh(sum);\n }\n output = input = this.outputs[layer];\n }\n return output;\n }\n\n /**\n *\n * @param data\n * Verifies network sizes are initilaized\n * If they are not it will initialize them based off the data set.\n */\n _verifyIsInitialized(data) {\n if (this.sizes) return;\n\n this.sizes = [];\n this.sizes.push(data[0].input.length);\n if (!this.hiddenSizes) {\n this.sizes.push(Math.max(3, Math.floor(data[0].input.length / 2)));\n } else {\n this.hiddenSizes.forEach(size => {\n this.sizes.push(size);\n });\n }\n this.sizes.push(data[0].output.length)\n\n this._initialize();\n }\n\n /**\n *\n * @param options\n * Supports all `trainDefaults` properties\n * also supports:\n * learningRate: (number),\n * momentum: (number),\n * activation: ['sigmoid', 'relu', 'leaky-relu', 'tanh']\n */\n _updateTrainingOptions(opts) {\n Object.keys(NeuralNetwork.trainDefaults).forEach(opt => this.trainOpts[opt] = opts[opt] || this.trainOpts[opt]);\n this._setLogMethod(opts.log || this.trainOpts.log);\n this.activation = opts.activation || this.activation;\n }\n\n /**\n *\n * Gets JSON of trainOpts object\n * NOTE: Activation is stored directly on JSON object and not in the training options\n */\n _getTrainOptsJSON() {\n return Object.keys(NeuralNetwork.trainDefaults)\n .reduce((opts, opt) => {\n if (this.trainOpts[opt]) opts[opt] = this.trainOpts[opt];\n if (opt === 'log') opts.log = typeof opts.log === 'function';\n return opts;\n }, {});\n }\n\n /**\n *\n * @param log\n * if a method is passed in method is used\n * if false passed in nothing is logged\n * @returns error\n */\n _setLogMethod(log) {\n if (typeof log === 'function'){\n this.trainOpts.log = log;\n } else if (log) {\n this.trainOpts.log = console.log;\n } else {\n this.trainOpts.log = false;\n }\n }\n\n /**\n *\n * @param data\n * @param learning Rate\n * @returns error\n */\n _calculateTrainingError(data) {\n let sum = 0;\n for (let i = 0; i < data.length; ++i) {\n sum += this._trainPattern(data[i].input, data[i].output);\n }\n return sum / data.length;\n }\n\n /**\n *\n * @param status { iterations: number, error: number}\n * @param options\n */\n _trainingTick(data, status, endTime) {\n if (status.iterations >= this.trainOpts.iterations || status.error <= this.trainOpts.errorThresh || Date.now() >= endTime) {\n return false;\n }\n\n status.iterations++;\n status.error = this._calculateTrainingError(data);\n\n if (this.trainOpts.log && (status.iterations % this.trainOpts.logPeriod === 0)) {\n this.trainOpts.log(`iterations: ${status.iterations}, training error: ${status.error}`);\n }\n\n if (this.trainOpts.callback && (status.iterations % this.trainOpts.callbackPeriod === 0)) {\n this.trainOpts.callback(Object.assign(status));\n }\n return true;\n }\n\n /**\n *\n * @param data\n * @param options\n * @private\n * @return {{runTrainingTick: function, status: {error: number, iterations: number}}}\n */\n _prepTraining(data, options) {\n this.updateTrainingOptions(options);\n data = this._formatData(data);\n const endTime = Date.now() + this.trainOpts.timeout;\n\n const status = {\n error: 1,\n iterations: 0\n };\n\n this._verifyIsInitialized(data);\n\n return {\n data,\n status,\n endTime\n }\n }\n\n /**\n *\n * @param data\n * @param options\n * @returns {{error: number, iterations: number}}\n */\n train(data, options = {}) {\n let status, endTime;\n ({ data, status, endTime } = this._prepTraining(data, options));\n\n while (this._trainingTick(data, status, endTime));\n return status;\n }\n\n /**\n *\n * @param data\n * @param options\n * @returns {Promise}\n * @resolves {{error: number, iterations: number}}\n * @rejects {{trainError: string, status: {error: number, iterations: number}}\n */\n trainAsync(data, options = {}) {\n let status, endTime;\n ({ data, status, endTime } = this._prepTraining(data, options));\n\n return new Promise((resolve, reject) => {\n try {\n const thawedTrain = new Thaw(new Array(this.trainOpts.iterations), {\n delay: true,\n each: () => this._trainingTick(data, status, endTime) || thawedTrain.stop(),\n done: () => resolve(status)\n });\n thawedTrain.tick();\n } catch (trainError) {\n reject({trainError, status});\n }\n });\n }\n\n /**\n *\n * @param input\n * @param target\n */\n _trainPattern(input, target) {\n\n // forward propagate\n this.runInput(input);\n\n // back propagate\n this.calculateDeltas(target);\n this._adjustWeights();\n\n let error = mse(this.errors[this.outputLayer]);\n return error;\n }\n\n /**\n *\n * @param target\n */\n _calculateDeltasSigmoid(target) {\n for (let layer = this.outputLayer; layer >= 0; layer--) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let output = this.outputs[layer][node];\n\n let error = 0;\n if (layer === this.outputLayer) {\n error = target[node] - output;\n }\n else {\n let deltas = this.deltas[layer + 1];\n for (let k = 0; k < deltas.length; k++) {\n error += deltas[k] * this.weights[layer + 1][k][node];\n }\n }\n this.errors[layer][node] = error;\n this.deltas[layer][node] = error * output * (1 - output);\n }\n }\n }\n\n /**\n *\n * @param target\n */\n _calculateDeltasRelu(target) {\n for (let layer = this.outputLayer; layer >= 0; layer--) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let output = this.outputs[layer][node];\n\n let error = 0;\n if (layer === this.outputLayer) {\n error = target[node] - output;\n }\n else {\n let deltas = this.deltas[layer + 1];\n for (let k = 0; k < deltas.length; k++) {\n error += deltas[k] * this.weights[layer + 1][k][node];\n }\n }\n this.errors[layer][node] = error;\n this.deltas[layer][node] = output > 0 ? error : 0;\n }\n }\n }\n\n /**\n *\n * @param target\n */\n _calculateDeltasLeakyRelu(target) {\n for (let layer = this.outputLayer; layer >= 0; layer--) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let output = this.outputs[layer][node];\n\n let error = 0;\n if (layer === this.outputLayer) {\n error = target[node] - output;\n }\n else {\n let deltas = this.deltas[layer + 1];\n for (let k = 0; k < deltas.length; k++) {\n error += deltas[k] * this.weights[layer + 1][k][node];\n }\n }\n this.errors[layer][node] = error;\n this.deltas[layer][node] = output > 0 ? error : 0.01 * error;\n }\n }\n }\n\n /**\n *\n * @param target\n */\n _calculateDeltasTanh(target) {\n for (let layer = this.outputLayer; layer >= 0; layer--) {\n for (let node = 0; node < this.sizes[layer]; node++) {\n let output = this.outputs[layer][node];\n\n let error = 0;\n if (layer === this.outputLayer) {\n error = target[node] - output;\n }\n else {\n let deltas = this.deltas[layer + 1];\n for (let k = 0; k < deltas.length; k++) {\n error += deltas[k] * this.weights[layer + 1][k][node];\n }\n }\n this.errors[layer][node] = error;\n this.deltas[layer][node] = (1 - output * output) * error;\n }\n }\n }\n\n /**\n *\n * Changes weights of networks\n */\n _adjustWeights() {\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n let incoming = this.outputs[layer - 1];\n\n for (let node = 0; node < this.sizes[layer]; node++) {\n let delta = this.deltas[layer][node];\n\n for (let k = 0; k < incoming.length; k++) {\n let change = this.changes[layer][node][k];\n\n change = (this.trainOpts.learningRate * delta * incoming[k])\n + (this.trainOpts.momentum * change);\n\n this.changes[layer][node][k] = change;\n this.weights[layer][node][k] += change;\n }\n this.biases[layer][node] += this.trainOpts.learningRate * delta;\n }\n }\n }\n\n /**\n *\n * @param data\n * @returns {*}\n */\n _formatData(data) {\n if (!Array.isArray(data)) { // turn stream datum into array\n let tmp = [];\n tmp.push(data);\n data = tmp;\n }\n // turn sparse hash input into arrays with 0s as filler\n let datum = data[0].input;\n if (!Array.isArray(datum) && !(datum instanceof Float32Array)) {\n if (!this.inputLookup) {\n this.inputLookup = lookup.buildLookup(data.map(value => value['input']));\n }\n data = data.map(datum => {\n let array = lookup.toArray(this.inputLookup, datum.input);\n return Object.assign({}, datum, { input: array });\n }, this);\n }\n\n if (!Array.isArray(data[0].output)) {\n if (!this.outputLookup) {\n this.outputLookup = lookup.buildLookup(data.map(value => value['output']));\n }\n data = data.map(datum => {\n let array = lookup.toArray(this.outputLookup, datum.output);\n return Object.assign({}, datum, { output: array });\n }, this);\n }\n return data;\n }\n\n /**\n *\n * @param data\n * @returns {\n * {\n * error: number,\n * misclasses: Array\n * }\n * }\n */\n test(data) {\n data = this._formatData(data);\n\n // for binary classification problems with one output node\n let isBinary = data[0].output.length === 1;\n let falsePos = 0;\n let falseNeg = 0;\n let truePos = 0;\n let trueNeg = 0;\n\n // for classification problems\n let misclasses = [];\n\n // run each pattern through the trained network and collect\n // error and misclassification statistics\n let sum = 0;\n for (let i = 0; i < data.length; i++) {\n let output = this.runInput(data[i].input);\n let target = data[i].output;\n\n let actual, expected;\n if (isBinary) {\n actual = output[0] > this.binaryThresh ? 1 : 0;\n expected = target[0];\n }\n else {\n actual = output.indexOf(max(output));\n expected = target.indexOf(max(target));\n }\n\n if (actual !== expected) {\n let misclass = data[i];\n Object.assign(misclass, {\n actual: actual,\n expected: expected\n });\n misclasses.push(misclass);\n }\n\n if (isBinary) {\n if (actual === 0 && expected === 0) {\n trueNeg++;\n } else if (actual === 1 && expected === 1) {\n truePos++;\n } else if (actual === 0 && expected === 1) {\n falseNeg++;\n } else if (actual === 1 && expected === 0) {\n falsePos++;\n }\n }\n\n let errors = output.map((value, i) => {\n return target[i] - value;\n });\n sum += mse(errors);\n }\n let error = sum / data.length;\n\n let stats = {\n error: error,\n misclasses: misclasses\n };\n\n if (isBinary) {\n Object.assign(stats, {\n trueNeg: trueNeg,\n truePos: truePos,\n falseNeg: falseNeg,\n falsePos: falsePos,\n total: data.length,\n precision: truePos / (truePos + falsePos),\n recall: truePos / (truePos + falseNeg),\n accuracy: (trueNeg + truePos) / data.length\n });\n }\n return stats;\n }\n\n /**\n *\n * @returns\n * {\n * layers: [\n * {\n * x: {},\n * y: {}\n * },\n * {\n * '0': {\n * bias: -0.98771313,\n * weights: {\n * x: 0.8374838,\n * y: 1.245858\n * },\n * '1': {\n * bias: 3.48192004,\n * weights: {\n * x: 1.7825821,\n * y: -2.67899\n * }\n * }\n * },\n * {\n * f: {\n * bias: 0.27205739,\n * weights: {\n * '0': 1.3161821,\n * '1': 2.00436\n * }\n * }\n * }\n * ]\n * }\n */\n toJSON() {\n let layers = [];\n for (let layer = 0; layer <= this.outputLayer; layer++) {\n layers[layer] = {};\n\n let nodes;\n // turn any internal arrays back into hashes for readable json\n if (layer === 0 && this.inputLookup) {\n nodes = Object.keys(this.inputLookup);\n }\n else if (layer === this.outputLayer && this.outputLookup) {\n nodes = Object.keys(this.outputLookup);\n }\n else {\n nodes = range(0, this.sizes[layer]);\n }\n\n for (let j = 0; j < nodes.length; j++) {\n let node = nodes[j];\n layers[layer][node] = {};\n\n if (layer > 0) {\n layers[layer][node].bias = this.biases[layer][j];\n layers[layer][node].weights = {};\n for (let k in layers[layer - 1]) {\n let index = k;\n if (layer === 1 && this.inputLookup) {\n index = this.inputLookup[k];\n }\n layers[layer][node].weights[k] = this.weights[layer][j][index];\n }\n }\n }\n }\n return {\n sizes: this.sizes,\n layers,\n outputLookup:!!this.outputLookup,\n inputLookup:!!this.inputLookup,\n activation: this.activation,\n trainOpts: this._getTrainOptsJSON()\n };\n }\n\n /**\n *\n * @param json\n * @returns {NeuralNetwork}\n */\n fromJSON (json) {\n this.sizes = json.sizes\n this._initialize();\n\n for (let i = 0; i <= this.outputLayer; i++) {\n let layer = json.layers[i];\n if (i === 0 && (!layer[0] || json.inputLookup)) {\n this.inputLookup = lookup.lookupFromHash(layer);\n }\n else if (i === this.outputLayer && (!layer[0] || json.outputLookup)) {\n this.outputLookup = lookup.lookupFromHash(layer);\n }\n if (i > 0) {\n const nodes = Object.keys(layer);\n this.sizes[i] = nodes.length;\n for (let j in nodes) {\n const node = nodes[j];\n this.biases[i][j] = layer[node].bias;\n this.weights[i][j] = toArray(layer[node].weights);\n }\n }\n }\n this._updateTrainingOptions(json.trainOpts)\n this.setActivation();\n return this;\n }\n\n /**\n *\n * @returns {Function}\n */\n toFunction() {\n const activation = this.activation;\n function nodeHandle(layers, layerNumber, nodeKey) {\n if (layerNumber === 0) {\n return (typeof nodeKey === 'string'\n ? `input['${nodeKey}']`\n : `input[${nodeKey}]`);\n }\n\n const layer = layers[layerNumber];\n const node = layer[nodeKey];\n let result = [node.bias];\n for (let w in node.weights) {\n if (node.weights[w] < 0) {\n result.push(`${node.weights[w]}*(${nodeHandle(layers, layerNumber - 1, w)})`);\n } else {\n result.push(`+${node.weights[w]}*(${nodeHandle(layers, layerNumber - 1, w)})`);\n }\n }\n\n switch (activation) {\n case 'sigmoid':\n return `1/(1+1/Math.exp(${result.join('')}))`;\n case 'relu':\n return `var sum = ${result.join('')};(sum < 0 ? 0 : sum);`;\n case 'leaky-relu':\n return `var sum = ${result.join('')};(sum < 0 ? 0 : 0.01 * sum);`;\n case 'tanh':\n return `Math.tanh(${result.join('')});`;\n default:\n throw new Error('unknown activation type ' + activation);\n }\n }\n\n const layers = this.toJSON().layers;\n const layersAsMath = [];\n let result;\n for (let i in layers[layers.length - 1]) {\n layersAsMath.push(nodeHandle(layers, layers.length - 1, i));\n }\n if (this.outputLookup) {\n result = `{${\n Object.keys(this.outputLookup)\n .map((key, i) => `'${key}':${layersAsMath[i]}`)\n }}`;\n } else {\n result = `[${layersAsMath.join(',')}]`;\n }\n return new Function('input', `return ${result}`);\n }\n\n /**\n * This will create a TrainStream (WriteStream) for us to send the training data to.\n * @param opts training options\n * @returns {TrainStream|*}\n */\n createTrainStream(opts) {\n opts = opts || {};\n opts.neuralNetwork = this;\n this.setActivation();\n this.trainStream = new TrainStream(opts);\n return this.trainStream;\n }\n}"]} \ No newline at end of file diff --git a/src/neural-network.js b/src/neural-network.js index 15370edac..d753a9cf8 100644 --- a/src/neural-network.js +++ b/src/neural-network.js @@ -39,7 +39,7 @@ export default class NeuralNetwork { Object.assign(this, this.constructor.defaults, options); this.hiddenSizes = options.hiddenLayers; this.trainOpts = {}; - this.updateTrainingOptions(Object.assign({}, this.constructor.trainDefaults, options)); + this._updateTrainingOptions(Object.assign({}, this.constructor.trainDefaults, options)); this.sizes = null; this.outputLayer = null; @@ -292,17 +292,10 @@ export default class NeuralNetwork { * momentum: (number), * activation: ['sigmoid', 'relu', 'leaky-relu', 'tanh'] */ - updateTrainingOptions(opts) { - if (opts.iterations) { this.trainOpts.iterations = opts.iterations; } - if (opts.errorThresh) { this.trainOpts.errorThresh = opts.errorThresh; } - if (opts.log) { this._setLogMethod(opts.log); } - if (opts.logPeriod) { this.trainOpts.logPeriod = opts.logPeriod; } - if (opts.learningRate) { this.trainOpts.learningRate = opts.learningRate; } - if (opts.momentum) { this.trainOpts.momentum = opts.momentum; } - if (opts.callback) { this.trainOpts.callback = opts.callback; } - if (opts.callbackPeriod) { this.trainOpts.callbackPeriod = opts.callbackPeriod; } - if (opts.timeout) { this.trainOpts.timeout = opts.timeout; } - if (opts.activation) { this.activation = opts.activation; } + _updateTrainingOptions(opts) { + Object.keys(NeuralNetwork.trainDefaults).forEach(opt => this.trainOpts[opt] = opts[opt] || this.trainOpts[opt]); + this._setLogMethod(opts.log || this.trainOpts.log); + this.activation = opts.activation || this.activation; } /** @@ -311,17 +304,12 @@ export default class NeuralNetwork { * NOTE: Activation is stored directly on JSON object and not in the training options */ _getTrainOptsJSON() { - let results = {} - if (this.trainOpts.iterations) { results.iterations = this.trainOpts.iterations; } - if (this.trainOpts.errorThresh) { results.errorThresh = this.trainOpts.errorThresh; } - if (this.trainOpts.logPeriod) { results.logPeriod = this.trainOpts.logPeriod; } - if (this.trainOpts.learningRate) { results.learningRate = this.trainOpts.learningRate; } - if (this.trainOpts.momentum) { results.momentum = this.trainOpts.momentum; } - if (this.trainOpts.callback) { results.callback = this.trainOpts.callback; } - if (this.trainOpts.callbackPeriod) { results.callbackPeriod = this.trainOpts.callbackPeriod; } - if (this.trainOpts.timeout) { results.timeout = this.trainOpts.timeout; } - if (this.trainOpts.log) { results.log = true; } - return results; + return Object.keys(NeuralNetwork.trainDefaults) + .reduce((opts, opt) => { + if (this.trainOpts[opt]) opts[opt] = this.trainOpts[opt]; + if (opt === 'log') opts.log = typeof opts.log === 'function'; + return opts; + }, {}); } /** @@ -386,7 +374,7 @@ export default class NeuralNetwork { * @return {{runTrainingTick: function, status: {error: number, iterations: number}}} */ _prepTraining(data, options) { - this.updateTrainingOptions(options); + this._updateTrainingOptions(options); data = this._formatData(data); const endTime = Date.now() + this.trainOpts.timeout; @@ -817,7 +805,7 @@ export default class NeuralNetwork { } } } - this.updateTrainingOptions(json.trainOpts) + this._updateTrainingOptions(json.trainOpts) this.setActivation(); return this; }