Java: training a perceptron to learn AND
Update the weights of a single neuron with the perceptron rule until it classifies all four inputs correctly.
On this page
Java arrays and loops.
- Update the weights of a single neuron with the perceptron rule until it classifies all four inputs correctly.
- Predict the sample output and explain the state changes.
- Complete the practice task and check the boundary cases.
The concept
A perceptron computes a weighted sum of its inputs plus a bias and outputs 1 if the sum is above zero, otherwise 0. Learning adjusts the weights whenever the output is wrong: each weight changes by the learning rate times the error times its input.
AND is linearly separable, meaning a single straight line can separate the inputs that give 1 from those that give 0, so the perceptron convergence theorem guarantees that this procedure finds weights after finitely many mistakes. XOR is not linearly separable, which a single perceptron can never learn.
Code example
class Main {
public static void main(String[] args) {
int[][] inputs = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
int[] targets = {0, 0, 0, 1};
double w1 = 0, w2 = 0, bias = 0, rate = 0.1;
for (int epoch = 0; epoch < 50; epoch++) {
for (int i = 0; i < inputs.length; 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;
}
}
for (int[] in : inputs) {
double sum = w1 * in[0] + w2 * in[1] + bias;
System.out.println(in[0] + " AND " + in[1] + " = " + (sum > 0 ? 1 : 0));
}
}
}0 AND 0 = 0 0 AND 1 = 0 1 AND 0 = 0 1 AND 1 = 1
Follow the code
Open the walkthrough to inspect the example one step at a time.
Show guided walkthrough
class Main { public static void main(String[] args) { int[][] inputs = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; int[] targets = {0, 0, 0, 1}; double w1 = 0, w2 = 0, bias = 0, rate = 0.1; for (int epoch = 0; epoch < 50; epoch++) { for (int i = 0; i < inputs.length; 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; } } for (int[] in : inputs) { double sum = w1 * in[0] + w2 * in[1] + bias; System.out.println(in[0] + " AND " + in[1] + " = " + (sum > 0 ? 1 : 0)); } }}Follow the example
Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.
View the complete dry-run table
| Step / line | What happens | State after step | Output so far |
|---|---|---|---|
| Start with all weights at zero. | w1 = 0, w2 = 0, bias = 0 | — | |
| The error is 0 when the neuron is right, and +1 or -1 when it is wrong. | error ∈ {-1, 0, 1} | — | |
| Only inputs that were active change their weight. | weights shift toward the correct answer | — | |
| After training, all four cases are classified correctly. | weights shift toward the correct answer | 0 AND 0 = 0 0 AND 1 = 0 1 AND 0 = 0 1 AND 1 = 1 |
Behind the scenes
How Java processes this code
The Java compiler produces bytecode. The JVM loads the class and invokes its main method.
Cost and common mistakes
O(epochs · n) time for n training examples.
- The rule only converges on linearly separable data. On XOR it keeps changing the weights forever.
- Comparing a floating-point sum to exactly zero is fragile; this example avoids ties because the weights settle away from zero for every input.
Try it yourself
What would happen if you trained on XOR targets {0, 1, 1, 0}?
Reveal answer and reasoning
The perceptron would never classify all four correctly, because no single line separates the XOR classes.