Skip to content

Instantly share code, notes, and snippets.

@umaar
Forked from primaryobjects/perceptron.js
Created September 15, 2018 00:14
Show Gist options
  • Select an option

  • Save umaar/f97eede753bcfdf4d8de9140ac0168a2 to your computer and use it in GitHub Desktop.

Select an option

Save umaar/f97eede753bcfdf4d8de9140ac0168a2 to your computer and use it in GitHub Desktop.

Revisions

  1. @primaryobjects primaryobjects revised this gist Oct 4, 2017. No changes.
  2. @primaryobjects primaryobjects revised this gist Oct 4, 2017. 1 changed file with 3 additions and 0 deletions.
    3 changes: 3 additions & 0 deletions zoutput.md
    Original file line number Diff line number Diff line change
    @@ -6,6 +6,7 @@ OR
    1
    1
    1
    AND
    0
    0
    @@ -21,6 +22,7 @@ OR
    0.997979609625522
    0.997978808477126
    0.9999999791643208
    AND
    1.8291439124699984e-7
    0.005047459025409658
    @@ -36,6 +38,7 @@ OR
    1
    1
    1
    AND
    0
    0
  3. @primaryobjects primaryobjects renamed this gist Oct 4, 2017. 1 changed file with 10 additions and 7 deletions.
    17 changes: 10 additions & 7 deletions zoutput.txt → zoutput.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    Sigmoid activation with a threshold of >= 0.5
    =============================================
    ## Sigmoid activation with a threshold of >= 0.5

    ```
    OR
    0
    1
    @@ -11,10 +11,11 @@ AND
    0
    0
    1
    ```

    Sigmoid activation raw
    ======================
    ## Sigmoid activation raw

    ```
    OR
    0.005055993896717148
    0.997979609625522
    @@ -25,10 +26,11 @@ AND
    0.005047459025409658
    0.005050628299542594
    0.9929472374083017
    ```

    Hardside activation
    ===================
    ## Hardside activation

    ```
    OR
    0
    1
    @@ -38,4 +40,5 @@ AND
    0
    0
    0
    1
    1
    ```
  4. @primaryobjects primaryobjects renamed this gist Oct 4, 2017. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  5. @primaryobjects primaryobjects revised this gist Oct 4, 2017. 1 changed file with 41 additions and 0 deletions.
    41 changes: 41 additions & 0 deletions perceptron-output.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,41 @@
    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
  6. @primaryobjects primaryobjects revised this gist Oct 4, 2017. 1 changed file with 20 additions and 6 deletions.
    26 changes: 20 additions & 6 deletions perceptron.js
    Original file line number Diff line number Diff line change
    @@ -72,23 +72,37 @@ function Perceptron(opts) {
    return (expected - actual) * learnrate * input
    },

    perceive: function(inputs, net) {
    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]
    return net
    ? result
    : result > 0 ? 1 : 0

    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/>';
    document.getElementById('output').innerHTML += msg + '<br/>';
    console.log(msg);
    }

  7. @primaryobjects primaryobjects created this gist Oct 2, 2017.
    127 changes: 127 additions & 0 deletions perceptron.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,127 @@
    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) {
    var result = 0
    for(var i=0; i<inputs.length; i++) {
    result += inputs[i] * weights[i]
    }
    result += threshold * weights[weights.length - 1]
    return net
    ? result
    : result > 0 ? 1 : 0
    },
    }

    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]));