为什么此感知器无法正确分类?

时间:2019-02-05 11:46:34

标签: javascript neural-network perceptron

我试图建立我的第一个神经网络示例,并从代码中名为brain的感知器开始。它试图对x = y线以上或以下的一些随机点进行分类。

在这里,我有很多由Point类随机生成的点,而points数组是我已知的训练数据。 train函数基本上是在单击鼠标时训练感知器,如果不正确则用黑点表示,如果正确则用白点表示。

这是我的代码:

var canvas = document.querySelector("canvas");
var c = canvas.getContext("2d");

canvas.height = innerHeight;
canvas.width = canvas.height;

var width = canvas.width;
var height = canvas.height;

//The activation function
const sign = (n) => {
    if (n > 0) return 1;
    else return -1;
}

class Perceptron {
    // a constructor with n number of weights
    constructor (n) {
        this.weights = new Array(n);
        this.lr = 0.1   //Learning rate

        //Initialize the weights randomly
        for (var i = 0; i < this.weights.length; i++) {
            this.weights[i] = Math.random() * -2 + 1;
        }

        //Calculate weighted sum
        this.sum = 0;
        this.guess = (inputs) => {
            for (var i = 0; i < this.weights.length; i++) {
                this.sum += this.weights[i] * inputs[i];
            }
            return sign(this.sum);
        }

        this.train = (inputs, target) => {

            var guess = this.guess(inputs);
            var error = target - guess;

            //Tune the weights
            for (var i = 0; i < this.weights.length; i++) {
                this.weights[i] += error * inputs[i] * this.lr;
            }
        }
    }
}

class Point {
    constructor () {
        this.x = Math.random() * width;
        this.y = Math.random() * height;

        if (this.x > this.y) {
            this.label = 1;
        } else {
            this.label = -1;
        }

        this.show = () => {
            if (this.label == 1) {
                c.fillStyle = 'tomato';
            } else {
                c.fillStyle = 'dodgerblue';
            }
            c.beginPath();
            c.arc(this.x, this.y, 8, 0, Math.PI * 2, false);
            c.fill();
        }
    }
}

var points = [];    //Our known training data
var brain = new Perceptron(2);

//Fill points array
for (var i = 0; i < 100; i++) {
    points.push(new Point());
}




const training = () => {

    for (var i = 0; i < points.length; i++) {
        let input = [points[i].x, points[i].y];
        let target = points[i].label;

        brain.train(input, target);

        let guess = brain.guess(input);
        if (guess == target) {
            c.fillStyle = '#fff';
        } else {
            c.fillStyle = '#000';
        }

        c.beginPath();
        c.arc(points[i].x, points[i].y, 4, 0, Math.PI * 2, false);
        c.fill();
    }
}

window.addEventListener('click', (event) => {
    training();
})


const drawLine = () => {
    c.beginPath();
    c.moveTo(0, 0);
    c.lineTo(width, height);
    c.stroke();
}


const animate = () => {
    // requestAnimationFrame(animate);
    c.clearRect(0, 0, width, height);

    drawLine();
    for (var i = 0; i < points.length; i++) {
        points[i].show();
    }

    // train();
}
animate();

问题在于,它仅对x = y线以上或以下的点进行了正确分类,而另一半仍然完全不正确。怎么了?

我还注意到,当我将var error = target - guess;更改为var error = guess - target;(在train类的Perceptron方法中)时,它仅在第一次迭代中得到了所有正确的半点。这是怎么回事?

在此先感谢您的帮助。

0 个答案:

没有答案