Problema
La retropropagación multiplica los gradientes por la derivada de cada función de activación. Implementa activation_derivative(name, values) y devuelve la derivada en cada valor:
| name | Derivada |
|---|---|
"sigmoid" | s × (1 - s), donde s = 1 / (1 + e^(-x)) |
"relu" | 1 si x > 0, si no 0 |
"leaky_relu" | 1 si x > 0, si no 0.01 |
"tanh" | 1 - tanh(x)² |
Entrada
name: Uno de "sigmoid", "relu", "leaky_relu" o "tanh".
values: Las entradas x de la activación.
Salida
Devuelve la derivada en cada valor, en el mismo orden.
Restricciones
1 ≤ longitud ≤ 1.000
-50 ≤ cada valor ≤ 50
Ejemplos
Entrada:
name = "sigmoid"
values = [0.0, 2.0]
Salida esperada:
expected = [0.25, 0.104994]
Entrada:
std::string name = "sigmoid";
std::vector<double> values = {0.0, 2.0};
Salida esperada:
std::vector<double> expected = {0.25, 0.104994};
Entrada:
string name = "sigmoid";
double[] values = new double[] {0.0, 2.0};
Salida esperada:
double[] expected = new double[] {0.25, 0.104994};
Explicación
En 0, s = 0.5 y la pendiente es 0.5 × 0.5 = 0.25, el punto más empinado de la sigmoide. En 2, s ≈ 0.880797 y la pendiente es aproximadamente 0.104994.
Entrada:
name = "relu"
values = [-3.0, 0.0, 4.5]
Salida esperada:
expected = [0.0, 0.0, 1.0]
Entrada:
std::string name = "relu";
std::vector<double> values = {-3.0, 0.0, 4.5};
Salida esperada:
std::vector<double> expected = {0.0, 0.0, 1.0};
Entrada:
string name = "relu";
double[] values = new double[] {-3.0, 0.0, 4.5};
Salida esperada:
double[] expected = new double[] {0.0, 0.0, 1.0};
Explicación
ReLU es plana para x ≤ 0 (pendiente 0) y tiene pendiente 1 para x > 0, así que el resultado es [0, 0, 1].
Cómo abordarlo
Inténtalo primero por tu cuenta y luego abre las pistas una a una.
Pista 1
La derivada depende del tipo de activación, así que maneja cada función por separado para cada valor de entrada.
Pista 2
Para sigmoid y tanh, reutiliza la salida de la activación o su valor estándar en vez de recalcular desde cero de forma complicada.
Pista 3
Ojo con los umbrales de signo: ReLU usa una prueba estricta de positivo, mientras que leaky ReLU mantiene una pequeña pendiente para valores no positivos.
Complejidad esperada
tiempo O(n), espacio extra O(n)
Referencias
Este reto está adaptado para CodeUtility. Sigue el enunciado y las restricciones indicadas arriba.