Lab de evolución

Construí un laboratorio de evolución para entender las redes neuronales desde cero

Criaturas 2D con un cerebro de 211 pesos, sin PyTorch ni frameworks: evolucionan solas hasta aprender a distinguir la fruta madura de la venenosa. Primer post de una serie sobre mutación, olvido y aprendizaje.

Llevo toda una vida programando, y las redes neuronales siempre fueron para mí una caja negra que funciona. Sabía usarlas; no sabía por qué funcionan. Así que decidí construir algo donde no hubiera nada escondido: un pequeño mundo 2D con criaturas que tienen un cerebro hecho a mano con NumPy y que evolucionan sin que nadie les enseñe nada.

Sin PyTorch, sin TensorFlow, sin librerías de algoritmos genéticos. Python, NumPy para las cuentas, pygame para verlas moverse y matplotlib para los gráficos. Si algo aprende, quiero poder señalar exactamente qué número cambió y por qué.

Este es el primer post de una serie. Aquí cuento cómo es el laboratorio y lo primero que me sorprendió. En los siguientes van los experimentos.

Treinta criaturas buscando fruta en el mundo del laboratorio

El mundo

Cada criatura (en el código, critter) es un círculo con una antena a cada lado. Vive en un mundo con fruta en tres estados:

Fruta Energía al morderla
Verde +20
Madura +70
Pasada −30 (venenosa)

También hay zonas tóxicas: manchas de cuatro niveles que quitan energía cada tick: 2 en el borde y hasta 518 en el centro de las más fuertes, que en la práctica mata al instante.

Cada critter percibe el mundo con:

  • 5 rayos de visión: qué tan cerca hay comida o pared en cada dirección, y de qué color es la fruta que ve.
  • 2 antenas que huelen la toxicidad, una a cada lado.
  • Gusto: tres receptores (ácido, dulce, amargo) para la fruta que tiene al alcance.
  • Sensores internos: cuánta energía le queda y cuánto cambió en el último instante.

Son 22 números de entrada. Ninguno trae significado: para el cerebro, “amargo” es solo la entrada número 22. Que amargo signifique “no muerdas” lo tiene que descubrir la evolución.

El cerebro

Una red neuronal pequeña: 22 entradas, 8 neuronas ocultas y 3 salidas (girar, velocidad y morder o no). En total, 211 pesos.

El cerebro de una criatura en vivo: neuronas coloreadas por activación y conexiones por peso

Con un clic en cualquier critter se ve su cerebro funcionando en tiempo real: las neuronas se encienden en naranja o azul según su activación, y cada conexión se pinta según su peso (naranja positivo, azul negativo). Ver la red pensando cambió por completo mi forma de entenderla.

Cómo evoluciona

No hay entrenamiento ni respuestas correctas. Solo una vida y una nota:

  1. Nacen 30 critters con pesos al azar y viven hasta 3000 ticks.
  2. Su nota (fitness) es la energía total que lograron comer.
  3. Los mejores tienen más probabilidad de ser padres. Los 2 mejores pasan intactos a la siguiente generación (elitismo).
  4. Cada hijo es una copia de su padre con mutaciones: a algunos pesos, elegidos al azar, se les suma un poco de ruido.
  5. Se repite cientos de generaciones.

Es el algoritmo genético clásico: mutación ciega más selección natural. El genoma de un critter es literalmente el arreglo con los 211 pesos de su cerebro.

Los ojos también evolucionan

Aquí hice una trampa a propósito. Los critters nacen casi ciegos al color y al sabor: tienen dos genes de “cuerpo”, la agudeza de la vista y la del gusto, que empiezan en 0.05 sobre 1. Lo que perciben es esa agudeza por la señal real, más ruido. Con 0.05, la señal se pierde en el ruido.

Y tener buenos sentidos cuesta energía: el costo crece con el cuadrado de la agudeza. Lo hice así después de un primer intento con costo lineal, en el que la evolución descartaba el órgano. Es el viejo argumento de “¿para qué sirve medio ojo?”: si medio ojo cuesta la mitad pero no sirve de nada, nunca llega a ser un ojo entero.

