微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JavaScript:简单感知器无法训练

如何解决JavaScript:简单感知器无法训练

我尝试制作简单的感知器来预测真假,其中 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,target: -1
},{
    inputx: 1,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)
}

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

解决方法

我把你的代码放在一个片段中,所以你可以在这里运行它。

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,target: -1
  },{
    inputx: 1,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 初始化为随机权重 - OK
  2. Perceptron 输入数据 - OK

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

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

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

修改后的猜测函数

-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: -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].target)
  }
}

console.log('After 1000 round of training:')
guess = brain.guess([1,brain.weights)

并添加了更多轮训练。我认为结果不言自明(运行几次以查看 1 轮训练与 1000 轮训练之间的差异)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?