Back to challenges
Medium 0 solved 0% acceptance

Perceptron Learning Algorithm

Train the original perceptron, which updates its weights only when it makes a mistake.

What you'll learn

  • Update weights only on mistakes
  • Train over several epochs
  • Learn how the first neural model worked

Problem

The perceptron (1958) is the first learning algorithm for an artificial neuron. It predicts with a step function and learns from its mistakes.

Start with all weights and the bias at 0. For each epoch, go through the samples in order, and for each sample x with label y (0 or 1):

  1. prediction = 1 if x · weights + bias > 0, otherwise 0
  2. error = y - prediction (so -1, 0 or 1)
  3. If error ≠ 0: weights[i] ← weights[i] + learning_rate × error × x[i] for every i, and bias ← bias + learning_rate × error

Implement train_perceptron(samples, labels, learning_rate, epochs).

Input

samples: m samples with n features each.

labels: The m labels, each 0 or 1.

learning_rate, epochs: The step size and the number of passes over the data.

Output

Return the final weights followed by the bias (n + 1 numbers).

Constraints

1 ≤ m ≤ 100, 1 ≤ n ≤ 10, 1 ≤ epochs ≤ 100

0 < learning_rate ≤ 1

-10 ≤ each feature ≤ 10

Examples

Example 1
Input:
epochs = 1
labels = [0, 0, 0, 1]
samples = [
    [0.0, 0.0],
    [0.0, 1.0],
    [1.0, 0.0],
    [1.0, 1.0]
]
learning_rate = 1.0

Expected output:
expected = [1.0, 1.0, 1.0]
Input:
long long epochs = 1;
std::vector<long long> labels = {0, 0, 0, 1};
std::vector<std::vector<double>> samples = {
    {0.0, 0.0},
    {0.0, 1.0},
    {1.0, 0.0},
    {1.0, 1.0}
};
double learning_rate = 1.0;

Expected output:
std::vector<double> expected = {1.0, 1.0, 1.0};
Input:
long epochs = 1;
long[] labels = new long[] {0, 0, 0, 1};
double[][] samples = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {0.0, 1.0},
    new double[] {1.0, 0.0},
    new double[] {1.0, 1.0}
};
double learning_rate = 1.0;

Expected output:
double[] expected = new double[] {1.0, 1.0, 1.0};

Explanation

[0, 0]: z = 0, predicts 0, correct. [0, 1] and [1, 0]: also predict 0, correct. [1, 1]: predicts 0 but the label is 1, so error = 1: weights become [1, 1] and the bias becomes 1. Result: [1, 1, 1].

Example 2
Input:
epochs = 10
labels = [0, 0, 0, 1]
samples = [
    [0.0, 0.0],
    [0.0, 1.0],
    [1.0, 0.0],
    [1.0, 1.0]
]
learning_rate = 1.0

Expected output:
expected = [2.0, 1.0, -2.0]
Input:
long long epochs = 10;
std::vector<long long> labels = {0, 0, 0, 1};
std::vector<std::vector<double>> samples = {
    {0.0, 0.0},
    {0.0, 1.0},
    {1.0, 0.0},
    {1.0, 1.0}
};
double learning_rate = 1.0;

Expected output:
std::vector<double> expected = {2.0, 1.0, -2.0};
Input:
long epochs = 10;
long[] labels = new long[] {0, 0, 0, 1};
double[][] samples = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {0.0, 1.0},
    new double[] {1.0, 0.0},
    new double[] {1.0, 1.0}
};
double learning_rate = 1.0;

Expected output:
double[] expected = new double[] {2.0, 1.0, -2.0};

Explanation

After 10 epochs the perceptron has learned the AND gate: with weights [2, 1] and bias -2, only [1, 1] gives z > 0.

How to approach it

Try on your own first, then open one hint at a time.

Hint 1

Process samples in order for each epoch, because earlier updates affect later predictions.

Hint 2

Only update when the predicted class differs from the label, and adjust both weights and bias together.

Hint 3

The prediction rule uses a strict sign test, so a score of zero counts as class 0.

Expected complexity

O(epochs × m × n) time, O(n) extra space

References

This challenge is adapted for CodeUtility. Follow the statement and constraints above.

Learn from others

Community solutions

No published solutions yet. Solve this challenge to share the first one.