【问题标题】:Simple/Single layer perceptron algorithm doesn't work简单/单层感知器算法不起作用
【发布时间】:2013-08-20 01:13:32
【问题描述】:

我正在尝试(完全)掌握神经网络背后的想法,因此我开始创建自己的 simple perceptron 算法。

这是我的代码(在 JavaScript 中):

var lr = 0.1;//learning rate

//Initiate the weights randomly
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
}


//Return the raw activation value for a giving trainingSet
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;
}

//Activation function
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)) //should be negative
console.log("y=("+w[1]+"*x+"+w[2]+")/"+w[1])

结果不一致,(我正在使用 AND 算法来学习)。
情节应如下所示:

但通常看起来像这样:

我确定我在这里遗漏了一些小东西,
提前致谢。

【问题讨论】:

    标签: javascript artificial-intelligence neural-network perceptron


    【解决方案1】:

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

    • 您正在重新声明错误变量,它最初是一个总结错误,然后您再次将其声明为每个输出神经元错误,这会导致到整个过程的信息丢失
    • 您的停止标准不好 - 它应该是平均绝对错误值,而不仅仅是错误的总和 - 考虑简单的网络,它将标签 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 
    

    【讨论】:

    • 嘿,我正要写我的答案,结果相同。
    • 是的,错误被重新声明,我的错(我不是故意的)。另外,最后一点让我感到困惑,难道不是给出一组基本规则(不是全部)和(希望)网络会相应地表现的整个想法吗?
    • 但它确实有相应的行为。只是你的规则集太小,无法期待如此大的概括。有太多可能的模型,完全符合您所期望的一组规则,它会神奇地选择您唯一感兴趣的模型。
    • @lejlot,那么我该如何训练它的 AND 规则呢? (没有教它所有 4 种可能性)
    • 不是神经网络的用途。如果是 and,你可以用 (0,1)->0, (1,0)->0, (1,1)->1 训练它,它会推断出 (0, 0)->0 本身(仅因为 R^2 空间中没有与这 3 个值一致且与第四个值不一致的行),但再次这不是 nn 的用途.
    猜你喜欢
    • 2012-04-30
    • 2016-11-11
    • 2020-11-04
    • 2015-08-14
    • 1970-01-01
    • 2014-12-06
    • 2017-04-19
    • 2015-08-05
    相关资源
    最近更新 更多