Lo que me sorprendió: aprenden a elegir solos

Este es un mundo real del laboratorio, con mutación puramente al azar:

En un mundo, la fruta venenosa baja de 31% a 15% y el gusto sube de 0.05 a 0.92

Durante 100 generaciones muerden casi al azar: alrededor del 30% de lo que comen es venenoso, que es lo esperable si no distinguen nada. Mientras tanto, el gusto va mejorando poco a poco, pero todavía no lo usan. Cerca de la generación 113 algo hace clic: el cerebro empieza a usar lo que el órgano ya percibía, el veneno cae a la mitad y el gusto se estabiliza cerca de 0.9. Primero evoluciona el órgano; después, el cerebro aprende a usarlo.

Nadie programó la regla “si es amargo, no muerdas”. Les di sentidos que empiezan casi inútiles y la posibilidad de decidir; qué hacer con ellos lo encontraron la mutación y la selección. Otro detalle: casi siempre evolucionan el gusto y descartan la vista. Probar de cerca resulta más rentable que ver de lejos.

La parte honesta: casi nunca pasa

Ese gráfico es un mundo donde salió bien. En 20 mundos distintos (cada uno con otra posición de comida, zonas y cerebros iniciales), con mutación darwiniana pura, aprenden a elegir fruta en apenas 5 de 20. En los demás siguen mordiendo al azar las 400 generaciones.

Y cuando miro de cerca los que fallan, veo algo que me obsesiona: la mutación al azar rompe lo que ya funcionaba. Un critter descubre algo útil, sus hijos lo heredan con decenas de pesos movidos al azar, y la mitad pierde justo lo que lo hacía bueno. Es el mismo problema que se ve en los videos de “IA que aprende a jugar Snake”: aprende, mejora, y luego se vuelve más torpe, como si olvidara.

La pregunta de la serie

La mutación darwiniana es ciega: no sabe qué salió mal ni dónde. Pero el critter sí tuvo una vida, y en esa vida hubo dolor (morder algo amargo) y placer (morder algo dulce). Así que la pregunta que guía este laboratorio es:

¿Y si la mutación supiera dónde dolió?

No para decidir la dirección del cambio, que sigue siendo al azar, sino para decidir dónde y cuándo mutar. Mutar más las conexiones que empujaron el mordisco venenoso y proteger las que empujaron los buenos. La biología tiene algo parecido: las bacterias suben su tasa de mutación cuando están bajo estrés.

Para no engañarme, cada experimento sigue tres reglas:

  1. Una variable a la vez: cada estrategia es una pieza intercambiable, y entre experimentos cambia solo una.
  2. Muchos mundos: cada resultado se mide en 10 o 20 mundos distintos y se compara mundo por mundo.
  3. Controles justos: si una estrategia muta menos, se compara contra Darwin con exactamente el mismo número de mutaciones. Si no, no sé si ganó por mutar mejor o simplemente por mutar menos.

Spoiler del próximo post: con el mismo número de mutaciones, una de estas estrategias aprende a elegir fruta en 12 de 20 mundos, contra 4 de 20 de Darwin, y no hay ni un solo mundo donde Darwin aprenda y ella no. También hubo fracasos claros: heredar todo lo aprendido en vida (Lamarck puro) destruye la evolución en todos los mundos, y darle al critter un sentido del dolor más fino no cambió absolutamente nada. Los fracasos también van en la serie.

Lo que sigue

  • Mutar donde dolió: la estrategia que culpa y protege, con todos los números.
  • Un mundo que cambia las reglas: ¿qué pasa cuando la fruta madura se vuelve venenosa de un día para otro? ¿Quién se readapta más rápido sin olvidar todo? Ese experimento está corriendo mientras escribo esto.
  • Memoria y Snake: darle memoria al cerebro y llevar lo aprendido a un juego donde se ve si una red evoluciona sin volverse torpe.