diff --git a/README.md b/README.md index 64ea87605..afb3e735c 100644 --- a/README.md +++ b/README.md @@ -279,8 +279,9 @@ With multiple networks you can train in parallel like this: ### Cross Validation [Cross Validation](https://en.wikipedia.org/wiki/Cross-validation_(statistics)) can provide a less fragile way of training on larger data sets. The brain.js api provides Cross Validation in this example: ```js -const crossValidate = new CrossValidate(brain.NeuralNetwork, networkOptions); -const stats = crossValidate.train(data, trainingOptions, k); //note k (or KFolds) is optional +const crossValidate = new brain.CrossValidate(brain.NeuralNetwork, networkOptions); +crossValidate.train(data, trainingOptions, k); //note k (or KFolds) is optional +const json = crossValidate.toJSON(); // all stats in json as well as neural networks const net = crossValidate.toNeuralNetwork(); diff --git a/bower.json b/bower.json index 1f808b5e9..ff65e808f 100644 --- a/bower.json +++ b/bower.json @@ -31,5 +31,5 @@ "node_modules", "test" ], - "version": "1.4.1" + "version": "1.4.2" } diff --git a/browser.js b/browser.js index 4053ac077..584003425 100644 --- a/browser.js +++ b/browser.js @@ -6,7 +6,7 @@ * license: MIT (http://opensource.org/licenses/MIT) * author: Heather Arthur * homepage: https://github.com/brainjs/brain.js#readme - * version: 1.4.1 + * version: 1.4.2 * * acorn: * license: MIT (http://opensource.org/licenses/MIT) @@ -214,8 +214,13 @@ var CrossValidate = function () { }, { key: "train", - value: function train(data, trainOpts, k) { - k = k || 4; + value: function train(data) { + var trainOpts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + var k = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4; + + if (data.length <= k) { + throw new Error("Training set size is too small for " + data.length + " k folds of " + k); + } var size = data.length / k; if (data.constructor === Array) { @@ -1946,8 +1951,8 @@ var NeuralNetwork = function () { falseNeg: falseNeg, falsePos: falsePos, total: data.length, - precision: truePos / (truePos + falsePos), - recall: truePos / (truePos + falseNeg), + precision: truePos > 0 ? truePos / (truePos + falsePos) : 0, + recall: truePos > 0 ? truePos / (truePos + falseNeg) : 0, accuracy: (trueNeg + truePos) / data.length }); } diff --git a/browser.min.js b/browser.min.js index 768781a3a..bc4d20aae 100644 --- a/browser.min.js +++ b/browser.min.js @@ -6,7 +6,7 @@ * license: MIT (http://opensource.org/licenses/MIT) * author: Heather Arthur * homepage: https://github.com/brainjs/brain.js#readme - * version: 1.4.1 + * version: 1.4.2 * * acorn: * license: MIT (http://opensource.org/licenses/MIT) @@ -112,7 +112,7 @@ * This header is generated by licensify (https://github.com/twada/licensify) */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.brain = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i0;r--){var t=Math.floor(Math.random()*(r+1)),n=e[r];e[r]=e[t],e[t]=n}return e}},{key:"train",value:function(e,r,t){t=t||4;var n=e.length/t;if(e.constructor===Array)this.shuffleArray(e);else{var i={};this.shuffleArray(Object.keys(e)).forEach(function(r){i[r]=e[r]}),e=i}for(var o={error:0,trainTime:0,testTime:0,iterations:0,trainError:0},s={truePos:0,trueNeg:0,falsePos:0,falseNeg:0,total:0},a=[],u=void 0,l=void 0,f=0;f0;r--){var t=Math.floor(Math.random()*(r+1)),n=e[r];e[r]=e[t],e[t]=n}return e}},{key:"train",value:function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=arguments.length>2&&void 0!==arguments[2]?arguments[2]:4;if(e.length<=t)throw new Error("Training set size is too small for "+e.length+" k folds of "+t);var n=e.length/t;if(e.constructor===Array)this.shuffleArray(e);else{var i={};this.shuffleArray(Object.keys(e)).forEach(function(r){i[r]=e[r]}),e=i}for(var o={error:0,trainTime:0,testTime:0,iterations:0,trainError:0},s={truePos:0,trueNeg:0,falsePos:0,falseNeg:0,total:0},a=[],l=void 0,u=void 0,f=0;fu&&(t=n,u=i)}return t}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=likely; @@ -123,7 +123,7 @@ "use strict";function _interopRequireDefault(t){return t&&t.__esModule?t:{default:t}}function _classCallCheck(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function _inherits(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function weightedSumSigmoid(t,e,a){for(var s=e[this.thread.x],i=0;i0?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 a=0,s=0;s0&&void 0!==arguments[0]?arguments[0]:{};_classCallCheck(this,e);var a=_possibleConstructorReturn(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,t));return a.forwardPropagate=[],a.backwardPropagate=[],a.changesPropagate=[],a.biasesPropagate=[],a.biasCopies=[],a.copyBias=[],a.changesCopies=[],a.copyChanges=[],a.weightsCopies=[],a.copyWeights=[],a.errorCheckInterval=100,a.gpu=new _gpu2.default({mode:t.mode}),a}return _inherits(e,t),_createClass(e,[{key:"_initialize",value:function(){_get(e.prototype.__proto__||Object.getPrototypeOf(e.prototype),"_initialize",this).call(this),this.buildRunInput(),this.buildCalculateDeltas(),this.buildGetChanges(),this.buildChangeBiases(),this.buildGetMSE()}},{key:"setActivation",value:function(){}},{key:"_trainPattern",value:function(t,e,a){return this.runInput(t),this.calculateDeltas(e),this.getChanges(),this.changeBiases(),a?this.getMSE(this.errors[this.outputLayer])[0]:null}},{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,hardcodeConstants:!0,constants:{size:this.sizes[e-1]}});this._texturizeInputData=this.gpu.createKernel(function(t){return t[this.thread.x]},{output:[this.sizes[1]],outputToTexture:!0,hardcodeConstants:!0,outputImmutable:!0})}},{key:"runInput",value:function(t){var e=void 0;this.outputs[0]=t;for(var a=1;a<=this.outputLayer;a++)this.outputs[a]=this.forwardPropagate[a](this.weights[a],this.biases[a],t),e=t=this.outputs[a];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,a){var s=e[this.thread.x];return t(calcErrorOutput(s,a),s)},{output:[this.sizes[e]],outputToTexture:!0,hardcodeConstants:!0}):this.backwardPropagate[e]=this.gpu.createKernelMap({error:_gpu2.default.alias("calcError",calcError),deltas:_gpu2.default.alias("calcDeltas",t)},function(e,a,s){var i=a[this.thread.x];return t(calcError(e,s),i)},{output:[this.sizes[e]],outputToTexture:!0,hardcodeConstants:!0,constants:{size:this.deltas[e+1].length}})}},{key:"calculateDeltas",value:function(t){for(var e=this.outputLayer;e>0;e--){var a=void 0;a=e===this.outputLayer?this.backwardPropagate[e](this.outputs[e],t):this.backwardPropagate[e](this.weights[e+1],this.outputs[e],this.deltas[e+1]),this.deltas[e]=a.deltas,this.errors[e]=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,a,s){return addWeights(calcChanges(s,e,t),a)},{output:[this.sizes[t-1],this.sizes[t]],outputToTexture:!0,hardcodeConstants:!0,constants:{size:this.outputs[t-1].length,learningRate:this.trainOpts.learningRate,momentum:this.trainOpts.momentum}}),this.copyChanges[t]=this.gpu.createKernel(function(t){return t[this.thread.y][this.thread.x]},{output:this.changesPropagate[t].output,outputToTexture:!0,hardCodeConstants:!0}),this.copyWeights[t]=this.gpu.createKernel(function(t){return t[this.thread.y][this.thread.x]},{output:this.changesPropagate[t].output,outputToTexture:!0,hardCodeConstants:!0})}},{key:"getChanges",value:function(){for(var t=1;t<=this.outputLayer;t++){var e=this.changesPropagate[t](this.outputs[t-1],this.deltas[t],this.weightsCopies[t]||this.weights[t],this.changesCopies[t]||this.changes[t]);this.changes[t]=e.changes,this.weights[t]=e.weights,this.changesCopies[t]=this.copyChanges[t](e.changes),this.weightsCopies[t]=this.copyWeights[t](e.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,hardcodeConstants:!0,constants:{learningRate:this.trainOpts.learningRate}}),this.copyBias[t]=this.gpu.createKernel(function(t){return t[this.thread.x]},{output:this.biasesPropagate[t].output,outputToTexture:!0,hardCodeConstants:!0})}},{key:"changeBiases",value:function(){for(var t=1;t<=this.outputLayer;t++)this.biases[t]=this.biasesPropagate[t](this.biasCopies[t]||this.biases[t],this.deltas[t]),this.biasCopies[t]=this.copyBias[t](this.biases[t])}},{key:"buildGetMSE",value:function(){this.getMSE=this.gpu.createKernel(mse,{output:[1],hardcodeConstants:!0,constants:{size:this.sizes[this.outputLayer]}})}},{key:"run",value:function(t){if(!this.isRunnable)return null;this.inputLookup&&(t=_lookup2.default.toArray(this.inputLookup,t));var e=this._texturizeInputData(t),a=this.runInput(e),s=a.toArray(this.gpu);return this.outputLookup&&(s=_lookup2.default.toHash(this.outputLookup,s)),s}},{key:"_verifyIsInitialized",value:function(t){var e=this;this.sizes||(this.sizes=[],t[0].size||(t[0].size={input:t[0].input.length,output:t[0].output.length}),this.sizes.push(t[0].size.input),this.hiddenSizes?this.hiddenSizes.forEach(function(t){e.sizes.push(t)}):this.sizes.push(Math.max(3,Math.floor(t[0].size.input/2))),this.sizes.push(t[0].size.output),this._initialize())}},{key:"_prepTraining",value:function(t,e){var a=this;this._updateTrainingOptions(e),t=this._formatData(t);var s=Date.now()+this.trainOpts.timeout,i={error:1,iterations:0};this._verifyIsInitialized(t);var r=this.gpu.createKernel(function(t){return t[this.thread.x]},{output:[t[0].output.length],outputToTexture:!0,hardcodeConstants:!0,outputImmutable:!0});return{data:t.map(function(t){return{size:t.size,input:a._texturizeInputData(t.input),output:r(t.output)}}),status:i,endTime:s}}},{key:"toFunction",value:function(){throw new Error("not implemented on NeuralNetworkGPU")}}]),e}(_neuralNetwork2.default);exports.default=NeuralNetworkGPU; },{"./lookup":3,"./neural-network":5,"gpu.js":86}],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.errorCheckInterval=1,this.constructor.prototype.hasOwnProperty("runInput")||(this.runInput=null),this.constructor.prototype.hasOwnProperty("calculateDeltas")||(this.calculateDeltas=null)}return _createClass(t,null,[{key:"_validateTrainingOptions",value:function(i){var e={iterations:function(t){return"number"==typeof t&&t>0},errorThresh:function(t){return"number"==typeof t&&t>0&&t<1},log:function(t){return"function"==typeof t||"boolean"==typeof t},logPeriod:function(t){return"number"==typeof t&&t>0},learningRate:function(t){return"number"==typeof t&&t>0&&t<1},momentum:function(t){return"number"==typeof t&&t>0&&t<1},callback:function(t){return"function"==typeof t||null===t},callbackPeriod:function(t){return"number"==typeof t&&t>0},timeout:function(t){return"number"==typeof t&&t>0}};Object.keys(t.trainDefaults).forEach(function(t){if(e.hasOwnProperty(t)&&!e[t](i[t]))throw new Error("["+t+", "+i[t]+"] is out of normal training range, your network will probably not train.")})}},{key:"trainDefaults",get:function(){return{iterations:2e4,errorThresh:.005,log:!1,logPeriod:10,learningRate:.3,momentum:.1,callback:null,callbackPeriod:10,timeout:1/0,praxis:null,beta1:.9,beta2:.999,epsilon:1e-8}}},{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++,this.trainOpts.log&&i.iterations%this.trainOpts.logPeriod==0?(i.error=this._calculateTrainingError(t),this.trainOpts.log("iterations: "+i.iterations+", training error: "+i.error)):i.iterations%this.errorCheckInterval==0?i.error=this._calculateTrainingError(t):this._trainPatterns(t),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,"adam"===i.praxis&&this._setupAdam();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 n=new _thaw2.default(new Array(i.trainOpts.iterations),{delay:!0,each:function(){return i._trainingTick(t,s,r)||n.stop()},done:function(){return e(s)}});n.tick()}catch(t){a({trainError:t,status:s})}})}},{key:"_trainPattern",value:function(t,i,e){return this.runInput(t),this.calculateDeltas(i),this._adjustWeights(),e?(0,_mse2.default)(this.errors[this.outputLayer]):null}},{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;e0){this.biasChangesLow[t]=(0,_zeros2.default)(i),this.biasChangesHigh[t]=(0,_zeros2.default)(i),this.changesLow[t]=new Array(i),this.changesHigh[t]=new Array(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 g=t[h];Object.assign(g,{actual:c,expected:f}),u.push(g)}e&&(0===c&&0===f?n++:1===c&&1===f?a++:0===c&&1===f?r++:1===c&&0===f&&s++);var v=l.map(function(t,i){return p[i]-t});o+=(0,_mse2.default)(v)}(h);var l=o/t.length,p={error:l,misclasses:u};return e&&Object.assign(p,{trueNeg:n,truePos:a,falseNeg:r,falsePos:s,total:t.length,precision:a/(a+s),recall:a/(a+r),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 s=0;s0){t[i][r].bias=this.biases[i][s],t[i][r].weights={};for(var a in t[i-1]){var n=a;1===i&&this.inputLookup&&(n=this.inputLookup[a]),t[i][r].weights[a]=this.weights[i][s][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 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 t.hasOwnProperty("trainOpts")&&this._updateTrainingOptions(t.trainOpts),this.setActivation(this.activation||"sigmoid"),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],n=a[r],u=[n.bias];for(var o in n.weights)n.weights[o]<0?u.push(n.weights[o]+"*("+t(e,s-1,o)+")"):u.push("+"+n.weights[o]+"*("+t(e,s-1,o)+")");switch(i){case"sigmoid":return"1/(1+1/Math.exp("+u.join("")+"))";case"relu":return"("+u.join("")+" < 0 ? 0 : "+u.join("")+")";case"leaky-relu":return"("+u.join("")+" < 0 ? 0 : 0.01 * "+u.join("")+")";case"tanh":return"Math.tanh("+u.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:"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.errorCheckInterval=1,this.constructor.prototype.hasOwnProperty("runInput")||(this.runInput=null),this.constructor.prototype.hasOwnProperty("calculateDeltas")||(this.calculateDeltas=null)}return _createClass(t,null,[{key:"_validateTrainingOptions",value:function(i){var e={iterations:function(t){return"number"==typeof t&&t>0},errorThresh:function(t){return"number"==typeof t&&t>0&&t<1},log:function(t){return"function"==typeof t||"boolean"==typeof t},logPeriod:function(t){return"number"==typeof t&&t>0},learningRate:function(t){return"number"==typeof t&&t>0&&t<1},momentum:function(t){return"number"==typeof t&&t>0&&t<1},callback:function(t){return"function"==typeof t||null===t},callbackPeriod:function(t){return"number"==typeof t&&t>0},timeout:function(t){return"number"==typeof t&&t>0}};Object.keys(t.trainDefaults).forEach(function(t){if(e.hasOwnProperty(t)&&!e[t](i[t]))throw new Error("["+t+", "+i[t]+"] is out of normal training range, your network will probably not train.")})}},{key:"trainDefaults",get:function(){return{iterations:2e4,errorThresh:.005,log:!1,logPeriod:10,learningRate:.3,momentum:.1,callback:null,callbackPeriod:10,timeout:1/0,praxis:null,beta1:.9,beta2:.999,epsilon:1e-8}}},{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++,this.trainOpts.log&&i.iterations%this.trainOpts.logPeriod==0?(i.error=this._calculateTrainingError(t),this.trainOpts.log("iterations: "+i.iterations+", training error: "+i.error)):i.iterations%this.errorCheckInterval==0?i.error=this._calculateTrainingError(t):this._trainPatterns(t),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,"adam"===i.praxis&&this._setupAdam();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 n=new _thaw2.default(new Array(i.trainOpts.iterations),{delay:!0,each:function(){return i._trainingTick(t,s,r)||n.stop()},done:function(){return e(s)}});n.tick()}catch(t){a({trainError:t,status:s})}})}},{key:"_trainPattern",value:function(t,i,e){return this.runInput(t),this.calculateDeltas(i),this._adjustWeights(),e?(0,_mse2.default)(this.errors[this.outputLayer]):null}},{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;e0){this.biasChangesLow[t]=(0,_zeros2.default)(i),this.biasChangesHigh[t]=(0,_zeros2.default)(i),this.changesLow[t]=new Array(i),this.changesHigh[t]=new Array(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 g=t[h];Object.assign(g,{actual:c,expected:f}),u.push(g)}e&&(0===c&&0===f?n++:1===c&&1===f?a++:0===c&&1===f?r++:1===c&&0===f&&s++);var v=l.map(function(t,i){return p[i]-t});o+=(0,_mse2.default)(v)}(h);var l=o/t.length,p={error:l,misclasses:u};return e&&Object.assign(p,{trueNeg:n,truePos:a,falseNeg:r,falsePos:s,total:t.length,precision:a>0?a/(a+s):0,recall:a>0?a/(a+r):0,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 s=0;s0){t[i][r].bias=this.biases[i][s],t[i][r].weights={};for(var a in t[i-1]){var n=a;1===i&&this.inputLookup&&(n=this.inputLookup[a]),t[i][r].weights[a]=this.weights[i][s][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 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 t.hasOwnProperty("trainOpts")&&this._updateTrainingOptions(t.trainOpts),this.setActivation(this.activation||"sigmoid"),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],n=a[r],u=[n.bias];for(var o in n.weights)n.weights[o]<0?u.push(n.weights[o]+"*("+t(e,s-1,o)+")"):u.push("+"+n.weights[o]+"*("+t(e,s-1,o)+")");switch(i){case"sigmoid":return"1/(1+1/Math.exp("+u.join("")+"))";case"relu":return"("+u.join("")+" < 0 ? 0 : "+u.join("")+")";case"leaky-relu":return"("+u.join("")+" < 0 ? 0 : 0.01 * "+u.join("")+")";case"tanh":return"Math.tanh("+u.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:"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,"./utilities/max":38,"./utilities/mse":39,"./utilities/randos":43,"./utilities/range":44,"./utilities/to-array":45,"./utilities/zeros":46,"thaw.js":110}],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;r=i)return i;var s=e.charCodeAt(t);return!this.switchU||s<=55295||s>=57344||t+1>=i?t+1:t+2},Et.prototype.current=function(){return this.at(this.pos)},Et.prototype.lookahead=function(){return this.at(this.nextIndex(this.pos))},Et.prototype.advance=function(){this.pos=this.nextIndex(this.pos)},Et.prototype.eat=function(t){return this.current()===t&&(this.advance(),!0)},St.validateRegExpFlags=function(t){for(var e=this,i=t.validFlags,s=t.flags,r=0;r-1&&e.raise(t.start,"Duplicate regular expression flag")}},St.validateRegExpPattern=function(t){this.regexp_pattern(t),!t.switchN&&this.options.ecmaVersion>=9&&t.groupNames.length>0&&(t.switchN=!0,this.regexp_pattern(t))},St.regexp_pattern=function(t){t.pos=0,t.lastIntValue=0,t.lastStringValue="",t.lastAssertionIsQuantifiable=!1,t.numCapturingParens=0,t.maxBackReference=0,t.groupNames.length=0,t.backReferenceNames.length=0,this.regexp_disjunction(t),t.pos!==t.source.length&&(t.eat(41)&&t.raise("Unmatched ')'"),(t.eat(93)||t.eat(125))&&t.raise("Lone quantifier brackets")),t.maxBackReference>t.numCapturingParens&&t.raise("Invalid escape");for(var e=0,i=t.backReferenceNames;e=9&&(i=t.eat(60)),t.eat(61)||t.eat(33))return this.regexp_disjunction(t),t.eat(41)||t.raise("Unterminated group"),t.lastAssertionIsQuantifiable=!i,!0}return t.pos=e,!1},St.regexp_eatQuantifier=function(t,e){return void 0===e&&(e=!1),!!this.regexp_eatQuantifierPrefix(t,e)&&(t.eat(63),!0)},St.regexp_eatQuantifierPrefix=function(t,e){return t.eat(42)||t.eat(43)||t.eat(63)||this.regexp_eatBracedQuantifier(t,e)},St.regexp_eatBracedQuantifier=function(t,e){var i=t.pos;if(t.eat(123)){var s=0,r=-1;if(this.regexp_eatDecimalDigits(t)&&(s=t.lastIntValue,t.eat(44)&&this.regexp_eatDecimalDigits(t)&&(r=t.lastIntValue),t.eat(125)))return-1!==r&&r=9?this.regexp_groupSpecifier(t):63===t.current()&&t.raise("Invalid group"),this.regexp_disjunction(t),t.eat(41))return t.numCapturingParens+=1,!0;t.raise("Unterminated group")}return!1},St.regexp_eatExtendedAtom=function(t){return t.eat(46)||this.regexp_eatReverseSolidusAtomEscape(t)||this.regexp_eatCharacterClass(t)||this.regexp_eatUncapturingGroup(t)||this.regexp_eatCapturingGroup(t)||this.regexp_eatInvalidBracedQuantifier(t)||this.regexp_eatExtendedPatternCharacter(t)},St.regexp_eatInvalidBracedQuantifier=function(t){return this.regexp_eatBracedQuantifier(t,!0)&&t.raise("Nothing to repeat"),!1},St.regexp_eatSyntaxCharacter=function(t){var e=t.current();return!!m(e)&&(t.lastIntValue=e,t.advance(),!0)},St.regexp_eatPatternCharacters=function(t){for(var e=t.pos,i=0;-1!==(i=t.current())&&!m(i);)t.advance();return t.pos!==e},St.regexp_eatExtendedPatternCharacter=function(t){var e=t.current();return!(-1===e||36===e||e>=40&&e<=43||46===e||63===e||91===e||94===e||124===e)&&(t.advance(),!0)},St.regexp_groupSpecifier=function(t){if(t.eat(63)){if(this.regexp_eatGroupName(t))return-1!==t.groupNames.indexOf(t.lastStringValue)&&t.raise("Duplicate capture group name"),void t.groupNames.push(t.lastStringValue);t.raise("Invalid group")}},St.regexp_eatGroupName=function(t){if(t.lastStringValue="",t.eat(60)){if(this.regexp_eatRegExpIdentifierName(t)&&t.eat(62))return!0;t.raise("Invalid capture group name")}return!1},St.regexp_eatRegExpIdentifierName=function(t){if(t.lastStringValue="",this.regexp_eatRegExpIdentifierStart(t)){for(t.lastStringValue+=f(t.lastIntValue);this.regexp_eatRegExpIdentifierPart(t);)t.lastStringValue+=f(t.lastIntValue);return!0}return!1},St.regexp_eatRegExpIdentifierStart=function(t){var e=t.pos,i=t.current();return t.advance(),92===i&&this.regexp_eatRegExpUnicodeEscapeSequence(t)&&(i=t.lastIntValue),x(i)?(t.lastIntValue=i,!0):(t.pos=e,!1)},St.regexp_eatRegExpIdentifierPart=function(t){var e=t.pos,i=t.current();return t.advance(),92===i&&this.regexp_eatRegExpUnicodeEscapeSequence(t)&&(i=t.lastIntValue),g(i)?(t.lastIntValue=i,!0):(t.pos=e,!1)},St.regexp_eatAtomEscape=function(t){return!!(this.regexp_eatBackReference(t)||this.regexp_eatCharacterClassEscape(t)||this.regexp_eatCharacterEscape(t)||t.switchN&&this.regexp_eatKGroupName(t))||(t.switchU&&(99===t.current()&&t.raise("Invalid unicode escape"),t.raise("Invalid escape")),!1)},St.regexp_eatBackReference=function(t){var e=t.pos;if(this.regexp_eatDecimalEscape(t)){var i=t.lastIntValue;if(t.switchU)return i>t.maxBackReference&&(t.maxBackReference=i),!0;if(i<=t.numCapturingParens)return!0;t.pos=e}return!1},St.regexp_eatKGroupName=function(t){if(t.eat(107)){if(this.regexp_eatGroupName(t))return t.backReferenceNames.push(t.lastStringValue),!0;t.raise("Invalid named reference")}return!1},St.regexp_eatCharacterEscape=function(t){return this.regexp_eatControlEscape(t)||this.regexp_eatCControlLetter(t)||this.regexp_eatZero(t)||this.regexp_eatHexEscapeSequence(t)||this.regexp_eatRegExpUnicodeEscapeSequence(t)||!t.switchU&&this.regexp_eatLegacyOctalEscapeSequence(t)||this.regexp_eatIdentityEscape(t)},St.regexp_eatCControlLetter=function(t){var e=t.pos;if(t.eat(99)){if(this.regexp_eatControlLetter(t))return!0;t.pos=e}return!1},St.regexp_eatZero=function(t){return 48===t.current()&&!C(t.lookahead())&&(t.lastIntValue=0,t.advance(),!0)},St.regexp_eatControlEscape=function(t){var e=t.current();return 116===e?(t.lastIntValue=9,t.advance(),!0):110===e?(t.lastIntValue=10,t.advance(),!0):118===e?(t.lastIntValue=11,t.advance(),!0):102===e?(t.lastIntValue=12,t.advance(),!0):114===e&&(t.lastIntValue=13,t.advance(),!0)},St.regexp_eatControlLetter=function(t){var e=t.current();return!!v(e)&&(t.lastIntValue=e%32,t.advance(),!0)},St.regexp_eatRegExpUnicodeEscapeSequence=function(t){var e=t.pos;if(t.eat(117)){if(this.regexp_eatFixedHexDigits(t,4)){var i=t.lastIntValue;if(t.switchU&&i>=55296&&i<=56319){var s=t.pos;if(t.eat(92)&&t.eat(117)&&this.regexp_eatFixedHexDigits(t,4)){var r=t.lastIntValue;if(r>=56320&&r<=57343)return t.lastIntValue=1024*(i-55296)+(r-56320)+65536,!0}t.pos=s,t.lastIntValue=i}return!0}if(t.switchU&&t.eat(123)&&this.regexp_eatHexDigits(t)&&t.eat(125)&&y(t.lastIntValue))return!0;t.switchU&&t.raise("Invalid unicode escape"),t.pos=e}return!1},St.regexp_eatIdentityEscape=function(t){if(t.switchU)return!!this.regexp_eatSyntaxCharacter(t)||!!t.eat(47)&&(t.lastIntValue=47,!0);var e=t.current();return!(99===e||t.switchN&&107===e)&&(t.lastIntValue=e,t.advance(),!0)},St.regexp_eatDecimalEscape=function(t){t.lastIntValue=0;var e=t.current();if(e>=49&&e<=57){do{t.lastIntValue=10*t.lastIntValue+(e-48),t.advance()}while((e=t.current())>=48&&e<=57);return!0}return!1},St.regexp_eatCharacterClassEscape=function(t){var e=t.current();if(_(e))return t.lastIntValue=-1,t.advance(),!0;if(t.switchU&&this.options.ecmaVersion>=9&&(80===e||112===e)){if(t.lastIntValue=-1,t.advance(),t.eat(123)&&this.regexp_eatUnicodePropertyValueExpression(t)&&t.eat(125))return!0;t.raise("Invalid property name")}return!1},St.regexp_eatUnicodePropertyValueExpression=function(t){var e=t.pos;if(this.regexp_eatUnicodePropertyName(t)&&t.eat(61)){var i=t.lastStringValue;if(this.regexp_eatUnicodePropertyValue(t)){var s=t.lastStringValue;return this.regexp_validateUnicodePropertyNameAndValue(t,i,s),!0}}if(t.pos=e,this.regexp_eatLoneUnicodePropertyNameOrValue(t)){var r=t.lastStringValue;return this.regexp_validateUnicodePropertyNameOrValue(t,r),!0}return!1},St.regexp_validateUnicodePropertyNameAndValue=function(t,e,i){Ct.hasOwnProperty(e)&&-1!==Ct[e].indexOf(i)||t.raise("Invalid property name")},St.regexp_validateUnicodePropertyNameOrValue=function(t,e){-1===Ct.$LONE.indexOf(e)&&t.raise("Invalid property name")},St.regexp_eatUnicodePropertyName=function(t){var e=0;for(t.lastStringValue="";b(e=t.current());)t.lastStringValue+=f(e),t.advance();return""!==t.lastStringValue},St.regexp_eatUnicodePropertyValue=function(t){var e=0;for(t.lastStringValue="";k(e=t.current());)t.lastStringValue+=f(e),t.advance();return""!==t.lastStringValue},St.regexp_eatLoneUnicodePropertyNameOrValue=function(t){return this.regexp_eatUnicodePropertyValue(t)},St.regexp_eatCharacterClass=function(t){if(t.eat(91)){if(t.eat(94),this.regexp_classRanges(t),t.eat(93))return!0;t.raise("Unterminated character class")}return!1},St.regexp_classRanges=function(t){for(var e=this;this.regexp_eatClassAtom(t);){var i=t.lastIntValue;if(t.eat(45)&&e.regexp_eatClassAtom(t)){var s=t.lastIntValue;!t.switchU||-1!==i&&-1!==s||t.raise("Invalid character class"),-1!==i&&-1!==s&&i>s&&t.raise("Range out of order in character class")}}},St.regexp_eatClassAtom=function(t){var e=t.pos;if(t.eat(92)){if(this.regexp_eatClassEscape(t))return!0;if(t.switchU){var i=t.current();(99===i||w(i))&&t.raise("Invalid class escape"),t.raise("Invalid escape")}t.pos=e}var s=t.current();return 93!==s&&(t.lastIntValue=s,t.advance(),!0)},St.regexp_eatClassEscape=function(t){var e=t.pos;if(t.eat(98))return t.lastIntValue=8,!0;if(t.switchU&&t.eat(45))return t.lastIntValue=45,!0;if(!t.switchU&&t.eat(99)){if(this.regexp_eatClassControlLetter(t))return!0;t.pos=e}return this.regexp_eatCharacterClassEscape(t)||this.regexp_eatCharacterEscape(t)},St.regexp_eatClassControlLetter=function(t){var e=t.current();return!(!C(e)&&95!==e)&&(t.lastIntValue=e%32,t.advance(),!0)},St.regexp_eatHexEscapeSequence=function(t){var e=t.pos;if(t.eat(120)){if(this.regexp_eatFixedHexDigits(t,2))return!0;t.switchU&&t.raise("Invalid escape"),t.pos=e}return!1},St.regexp_eatDecimalDigits=function(t){var e=t.pos,i=0;for(t.lastIntValue=0;C(i=t.current());)t.lastIntValue=10*t.lastIntValue+(i-48),t.advance();return t.pos!==e},St.regexp_eatHexDigits=function(t){var e=t.pos,i=0;for(t.lastIntValue=0;S(i=t.current());)t.lastIntValue=16*t.lastIntValue+E(i),t.advance();return t.pos!==e},St.regexp_eatLegacyOctalEscapeSequence=function(t){if(this.regexp_eatOctalDigit(t)){var e=t.lastIntValue;if(this.regexp_eatOctalDigit(t)){var i=t.lastIntValue;e<=3&&this.regexp_eatOctalDigit(t)?t.lastIntValue=64*e+8*i+t.lastIntValue:t.lastIntValue=8*e+i}else t.lastIntValue=e;return!0}return!1},St.regexp_eatOctalDigit=function(t){var e=t.current();return w(e)?(t.lastIntValue=e-48,t.advance(),!0):(t.lastIntValue=0,!1)},St.regexp_eatFixedHexDigits=function(t,e){var i=t.pos;t.lastIntValue=0;for(var s=0;s=this.input.length?this.finishToken(z.eof):t.override?t.override(this):void this.readToken(this.fullCharCodeAtPos())},At.readToken=function(t){return i(t,this.options.ecmaVersion>=6)||92===t?this.readWord():this.getTokenFromCode(t)},At.fullCharCodeAtPos=function(){var t=this.input.charCodeAt(this.pos);return t<=55295||t>=57344?t:(t<<10)+this.input.charCodeAt(this.pos+1)-56613888},At.skipBlockComment=function(){var t=this,e=this.options.onComment&&this.curPosition(),i=this.pos,s=this.input.indexOf("*/",this.pos+=2);if(-1===s&&this.raise(this.pos-2,"Unterminated comment"),this.pos=s+2,this.options.locations){K.lastIndex=i;for(var r;(r=K.exec(this.input))&&r.index8&&e<14||e>=5760&&X.test(String.fromCharCode(e))))break t;++t.pos}}},At.finishToken=function(t,e){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var i=this.type;this.type=t,this.value=e,this.updateContext(i)},At.readToken_dot=function(){var t=this.input.charCodeAt(this.pos+1);if(t>=48&&t<=57)return this.readNumber(!0);var e=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===t&&46===e?(this.pos+=3,this.finishToken(z.ellipsis)):(++this.pos,this.finishToken(z.dot))},At.readToken_slash=function(){var t=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===t?this.finishOp(z.assign,2):this.finishOp(z.slash,1)},At.readToken_mult_modulo_exp=function(t){var e=this.input.charCodeAt(this.pos+1),i=1,s=42===t?z.star:z.modulo;return this.options.ecmaVersion>=7&&42===t&&42===e&&(++i,s=z.starstar,e=this.input.charCodeAt(this.pos+2)),61===e?this.finishOp(z.assign,i+1):this.finishOp(s,i)},At.readToken_pipe_amp=function(t){var e=this.input.charCodeAt(this.pos+1);return e===t?this.finishOp(124===t?z.logicalOR:z.logicalAND,2):61===e?this.finishOp(z.assign,2):this.finishOp(124===t?z.bitwiseOR:z.bitwiseAND,1)},At.readToken_caret=function(){return 61===this.input.charCodeAt(this.pos+1)?this.finishOp(z.assign,2):this.finishOp(z.bitwiseXOR,1)},At.readToken_plus_min=function(t){var e=this.input.charCodeAt(this.pos+1);return e===t?45!==e||this.inModule||62!==this.input.charCodeAt(this.pos+2)||0!==this.lastTokEnd&&!Q.test(this.input.slice(this.lastTokEnd,this.pos))?this.finishOp(z.incDec,2):(this.skipLineComment(3),this.skipSpace(),this.nextToken()):61===e?this.finishOp(z.assign,2):this.finishOp(z.plusMin,1)},At.readToken_lt_gt=function(t){var e=this.input.charCodeAt(this.pos+1),i=1;return e===t?(i=62===t&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+i)?this.finishOp(z.assign,i+1):this.finishOp(z.bitShift,i)):33!==e||60!==t||this.inModule||45!==this.input.charCodeAt(this.pos+2)||45!==this.input.charCodeAt(this.pos+3)?(61===e&&(i=2),this.finishOp(z.relational,i)):(this.skipLineComment(4),this.skipSpace(),this.nextToken())},At.readToken_eq_excl=function(t){var e=this.input.charCodeAt(this.pos+1);return 61===e?this.finishOp(z.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===t&&62===e&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(z.arrow)):this.finishOp(61===t?z.eq:z.prefix,1)},At.getTokenFromCode=function(t){switch(t){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(z.parenL);case 41:return++this.pos,this.finishToken(z.parenR);case 59:return++this.pos,this.finishToken(z.semi);case 44:return++this.pos,this.finishToken(z.comma);case 91:return++this.pos,this.finishToken(z.bracketL);case 93:return++this.pos,this.finishToken(z.bracketR);case 123:return++this.pos,this.finishToken(z.braceL);case 125:return++this.pos,this.finishToken(z.braceR);case 58:return++this.pos,this.finishToken(z.colon);case 63:return++this.pos,this.finishToken(z.question);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(z.backQuote);case 48:var e=this.input.charCodeAt(this.pos+1);if(120===e||88===e)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===e||79===e)return this.readRadixNumber(8);if(98===e||66===e)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(t);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo_exp(t);case 124:case 38:return this.readToken_pipe_amp(t);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(t);case 60:case 62:return this.readToken_lt_gt(t);case 61:case 33:return this.readToken_eq_excl(t);case 126:return this.finishOp(z.prefix,1)}this.raise(this.pos,"Unexpected character '"+A(t)+"'")},At.finishOp=function(t,e){var i=this.input.slice(this.pos,this.pos+e);return this.pos+=e,this.finishToken(t,i)},At.readRegexp=function(){for(var t,e,i=this,s=this.pos;;){i.pos>=i.input.length&&i.raise(s,"Unterminated regular expression");var r=i.input.charAt(i.pos);if(Q.test(r)&&i.raise(s,"Unterminated regular expression"),t)t=!1;else{if("["===r)e=!0;else if("]"===r&&e)e=!1;else if("/"===r&&!e)break;t="\\"===r}++i.pos}var a=this.input.slice(s,this.pos);++this.pos;var n=this.pos,o=this.readWord1();this.containsEsc&&this.unexpected(n);var h=this.regexpState||(this.regexpState=new Et(this));h.reset(s,a,o),this.validateRegExpFlags(h),this.validateRegExpPattern(h);var p=null;try{p=new RegExp(a,o)}catch(t){}return this.finishToken(z.regexp,{pattern:a,flags:o,value:p})},At.readInt=function(t,e){for(var i=this,s=this.pos,r=0,a=0,n=null==e?1/0:e;a=97?o-97+10:o>=65?o-65+10:o>=48&&o<=57?o-48:1/0)>=t)break;++i.pos,r=r*t+h}return this.pos===s||null!=e&&this.pos-s!==e?null:r},At.readRadixNumber=function(t){this.pos+=2;var e=this.readInt(t);return null==e&&this.raise(this.start+2,"Expected number in radix "+t),i(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(z.num,e)},At.readNumber=function(t){var e=this.pos;t||null!==this.readInt(10)||this.raise(e,"Invalid number");var s=this.pos-e>=2&&48===this.input.charCodeAt(e);s&&this.strict&&this.raise(e,"Invalid number"),s&&/[89]/.test(this.input.slice(e,this.pos))&&(s=!1);var r=this.input.charCodeAt(this.pos);46!==r||s||(++this.pos,this.readInt(10),r=this.input.charCodeAt(this.pos)),69!==r&&101!==r||s||(r=this.input.charCodeAt(++this.pos),43!==r&&45!==r||++this.pos,null===this.readInt(10)&&this.raise(e,"Invalid number")),i(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var a=this.input.slice(e,this.pos),n=s?parseInt(a,8):parseFloat(a);return this.finishToken(z.num,n)},At.readCodePoint=function(){var t,e=this.input.charCodeAt(this.pos);if(123===e){this.options.ecmaVersion<6&&this.unexpected();var i=++this.pos;t=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,t>1114111&&this.invalidStringToken(i,"Code point out of bounds")}else t=this.readHexChar(4);return t},At.readString=function(t){for(var e=this,i="",s=++this.pos;;){e.pos>=e.input.length&&e.raise(e.start,"Unterminated string constant");var r=e.input.charCodeAt(e.pos);if(r===t)break;92===r?(i+=e.input.slice(s,e.pos),i+=e.readEscapedChar(!1),s=e.pos):(n(r,e.options.ecmaVersion>=10)&&e.raise(e.start,"Unterminated string constant"),++e.pos)}return i+=this.input.slice(s,this.pos++),this.finishToken(z.string,i)};var It={};At.tryReadTemplateToken=function(){this.inTemplateElement=!0;try{this.readTmplToken()}catch(t){if(t!==It)throw t;this.readInvalidTemplateToken()}this.inTemplateElement=!1},At.invalidStringToken=function(t,e){if(this.inTemplateElement&&this.options.ecmaVersion>=9)throw It;this.raise(t,e)},At.readTmplToken=function(){for(var t=this,e="",i=this.pos;;){t.pos>=t.input.length&&t.raise(t.start,"Unterminated template");var s=t.input.charCodeAt(t.pos);if(96===s||36===s&&123===t.input.charCodeAt(t.pos+1))return t.pos!==t.start||t.type!==z.template&&t.type!==z.invalidTemplate?(e+=t.input.slice(i,t.pos),t.finishToken(z.template,e)):36===s?(t.pos+=2,t.finishToken(z.dollarBraceL)):(++t.pos,t.finishToken(z.backQuote));if(92===s)e+=t.input.slice(i,t.pos),e+=t.readEscapedChar(!0),i=t.pos;else if(n(s)){switch(e+=t.input.slice(i,t.pos),++t.pos,s){case 13:10===t.input.charCodeAt(t.pos)&&++t.pos;case 10:e+="\n";break;default:e+=String.fromCharCode(s)}t.options.locations&&(++t.curLine,t.lineStart=t.pos),i=t.pos}else++t.pos}},At.readInvalidTemplateToken=function(){for(var t=this;this.pos=48&&e<=55){var i=this.input.substr(this.pos-1,3).match(/^[0-7]+/)[0],s=parseInt(i,8);return s>255&&(i=i.slice(0,-1),s=parseInt(i,8)),this.pos+=i.length-1,e=this.input.charCodeAt(this.pos),"0"===i&&56!==e&&57!==e||!this.strict&&!t||this.invalidStringToken(this.pos-1-i.length,t?"Octal literal in template string":"Octal literal in strict mode"),String.fromCharCode(s)}return String.fromCharCode(e)}},At.readHexChar=function(t){var e=this.pos,i=this.readInt(16,t);return null===i&&this.invalidStringToken(e,"Bad character escape sequence"),i},At.readWord1=function(){var t=this;this.containsEsc=!1;for(var e="",r=!0,a=this.pos,n=this.options.ecmaVersion>=6;this.pos0)throw new Error("Invalid string. Length must be a multiple of 4");var e=o.indexOf("=");return-1===e&&(e=r),[e,e===r?0:4-e%4]}function byteLength(o){var r=getLens(o),e=r[0],t=r[1];return 3*(e+t)/4-t}function _byteLength(o,r,e){return 3*(r+e)/4-e}function toByteArray(o){for(var r,e=getLens(o),t=e[0],n=e[1],u=new Arr(_byteLength(o,t,n)),p=0,a=n>0?t-4:t,h=0;h>16&255,u[p++]=r>>8&255,u[p++]=255&r;return 2===n&&(r=revLookup[o.charCodeAt(h)]<<2|revLookup[o.charCodeAt(h+1)]>>4,u[p++]=255&r),1===n&&(r=revLookup[o.charCodeAt(h)]<<10|revLookup[o.charCodeAt(h+1)]<<4|revLookup[o.charCodeAt(h+2)]>>2,u[p++]=r>>8&255,u[p++]=255&r),u}function tripletToBase64(o){return lookup[o>>18&63]+lookup[o>>12&63]+lookup[o>>6&63]+lookup[63&o]}function encodeChunk(o,r,e){for(var t,n=[],u=r;up?p:u+16383));return 1===t?(r=o[e-1],n.push(lookup[r>>2]+lookup[r<<4&63]+"==")):2===t&&(r=(o[e-2]<<8)+o[e-1],n.push(lookup[r>>10]+lookup[r>>4&63]+lookup[r<<2&63]+"=")),n.join("")}exports.byteLength=byteLength,exports.toByteArray=toByteArray,exports.fromByteArray=fromByteArray;for(var lookup=[],revLookup=[],Arr="undefined"!=typeof Uint8Array?Uint8Array:Array,code="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,len=code.length;i>1,i=-7,N=t?h-1:0,n=t?-1:1,s=a[o+N];for(N+=n,M=s&(1<<-i)-1,s>>=-i,i+=w;i>0;M=256*M+a[o+N],N+=n,i-=8);for(p=M&(1<<-i)-1,M>>=-i,i+=r;i>0;p=256*p+a[o+N],N+=n,i-=8);if(0===M)M=1-e;else{if(M===f)return p?NaN:1/0*(s?-1:1);p+=Math.pow(2,r),M-=e}return(s?-1:1)*p*Math.pow(2,M-r)},exports.write=function(a,o,t,r,h,M){var p,w,f,e=8*M-h-1,i=(1<>1,n=23===h?Math.pow(2,-24)-Math.pow(2,-77):0,s=r?0:M-1,u=r?1:-1,l=o<0||0===o&&1/o<0?1:0;for(o=Math.abs(o),isNaN(o)||o===1/0?(w=isNaN(o)?1:0,p=i):(p=Math.floor(Math.log(o)/Math.LN2),o*(f=Math.pow(2,-p))<1&&(p--,f*=2),o+=p+N>=1?n/f:n*Math.pow(2,1-N),o*f>=2&&(p++,f/=2),p+N>=i?(w=0,p=i):p+N>=1?(w=(o*f-1)*Math.pow(2,h),p+=N):(w=o*Math.pow(2,N-1)*Math.pow(2,h),p=0));h>=8;a[t+s]=255&w,s+=u,w/=256,h-=8);for(p=p<0;a[t+s]=255&p,s+=u,p/=256,e-=8);a[t+s-u]|=128*l}; - },{}],88:[function(require,module,exports){ "function"==typeof Object.create?module.exports=function(t,e){t.super_=e,t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:module.exports=function(t,e){t.super_=e;var o=function(){};o.prototype=e.prototype,t.prototype=new o,t.prototype.constructor=t}; },{}],89:[function(require,module,exports){ @@ -378,7 +379,6 @@ function isBuffer(f){return!!f.constructor&&"function"==typeof f.constructor.isB },{}],90:[function(require,module,exports){ var toString={}.toString;module.exports=Array.isArray||function(r){return"[object Array]"==toString.call(r)}; - },{}],91:[function(require,module,exports){ (function (process){ "use strict";function nextTick(e,n,c,r){if("function"!=typeof e)throw new TypeError('"callback" argument must be a function');var s,t,o=arguments.length;switch(o){case 0:case 1:return process.nextTick(e);case 2:return process.nextTick(function(){e.call(null,n)});case 3:return process.nextTick(function(){e.call(null,n,c)});case 4:return process.nextTick(function(){e.call(null,n,c,r)});default:for(s=new Array(o-1),t=0;t1)for(var r=1;r>5==6?2:t>>4==14?3:t>>3==30?4:t>>6==2?-1:-2}function utf8CheckIncomplete(t,e,s){var i=e.length-1;if(i=0?(n>0&&(t.lastNeed=n-1),n):--i=0?(n>0&&(t.lastNeed=n-2),n):--i=0?(n>0&&(2===n?n=0:t.lastNeed=n-3),n):0)}function utf8CheckExtraBytes(t,e,s){if(128!=(192&e[0]))return t.lastNeed=0,"�";if(t.lastNeed>1&&e.length>1){if(128!=(192&e[1]))return t.lastNeed=1,"�";if(t.lastNeed>2&&e.length>2&&128!=(192&e[2]))return t.lastNeed=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+"�":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] : {}; + var k = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 4; + + if (data.length <= k) { + throw new Error("Training set size is too small for " + data.length + " k folds of " + k); + } var size = data.length / k; if (data.constructor === Array) { diff --git a/dist/cross-validate.js.map b/dist/cross-validate.js.map index cb90ef569..0cbfe7d90 100644 --- a/dist/cross-validate.js.map +++ b/dist/cross-validate.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/cross-validate.js"],"names":["CrossValidate","Classifier","options","json","trainOpts","trainSet","testSet","classifier","beginTrain","Date","now","trainingStats","train","beginTest","testStats","test","endTest","stats","Object","assign","trainTime","testTime","iterations","trainError","error","learningRate","hidden","hiddenSizes","network","toJSON","array","i","length","j","Math","floor","random","temp","data","k","size","constructor","Array","shuffleArray","newData","keys","forEach","key","avgs","truePos","trueNeg","falsePos","falseNeg","total","results","stat","sum","dclone","slice","splice","result","testPartition","push","precision","recall","accuracy","testSize","trainSize","sets","fromJSON","crossValidateJson","reduce","prev","cur","Infinity","instance"],"mappings":";;;;;;;;;;IAAqBA,a;;AAEnB;;;;;AAKA,yBAAYC,UAAZ,EAAwBC,OAAxB,EAAiC;AAAA;;AAC/B,SAAKD,UAAL,GAAkBA,UAAlB;AACA,SAAKC,OAAL,GAAeA,OAAf;AACA,SAAKC,IAAL,GAAY,IAAZ;AACD;;AAED;;;;;;;;;;;kCAOcC,S,EAAWC,Q,EAAUC,O,EAAS;AAC1C,UAAIC,aAAa,IAAI,KAAKN,UAAT,CAAoB,KAAKC,OAAzB,CAAjB;AACA,UAAIM,aAAaC,KAAKC,GAAL,EAAjB;AACA,UAAIC,gBAAgBJ,WAAWK,KAAX,CAAiBP,QAAjB,EAA2BD,SAA3B,CAApB;AACA,UAAIS,YAAYJ,KAAKC,GAAL,EAAhB;AACA,UAAII,YAAYP,WAAWQ,IAAX,CAAgBT,OAAhB,CAAhB;AACA,UAAIU,UAAUP,KAAKC,GAAL,EAAd;AACA,UAAIO,QAAQC,OAAOC,MAAP,CAAc,EAAd,EAAkBL,SAAlB,EAA6B;AACvCM,mBAAWP,YAAYL,UADgB;AAEvCa,kBAAUL,UAAUH,SAFmB;AAGvCS,oBAAYX,cAAcW,UAHa;AAIvCC,oBAAYZ,cAAca,KAJa;AAKvCC,sBAAcrB,UAAUqB,YALe;AAMvCC,gBAAQnB,WAAWoB,WANoB;AAOvCC,iBAASrB,WAAWsB,MAAX;AAP8B,OAA7B,CAAZ;;AAUA,aAAOZ,KAAP;AACD;;AAED;;;;;;;;iCAKaa,K,EAAO;AAClB,WAAK,IAAIC,IAAID,MAAME,MAAN,GAAe,CAA5B,EAA+BD,IAAI,CAAnC,EAAsCA,GAAtC,EAA2C;AACzC,YAAIE,IAAIC,KAAKC,KAAL,CAAWD,KAAKE,MAAL,MAAiBL,IAAI,CAArB,CAAX,CAAR;AACA,YAAIM,OAAOP,MAAMC,CAAN,CAAX;AACAD,cAAMC,CAAN,IAAWD,MAAMG,CAAN,CAAX;AACAH,cAAMG,CAAN,IAAWI,IAAX;AACD;AACD,aAAOP,KAAP;AACD;;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAyBMQ,I,EAAMlC,S,EAAWmC,C,EAAG;AACxBA,UAAIA,KAAK,CAAT;AACA,UAAIC,OAAOF,KAAKN,MAAL,GAAcO,CAAzB;;AAEA,UAAID,KAAKG,WAAL,KAAqBC,KAAzB,EAAgC;AAC9B,aAAKC,YAAL,CAAkBL,IAAlB;AACD,OAFD,MAEO;AACL,YAAIM,UAAU,EAAd;AACA,aAAKD,YAAL,CAAkBzB,OAAO2B,IAAP,CAAYP,IAAZ,CAAlB,EAAqCQ,OAArC,CAA6C,UAACC,GAAD,EAAS;AACpDH,kBAAQG,GAAR,IAAeT,KAAKS,GAAL,CAAf;AACD,SAFD;AAGAT,eAAOM,OAAP;AACD;;AAED,UAAII,OAAO;AACTxB,eAAO,CADE;AAETJ,mBAAW,CAFF;AAGTC,kBAAU,CAHD;AAITC,oBAAY,CAJH;AAKTC,oBAAY;AALH,OAAX;;AAQA,UAAIN,QAAQ;AACVgC,iBAAS,CADC;AAEVC,iBAAS,CAFC;AAGVC,kBAAU,CAHA;AAIVC,kBAAU,CAJA;AAKVC,eAAO;AALG,OAAZ;;AAQA,UAAIC,UAAU,EAAd;AACA,UAAIC,aAAJ;AACA,UAAIC,YAAJ;;AAEA,WAAK,IAAIzB,IAAI,CAAb,EAAgBA,IAAIQ,CAApB,EAAuBR,GAAvB,EAA4B;AAC1B,YAAI0B,SAASnB,KAAKoB,KAAL,CAAW,CAAX,CAAb;AACA,YAAIpD,UAAUmD,OAAOE,MAAP,CAAc5B,IAAIS,IAAlB,EAAwBA,IAAxB,CAAd;AACA,YAAInC,WAAWoD,MAAf;AACA,YAAIG,SAAS,KAAKC,aAAL,CAAmBzD,SAAnB,EAA8BC,QAA9B,EAAwCC,OAAxC,CAAb;AACA,aAAKiD,IAAL,IAAaP,IAAb,EAAmB;AACjB,cAAIO,QAAQP,IAAZ,EAAkB;AAChBQ,kBAAMR,KAAKO,IAAL,CAAN;AACAP,iBAAKO,IAAL,IAAaC,MAAMI,OAAOL,IAAP,CAAnB;AACD;AACF;;AAED,aAAKA,IAAL,IAAatC,KAAb,EAAoB;AAClB,cAAIsC,QAAQtC,KAAZ,EAAmB;AACjBuC,kBAAMvC,MAAMsC,IAAN,CAAN;AACAtC,kBAAMsC,IAAN,IAAcC,MAAMI,OAAOL,IAAP,CAApB;AACD;AACF;;AAEDD,gBAAQQ,IAAR,CAAaF,MAAb;AACD;;AAED,WAAKL,IAAL,IAAaP,IAAb,EAAmB;AACjB,YAAIO,QAAQP,IAAZ,EAAkB;AAChBQ,gBAAMR,KAAKO,IAAL,CAAN;AACAP,eAAKO,IAAL,IAAaC,MAAMjB,CAAnB;AACD;AACF;;AAEDtB,YAAM8C,SAAN,GAAkB9C,MAAMgC,OAAN,IAAiBhC,MAAMgC,OAAN,GAAgBhC,MAAMkC,QAAvC,CAAlB;AACAlC,YAAM+C,MAAN,GAAe/C,MAAMgC,OAAN,IAAiBhC,MAAMgC,OAAN,GAAgBhC,MAAMmC,QAAvC,CAAf;AACAnC,YAAMgD,QAAN,GAAiB,CAAChD,MAAMiC,OAAN,GAAgBjC,MAAMgC,OAAvB,IAAkChC,MAAMoC,KAAzD;;AAEApC,YAAMiD,QAAN,GAAiB1B,IAAjB;AACAvB,YAAMkD,SAAN,GAAkB7B,KAAKN,MAAL,GAAcQ,IAAhC;;AAGA,WAAKrC,IAAL,GAAY;AACV6C,cAAMA,IADI;AAEV/B,eAAOA,KAFG;AAGVmD,cAAMd;AAHI,OAAZ;AAKD;;;sCAEiB;AAChB,aAAO,KAAKe,QAAL,CAAc,KAAKlE,IAAnB,CAAP;AACD;;;6BAEQ;AACP,aAAO,KAAKA,IAAZ;AACD;;;6BAEQmE,iB,EAAmB;AAC1B,UAAMrE,aAAa,KAAKA,UAAxB;AACA,UAAME,OAAOmE,kBAAkBF,IAAlB,CAAuBG,MAAvB,CAA8B,UAACC,IAAD,EAAOC,GAAP;AAAA,eAAeD,KAAKhD,KAAL,GAAaiD,IAAIjD,KAAjB,GAAyBgD,IAAzB,GAAgCC,GAA/C;AAAA,OAA9B,EAAkF,EAACjD,OAAOkD,QAAR,EAAlF,EAAqG9C,OAAlH;AACA,UAAI3B,WAAWoE,QAAf,EAAyB;AACvB,eAAOpE,WAAWoE,QAAX,CAAoBlE,IAApB,CAAP;AACD;AACD,UAAMwE,WAAW,IAAI1E,UAAJ,EAAjB;AACA0E,eAASN,QAAT,CAAkBlE,IAAlB;AACA,aAAOwE,QAAP;AACD;;;;;;kBA/KkB3E,a","file":"cross-validate.js","sourcesContent":["export default class CrossValidate {\n\n /**\n *\n * @param {NeuralNetwork|constructor} Classifier\n * @param {object} [options]\n */\n constructor(Classifier, options) {\n this.Classifier = Classifier;\n this.options = options;\n this.json = null;\n }\n\n /**\n *\n * @param {object} trainOpts\n * @param {object} trainSet\n * @param {object} testSet\n * @returns {void|*}\n */\n testPartition(trainOpts, trainSet, testSet) {\n let classifier = new this.Classifier(this.options);\n let beginTrain = Date.now();\n let trainingStats = classifier.train(trainSet, trainOpts);\n let beginTest = Date.now();\n let testStats = classifier.test(testSet);\n let endTest = Date.now();\n let stats = Object.assign({}, testStats, {\n trainTime: beginTest - beginTrain,\n testTime: endTest - beginTest,\n iterations: trainingStats.iterations,\n trainError: trainingStats.error,\n learningRate: trainOpts.learningRate,\n hidden: classifier.hiddenSizes,\n network: classifier.toJSON()\n });\n\n return stats;\n }\n\n /**\n * Randomize array element order in-place.\n * Using Durstenfeld shuffle algorithm.\n * source: http://stackoverflow.com/a/12646864/1324039\n */\n shuffleArray(array) {\n for (let i = array.length - 1; i > 0; i--) {\n let j = Math.floor(Math.random() * (i + 1));\n let temp = array[i];\n array[i] = array[j];\n array[j] = temp;\n }\n return array;\n }\n\n /**\n *\n * @param {object} data\n * @param {object} trainOpts\n * @param {number} [k]\n * @returns {\n * {\n * avgs: {\n * error: number,\n * trainTime: number,\n * testTime: number,\n * iterations: number,\n * trainError: number\n * },\n * stats: {\n * truePos: number,\n * trueNeg: number,\n * falsePos: number,\n * falseNeg: number,\n * total: number\n * },\n * sets: Array\n * }\n * }\n */\n train(data, trainOpts, k) {\n k = k || 4;\n let size = data.length / k;\n\n if (data.constructor === Array) {\n this.shuffleArray(data);\n } else {\n let newData = {};\n this.shuffleArray(Object.keys(data)).forEach((key) => {\n newData[key] = data[key];\n });\n data = newData;\n }\n\n let avgs = {\n error: 0,\n trainTime: 0,\n testTime: 0,\n iterations: 0,\n trainError: 0\n };\n\n let stats = {\n truePos: 0,\n trueNeg: 0,\n falsePos: 0,\n falseNeg: 0,\n total: 0\n };\n\n let results = [];\n let stat;\n let sum;\n\n for (let i = 0; i < k; i++) {\n let dclone = data.slice(0);\n let testSet = dclone.splice(i * size, size);\n let trainSet = dclone;\n let result = this.testPartition(trainOpts, trainSet, testSet);\n for (stat in avgs) {\n if (stat in avgs) {\n sum = avgs[stat];\n avgs[stat] = sum + result[stat];\n }\n }\n\n for (stat in stats) {\n if (stat in stats) {\n sum = stats[stat];\n stats[stat] = sum + result[stat];\n }\n }\n\n results.push(result);\n }\n\n for (stat in avgs) {\n if (stat in avgs) {\n sum = avgs[stat];\n avgs[stat] = sum / k;\n }\n }\n\n stats.precision = stats.truePos / (stats.truePos + stats.falsePos);\n stats.recall = stats.truePos / (stats.truePos + stats.falseNeg);\n stats.accuracy = (stats.trueNeg + stats.truePos) / stats.total;\n\n stats.testSize = size;\n stats.trainSize = data.length - size;\n\n\n this.json = {\n avgs: avgs,\n stats: stats,\n sets: results\n };\n }\n\n toNeuralNetwork() {\n return this.fromJSON(this.json);\n }\n\n toJSON() {\n return this.json;\n }\n\n fromJSON(crossValidateJson) {\n const Classifier = this.Classifier;\n const json = crossValidateJson.sets.reduce((prev, cur) => prev.error < cur.error ? prev : cur, {error: Infinity}).network;\n if (Classifier.fromJSON) {\n return Classifier.fromJSON(json);\n }\n const instance = new Classifier();\n instance.fromJSON(json);\n return instance;\n }\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../src/cross-validate.js"],"names":["CrossValidate","Classifier","options","json","trainOpts","trainSet","testSet","classifier","beginTrain","Date","now","trainingStats","train","beginTest","testStats","test","endTest","stats","Object","assign","trainTime","testTime","iterations","trainError","error","learningRate","hidden","hiddenSizes","network","toJSON","array","i","length","j","Math","floor","random","temp","data","k","Error","size","constructor","Array","shuffleArray","newData","keys","forEach","key","avgs","truePos","trueNeg","falsePos","falseNeg","total","results","stat","sum","dclone","slice","splice","result","testPartition","push","precision","recall","accuracy","testSize","trainSize","sets","fromJSON","crossValidateJson","reduce","prev","cur","Infinity","instance"],"mappings":"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","file":"cross-validate.js","sourcesContent":["export default class CrossValidate {\n\n /**\n *\n * @param {NeuralNetwork|constructor} Classifier\n * @param {object} [options]\n */\n constructor(Classifier, options) {\n this.Classifier = Classifier;\n this.options = options;\n this.json = null;\n }\n\n /**\n *\n * @param {object} trainOpts\n * @param {object} trainSet\n * @param {object} testSet\n * @returns {void|*}\n */\n testPartition(trainOpts, trainSet, testSet) {\n let classifier = new this.Classifier(this.options);\n let beginTrain = Date.now();\n let trainingStats = classifier.train(trainSet, trainOpts);\n let beginTest = Date.now();\n let testStats = classifier.test(testSet);\n let endTest = Date.now();\n let stats = Object.assign({}, testStats, {\n trainTime: beginTest - beginTrain,\n testTime: endTest - beginTest,\n iterations: trainingStats.iterations,\n trainError: trainingStats.error,\n learningRate: trainOpts.learningRate,\n hidden: classifier.hiddenSizes,\n network: classifier.toJSON()\n });\n\n return stats;\n }\n\n /**\n * Randomize array element order in-place.\n * Using Durstenfeld shuffle algorithm.\n * source: http://stackoverflow.com/a/12646864/1324039\n */\n shuffleArray(array) {\n for (let i = array.length - 1; i > 0; i--) {\n let j = Math.floor(Math.random() * (i + 1));\n let temp = array[i];\n array[i] = array[j];\n array[j] = temp;\n }\n return array;\n }\n\n /**\n *\n * @param {object} data\n * @param {object} trainOpts\n * @param {number} [k]\n * @returns {\n * {\n * avgs: {\n * error: number,\n * trainTime: number,\n * testTime: number,\n * iterations: number,\n * trainError: number\n * },\n * stats: {\n * truePos: number,\n * trueNeg: number,\n * falsePos: number,\n * falseNeg: number,\n * total: number\n * },\n * sets: Array\n * }\n * }\n */\n train(data, trainOpts = {}, k = 4) {\n if (data.length <= k) {\n throw new Error(`Training set size is too small for ${ data.length } k folds of ${ k }`);\n }\n let size = data.length / k;\n\n if (data.constructor === Array) {\n this.shuffleArray(data);\n } else {\n let newData = {};\n this.shuffleArray(Object.keys(data)).forEach((key) => {\n newData[key] = data[key];\n });\n data = newData;\n }\n\n let avgs = {\n error: 0,\n trainTime: 0,\n testTime: 0,\n iterations: 0,\n trainError: 0\n };\n\n let stats = {\n truePos: 0,\n trueNeg: 0,\n falsePos: 0,\n falseNeg: 0,\n total: 0\n };\n\n let results = [];\n let stat;\n let sum;\n\n for (let i = 0; i < k; i++) {\n let dclone = data.slice(0);\n let testSet = dclone.splice(i * size, size);\n let trainSet = dclone;\n let result = this.testPartition(trainOpts, trainSet, testSet);\n for (stat in avgs) {\n if (stat in avgs) {\n sum = avgs[stat];\n avgs[stat] = sum + result[stat];\n }\n }\n\n for (stat in stats) {\n if (stat in stats) {\n sum = stats[stat];\n stats[stat] = sum + result[stat];\n }\n }\n\n results.push(result);\n }\n\n for (stat in avgs) {\n if (stat in avgs) {\n sum = avgs[stat];\n avgs[stat] = sum / k;\n }\n }\n\n stats.precision = stats.truePos / (stats.truePos + stats.falsePos);\n stats.recall = stats.truePos / (stats.truePos + stats.falseNeg);\n stats.accuracy = (stats.trueNeg + stats.truePos) / stats.total;\n\n stats.testSize = size;\n stats.trainSize = data.length - size;\n\n\n this.json = {\n avgs: avgs,\n stats: stats,\n sets: results\n };\n }\n\n toNeuralNetwork() {\n return this.fromJSON(this.json);\n }\n\n toJSON() {\n return this.json;\n }\n\n fromJSON(crossValidateJson) {\n const Classifier = this.Classifier;\n const json = crossValidateJson.sets.reduce((prev, cur) => prev.error < cur.error ? prev : cur, {error: Infinity}).network;\n if (Classifier.fromJSON) {\n return Classifier.fromJSON(json);\n }\n const instance = new Classifier();\n instance.fromJSON(json);\n return instance;\n }\n}\n"]} \ No newline at end of file diff --git a/dist/neural-network.js b/dist/neural-network.js index 8342386f8..2001d95bc 100644 --- a/dist/neural-network.js +++ b/dist/neural-network.js @@ -960,8 +960,8 @@ var NeuralNetwork = function () { falseNeg: falseNeg, falsePos: falsePos, total: data.length, - precision: truePos / (truePos + falsePos), - recall: truePos / (truePos + falseNeg), + precision: truePos > 0 ? truePos / (truePos + falsePos) : 0, + recall: truePos > 0 ? truePos / (truePos + falseNeg) : 0, accuracy: (trueNeg + truePos) / data.length }); } diff --git a/dist/neural-network.js.map b/dist/neural-network.js.map index 7c849fa8f..daf786134 100644 --- a/dist/neural-network.js.map +++ b/dist/neural-network.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/neural-network.js"],"names":["NeuralNetwork","options","validations","iterations","val","errorThresh","log","logPeriod","learningRate","momentum","callback","callbackPeriod","timeout","Object","keys","trainDefaults","forEach","hasOwnProperty","key","Error","Infinity","praxis","beta1","beta2","epsilon","binaryThresh","hiddenLayers","activation","assign","constructor","defaults","hiddenSizes","trainOpts","_updateTrainingOptions","sizes","outputLayer","biases","weights","outputs","deltas","changes","errors","errorCheckInterval","prototype","runInput","calculateDeltas","length","layer","size","Array","node","prevSize","setActivation","_runInputSigmoid","_calculateDeltasSigmoid","_runInputRelu","_calculateDeltasRelu","_runInputLeakyRelu","_calculateDeltasLeakyRelu","_runInputTanh","_calculateDeltasTanh","input","isRunnable","inputLookup","lookup","toArray","output","outputLookup","toHash","sum","k","Math","exp","tanh","data","push","max","floor","_initialize","opts","opt","_validateTrainingOptions","_setLogMethod","reduce","console","i","_trainPattern","status","endTime","error","Date","now","_calculateTrainingError","_trainPatterns","_formatData","_verifyIsInitialized","_prepTraining","_setupAdam","_trainingTick","Promise","resolve","reject","thawedTrain","Thaw","delay","each","stop","done","tick","trainError","target","logErrorRate","_adjustWeights","incoming","delta","change","biasChangesLow","biasChangesHigh","changesLow","changesHigh","_adjustWeightsAdam","gradient","changeLow","changeHigh","momentumCorrection","pow","gradientCorrection","sqrt","biasGradient","biasChangeLow","biasChangeHigh","biasMomentumCorrection","biasGradientCorrection","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","Function","checkFns","filter","c"],"mappings":"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","file":"neural-network.js","sourcesContent":["import lookup from './lookup';\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 praxis: null,\n beta1: 0.9,\n beta2: 0.999,\n epsilon: 1e-8,\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 /**\n *\n * @param options\n * @private\n */\n static _validateTrainingOptions(options) {\n const validations = {\n iterations: (val) => { return typeof val === 'number' && val > 0; },\n errorThresh: (val) => { return typeof val === 'number' && val > 0 && val < 1; },\n log: (val) => { return typeof val === 'function' || typeof val === 'boolean'; },\n logPeriod: (val) => { return typeof val === 'number' && val > 0; },\n learningRate: (val) => { return typeof val === 'number' && val > 0 && val < 1; },\n momentum: (val) => { return typeof val === 'number' && val > 0 && val < 1; },\n callback: (val) => { return typeof val === 'function' || val === null },\n callbackPeriod: (val) => { return typeof val === 'number' && val > 0; },\n timeout: (val) => { return typeof val === 'number' && val > 0 }\n };\n Object.keys(NeuralNetwork.trainDefaults).forEach(key => {\n if (validations.hasOwnProperty(key) && !validations[key](options[key])) {\n throw new Error(`[${key}, ${options[key]}] is out of normal training range, your network will probably not train.`);\n }\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 this.errorCheckInterval = 1;\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 activation supported inputs: '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 opts\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.hasOwnProperty(opt)) ? opts[opt] : this.trainOpts[opt]);\n NeuralNetwork._validateTrainingOptions(this.trainOpts);\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 (opt === 'timeout' && this.trainOpts[opt] === Infinity) return opts;\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 * @returns {Number} 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, true);\n }\n return sum / data.length;\n }\n\n /**\n * @param data\n * @private\n */\n _trainPatterns(data) {\n for (let i = 0; i < data.length; ++i) {\n this._trainPattern(data[i].input, data[i].output, false);\n }\n }\n\n /**\n *\n * @param {object} data\n * @param {object} status { iterations: number, error: number }\n * @param endTime\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\n if (this.trainOpts.log && (status.iterations % this.trainOpts.logPeriod === 0)) {\n status.error = this._calculateTrainingError(data);\n this.trainOpts.log(`iterations: ${status.iterations}, training error: ${status.error}`);\n } else {\n if (status.iterations % this.errorCheckInterval === 0) {\n status.error = this._calculateTrainingError(data);\n } else {\n this._trainPatterns(data);\n }\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 * @protected\n * @return { data, status, endTime }\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 if (options.praxis === 'adam') {\n this._setupAdam();\n }\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, logErrorRate) {\n\n // forward propagate\n this.runInput(input);\n\n // back propagate\n this.calculateDeltas(target);\n this._adjustWeights();\n\n if (logErrorRate) {\n return mse(this.errors[this.outputLayer]);\n } else {\n return null;\n }\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 _setupAdam() {\n this.biasChangesLow = [];\n this.biasChangesHigh = [];\n this.changesLow = [];\n this.changesHigh = [];\n this.iterations = 0;\n\n for (let layer = 0; layer <= this.outputLayer; layer++) {\n let size = this.sizes[layer];\n if (layer > 0) {\n this.biasChangesLow[layer] = zeros(size);\n this.biasChangesHigh[layer] = zeros(size);\n this.changesLow[layer] = new Array(size);\n this.changesHigh[layer] = new Array(size);\n\n for (let node = 0; node < size; node++) {\n let prevSize = this.sizes[layer - 1];\n this.changesLow[layer][node] = zeros(prevSize);\n this.changesHigh[layer][node] = zeros(prevSize);\n }\n }\n }\n\n this._adjustWeights = this._adjustWeightsAdam;\n }\n\n _adjustWeightsAdam() {\n const trainOpts = this.trainOpts;\n this.iterations++;\n\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n const incoming = this.outputs[layer - 1];\n\n for (let node = 0; node < this.sizes[layer]; node++) {\n const delta = this.deltas[layer][node];\n\n for (let k = 0; k < incoming.length; k++) {\n const gradient = delta * incoming[k];\n const changeLow = this.changesLow[layer][node][k] * trainOpts.beta1 + (1 - trainOpts.beta1) * gradient;\n const changeHigh = this.changesHigh[layer][node][k] * trainOpts.beta2 + (1 - trainOpts.beta2) * gradient * gradient;\n \n const momentumCorrection = changeLow / (1 - Math.pow(trainOpts.beta1, this.iterations));\n const gradientCorrection = changeHigh / (1 - Math.pow(trainOpts.beta2, this.iterations));\n\n this.changesLow[layer][node][k] = changeLow;\n this.changesHigh[layer][node][k] = changeHigh;\n this.weights[layer][node][k] += this.trainOpts.learningRate * momentumCorrection / (Math.sqrt(gradientCorrection) + trainOpts.epsilon);\n }\n\n const biasGradient = this.deltas[layer][node];\n const biasChangeLow = this.biasChangesLow[layer][node] * trainOpts.beta1 + (1 - trainOpts.beta1) * biasGradient;\n const biasChangeHigh = this.biasChangesHigh[layer][node] * trainOpts.beta2 + (1 - trainOpts.beta2) * biasGradient * biasGradient;\n\n const biasMomentumCorrection = this.biasChangesLow[layer][node] / (1 - Math.pow(trainOpts.beta1, this.iterations));\n const biasGradientCorrection = this.biasChangesHigh[layer][node] / (1 - Math.pow(trainOpts.beta2, this.iterations));\n\n this.biasChangesLow[layer][node] = biasChangeLow;\n this.biasChangesHigh[layer][node] = biasChangeHigh;\n this.biases[layer][node] += trainOpts.learningRate * biasMomentumCorrection / (Math.sqrt(biasGradientCorrection) + trainOpts.epsilon);\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 if (json.hasOwnProperty('trainOpts')) {\n this._updateTrainingOptions(json.trainOpts);\n }\n this.setActivation(this.activation || 'sigmoid');\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 `(${result.join('')} < 0 ? 0 : ${result.join('')})`;\n case 'leaky-relu':\n return `(${result.join('')} < 0 ? 0 : 0.01 * ${result.join('')})`;\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}"]} \ No newline at end of file +{"version":3,"sources":["../src/neural-network.js"],"names":["NeuralNetwork","options","validations","iterations","val","errorThresh","log","logPeriod","learningRate","momentum","callback","callbackPeriod","timeout","Object","keys","trainDefaults","forEach","hasOwnProperty","key","Error","Infinity","praxis","beta1","beta2","epsilon","binaryThresh","hiddenLayers","activation","assign","constructor","defaults","hiddenSizes","trainOpts","_updateTrainingOptions","sizes","outputLayer","biases","weights","outputs","deltas","changes","errors","errorCheckInterval","prototype","runInput","calculateDeltas","length","layer","size","Array","node","prevSize","setActivation","_runInputSigmoid","_calculateDeltasSigmoid","_runInputRelu","_calculateDeltasRelu","_runInputLeakyRelu","_calculateDeltasLeakyRelu","_runInputTanh","_calculateDeltasTanh","input","isRunnable","inputLookup","lookup","toArray","output","outputLookup","toHash","sum","k","Math","exp","tanh","data","push","max","floor","_initialize","opts","opt","_validateTrainingOptions","_setLogMethod","reduce","console","i","_trainPattern","status","endTime","error","Date","now","_calculateTrainingError","_trainPatterns","_formatData","_verifyIsInitialized","_prepTraining","_setupAdam","_trainingTick","Promise","resolve","reject","thawedTrain","Thaw","delay","each","stop","done","tick","trainError","target","logErrorRate","_adjustWeights","incoming","delta","change","biasChangesLow","biasChangesHigh","changesLow","changesHigh","_adjustWeightsAdam","gradient","changeLow","changeHigh","momentumCorrection","pow","gradientCorrection","sqrt","biasGradient","biasChangeLow","biasChangeHigh","biasMomentumCorrection","biasGradientCorrection","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","Function","checkFns","filter","c"],"mappings":"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","file":"neural-network.js","sourcesContent":["import lookup from './lookup';\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 praxis: null,\n beta1: 0.9,\n beta2: 0.999,\n epsilon: 1e-8,\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 /**\n *\n * @param options\n * @private\n */\n static _validateTrainingOptions(options) {\n const validations = {\n iterations: (val) => { return typeof val === 'number' && val > 0; },\n errorThresh: (val) => { return typeof val === 'number' && val > 0 && val < 1; },\n log: (val) => { return typeof val === 'function' || typeof val === 'boolean'; },\n logPeriod: (val) => { return typeof val === 'number' && val > 0; },\n learningRate: (val) => { return typeof val === 'number' && val > 0 && val < 1; },\n momentum: (val) => { return typeof val === 'number' && val > 0 && val < 1; },\n callback: (val) => { return typeof val === 'function' || val === null },\n callbackPeriod: (val) => { return typeof val === 'number' && val > 0; },\n timeout: (val) => { return typeof val === 'number' && val > 0 }\n };\n Object.keys(NeuralNetwork.trainDefaults).forEach(key => {\n if (validations.hasOwnProperty(key) && !validations[key](options[key])) {\n throw new Error(`[${key}, ${options[key]}] is out of normal training range, your network will probably not train.`);\n }\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 this.errorCheckInterval = 1;\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 activation supported inputs: '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 opts\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.hasOwnProperty(opt)) ? opts[opt] : this.trainOpts[opt]);\n NeuralNetwork._validateTrainingOptions(this.trainOpts);\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 (opt === 'timeout' && this.trainOpts[opt] === Infinity) return opts;\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 * @returns {Number} 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, true);\n }\n return sum / data.length;\n }\n\n /**\n * @param data\n * @private\n */\n _trainPatterns(data) {\n for (let i = 0; i < data.length; ++i) {\n this._trainPattern(data[i].input, data[i].output, false);\n }\n }\n\n /**\n *\n * @param {object} data\n * @param {object} status { iterations: number, error: number }\n * @param endTime\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\n if (this.trainOpts.log && (status.iterations % this.trainOpts.logPeriod === 0)) {\n status.error = this._calculateTrainingError(data);\n this.trainOpts.log(`iterations: ${status.iterations}, training error: ${status.error}`);\n } else {\n if (status.iterations % this.errorCheckInterval === 0) {\n status.error = this._calculateTrainingError(data);\n } else {\n this._trainPatterns(data);\n }\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 * @protected\n * @return { data, status, endTime }\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 if (options.praxis === 'adam') {\n this._setupAdam();\n }\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, logErrorRate) {\n\n // forward propagate\n this.runInput(input);\n\n // back propagate\n this.calculateDeltas(target);\n this._adjustWeights();\n\n if (logErrorRate) {\n return mse(this.errors[this.outputLayer]);\n } else {\n return null;\n }\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 _setupAdam() {\n this.biasChangesLow = [];\n this.biasChangesHigh = [];\n this.changesLow = [];\n this.changesHigh = [];\n this.iterations = 0;\n\n for (let layer = 0; layer <= this.outputLayer; layer++) {\n let size = this.sizes[layer];\n if (layer > 0) {\n this.biasChangesLow[layer] = zeros(size);\n this.biasChangesHigh[layer] = zeros(size);\n this.changesLow[layer] = new Array(size);\n this.changesHigh[layer] = new Array(size);\n\n for (let node = 0; node < size; node++) {\n let prevSize = this.sizes[layer - 1];\n this.changesLow[layer][node] = zeros(prevSize);\n this.changesHigh[layer][node] = zeros(prevSize);\n }\n }\n }\n\n this._adjustWeights = this._adjustWeightsAdam;\n }\n\n _adjustWeightsAdam() {\n const trainOpts = this.trainOpts;\n this.iterations++;\n\n for (let layer = 1; layer <= this.outputLayer; layer++) {\n const incoming = this.outputs[layer - 1];\n\n for (let node = 0; node < this.sizes[layer]; node++) {\n const delta = this.deltas[layer][node];\n\n for (let k = 0; k < incoming.length; k++) {\n const gradient = delta * incoming[k];\n const changeLow = this.changesLow[layer][node][k] * trainOpts.beta1 + (1 - trainOpts.beta1) * gradient;\n const changeHigh = this.changesHigh[layer][node][k] * trainOpts.beta2 + (1 - trainOpts.beta2) * gradient * gradient;\n \n const momentumCorrection = changeLow / (1 - Math.pow(trainOpts.beta1, this.iterations));\n const gradientCorrection = changeHigh / (1 - Math.pow(trainOpts.beta2, this.iterations));\n\n this.changesLow[layer][node][k] = changeLow;\n this.changesHigh[layer][node][k] = changeHigh;\n this.weights[layer][node][k] += this.trainOpts.learningRate * momentumCorrection / (Math.sqrt(gradientCorrection) + trainOpts.epsilon);\n }\n\n const biasGradient = this.deltas[layer][node];\n const biasChangeLow = this.biasChangesLow[layer][node] * trainOpts.beta1 + (1 - trainOpts.beta1) * biasGradient;\n const biasChangeHigh = this.biasChangesHigh[layer][node] * trainOpts.beta2 + (1 - trainOpts.beta2) * biasGradient * biasGradient;\n\n const biasMomentumCorrection = this.biasChangesLow[layer][node] / (1 - Math.pow(trainOpts.beta1, this.iterations));\n const biasGradientCorrection = this.biasChangesHigh[layer][node] / (1 - Math.pow(trainOpts.beta2, this.iterations));\n\n this.biasChangesLow[layer][node] = biasChangeLow;\n this.biasChangesHigh[layer][node] = biasChangeHigh;\n this.biases[layer][node] += trainOpts.learningRate * biasMomentumCorrection / (Math.sqrt(biasGradientCorrection) + trainOpts.epsilon);\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 > 0 ? truePos / (truePos + falsePos) : 0,\n recall: truePos > 0 ? truePos / (truePos + falseNeg) : 0,\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 if (json.hasOwnProperty('trainOpts')) {\n this._updateTrainingOptions(json.trainOpts);\n }\n this.setActivation(this.activation || 'sigmoid');\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 `(${result.join('')} < 0 ? 0 : ${result.join('')})`;\n case 'leaky-relu':\n return `(${result.join('')} < 0 ? 0 : 0.01 * ${result.join('')})`;\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}"]} \ No newline at end of file diff --git a/examples-typescript/cross-validate.ts b/examples-typescript/cross-validate.ts index fb2b87e5c..143706a90 100644 --- a/examples-typescript/cross-validate.ts +++ b/examples-typescript/cross-validate.ts @@ -8,23 +8,11 @@ const trainingData = [ { input: [1, 1], output: [0] }, { input: [1, 0], output: [1] }, - // xor repeats + // repeat xor data to have enough to train with { input: [0, 1], output: [1] }, { input: [0, 0], output: [0] }, { input: [1, 1], output: [0] }, - { input: [1, 0], output: [1] }, - - // xor repeats - { input: [0, 1], output: [1] }, - { input: [0, 0], output: [0] }, - { input: [1, 1], output: [0] }, - { input: [1, 0], output: [1] }, - - // xor repeats - { input: [0, 1], output: [1] }, - { input: [0, 0], output: [0] }, - { input: [1, 1], output: [0] }, - { input: [1, 0], output: [1] }, + { input: [1, 0], output: [1] } ]; const netOptions = { diff --git a/examples/cross-validate.js b/examples/cross-validate.js index 521d8bb7d..341511835 100644 --- a/examples/cross-validate.js +++ b/examples/cross-validate.js @@ -8,23 +8,11 @@ const trainingData = [ { input: [1, 1], output: [0] }, { input: [1, 0], output: [1] }, - // xor repeats + // repeat xor data to have enough to train with { input: [0, 1], output: [1] }, { input: [0, 0], output: [0] }, { input: [1, 1], output: [0] }, - { input: [1, 0], output: [1] }, - - // xor repeats - { input: [0, 1], output: [1] }, - { input: [0, 0], output: [0] }, - { input: [1, 1], output: [0] }, - { input: [1, 0], output: [1] }, - - // xor repeats - { input: [0, 1], output: [1] }, - { input: [0, 0], output: [0] }, - { input: [1, 1], output: [0] }, - { input: [1, 0], output: [1] }, + { input: [1, 0], output: [1] } ]; const netOptions = { diff --git a/package.json b/package.json index 88f16feae..7d99abba4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "brain.js", "description": "Neural network library", - "version": "1.4.1", + "version": "1.4.2", "author": "Heather Arthur ", "repository": { "type": "git", diff --git a/src/cross-validate.js b/src/cross-validate.js index bcf5aa566..a714e6a7d 100644 --- a/src/cross-validate.js +++ b/src/cross-validate.js @@ -78,8 +78,10 @@ export default class CrossValidate { * } * } */ - train(data, trainOpts, k) { - k = k || 4; + train(data, trainOpts = {}, k = 4) { + if (data.length <= k) { + throw new Error(`Training set size is too small for ${ data.length } k folds of ${ k }`); + } let size = data.length / k; if (data.constructor === Array) { diff --git a/src/neural-network.js b/src/neural-network.js index 0ac1c2e6c..db501497a 100644 --- a/src/neural-network.js +++ b/src/neural-network.js @@ -805,8 +805,8 @@ export default class NeuralNetwork { falseNeg: falseNeg, falsePos: falsePos, total: data.length, - precision: truePos / (truePos + falsePos), - recall: truePos / (truePos + falseNeg), + precision: truePos > 0 ? truePos / (truePos + falsePos) : 0, + recall: truePos > 0 ? truePos / (truePos + falseNeg) : 0, accuracy: (trueNeg + truePos) / data.length }); } diff --git a/test/base/cross-validation.js b/test/base/cross-validation.js new file mode 100644 index 000000000..2a0f72c10 --- /dev/null +++ b/test/base/cross-validation.js @@ -0,0 +1,42 @@ +import assert from 'assert'; +import brain from '../../src'; +import CrossValidate from '../../src/cross-validate'; + +describe('CrossValidation', () => { + describe('simple xor example', () => { + it('throws exception when training set is too small', () => { + const xorTrainingData = [ + { input: [0, 1], output: [1] }, + { input: [0, 0], output: [0] }, + { input: [1, 1], output: [0] }, + { input: [1, 0], output: [1] } + ]; + const net = new CrossValidate(brain.NeuralNetwork); + assert.throws(() => { + net.train(xorTrainingData); + }); + }); + it('handles training and outputs values that are all numbers', () => { + const xorTrainingData = [ + { input: [0, 1], output: [1] }, + { input: [0, 0], output: [0] }, + { input: [1, 1], output: [0] }, + { input: [1, 0], output: [1] }, + + { input: [0, 1], output: [1] }, + { input: [0, 0], output: [0] }, + { input: [1, 1], output: [0] }, + { input: [1, 0], output: [1] } + ]; + const net = new CrossValidate(brain.NeuralNetwork); + net.train(xorTrainingData); + const json = net.toJSON(); + for (let p in json.avgs) { + assert(json.avgs[p] >= 0); + } + for (let p in json.stats) { + assert(json.stats[p] >= 0); + } + }); + }); +});