单个感知器保持输出值接近 0.5
Single perceptron keeps outputting values close 0.5
我正在尝试用一个神经元创建最简单的感知(神经元采用 2 个输入值,* 它们按权重然后 + 偏置并激活它们的总和 (1 / (1 + Math.exp(-x))) sigmoid function ) 并通过反向传播训练它(通过从我获得的输出中减去期望值得到一个错误,找到我们乘以 wight 和输入值之间的差异的梯度和权重增量),但是在第一次迭代,我的权重非常接近 0 并开始生成一个 0.5 的 sigmoid(0)(它总是生成从 0.48 到 0.52 或接近的值。
class Neuron {constructor(){
this.inputs = [1,1];
this.inputWeights = [(Math.random()*2)-1,(Math.random()*2)-1];
this.bias = 0.1;
this.activate = () => {
if(this.inputs.length !== this.inputWeights.length)return "Wrong input length";
let sum = 0;
for(var n = 0; n < this.inputs.length;n++){
sum = sum + (this.inputs[n]*this.inputWeights[n]);
}
sum = sum + this.bias;
//return sigmoid activated value
let activated_output = (1 / (1 + Math.exp(-sum)));
return activated_output;
};
this.error = (predicted,desired) => {
let error = predicted - desired;
let gradient = predicted * (1-predicted);
let weights_delta = error * gradient;
return weights_delta;
};
this.changeWeights = (weights_delta) => {
let info = this.inputWeights[0];
for(var n = 0; n < this.inputWeights.length; n++){
this.inputWeights[n] = (this.inputWeights[n] - this.inputs[n]) * weights_delta * learning_rate;
}
return "first weight changed from " + info + " to " + this.inputWeights[0];
}
}}
var testNeuron = new Neuron();
var learning_rate = 0.05;
var dataset = [
{ inputs: [1,0], outputs: [1] },
{ inputs: [0,1], outputs: [0] },
{ inputs: [0.5,0.1], outputs: [1] },
{ inputs: [0.1,0.9], outputs: [0] }];
//train
var train = (iterations, data) => {
for(var i = 0; i < iterations; i++){
for(var n = 0; n < data.length; n++){
testNeuron.inputs = data[n].inputs;
console.log(testNeuron.changeWeights(testNeuron.error(testNeuron.activate() ,
data[n].outputs[0])));
}
}
}
train(10,dataset);
这是所有代码,我尝试过有偏见和没有偏见但我觉得我的数学肯定是错误的但我无法弄清楚在哪里因为我是一个菜鸟..halp sirs
最大的错误是我没有使用任何偏置输入,也没有为它调整权重。如果我们不使用偏差,那么像 0,0 这样的简单输入将始终 return 0,并且无法调整权重以使输出发生变化。
其次,如果我们查看简单的感知器,我们应该使用阈值函数而不是 sigmoid。(虽然 sigmoid 是可能的,但在这个例子中 imo 更慢)阈值保持函数是一个简单的函数 return s 如果输出为负则为 0,如果为正则为 1。
我的重做和工作代码看起来像这样,增加训练迭代会导致错误减少,就像它应该的那样,谢谢
class Perceptron{constructor(){
//bias , input1, input2
this.inputs = [1,0,0];
this.inputWeights = [(Math.random()*2)-1,(Math.random()*2)-1,(Math.random()*2)-1];
this.output = 0;
this.desiredOutput = 0;
}//perceptron methods
activate = () => {
let sum = 0;
for(var n = 0; n < this.inputs.length; n++){
sum += this.inputs[n] * this.inputWeights[n];
};
this.output = sum < 0 ? 0 : 1;
this.desiredOutput == this.output ? console.log("Correct answer") : console.log("Incorrect answer");
};
propagate = () => {
let error = this.desiredOutput - this.output;
for(var m = 0; m < this.inputs.length; m++){
let delta = error * this.inputs[m];
this.inputWeights[m] = this.inputWeights[m] + (delta * learningRate);
}
};
}
let learningRate = 0.1;
var train = (iterations) => {
for(var x = 0; x < iterations; x++){
for(var y = 0; y < dataset.length; y++){
perception.inputs = [1,dataset[y][0],dataset[y][1]];
perception.desiredOutput = dataset[y][2];
perception.activate();
perception.propagate();
}
}
}
var perception = new Perceptron();
//[input1 , input2 , desiredOutput]
var dataset = [
[0,0,1],
[1,1,0],
[0.1,0.3,1],
[1.5,1.8,0]
];
train(100);
我正在尝试用一个神经元创建最简单的感知(神经元采用 2 个输入值,* 它们按权重然后 + 偏置并激活它们的总和 (1 / (1 + Math.exp(-x))) sigmoid function ) 并通过反向传播训练它(通过从我获得的输出中减去期望值得到一个错误,找到我们乘以 wight 和输入值之间的差异的梯度和权重增量),但是在第一次迭代,我的权重非常接近 0 并开始生成一个 0.5 的 sigmoid(0)(它总是生成从 0.48 到 0.52 或接近的值。
class Neuron {constructor(){
this.inputs = [1,1];
this.inputWeights = [(Math.random()*2)-1,(Math.random()*2)-1];
this.bias = 0.1;
this.activate = () => {
if(this.inputs.length !== this.inputWeights.length)return "Wrong input length";
let sum = 0;
for(var n = 0; n < this.inputs.length;n++){
sum = sum + (this.inputs[n]*this.inputWeights[n]);
}
sum = sum + this.bias;
//return sigmoid activated value
let activated_output = (1 / (1 + Math.exp(-sum)));
return activated_output;
};
this.error = (predicted,desired) => {
let error = predicted - desired;
let gradient = predicted * (1-predicted);
let weights_delta = error * gradient;
return weights_delta;
};
this.changeWeights = (weights_delta) => {
let info = this.inputWeights[0];
for(var n = 0; n < this.inputWeights.length; n++){
this.inputWeights[n] = (this.inputWeights[n] - this.inputs[n]) * weights_delta * learning_rate;
}
return "first weight changed from " + info + " to " + this.inputWeights[0];
}
}}
var testNeuron = new Neuron();
var learning_rate = 0.05;
var dataset = [
{ inputs: [1,0], outputs: [1] },
{ inputs: [0,1], outputs: [0] },
{ inputs: [0.5,0.1], outputs: [1] },
{ inputs: [0.1,0.9], outputs: [0] }];
//train
var train = (iterations, data) => {
for(var i = 0; i < iterations; i++){
for(var n = 0; n < data.length; n++){
testNeuron.inputs = data[n].inputs;
console.log(testNeuron.changeWeights(testNeuron.error(testNeuron.activate() ,
data[n].outputs[0])));
}
}
}
train(10,dataset);
这是所有代码,我尝试过有偏见和没有偏见但我觉得我的数学肯定是错误的但我无法弄清楚在哪里因为我是一个菜鸟..halp sirs
最大的错误是我没有使用任何偏置输入,也没有为它调整权重。如果我们不使用偏差,那么像 0,0 这样的简单输入将始终 return 0,并且无法调整权重以使输出发生变化。
其次,如果我们查看简单的感知器,我们应该使用阈值函数而不是 sigmoid。(虽然 sigmoid 是可能的,但在这个例子中 imo 更慢)阈值保持函数是一个简单的函数 return s 如果输出为负则为 0,如果为正则为 1。 我的重做和工作代码看起来像这样,增加训练迭代会导致错误减少,就像它应该的那样,谢谢
class Perceptron{constructor(){
//bias , input1, input2
this.inputs = [1,0,0];
this.inputWeights = [(Math.random()*2)-1,(Math.random()*2)-1,(Math.random()*2)-1];
this.output = 0;
this.desiredOutput = 0;
}//perceptron methods
activate = () => {
let sum = 0;
for(var n = 0; n < this.inputs.length; n++){
sum += this.inputs[n] * this.inputWeights[n];
};
this.output = sum < 0 ? 0 : 1;
this.desiredOutput == this.output ? console.log("Correct answer") : console.log("Incorrect answer");
};
propagate = () => {
let error = this.desiredOutput - this.output;
for(var m = 0; m < this.inputs.length; m++){
let delta = error * this.inputs[m];
this.inputWeights[m] = this.inputWeights[m] + (delta * learningRate);
}
};
}
let learningRate = 0.1;
var train = (iterations) => {
for(var x = 0; x < iterations; x++){
for(var y = 0; y < dataset.length; y++){
perception.inputs = [1,dataset[y][0],dataset[y][1]];
perception.desiredOutput = dataset[y][2];
perception.activate();
perception.propagate();
}
}
}
var perception = new Perceptron();
//[input1 , input2 , desiredOutput]
var dataset = [
[0,0,1],
[1,1,0],
[0.1,0.3,1],
[1.5,1.8,0]
];
train(100);