2015-11-28 7 views
1

Я пытаюсь обучить персептрон для логической функции 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; 
    }   
} 

Учебные примеры (логическое И):

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, в то время как невозможно разделить И без смещение в такой настройке, так как вам нужно ответить -1, когда активация равна 0.

Попробуйте нарисовать правильный разделитель на листе бумаги, вы заметите, что без смещения ваша линия должна пересекать (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