JavaScript:简单感知器无法训练
JavaScript: Simple Perceptron fails to train
我尝试制作简单的感知器来预测真假,其中 1 表示真,假表示 -1。
但是我的感知器无法自我训练,而是给出随机值。
这是我的 class 感知器:
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)
}
感知器不会预测准确的数据,而是给出随机答案。我在这里做错了什么
我把你的代码放在一个片段中,所以你可以运行在这里。
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)
}
从代码中我看到:
Perceptron
使用随机权重初始化 - OK
Perceptron
已输入数据 - OK
如果你分析猜测函数,那么你会发现一些问题:
guess[1, 1]
:权重相加。很可能他们的总和是0+,所以大部分时间猜测都会得出正确答案
guess[0, 1]
和guess[1, 0]
:只考虑与1
配对的权重(另一个乘以0,然后相加);产生 1
的机会比 -1
稍大(这意味着错误的猜测),但主要是随机的
guess[0, 0]
将始终为 false
,因为它的内部总和(在 guess
函数中)将始终为 0,因此产生 1
来自 f(x)
-> 目标是 -1
(错误结果)
Perceptron 有效 - 因为它在“学习”期间修改权重,但不会产生与随机猜测明显不同的答案。
修改后的猜测功能
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 轮训练的区别)。
我尝试制作简单的感知器来预测真假,其中 1 表示真,假表示 -1。 但是我的感知器无法自我训练,而是给出随机值。
这是我的 class 感知器:
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)
}
感知器不会预测准确的数据,而是给出随机答案。我在这里做错了什么
我把你的代码放在一个片段中,所以你可以运行在这里。
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)
}
从代码中我看到:
Perceptron
使用随机权重初始化 - OKPerceptron
已输入数据 - OK
如果你分析猜测函数,那么你会发现一些问题:
guess[1, 1]
:权重相加。很可能他们的总和是0+,所以大部分时间猜测都会得出正确答案guess[0, 1]
和guess[1, 0]
:只考虑与1
配对的权重(另一个乘以0,然后相加);产生1
的机会比-1
稍大(这意味着错误的猜测),但主要是随机的guess[0, 0]
将始终为false
,因为它的内部总和(在guess
函数中)将始终为 0,因此产生1
来自f(x)
-> 目标是-1
(错误结果)
Perceptron 有效 - 因为它在“学习”期间修改权重,但不会产生与随机猜测明显不同的答案。
修改后的猜测功能
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 轮训练的区别)。