All challenges
Hard 0 solved 0% acceptance

Backpropagation in a Two-Layer Network

Compute every weight and bias gradient of a network with one sigmoid hidden layer and one sigmoid output.

What you'll learn

  • Compute every gradient of a two-layer network
  • Pass error terms backwards through layers
  • Connect math to code step by step

Problem

Backpropagation applies the chain rule layer by layer, from the output back to the inputs. The network has n inputs, h hidden neurons and one output, all with sigmoid activation (σ(z) = 1 / (1 + e^(-z))):

  • hidden: a_j = σ(inputs · hidden_weights[j] + hidden_biases[j])
  • output: y = σ(a · output_weights + output_bias)
  • loss: L = (y - target)²

Gradients:

  1. delta_out = 2 × (y - target) × y × (1 - y)
  2. Output layer: dL/doutput_weights[j] = delta_out × a_j and dL/doutput_bias = delta_out
  3. delta_j = delta_out × output_weights[j] × a_j × (1 - a_j)
  4. Hidden layer: dL/dhidden_weights[j][i] = delta_j × inputs[i] and dL/dhidden_biases[j] = delta_j

Implement backprop_gradients(inputs, hidden_weights, hidden_biases, output_weights, output_bias, target).

Output

Return a matrix with h + 1 rows:

  • Row j (for each hidden neuron j, in order): the n gradients of hidden_weights[j], then the gradient of hidden_biases[j].
  • Last row: the h gradients of output_weights, then the gradient of output_bias.

Constraints

1 ≤ n, h ≤ 20

-5 ≤ each input, weight and bias ≤ 5

0 ≤ target ≤ 1

Examples

Example 1
Input:
inputs = [1.0]
target = 1.0
output_bias = 0.0
hidden_biases = [0.0]
hidden_weights = [
    [0.0]
]
output_weights = [0.0]

Expected output:
expected = [
    [0.0, 0.0],
    [-0.125, -0.25]
]
Input:
std::vector<double> inputs = {1.0};
double target = 1.0;
double output_bias = 0.0;
std::vector<double> hidden_biases = {0.0};
std::vector<std::vector<double>> hidden_weights = {
    {0.0}
};
std::vector<double> output_weights = {0.0};

Expected output:
std::vector<std::vector<double>> expected = {
    {0.0, 0.0},
    {-0.125, -0.25}
};
Input:
double[] inputs = new double[] {1.0};
double target = 1.0;
double output_bias = 0.0;
double[] hidden_biases = new double[] {0.0};
double[][] hidden_weights = new double[][] {
    new double[] {0.0}
};
double[] output_weights = new double[] {0.0};

Expected output:
double[][] expected = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {-0.125, -0.25}
};

Explanation

a = σ(0) = 0.5 and y = σ(0) = 0.5. delta_out = 2 × (0.5 - 1) × 0.25 = -0.25. Output row: [-0.25 × 0.5, -0.25] = [-0.125, -0.25]. delta_1 = -0.25 × 0 × 0.25 = 0, so the hidden row is [0, 0]: a zero output weight blocks the gradient.

Example 2
Input:
inputs = [1.0, 0.0]
target = 0.0
output_bias = -1.0
hidden_biases = [0.0, 0.0]
hidden_weights = [
    [0.0, 1.0],
    [0.0, -1.0]
]
output_weights = [1.0, 1.0]

Expected output:
expected = [
    [0.0625, 0.0, 0.0625],
    [0.0625, 0.0, 0.0625],
    [0.125, 0.125, 0.25]
]
Input:
std::vector<double> inputs = {1.0, 0.0};
double target = 0.0;
double output_bias = -1.0;
std::vector<double> hidden_biases = {0.0, 0.0};
std::vector<std::vector<double>> hidden_weights = {
    {0.0, 1.0},
    {0.0, -1.0}
};
std::vector<double> output_weights = {1.0, 1.0};

Expected output:
std::vector<std::vector<double>> expected = {
    {0.0625, 0.0, 0.0625},
    {0.0625, 0.0, 0.0625},
    {0.125, 0.125, 0.25}
};
Input:
double[] inputs = new double[] {1.0, 0.0};
double target = 0.0;
double output_bias = -1.0;
double[] hidden_biases = new double[] {0.0, 0.0};
double[][] hidden_weights = new double[][] {
    new double[] {0.0, 1.0},
    new double[] {0.0, -1.0}
};
double[] output_weights = new double[] {1.0, 1.0};

Expected output:
double[][] expected = new double[][] {
    new double[] {0.0625, 0.0, 0.0625},
    new double[] {0.0625, 0.0, 0.0625},
    new double[] {0.125, 0.125, 0.25}
};

Explanation

Both hidden values are σ(0) = 0.5, so y = σ(0.5 + 0.5 - 1) = 0.5 and delta_out = 2 × 0.5 × 0.25 = 0.25. Output row: [0.125, 0.125, 0.25]. Each delta_j = 0.25 × 1 × 0.25 = 0.0625, giving hidden rows [0.0625, 0, 0.0625] (the second input is 0).

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.