【问题标题】:JavaScript: Simple Perceptron fails to trainJavaScript:简单感知器无法训练
【发布时间】:2021-04-07 13:25:03
【问题描述】:

我尝试制作简单的感知器来预测真假,其中 1 表示真,假表示 -1。 但我的感知器无法训练自己,而是给出随机值。

这是我的类感知器:

function f(x){
    //number is in negative it returns -1
    if(x<0){
        return -1
    //number is in positive it returns 1
    }else{
        return 1
    }
}

class Perceptron{
    constructor(){
        //two weights
        this.weights = new Array(2)
        //intitializing two random weights
        for(let i = 0; i<this.weights.length; i++){
            this.weights[i] = Math.random()*2-1
        }
    }
    //prediction
    guess(input){
        let sum = 0;
        for(let i = 0; i<input.length; i++){
           sum += this.weights[i]*input[i]//sum of all product of inputs and weights 
        }
        return f(sum)//returns -1 or 1
    }
    //training data
    train(inputs, target){
        this.lr = 0.1//learning rate
        let guess = this.guess(inputs)//answer comes either 1 or -1
        let err = target - guess//calc error
        for(let i = 0; i<this.weights.length; i++){
            this.weights[i] += err * inputs[i] * this.lr// re adjust the weights
        }
    }
}

export default Perceptron;

这是我的主要js:

import Perceptron from "./perceptron.js"
const brain = new Perceptron;

let data = [{
    inputx: 1,
    inputy: 1,
    target: 1
},
{
    inputx: 0,
    inputy: 1,
    target: -1
},
{
    inputx: 1,
    inputy: 0,
    target: -1
},
{
    inputx: 0,
    inputy: 0,
    target: -1
}
]
for(let i = 0; i<data.length; i++){
    let inputs = [data[i].inputx, data[i].inputy]
    brain.train(inputs, data[i].target)
    let guess = brain.guess([1, 0])
    console.log(guess)
}

感知器不会预测确切的数据,而是给出随机答案。我在这里做错了什么

