2015-11-28 148 views
1

我正在尝试使用德尔塔培训规则来训练感知器的与布尔函数。但即使在收敛之后,它错误地将输入分类(实际上是1个输入)。你能告诉我在哪里,我错了:http://ideone.com/CDgTQE感知器培训的三角洲培训规则

这是用来训练功能:

public void trianWithDelta(Example[] examples){ 
    for(int i=0;i<1000;++i){ 

     dw1 = 0; 
     dw2 = 0; 

     for(Example ex:examples){ 
      double o = computeOutput(ex); 
      double t = ex.o; 

      dw1 = dw1 + n*(t-o)*ex.x1; 
      dw2 = dw2 + n*(t-o)*ex.x2; 
     } 

     w1 += dw1; 
     w2 += dw2; 
    }   
} 

的训练实例(布尔AND):

Example[] examples = new Example[]{ 
     new Example(-1, -1, -1), 
     new Example(-1 , 1, -1), 
     new Example(1, -1, -1), 
     new Example(1, 1, 1) 
    }; 

结果: W1:0.49999999999999994 w2:0.5000000000000002

使用培训后的培训示例进行测试:

-1

1(不正确)

-1

回答

1

你的代码实际上是正确,问题出在你的什么可以使用学到的理解无偏感知器和什么不能。

如果你没有偏见,那么学习,几乎是不可能的,因为:

  • 恰好有一个角分离在你的代码数据,这是实现了线y=-x,这将意味着即w1=w2,它们的值之间即使是最细微的差别也会打破分类器(如1e-20
  • 您分类器实际上回答三个值(如您使用符号函数):-1,0,1,而无法分离AND无在这种情况下的偏见,因为你需要回答-1时激活为0.

尝试在纸上绘制正确的分隔符,您会注意到,没有偏见,您的行必须跨越(0,0),因此它必须是y = -x,因此为(1,1)和(1,-1)激活是0

enter image description here

两个问题都可以仅仅通过增加偏置节点来解决(这是你应该做的)。

enter image description here

你也可以改变的 “位” 的定义和 - 通过编码 “假” 为-2

Example[] examples = new Example[]{ 
     new Example(-2, -2, -2), 
     new Example(-2 , 1, -2), 
     new Example(1, -2, -2), 
     new Example(1, 1, 1) 
    }; 

enter image description here

与乳宁你的代码的行为,例如如预期

Trained weights : 0.6363636363636364 0.6363636363636364 
-1 
-1 
-1 
1