javascript - Perceptron Javascript 不一致

标签 javascript machine-learning neural-network perceptron

构建一个基本的感知器。我训练后的结果非常不一致,即使经过 1000 个时代也是如此。权重似乎调整得当,但模型无法准确预测。将不胜感激第二双眼睛在结构上,努力寻找我哪里出错了。准确率始终达到 60%。

 // Perceptron
class Perceptron {

    constructor (x_train, y_train, learn_rate= 0.1, epochs=10) {
            this.epochs = epochs
            this.x_train = x_train
            this.y_train = y_train
            this.learn_rate = learn_rate
            this.weights = new Array(x_train[0].length)

            // initialize random weights
            for ( let n = 0; n < x_train[0].length; n++ ) {
                    this.weights[n] = this.random()
            }
    }

    // generate random float between -1 and 1 (for generating weights)
    random () {
            return Math.random() * 2 - 1
    }

    // activation function
    activation (n) {
            return n < 0 ? 0 : 1
    }

    // y-hat output given an input tensor 
    predict (input) {
            let total = 0
            this.weights.forEach((w, index) => { total += input[index] * w }) // multiply each weight by each input vector value
            return this.activation(total)
    }

    // training perceptron on data
    fit () {
            for ( let e = 0; e < this.epochs; e++) { // epochs loop
                    for ( let i = 0; i < this.x_train.length; i++ ) { // iterate over each training sample
                            let prediction = this.predict(this.x_train[i]) // predict sample output
                            console.log('Expected: ' + this.y_train[i] + '    Model Output: ' + prediction) // log expected vs predicted
                            let loss = this.y_train[i] - prediction // calculate loss
                            for ( let w = 0; w < this.weights.length; w++ ) { // loop weights for update
                                    this.weights[w] += loss * this.x_train[i][w] * this.learn_rate // update all weights to reduce loss
                            }
                    }
            }
    }
}

x = [[1, 1, 1], [0, 0, 0], [0, 0, 1], [1, 1, 0], [0, 0, 1]]
y = [1, 0, 0, 1, 0]

p = new Perceptron(x, y, epochs=5000, learn_rate=.1)

更新:

// Perceptron
module.exports = class Perceptron {

constructor (x_train, y_train, epochs=1000, learn_rate= 0.1) {

    // used to generate percent accuracy
    this.accuracy = 0
    this.samples = 0
    this.x_train = x_train
    this.y_train = y_train
    this.epochs = epochs
    this.learn_rate = learn_rate
    this.weights = new Array(x_train[0].length)
    this.bias = 0

    // initialize random weights
    for ( let n = 0; n < x_train[0].length; n++ ) {
                    this.weights[n] = this.random()
            }
}

// returns percent accuracy 
current_accuracy () {
    return this.accuracy/this.samples
}

// generate random float between -1 and 1 (for generating weights)
random () {
    return Math.random() * 2 - 1
}

// activation function
activation (n) {
    return n < 0 ? 0 : 1
}

// y-hat output given an input tensor 
predict (input) {
    let total = this.bias
    this.weights.forEach((w, index) => { total += input[index] * w }) // multiply each weight by each input vector value
    return this.activation(total)
}

// training perceptron on data
fit () {
    // epochs loop
    for ( let e = 0; e < this.epochs; e++) { 

        // for each training sample
        for ( let i = 0; i < this.x_train.length; i++ ) { 

            // get prediction
            let prediction = this.predict(this.x_train[i]) 
            console.log('Expected: ' + this.y_train[i] + '    Model Output: ' + prediction) 

            // update accuracy measures
            this.y_train[i] === prediction ? this.accuracy += 1 : this.accuracy -= 1
            this.samples++

            // calculate loss
            let loss = this.y_train[i] - prediction

            // update all weights
            for ( let w = 0; w < this.weights.length; w++ ) { 
                this.weights[w] += loss * this.x_train[i][w] * this.learn_rate
            }

            this.bias += loss * this.learn_rate
        }

        // accuracy post epoch
        console.log(this.current_accuracy())
    }
  }
}

最佳答案

这只是一个语法错误:)

调换最后两个参数的顺序,像这样:

p = new Perceptron(x, y, learn_rate=.1, epochs=5000)

现在一切正常。

然而,更严重的问题在于你的实现:

你忘记了偏见

通过感知器,您正在尝试学习线性函数,某种形式的

y = wx + b

但是你目前正在计算的只是

y = wx

如果您要学习的只是单个输入的身份函数,那么这很好,就像您的情况一样。但是一旦你开始做一些稍微复杂一点的事情,比如尝试学习 AND 函数,它就无法工作了,它可以这样表示:

y = x1 + x2 - 1.5

如何修复?

非常简单,只需在构造函数中初始化 this.bias = 0 即可。然后,在 predict() 中,初始化 let total = this.bias 并在 fit() 中添加 this.bias += loss * this.learn_rate 就在最内层循环之后。

关于javascript - Perceptron Javascript 不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48968050/

相关文章:

javascript - tinyMCE setContent 剥离结束 p 标签

javascript - 旋转文本生成器

python - DecisionTreeRegressor 参数调整的分数会引发错误

python - 如何在 tensorflow 中制作 reshape 层?

numpy - 如何使用 NumPy 在 Python 中按行应用均方误差而不循环

javascript - 在移动浏览器上设置缩放级别

java - Weka 错误消息 - 没有足够的带有类标签的训练实例(需要 : 1, 提供 : 0)!

python - Theano学习与门

machine-learning - 理解令人困惑的感知器输入数据

javascript - 如何避免在网页返回时通过 JS 触发重复的 PubNub 通知