C++: a perceptron learns OR but not XOR
A perceptron outputs 1 when a weighted sum of its inputs plus a bias is positive. The learning rule adds rate × error × input to each weight after every example. If the classes can be separated by a straight line, the rule is guaranteed to find such a line.
C++
#include <algorithm>
#include <iostream>
int train(const int targets[4], int epochs) {
const int inputs[4][2] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
double w1 = 0, w2 = 0, bias = 0, rate = 0.1;
int best = 0;
for (int epoch = 0; epoch < epochs; ++epoch) {
for (int i = 0; i < 4; ++i) {
double sum = w1 * inputs[i][0] + w2 * inputs[i][1] + bias;
int output = sum > 0 ? 1 : 0;
int error = targets[i] - output;
w1 += rate * error * inputs[i][0];
w2 += rate * error * inputs[i][1];
bias += rate * error;
}
int correct = 0;
for (int i = 0; i < 4; ++i) {
double sum = w1 * inputs[i][0] + w2 * inputs[i][1] + bias;
correct += ((sum > 0 ? 1 : 0) == targets[i]);
}
best = std::max(best, correct);
}
return best;
}
int main() {
const int or_targets[4] = {0, 1, 1, 1};
const int xor_targets[4] = {0, 1, 1, 0};
std::cout << "OR best accuracy: " << train(or_targets, 200) << "/4\n";
std::cout << "XOR best accuracy: " << train(xor_targets, 200) << "/4\n";
}