Дельта-тренировка для обучения персептрона

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

1 ответ

Решение

Ваш код на самом деле правильный, проблема заключается в том, что вы понимаете, что можно узнать, используя объективный персептрон, а что нет.

Если у вас нет предвзятости, то изучение И почти невозможно, потому что:

  • есть ровно один угол, разделяющий ваши данные, который реализуется для линии y=-xв вашем коде это будет означать, что w1=w2и даже малейшая разница между их значениями нарушит классификатор (такой как 1e-20)
  • Ваш классификатор фактически отвечает на три значения (поскольку вы используете знаковую функцию): -1, 0, 1, в то время как невозможно разделить И без смещения в такой настройке, так как вам нужно ответить -1, когда активация равна 0.

Попробуйте нарисовать правильный разделитель на листе бумаги, вы заметите, что без смещения ваша линия должна пересекать (0,0), таким образом, она должна быть y=-x, а следовательно, для (-1,1) и (1,-1) активация равна 0.

Обе проблемы можно решить, просто добавив узел смещения (и это то, что вы должны сделать).

Вы также можете изменить "немного" определение 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)
    };

И запуск вашего кода ведет себя как ожидалось

Trained weights : 0.6363636363636364 0.6363636363636364
-1
-1
-1
1
Другие вопросы по тегам