machine learning - redes - ¿Cómo utilizar el aprendizaje de Hebbian?
plasticidad neuronal hebb (4)
Quiero actualizar mi simulador de evolución para usar el aprendizaje Hebb, como este . Básicamente quiero que las criaturas pequeñas puedan aprender a encontrar comida. Logré eso con las redes básicas de feedforward, pero estoy atascado en comprender cómo hacerlo con el aprendizaje de Hebb. El principio básico del aprendizaje de Hebb es que, si dos neuronas disparan juntas, se conectan entre sí.
Entonces, los pesos se actualizan así:
weight_change = learning_rate * input * output
La información que he encontrado sobre cómo puede ser útil es bastante escasa, y no la entiendo.
En mi versión actual del simulador, los pesos entre una acción y una entrada (movimiento, ojos) aumentan cuando una criatura come un trozo de comida, y no veo cómo se puede traducir en este nuevo modelo. Simplemente no hay espacio para decir si hizo algo bien o mal aquí, ¡porque los únicos parámetros son de entrada y salida! Básicamente, si una entrada activa el movimiento en una dirección, el peso seguirá aumentando, ¡sin importar si la criatura está comiendo algo o no!
¿Estoy aplicando el aprendizaje de Hebb de una manera incorrecta? Solo como referencia, estoy usando Python.
Aunque el aprendizaje hebbiano, como concepto general, forma la base de muchos algoritmos de aprendizaje, incluida la retropropagación, la fórmula simple y lineal que utiliza es muy limitada. Los pesos no solo aumentan infinitamente, incluso cuando la red ha aprendido todos los patrones, sino que la red puede aprender perfectamente patrones ortogonales (linealmente independientes).
El aprendizaje lineal Hebbian ni siquiera es biológicamente plausible. Las redes neuronales biológicas son mucho más grandes que las tuyas y son altamente no lineales, tanto las neuronas como las sinapsis entre ellas. En redes grandes, no lineales, las posibilidades de que sus patrones sean cercanos a ortogonales son mayores.
Entonces, si insiste en usar una red neuronal, sugiero agregar capas ocultas de neuronas e introducir no linealidades, tanto en los pesos, por ejemplo, como propuso fraxel, como en el disparo de neuronas; aquí podría usar una función sigmoidea, como tanh
(sí, usar valores negativos para "no disparar" es bueno, ya que puede reducir los pesos). En su forma generalizada, la regla de Hebbian se puede expresar como
weight_change = learning_rate * f1(input, weight) * f2(output, target_output)
donde f1
y f2
son algunas funciones. En su caso, no hay target_output
, por lo que f2
puede ignorarlo.
Para que las neuronas de las capas ocultas se disparen y, por lo tanto, para establecer una conexión entre la entrada y la salida, puedes inicializar las ponderaciones en valores aleatorios.
Pero, ¿es realmente necesaria una red neuronal, o incluso adecuada para su problema? ¿Has considerado la correlación simple? Es decir, Hebb derivó su regla para explicar cómo el aprendizaje podría funcionar en sistemas biológicos, no como el mejor algoritmo de aprendizaje automático posible.
No estoy muy familiarizado con este tipo de red neuronal, pero parece que esperas que funcione como un método de actualización supervisada mientras no esté supervisado. Esto significa que no puedes enseñarle lo que es correcto, solo aprenderá lo que es diferente, por asociación. Es decir, eventualmente asociará acciones con grupos de entradas particulares. En su situación en la que desee que mejore su toma de decisiones mediante comentarios, no creo que las actualizaciones de Hebbian sean suficientes. Sin embargo, podrías combinarlo con algún tipo de retropropagación.
Puedes probar con mi código.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package modelhebb;
/**
*
* @author Raka
*/
public class ModelHebb {
public static void main(String[] args) {
Integer xinput[][] = new Integer[][]{
{1, 1},
{1, -1},
{-1, 1},
{-1, -1}
};
Integer xtarget[] = new Integer[]{
1,
-1,
-1,
-1
};
Integer xweight[] = new Integer[xinput[0].length];
System.out.println("/t Iterasi /t");
Integer bayes = 0;
for (int i = 0; i < xtarget.length; i++) {
for (int j = 0; j < xinput[i].length; j++) {
int temp = xweight[j]==null?0:xweight[j];
xweight[j] = temp + (xinput[i][j] * xtarget[i]);
System.out.print("W"+j+": "+xweight[j]+"/t");
}
bayes = bayes + xtarget[i];
System.out.println("Bobot : " + bayes);
}
}
}
Hebbs law
es una idea brillante para el associative learning
, pero es solo una parte de la imagen. Y tienes razón, implementado como lo has hecho, y si no se controla, un peso seguirá aumentando. La clave es agregar algún tipo de proceso de normalización o limitación. Esto se ilustra bastante bien en la página wiki para la regla de Oja . Lo que sugiero que hagas es agregar un paso de post-synaptic divisive normalisation
, lo que esto significa es que divides a través de un peso por la suma de todas las ponderaciones que convergen en la misma neurona postsináptica (es decir, la suma de todas las ponderaciones que convergen en una neurona se fija en 1
).
Lo que desea hacer se puede hacer mediante la construcción de una red que utiliza el Hebbian learning
. No estoy muy seguro de lo que está pasando como entrada en su sistema, o de cómo ha configurado las cosas. Pero podrías mirar LISSOM
que es una extensión de LISSOM
para SOM, (mapa autoorganizado) .
En una capa de este tipo, típicamente todas las neuronas pueden estar interconectadas. Usted pasa el vector de entrada y permite que se establezca la actividad en la red, este es un cierto número de pasos de establecimiento. Luego actualiza los pesos. Hace esto durante la fase de entrenamiento, al final de la cual los elementos asociados en el espacio de entrada tenderán a formar parches de actividad agrupados en el mapa de salida.
También vale la pena señalar que el cerebro está interconectado de forma masiva y altamente recursivo (es decir, hay retroalimentación, retroalimentación, interconectividad lateral, microcircuitos y muchas otras cosas también ...).