针对感知器训练的Delta训练规则

时间:2015-11-28 21:40:17

标签: java machine-learning perceptron

我试图使用delta训练规则为AND布尔函数训练感知器。但即使在收敛之后,它也错误地对输入进行了分类(实际上是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

1 个答案:

答案 0 :(得分:1)

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

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

  • 正好一个角度分隔您的数据,这是针对行y=-x实现的,在您的代码中它意味着w1=w2,甚至是它们的值之间的最小差异将打破分类器(例如1e-20
  • 你的分类器实际上回答三个值(当你使用符号函数时):-1,0,1,而在这样的设置中不可能分离和没有偏差,因为你需要在激活为0时回答-1。

尝试在纸上画出正确的分隔符,你会注意到,没有偏差你的线必须交叉(0,0),因此,它必须是y = -x,因此对于(-1, 1)和(1,-1)激活为0。

enter image description here

只需添加偏置节点就可以解决这两个问题(这就是你应该做的)。

enter image description here

您还可以更改AND的“位”定义 - 例如,将“False”编码为-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