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