Volver a los desafíos
Difícil 0 resueltos 0% de aceptación

Backpropagation in a Two-Layer Network

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

Lo que aprenderás

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

Problema

Ver traducción

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.

Restricciones

1 ≤ n, h ≤ 20

-5 ≤ each input, weight and bias ≤ 5

0 ≤ target ≤ 1

Ejemplos

Ejemplo 1
Entrada:
inputs = [1.0]
target = 1.0
output_bias = 0.0
hidden_biases = [0.0]
hidden_weights = [
    [0.0]
]
output_weights = [0.0]

Salida esperada:
expected = [
    [0.0, 0.0],
    [-0.125, -0.25]
]
Entrada:
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};

Salida esperada:
std::vector<std::vector<double>> expected = {
    {0.0, 0.0},
    {-0.125, -0.25}
};
Entrada:
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};

Salida esperada:
double[][] expected = new double[][] {
    new double[] {0.0, 0.0},
    new double[] {-0.125, -0.25}
};

Explicación

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.

Ejemplo 2
Entrada:
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]

Salida esperada:
expected = [
    [0.0625, 0.0, 0.0625],
    [0.0625, 0.0, 0.0625],
    [0.125, 0.125, 0.25]
]
Entrada:
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};

Salida esperada:
std::vector<std::vector<double>> expected = {
    {0.0625, 0.0, 0.0625},
    {0.0625, 0.0, 0.0625},
    {0.125, 0.125, 0.25}
};
Entrada:
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};

Salida esperada:
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}
};

Explicación

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).

Cómo abordarlo

Inténtalo primero por tu cuenta y luego abre las pistas una a una.

Pista 1

Work backward from the output neuron first, then reuse that signal to compute each hidden neuron's contribution.

Pista 2

You need one delta for the output layer and one delta per hidden neuron, both based on sigmoid derivatives.

Pista 3

Be careful to use each hidden neuron's own output weight when propagating error back to that neuron.

Complejidad esperada

O(hn) time, O(hn) extra space

Referencias

Este reto está adaptado para CodeUtility. Sigue el enunciado y las restricciones indicadas arriba.

Aprende de otros

Soluciones de la comunidad

Aún no hay soluciones publicadas. Resuelve este reto para compartir la primera.