Java 感知器训练的Delta训练规则

Java 感知器训练的Delta训练规则,java,machine-learning,perceptron,Java,Machine Learning,Perceptron,我正在尝试使用delta训练规则来训练感知器,使之适应AND布尔函数。但即使在收敛之后,它也错误地对输入进行了分类(实际上是1个输入)。你能告诉我哪里错了吗 这是使用的培训功能: public void trianWithDelta(Example[] examples){ for(int i=0;i<1000;++i){ dw1 = 0; dw2 = 0; for(Example ex:examples){

我正在尝试使用delta训练规则来训练感知器,使之适应AND布尔函数。但即使在收敛之后,它也错误地对输入进行了分类(实际上是1个输入)。你能告诉我哪里错了吗

这是使用的培训功能:

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; 
    }        
}
结果: w1:0.49999999994 w2:0.5000000000000002

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

-一,

1(不正确)

-一,


1

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

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

  • 在你的代码中,正好有一个角度来分隔你的数据,这是为行
    y=-x
    实现的,这意味着
    w1=w2
    ,它们的值之间的任何微小差异都会破坏分类器(例如
    1e-20
  • 您的分类器实际回答了三个值(当您使用符号函数时):-1、0、1,而在这种设置中不可能分离并且没有偏差,因为当激活为0时,您需要回答-1
试着在一张纸上画一个正确的分隔符,你会注意到,在没有偏差的情况下,你的线必须穿过(0,0),因此,它必须是y=-x,因此对于(-1,1)和(1,-1),激活是0

这两个问题都可以通过添加偏差节点来解决(这是您应该做的)

您还可以更改AND的“位”定义-例如,将“False”编码为-2

运行代码的行为与预期一致

Trained weights : 0.6363636363636364 0.6363636363636364
-1
-1
-1
1
Example[] examples = new Example[]{
        new Example(-2, -2, -2),
        new Example(-2 , 1, -2),
        new Example( 1, -2, -2),
        new Example( 1,  1, 1)
    };
Trained weights : 0.6363636363636364 0.6363636363636364
-1
-1
-1
1