Funciones de activación no lineales
Implementa las activaciones Sigmoide y ReLU para introducir no linealidad en la red.
Constrúyelo en tu lenguaje
El tester trata tu programa como una caja negra: sirve cualquier lenguaje. Estos son los más cómodos para este proyecto.
Fundamentos: ¿Por qué necesitamos funciones de activación?
En la etapa anterior aprendiste a calcular la combinación afín de una neurona: . Pero hay una limitación matemática fundamental: las combinaciones lineales solo pueden trazar líneas rectas o planos.
Si conectas múltiples capas de neuronas lineales en cascada, la combinación de una recta con otra recta sigue siendo matemáticamente una recta. Ninguna red meramente lineal, sin importar cuán profunda sea, podría resolver problemas no lineales elementales como la compuerta XOR o clasificar datos que forman círculos concéntricos.
Para otorgar a las redes neuronales la capacidad de aprender formas, curvas y fronteras de decisión complejas, la salida lineal debe pasar a través de una función de activaciónFunción matemática aplicada a la salida ponderada de una neurona para transformar la señal de forma no linealVer documentación oficial no lineal.
Entradas (x) ──> [ Suma ponderada: z = Σ w·x + b ] ──> [ Activación: f(z) ] ──> Salida (y)Las dos funciones esenciales de esta etapa
Implementarás las dos funciones más influyentes en la historia del aprendizaje profundo:
1. Sigmoide ()
Comprime cualquier número real del rango en un valor estrictamente comprendido en el intervalo . Esto la convierte en la herramienta perfecta para modelar probabilidades:
Propiedades intuitivas:
- Si , la neurona está en un punto neutro: , por lo que (50% de probabilidad).
- Con valores positivos crecientes (ej. ), , y .
- Con valores negativos decrecientes (ej. ), , y .
2. ReLU (Rectified Linear Unit)
Es la función de activación más utilizada en redes profundas modernas gracias a su simplicidad computacional y a que no sufre saturación en la región positiva:
- Si , devuelve exactamente (deja pasar la señal).
- Si , devuelve (apaga la neurona).
Tu objetivo en esta etapa
Cuando la entrada contenga "op": "activation", tu programa debe leer:
function: nombre de la función ("sigmoid"o"relu")value: valor flotante a activar
Ejemplos de entrada y salida
Ejemplo A (Sigmoide):
{ "op": "activation", "function": "sigmoid", "value": 2.0 }
Salida:
{ "output": 0.8808 }
Ejemplo B (ReLU):
{ "op": "activation", "function": "relu", "value": -3.2 }
Salida:
{ "output": 0 }
Implementación práctica y consejos de código
- En Python:
Usa el módulo estándar
math:python import math if fn == "relu": out = max(0.0, float(value)) elif fn == "sigmoid": out = 1.0 / (1.0 + math.exp(-float(value))) - En TypeScript:
Usa el objeto global
Math:typescript if (fn === "relu") { return { output: roundValue(Math.max(0, value)) }; } if (fn === "sigmoid") { return { output: roundValue(1 / (1 + Math.exp(-value))) }; }
Errores comunes de principiantes
- Olvidar el signo negativo en el exponente de la sigmoide: la fórmula es , no .
- En ReLU, no confundir con el valor absoluto
abs(z): los números negativos deben convertirse en0, no en números positivos.
Reglas de validación y salida
- Funciones válidas: Si el campo
functionno es exactamente"sigmoid"ni"relu", escribeerrorenstderry finaliza con código1. - Formato numérico: Redondea el valor resultante a 4 decimales. Si el número resultante no tiene parte decimal (como
0o3), emítelo como entero. - Salida compacta: Emite únicamente el JSON resultante en una línea:
json { "output": 0.5 }
Formato de salida y errores
Los ejemplos multilínea se muestran así para facilitar la lectura. Emite JSON compacto, sin espacios opcionales, con las propiedades en el orden de los ejemplos de salida y un salto de línea final. No escribas logs en stdout. Las pruebas comparan texto exacto.
Para entradas inválidas, usa stderr con la palabra error, stdout vacío y código 1. Para entradas válidas, código 0. Usa números JSON enteros cuando el resultado sea entero; en neural-network aplica el redondeo a cuatro decimales indicado en la etapa.