【问题讨论】:

    标签: javascript node.js algorithm neural-network perceptron


    【解决方案1】:

    我把你的代码放在一个sn-p里,所以你可以在这里运行。

    function f(x) {
      //number is in negative it returns -1
      if (x < 0) {
        return -1
        //number is in positive it returns 1
      } else {
        return 1
      }
    }
    
    class Perceptron {
      constructor() {
        //two weights
        this.weights = new Array(2)
        //intitializing two random weights
        for (let i = 0; i < this.weights.length; i++) {
          this.weights[i] = Math.random() * 2 - 1
        }
      }
    
      //prediction
      guess(input) {
        let sum = 0;
        for (let i = 0; i < input.length; i++) {
          sum += this.weights[i] * input[i] //sum of all product of inputs and weights 
        }
        return f(sum) //returns -1 or 1
      }
    
      //training data
      train(inputs, target) {
        this.lr = 0.1 //learning rate
        const guess = this.guess(inputs) //answer comes either 1 or -1
        const err = target - guess //calc error
        for (let i = 0; i < this.weights.length; i++) {
          this.weights[i] += err * inputs[i] * this.lr // re adjust the weights
        }
      }
    }
    
    const brain = new Perceptron;
    
    let data = [{
        inputx: 1,
        inputy: 1,
        target: 1
      },
      {
        inputx: 0,
        inputy: 1,
        target: -1
      },
      {
        inputx: 1,
        inputy: 0,
        target: -1
      },
      {
        inputx: 0,
        inputy: 0,
        target: -1
      }
    ]
    for (let i = 0; i < data.length; i++) {
      let inputs = [data[i].inputx, data[i].inputy]
      brain.train(inputs, data[i].target)
      let guess = brain.guess([1, 0])
      console.log(guess)
    }

    从我看到的代码中:

    1. Perceptron 用随机权重初始化 - 好的
    2. Perceptron 输入数据 - 好的

    如果你分析猜测函数,那么你会发现一些问题:

    • guess[1, 1]:权重相加。很可能他们的总和是 0+,所以猜测在大多数情况下都会产生正确的答案
    • guess[0, 1]guess[1, 0]:只考虑与1配对的权重(另一个乘以0,然后相加);产生 1 的机会比产生 -1 的机会稍大(这意味着错误的猜测),但大多是随机的
    • guess[0, 0] 将始终为 false,因为它的内部总和(在 guess 函数中)将始终为 0,因此从 f(x) 生成 1 -> 目标是 -1(错误结果)

    感知器有效 - 因为它在“学习”期间修改权重,但不会产生与随机猜测有显着差异的答案。

    修改猜测函数

    function f(x) {
      //number is in negative it returns -1
      if (x < 0) {
        return -1
        //number is in positive it returns 1
      } else {
        return 1
      }
    }
    
    class Perceptron {
      constructor() {
        //two weights
        this.weights = new Array(2)
        //intitializing two random weights
        for (let i = 0; i < this.weights.length; i++) {
          this.weights[i] = Math.random() * 2 - 1
        }
      }
    
      //prediction
      guess(input) {
        let sum = 0;
        for (let i = 0; i < input.length; i++) {
          // -----------------------
          // changed the * to + here
          // -----------------------
          sum += this.weights[i] + input[i] //sum of all product of inputs and weights 
        }
        return f(sum) //returns -1 or 1
      }
    
      //training data
      train(inputs, target) {
        this.lr = 0.1 //learning rate
        const guess = this.guess(inputs) //answer comes either 1 or -1
        const err = target - guess //calc error
        for (let i = 0; i < this.weights.length; i++) {
          this.weights[i] += err * inputs[i] * this.lr // re adjust the weights
        }
      }
    }
    
    const brain = new Perceptron;
    
    let data = [{
        inputx: 1,
        inputy: 1,
        target: 1
      },
      {
        inputx: 0,
        inputy: 1,
        target: -1
      },
      {
        inputx: 1,
        inputy: 0,
        target: -1
      },
      {
        inputx: 0,
        inputy: 0,
        target: -1
      }
    ]
    for (let j = 0; j < 1; j++) {
      for (let i = 0; i < data.length; i++) {
        let inputs = [data[i].inputx, data[i].inputy]
        brain.train(inputs, data[i].target)
      }
    }
    
    let guess = 0
    console.log('After 1 round of training:')
    guess = brain.guess([1, 1])
    console.log(guess)
    guess = brain.guess([0, 1])
    console.log(guess)
    guess = brain.guess([1, 0])
    console.log(guess)
    guess = brain.guess([0, 0])
    console.log(guess)
    console.log('Weights:', brain.weights)
    
    for (let j = 0; j < 999; j++) {
      for (let i = 0; i < data.length; i++) {
        let inputs = [data[i].inputx, data[i].inputy]
        brain.train(inputs, data[i].target)
      }
    }
    
    console.log('After 1000 round of training:')
    guess = brain.guess([1, 1])
    console.log(guess)
    guess = brain.guess([0, 1])
    console.log(guess)
    guess = brain.guess([1, 0])
    console.log(guess)
    guess = brain.guess([0, 0])
    console.log(guess)
    console.log('Weights:', brain.weights)

    我改变了猜测功能

    // from this:
    sum += this.weights[i] * input[i]
    // to this
    sum += this.weights[i] + input[i]
    

    并增加了几轮训练。我认为结果不言自明(运行几次,看看 1 轮训练与 1000 轮训练的区别)。

    【讨论】:

    • 哇,非常感谢您的精彩解释,我今年 15 岁,我想在未来制作 AI,这对我的未来有很大帮助,非常感谢
    • @DjBilljeOfficial 我认为这是一个非常好的方向——你可以试试BrainJS 或者只是看看一些好的Youtube视频,比如3Blue1Brown - Neural networks。我很高兴能帮上忙!
    • 是的,我将来会使用brain js,但我实际上想制作自己的神经网络,以便更好地了解它。
    猜你喜欢
    • 2014-11-04
    • 2017-05-10
    • 2016-03-02
    • 2019-08-19
    • 2021-09-07
    • 2013-12-23
    • 2013-01-03
    • 2017-03-27
    • 2017-07-16
    相关资源
    最近更新 更多