algorithm - simple - peso sinaptico
¿Cómo evolucionar los pesos de una red neuronal en Neuroevolution? (2)
Soy nuevo en Redes Neuronales Artificiales y algoritmos de NeuroEvolution en general. Estoy tratando de implementar el algoritmo llamado NEAT (NeuroEvolution of Augmented Topologies), pero la descripción en el documento público original omitió el método de cómo evolucionar los pesos de una red, dice "Los pesos de conexión mutan como en cualquier sistema NE, con cada conexión perturbada o no en cada generación ".
He hecho algunas búsquedas acerca de cómo mutar los pesos en los sistemas NE, pero no puedo encontrar ninguna descripción detallada, lamentablemente.
Sé que mientras entrena un NE, generalmente el algoritmo de retropropagación se usa para corregir los pesos, pero solo funciona si tiene una topología fija (estructura) a través de generaciones y conoce la respuesta al problema. En NeuroEvolution no conoce la respuesta, solo tiene la función de aptitud, por lo que no es posible usar la retropropagación aquí.
En NEAT, todo se hace a través de los operadores genéticos. Como ya sabe, la topología se desarrolla a través de eventos de crossover y mutación.
Los pesos se desarrollan a través de eventos de mutación. Al igual que en cualquier algoritmo evolutivo, existe cierta probabilidad de que un peso se cambie aleatoriamente (puede generar un número nuevo o puede, por ejemplo, agregar un número aleatorio distribuido normalmente al peso original).
Implementar NEAT puede parecer una tarea fácil, pero al final hay muchos pequeños detalles que lo hacen bastante complicado. Es posible que desee ver las implementaciones existentes y utilizar una de ellas o, al menos, inspirarse en ellas. Todo lo importante se puede encontrar en la página de usuarios de NEAT .
Tengo cierta experiencia en el entrenamiento de un NN de topología fija utilizando un algoritmo genético (lo que el documento llama el "enfoque tradicional del NE"). Hay varios operadores diferentes de mutación y reproducción que utilizamos para esto y los hemos seleccionado al azar.
Con dos padres, nuestros operadores de reproducción (también podrían llamar a estos operadores de cruce) incluyen:
Cambie pesos individuales o todos los pesos para una neurona dada en la red. Entonces, por ejemplo, dado que dos padres seleccionados para la reproducción eligen un peso particular en la red y cambian el valor (para nuestros swaps producimos dos hijos y luego elegimos el que tiene la mejor aptitud para sobrevivir en la siguiente generación de la población), o elige una neurona en particular en la red e intercambia todos los pesos para que esa neurona produzca dos crías.
intercambia los pesos de una capa completa. Entonces, dados los padres A y B, elijan una capa particular (la misma capa en ambos) y cambien todos los pesos entre ellos para producir dos derivaciones. Este es un movimiento grande, así que lo configuramos para que esta operación se seleccione con menos frecuencia que las otras. Además, esto puede no tener sentido si su red solo tiene algunas capas.
Nuestros operadores de mutación operaban en una sola red y seleccionaban un peso aleatorio y:
- reemplazarlo por completo con un nuevo valor aleatorio
- cambie el peso en algún porcentaje. (multiplique el peso por un número aleatorio entre 0 y 2 - prácticamente hablando, tenderíamos a restringirlo un poco y multiplicarlo por un número aleatorio entre 0.5 y 1.5. Esto tiene el efecto de aumentar el peso para que no cambie como radicalmente. También podría hacer este tipo de operación escalando todos los pesos de una neurona en particular.
- sume o reste un número aleatorio entre 0 y 1 a / desde el peso.
- Cambia el signo de un peso.
- intercambia pesos en una sola neurona.
Ciertamente puede ser creativo con los operadores de mutación, puede descubrir algo que funcione mejor para su problema particular.
IIRC, elegiríamos dos padres de la población en base a selección proporcional aleatoria, luego ejecutaremos las operaciones de mutación en cada uno de ellos y luego ejecutaremos a estos padres mutados a través de la operación de reproducción y ejecutaremos a los dos descendientes a través de la función de aptitud para seleccionar el más apto para ir en la población de la próxima generación.
Por supuesto, en su caso, ya que también está evolucionando la topología, algunas de estas operaciones de reproducción anteriores no tendrán mucho sentido porque dos padres seleccionados podrían tener topologías completamente diferentes. En NEAT (como yo lo entiendo) puede tener conexiones entre capas no contiguas de la red, por lo que puede hacer que una neurona de capa 1 alimente a otra en la capa 4, en lugar de alimentar directamente a la capa 2. Eso hace que las operaciones de intercambio involucren todos los pesos de una neurona son más difíciles: puede tratar de elegir dos neuronas en la red que tengan el mismo número de pesos, o simplemente mantener intercambiando pesos individuales en la red.
Sé que mientras se entrena un NE, generalmente el algoritmo de retropropagación se usa para corregir los pesos
En realidad, en NE backprop no se usa. Son las mutaciones realizadas por la AG que están entrenando a la red como una alternativa al backprop. En nuestro caso, backprop fue problemático debido a algunas adiciones "poco ortodoxas" a la red en las que no entraré. Sin embargo, si backprop hubiera sido posible, me habría ido con eso. El enfoque genético para entrenar a los NN definitivamente parece avanzar mucho más lentamente de lo que probablemente lo hubiera hecho el backprop. Además, cuando se usa un método evolutivo para ajustar los pesos de la red, se comienza a modificar varios parámetros de la GA, como las tasas de crossover y de mutación.