neural-networkperceptronactivation-function

Question about Perceptron activation threshold


I have a Perceptron written in Javascript that works fine, code below. My question is about the threshold in the activation function. Other code I have seen has something like if (sum > 0) {return 1} else {return 0}. My perceptron only works with if (sum > 1) {return 1} else {return 0}. Why is that? Full code below.

(function () {
    "use strict";

    function Perceptron(numInputs=2) {
        let weights = Array.from({length: numInputs}, () => 2 * Math.random() - 1);  // [-1, 1)
        this.learningRate = 0.5;

        this.train = function (inputs, goal) {
            // feed forward
            let guess = this.predict(inputs);

            // back propagation
            let error = goal - guess;
            if (error !== 0) {
                for (let i = 0; i < weights.length; i += 1) {
                    weights[i] += this.learningRate * error * inputs[i];
                }
            }
        }

        this.predict = function (inputs) {
            // transfer function
            let sumProducts = 0;
            for (let i = 0; i < inputs.length; i += 1) {
                sumProducts += inputs[i] * weights[i];
            }

            // activation function, threshold = 1
            return (sumProducts >= 1) ? 1 : 0;  // <-- this is the line I have a question about
        }
    }
    
    // train
    let data = [
        [0, 0, 0],
        [0, 1, 0],
        [1, 0, 0],
        [1, 1, 1]
    ];

    let p = new Perceptron(2);
    
    const epochs = 20;
    for (let i = 0; i < epochs; i += 1) {
        let r = Math.floor(Math.random() * data.length);
        p.train(data[r].slice(0, 2), data[r].slice(-1));
    }

    // test
    for (let i = 0; i < data.length; i += 1) {
        let inputs = data[i].slice(0, 2);
        console.log(`inputs = ${inputs}; output = ${p.predict(inputs)}`);
    }
}());

Solution

  • Your perceptron lacks a bias term, your equation is of form SUM_i w_i x_i, instead of SUM_i w_i x_i + b. With the functional form you have it is impossible to separate points, where the separating hyperplane does not cross the origin (and yours does not). Alternatively you can add a column of "1s" to your data, it will serve the same purpose, as the corresponding w_i will just behave as b (since all x_i will be 1)