La neurona
En resumen: Una neurona es la suma de sus entradas multiplicadas por pesos, más un sesgo, pasada por una activación como la sigmoide o ReLU.
Problema
La red detuvo el pago. ¿Por qué?
La tienda reemplaza su vieja regla antifraude por una «red neuronal» de una empresa externa. El primer día un cliente paga 230 € desde una cuenta nueva con una tarjeta extranjera, y el pago se detiene para una revisión manual. El cliente escribe a soporte: «¿Por qué?»
Nadie lo sabe. Para el equipo la red es una caja negra: entran las características del pago y sale un número. Y mientras no sepas qué pasa por dentro, no puedes explicar la decisión, corregir un error ni siquiera decir si el número tiene sentido.
La caja se abre. Dentro no hay nada que no hayas visto: multiplicación, suma y una función.
La idea
Una neurona: una suma con pesos
Una neurona artificial recibe unos cuantos números (sus entradas). Cada entrada tiene su propio peso: cuánto cuenta y en qué dirección. La neurona multiplica cada entrada por su peso, suma todo y suma un número más, el sesgo. El resultado se llama z.
Luego z pasa por una función que decide qué sale. Se llama función de activación. Por ahora es la sigmoide: comprime cualquier z hasta un número entre 0 y 1.
¿Te suena? Es la regresión logística: una suma ponderada, una sigmoide, una probabilidad y un umbral. Una neurona con sigmoide es exactamente eso. Una red neuronal son muchas neuronas así, conectadas una tras otra.
Míralo
La neurona en código
Las tres funciones: la suma ponderada, la sigmoide y la neurona que las une.
function weightedSum(x, w, b) { let z = b; // el sesgo for (let i = 0; i < x.length; i++) { z += x[i] * w[i]; // entrada × peso } return z;}
function sigmoid(z) { return 1 / (1 + Math.exp(-z));}
function neuron(x, w, b) { return sigmoid(weightedSum(x, w, b));}Los pagos tienen tres características: el monto en cientos de euros, una cuenta nueva (1 o 0) y una tarjeta extranjera (1 o 0). Los pesos están puestos a mano para que puedas hacer las cuentas de cabeza. Cómo los encuentra una red por sí sola lo explica la lección sobre retropropagación.
// monto (cientos de €), cuenta nueva, tarjeta extranjeraconst w = [0.9, 1.4, 1.8];const b = -4.0;const payments = [ [0.40, 0, 0], [1.20, 1, 0], [8.90, 1, 1], [0.60, 0, 1], [6.40, 0, 0], [2.30, 1, 1],];const fmt = (v, d, n = 0) => v.toFixed(d).padStart(n);console.log(" monto € nueva extr. z p");for (const x of payments) { const z = weightedSum(x, w, b); const p = sigmoid(z); const verdict = p >= 0.5 ? "revisar" : "ok"; console.log(`${fmt(x[0] * 100, 0, 8)} ${fmt(x[1], 0, 5)} ${fmt(x[2], 0, 7)} ${fmt(z, 2, 6)} ${fmt(p, 3, 6)} ${verdict}`);} monto € nueva extr. z p 40 0 0 -3.64 0.026 ok 120 1 0 -1.52 0.179 ok 890 1 1 7.21 0.999 revisar 60 0 1 -1.66 0.160 ok 640 0 0 1.76 0.853 revisar 230 1 1 1.27 0.781 revisarYa puedes responder al cliente. El pago de 230 € es la última fila: z = −4 + 2,3 × 0,9 + 1 × 1,4 + 1 × 1,8 = −4 + 2,07 + 1,4 + 1,8 = 1,27. La sigmoide da 0,781, por encima del umbral de 0,5. La cuenta nueva y la tarjeta extranjera sumaron 3,2. Sin ellas, z sería −1,93, y la probabilidad, alrededor de 0,13.
Míralo
La señal pasa por la neurona
function weightedSum(x, w, b) { let z = b; // el sesgo for (let i = 0; i < x.length; i++) { z += x[i] * w[i]; // entrada × peso } return z;}
function sigmoid(z) { return 1 / (1 + Math.exp(-z));}
function neuron(x, w, b) { return sigmoid(weightedSum(x, w, b));}Paso a paso, en palabras
- Un pago de 230 € desde una cuenta nueva con una tarjeta extranjera. Las entradas son 2,30, 1 y 1.
- z empieza con el sesgo: −4,00.
- Cada entrada por su peso: 2,30 × 0,9 = 2,07, 1 × 1,4 = 1,40, 1 × 1,8 = 1,80.
- La suma: z = −4 + 2,07 + 1,40 + 1,80 = 1,27.
- La sigmoide comprime z entre 0 y 1: σ(1,27) = 0,781.
- 0,781 está por encima del umbral de 0,5: el pago pasa a revisión.
- 40 € de una cuenta antigua con una tarjeta búlgara: z = −4 + 0,36 = −3,64, p = 0,026. Ok.
- Una neurona: una suma con pesos, un sesgo y una sigmoide. Eso es la regresión logística.
Primero va el sesgo, y luego cada entrada aporta su parte. La sigmoide no cambia el orden: un z mayor da una p mayor. Solo la comprime entre 0 y 1, para que se lea como una probabilidad.
Pruébalo
Encuentra el error
Un colega escribe la suma ponderada por su cuenta. Con un sesgo de −4, todos los pagos salen con un z mucho menor del que deberían, y ninguno llega a revisión. ¿En qué línea está el error?
Elige la línea con el error.
El sesgo se suma en cada entrada, no una sola vez: con tres entradas entra tres veces. Con b = −4 la suma queda 8 por debajo de lo debido. Lo correcto es empezar z con b y sumar en el ciclo solo entrada × peso.
Problema
Tres neuronas que valen una
Un colega quiere que la red capte reglas más complejas. Añade dos neuronas que leen el pago y una tercera que lee sus salidas. No hay ninguna activación: cada neurona devuelve la suma z tal cual.
El programa calcula las tres neuronas y, por separado, una neurona cuyos pesos se calculan a partir de los suyos:
const fmt = (v, d, n = 0) => v.toFixed(d).padStart(n);// dos neuronas leen el pago, sin activaciónconst w1 = [0.5, 1.0, 1.5];const b1 = -1.0;const w2 = [1.0, -0.5, 0.5];const b2 = 0.5;// una tercera neurona lee sus salidasconst v = [1.5, -0.5];const c = 0.5;// lo mismo que una neurona con estos pesosconst w3 = w1.map((_, i) => v[0] * w1[i] + v[1] * w2[i]);const b3 = v[0] * b1 + v[1] * b2 + c;console.log(`w = [${w3.map((x) => x.toFixed(2)).join(", ")}], b = ${b3.toFixed(2)}`);
const payments = [[0.40, 0, 0], [1.20, 1, 0], [8.90, 1, 1]];console.log(" monto € tres neuronas una neurona");for (const x of payments) { const a1 = weightedSum(x, w1, b1); const a2 = weightedSum(x, w2, b2); const out = weightedSum([a1, a2], v, c); const one = weightedSum(x, w3, b3); console.log(`${fmt(x[0] * 100, 0, 8)} ${fmt(out, 4, 13)} ${fmt(one, 4, 12)}`);}w = [0.25, 1.75, 2.00], b = -1.25 monto € tres neuronas una neurona 40 -1.1500 -1.1500 120 0.8000 0.8000 890 4.7250 4.7250Las columnas coinciden hasta el último dígito. Las tres neuronas valen una. La razón es álgebra de escuela: una suma de sumas sigue siendo una suma. Pongas lo que pongas una tras otra, sin activación el resultado es una línea recta (un plano, para ser exactos) con otros pesos.
La idea
La activación dobla la línea
Algo nuevo solo aparece cuando entre las neuronas hay una función que no es recta. Las dos más comunes:
- Sigmoide: comprime z entre 0 y 1. Es cómoda para la salida, cuando quieres una probabilidad.
- ReLU (rectified linear unit): max(0, z). Lo positivo pasa, lo negativo se vuelve 0. Es la activación más común en las neuronas ocultas de las redes de hoy.
function relu(z) { return Math.max(0, z);}const fmt = (v, d, n = 0) => v.toFixed(d).padStart(n);const zs = [-3, -1, 0, 1, 3];console.log(" z sigmoid ReLU");for (const z of zs) { console.log(`${fmt(z, 2, 6)} ${fmt(sigmoid(z), 4, 8)} ${fmt(relu(z), 2, 5)}`);} z sigmoid ReLU -3.00 0.0474 0.00 -1.00 0.2689 0.00 0.00 0.5000 0.00 1.00 0.7311 1.00 3.00 0.9526 3.00Las dos están dobladas. La sigmoide es una «S», y ReLU es una recta con un quiebre en cero. Una suma de líneas dobladas ya no es recta, así que las neuronas con activación una tras otra pueden describir una regla que una sola neurona no puede. Esa regla llega en la próxima lección.
Pruébalo
Predice la salida
Una neurona con ReLU estima cuántos días de retraso tiene una entrega. Las entradas son la distancia en cientos de kilómetros y si el paquete es pesado. Un retraso no puede ser negativo, de ahí ReLU. ¿Qué imprimirá?
const w = [0.5, 1.0]; // cientos de km, paquete pesado (1 o 0)const b = -1.0;const near = relu(weightedSum([1.5, 0], w, b));const far = relu(weightedSum([4.4, 0], w, b));const heavy = relu(weightedSum([3.0, 1], w, b));console.log(`${near.toFixed(1)} ${far.toFixed(1)} ${heavy.toFixed(1)}`);La entrega cercana: 0,5 × 1,5 − 1 = −0,25, y ReLU la deja en 0. La lejana: 0,5 × 4,4 − 1 = 1,2. El paquete pesado: 0,5 × 3 + 1 − 1 = 1,5. Con una sigmoide saldría 0,4 0,8 0,8, y sin ReLU el primer número sería negativo: −0,25.
Pruébalo
Completa
Termina ReLU.
function relu(z) {
return (0, z);
}Math.max(0, z) devuelve el mayor de 0 y z: lo positivo pasa, lo negativo se vuelve 0.
La idea
Cuándo basta una neurona y cuándo perjudica
- La regla es casi recta. Si las características dicen la respuesta por sí solas (un monto mayor, más riesgo), una neurona, es decir, la regresión logística, rinde igual que una red grande. Aprende más rápido y necesita menos datos.
- Hay pocos datos. Una red con cientos de pesos y 200 ejemplos se los aprende de memoria. Eso es sobreajuste.
- Tienes que explicar la decisión. Los pesos de una neurona se pueden leer: «la cuenta nueva sumó 1,4». En una red con muchas capas la respuesta al «por qué» es mucho más difícil, y para un pago detenido o un crédito rechazado se exige.
- La regla es conocida y firme. «Por encima de 5000 € siempre revisión manual» es un
if, no un modelo. - Las entradas tienen escalas distintas. Un monto en euros (40, 890) junto a características de 0 y 1 da pesos difíciles de aprender. Por eso aquí el monto está en cientos de euros. En un modelo real las entradas se normalizan.
Más precisamente, para curiosos
Las fórmulas. Para una neurona con entradas x₁, x₂, x₃:
z = w₁·x₁ + w₂·x₂ + w₃·x₃ + b
p = σ(z) = 1 / (1 + e^(−z))
En palabras: cada entrada por su peso, más el sesgo, y luego la sigmoide. e es el número de Euler (aproximadamente 2,718), y Math.exp(-z) es e elevado a −z.
Por qué tres neuronas sin activación son una. Si a₁ = w₁·x + b₁ y a₂ = w₂·x + b₂, entonces v₁·a₁ + v₂·a₂ + c = (v₁·w₁ + v₂·w₂)·x + (v₁·b₁ + v₂·b₂ + c). Eso es una neurona con pesos v₁·w₁ + v₂·w₂. Es exactamente lo que calcula el programa de las tres neuronas.
Otras activaciones: tanh (como la sigmoide, pero entre −1 y 1), leaky ReLU (lo negativo no es 0 sino pequeño, por ejemplo 0,01·z), softmax (en la salida, cuando hay más de dos clases: convierte varios números en probabilidades que suman 1). Hay muchas más, pero ReLU y la sigmoide bastan para entender todo lo de este módulo.
Con qué se construyen las redes reales. Aquí todo son ciclos y arreglos, para que veas cada número. Las redes reales tienen millones de pesos, y las matemáticas se hacen con matrices en una tarjeta gráfica. La práctica del aprendizaje automático es sobre todo en Python: NumPy para arreglos, scikit-learn para modelos clásicos, PyTorch para redes neuronales. Otros lenguajes también tienen herramientas: ML.NET para C#, DJL y Tribuo para Java, TensorFlow.js y ONNX Runtime para JavaScript. A menudo un modelo se entrena en Python y se usa desde un programa en otro lenguaje (por ejemplo, mediante ONNX).
El nombre. «Neurona» viene de la biología: una célula que reúne señales y «dispara» cuando su suma pasa un umbral. El parecido termina ahí. Una neurona artificial es una función de números.
Ejercicio
Una neurona para reseñas
Resuélvelo en tu editor.
La tienda quiere clasificar las reseñas en buenas y malas. De cada reseña ya están contadas las palabras buenas («rápido», «calidad») y las palabras malas («roto», «tarde»). Escribe una neurona con una sigmoide, con un peso de 1,1 para las palabras buenas, −1,7 para las malas y un sesgo de 0,2. Ejecútala con las cinco reseñas (buenas, malas): (3, 0), (1, 2), (0, 0), (2, 1), (0, 3). Una reseña es buena si p es al menos 0,5.
palabras buenas 3, palabras malas 0: p = 0.971 → buenapalabras buenas 1, palabras malas 2: p = 0.109 → malapalabras buenas 0, palabras malas 0: p = 0.550 → buenapalabras buenas 2, palabras malas 1: p = 0.668 → buenapalabras buenas 0, palabras malas 3: p = 0.007 → malaLa reseña sin ninguna palabra sale buena con 0,550: eso es solo el sesgo. Sin nada más en que apoyarse, el modelo cree levemente que la reseña es buena.
Más tareas
- Una tercera característica. Añade los signos de exclamación como característica con un peso de −0,3 y mira qué reseñas cambian su decisión.
- El umbral. Usa un umbral de 0,7 en lugar de 0,5. ¿Qué reseñas pasan a ser malas?
Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: Qué es el aprendizaje automático · Regresión lineal · Clasificación: fraude o no · Sobreajuste: el modelo que memoriza
- Continúa en: Capas · Retropropagación · El entrenamiento de principio a fin · Los dígitos del recibo
- Ejercicios sobre el tema: Una red neuronal por dentro