单层感知器算法不起作用

我正在努力全面理解神经网络的概念,因此我从创建自己的简单感知器算法开始。

这是我的代码(用JavaScript编写):

var lr = 0.1;//学习率//随机初始化权重function initWeights(weights, trainingSets){    for(var i=0; i<trainingSets[0].in.length; i++){        weights[i] = Math.random()*2 - 1;    }    weights.push(Math.random()*2 - 1); //b}//返回给定训练集的原始激活值function getSum(weights, trainingSet){    var sum = 0;    for(var i=0; i < trainingSet.in.length; i++){        sum += weights[i]*trainingSet.in[i];    }    sum += 1 * weights[weights.length-1];    return sum;}//激活函数function activate(value){    return (value >= 0)? 1 : 0;}function train(weights, trainingSets){    var error = 0;    for(var i=0; i<trainingSets.length; i++){        var currentSet = trainingSets[i];        var activationValue = getSum(weights, currentSet);        var error = currentSet.out - activate(activationValue);        error += error;        for(var j=0; j<weights.length-1; j++){            var deltaW = error * lr * currentSet.in[j];            weights[j] += deltaW;        }        weights[weights.length-1] += error * lr * 1;    }    return error/(weights.length);}var inp = [    {in:[1,1], out:1},    {in:[0,0], out:0},    {in:[0,1], out:0},];var w = [];initWeights(w, inp);//for(var j = 0; j < inp.length; j++){    var error = 1;    while(error >= 0.01){        error = train(w, inp);    }//}console.log("===")var tester = {in:[1,0], out: NaN};console.log(getSum(w, tester)) //应为负值console.log("y=("+w[1]+"*x+"+w[2]+")/"+w[1])

结果并不一致(我使用的是AND算法进行学习)。
图表应该看起来像这样:
http://puu.sh/44eIY/401f63cde7.png
但通常看起来像这样:
http://puu.sh/44eAJ/75488a05eb.png

我确定这里遗漏了一些小细节,
提前感谢您的帮助。


回答:

你的代码至少存在三个问题:

  • 重新声明了error变量,最初它被设计为一个总和误差,然后你再次声明它为每个输出神经元的误差,这导致了关于整个过程的信息丢失
  • 你的停止标准不好 – 它应该是误差的平均绝对值,而不仅仅是误差的总和 – 考虑一个简单的网络,它将一个标签为0的训练样本分类为1,这将在你的代码中导致误差,因此训练停止,尽管它远未结束
  • 训练后使用

    var inp = [  {in:[1,1], out:1},  {in:[0,0], out:0},  {in:[0,1], out:0},];

    你不会得到f( [1,0] ) == 0,这不是感知器的工作方式。它只会在二维平面上找到一条线,使[1,1]位于其一侧,而[0,0][0,1]位于另一侧。没有保证[1,0][0,0][0,1]位于同一侧,这是预期的行为。使用提供的数据,感知器没有理由不使用x=0.5的垂直线,这完美地分隔了你的数据,但f( [1,0] ) == 1。你的训练数据并没有“定义”操作,而只是一组简单的规则,这些规则被无限数量的分类器遵守。

    function train(weights, trainingSets){var error = 0;for(var i=0; i<trainingSets.length; i++){    var currentSet = trainingSets[i];    var activationValue = getSum(weights, currentSet);    var error_current = currentSet.out - activate(activationValue);    error += Math.abs( error_current );    for(var j=0; j<weights.length-1; j++){        var deltaW = error_current * lr * currentSet.in[j];        weights[j] += deltaW;    }    weights[weights.length-1] += error_current * lr * 1;}return error/(weights.length);}

如评论中所述,如果你用点(1,0)、(0,1)和(1,1)的值训练你的网络,它会自己推断出(0,0)的值

var inp = [    {in:[1,1], out:1},    {in:[0,1], out:0},    {in:[1,0], out:0},];var w = [];initWeights(w, inp);//for(var j = 0; j < inp.length; j++){    var error = 1;    while(error >= 0.01){        error = train(w, inp);    }//}console.log("===")var test = [    {in:[1,1], out:1},    {in:[0,0], out:0},    {in:[0,1], out:0},    {in:[1,0], out:0},];for(var i=0; i<test.length; ++i){ console.log(test[i].in + " out: " +test[i].out + " nn: " + activate(getSum(w, test[i]) ) );}

产生

1,1 out: 1 nn: 1 0,0 out: 0 nn: 0 0,1 out: 0 nn: 0 1,0 out: 0 nn: 0 

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注