-
-
Save umaar/f97eede753bcfdf4d8de9140ac0168a2 to your computer and use it in GitHub Desktop.
Perceptron in JavaScript, a simple example. Neural network. See https://jsfiddle.net/qu960cc2/1/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Sigmoid activation with a threshold of >= 0.5 | |
| ============================================= | |
| OR | |
| 0 | |
| 1 | |
| 1 | |
| 1 | |
| AND | |
| 0 | |
| 0 | |
| 0 | |
| 1 | |
| Sigmoid activation raw | |
| ====================== | |
| OR | |
| 0.005055993896717148 | |
| 0.997979609625522 | |
| 0.997978808477126 | |
| 0.9999999791643208 | |
| AND | |
| 1.8291439124699984e-7 | |
| 0.005047459025409658 | |
| 0.005050628299542594 | |
| 0.9929472374083017 | |
| Hardside activation | |
| =================== | |
| OR | |
| 0 | |
| 1 | |
| 1 | |
| 1 | |
| AND | |
| 0 | |
| 0 | |
| 0 | |
| 1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Perceptron(opts) { | |
| if (!opts) opts = {} | |
| var debug = 'debug' in opts ? opts.debug : false; | |
| var weights = 'weights' in opts | |
| ? opts.weights.slice() | |
| : [] | |
| var threshold = 'threshold' in opts | |
| ? opts.threshold | |
| : 1 | |
| var learningrate; | |
| if (!('learningrate' in opts)) { | |
| learningrate = 0.1 | |
| } | |
| else { | |
| learningrate = opts.learningrate | |
| } | |
| var data = [] | |
| var api = { | |
| weights: weights, | |
| retrain: function() { | |
| var length = data.length | |
| var success = true | |
| for(var i=0; i<length; i++) { | |
| var training = data.shift() | |
| success = api.train(training.input, training.target) && success | |
| } | |
| return success | |
| }, | |
| train: function(inputs, expected) { | |
| while (weights.length < inputs.length) { | |
| weights.push(Math.random()) | |
| } | |
| // add a bias weight for the threshold | |
| if (weights.length == inputs.length) { | |
| weights.push('bias' in opts ? opts.bias : 1) | |
| } | |
| var result = api.perceive(inputs) | |
| data.push({input: inputs, target: expected, prev: result}) | |
| if (debug) console.log('> training %s, expecting: %s got: %s', inputs, expected, result) | |
| if (result == expected) { | |
| return true | |
| } | |
| else { | |
| if (debug) console.log('> adjusting weights...', weights, inputs); | |
| for(var i=0; i < weights.length; i++) { | |
| var input = (i == inputs.length) | |
| ? threshold | |
| : inputs[i] | |
| api.adjust(result, expected, input, i) | |
| } | |
| if (debug) console.log(' -> weights:', weights) | |
| return false | |
| } | |
| }, | |
| adjust: function(result, expected, input, index) { | |
| var d = api.delta(result, expected, input, learningrate); | |
| weights[index] += d; | |
| if (isNaN(weights[index])) throw new Error('weights['+index+'] went to NaN!!') | |
| }, | |
| delta: function(actual, expected, input, learnrate) { | |
| return (expected - actual) * learnrate * input | |
| }, | |
| perceive: function(inputs, net, activationFunc) { | |
| var result = 0 | |
| for(var i=0; i<inputs.length; i++) { | |
| result += inputs[i] * weights[i] | |
| } | |
| result += threshold * weights[weights.length - 1]; | |
| // Set the activation function to sigmoid, hardside, or a custom formula. | |
| activationFunc = activationFunc || ((x) => { return Number(this.sigmoid(x) >= 0.5) }); | |
| //activationFunc = activationFunc || ((x) => { return this.sigmoid(x) }); | |
| //activationFunc = activationFunc || ((x) => { return Number(this.hardside(x) > 0) }); | |
| // Finally, pass the result through an activation function to determine if the neuron fires. | |
| return activationFunc ? activationFunc(result) : (net ? result : (result > 0 ? 1 : 0)); | |
| }, | |
| sigmoid: function(t) { | |
| return 1/(1+Math.pow(Math.E, -t)); | |
| }, | |
| hardside: function(t) { | |
| return t; | |
| } | |
| } | |
| return api; | |
| } | |
| var print = function(msg) { | |
| document.getElementById('output').innerHTML += msg + '<br/>'; | |
| console.log(msg); | |
| } | |
| var or = new Perceptron(); | |
| or.train([0, 0], 0); | |
| or.train([0, 1], 1); | |
| or.train([1, 0], 1); | |
| or.train([1, 1], 1); | |
| // practice makes perfect (we hope...) | |
| var i = 0; | |
| while(i++ < 10000 && !or.retrain()) {} | |
| print('OR'); | |
| print(or.perceive([0, 0])); | |
| print(or.perceive([0, 1])); | |
| print(or.perceive([1, 0])); | |
| print(or.perceive([1, 1])); | |
| var and = new Perceptron(); | |
| and.train([0, 0], 0); | |
| and.train([0, 1], 0); | |
| and.train([1, 0], 0); | |
| and.train([1, 1], 1); | |
| // practice makes perfect (we hope...) | |
| var i = 0; | |
| while(i++ < 10000 && !and.retrain()) {} | |
| print('AND'); | |
| print(and.perceive([0, 0])); | |
| print(and.perceive([0, 1])); | |
| print(and.perceive([1, 0])); | |
| print(and.perceive([1, 1])); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment