2011-05-01 25 views
11

que estoy tratando de hacer un trabajo simple red neuronal artificial con el algoritmo de retropropagación. He creado una ANN y creo que he implementado el algoritmo de BP correctamente, pero, por supuesto, puedo estar equivocado.Problema con la red neuronal artificial sencilla - la adición de

En este momento, estoy tratando de entrenar a la red, dándole dos números al azar (a, b) entre 0 y 0,5, y tener que añadir ellos. Entonces, por supuesto, cada vez que la salida de la red da se compara con la respuesta teórica de a + b (que siempre será alcanzable por la función sigmoide).

Curiosamente, la salida siempre converge a un número entre 0 y 1 (como debe ser, debido a la función sigmoide), pero los números aleatorios que estoy poniendo parecen no tener ningún efecto en él.

Edit: Lo siento, parece que no converge. Aquí es una imagen de la salida:

enter image description here

Los pesos se distribuyen al azar entre -1 y 1, pero también han tratado entre 0 y 1.

también probé dándole dos números constantes (0.35,0.9) y tratando de entrenar para escupir 0.5. Esto funciona y converge muy rápido a 0.5. También lo he entrenado para escupir 0.5 si le doy dos números al azar entre 0 y 1, y esto también funciona.

Si por el contrario, mi objetivo es:

vector<double> target; 
target.push_back(.5); 

Entonces converge muy rápidamente, incluso con entradas aleatorias:

enter image description here

he intentado un par de diferentes redes, ya que lo hice muy fácil de agregar capas a mi red. El estándar que estoy usando es uno con dos entradas, una capa de 2 neuronas y una segunda capa de una sola neurona (la neurona de salida). Sin embargo, también he intentado agregar algunas capas y agregarles neuronas. No parece cambiar nada. Mi índice de aprendizaje es igual a 1.0, aunque lo intenté igual a 0.5 y no fue muy diferente.

¿Alguien tiene alguna idea de lo que podría intentar?

¿Es esto algo que una RNA es capaz de hacer? No me puedo imaginar que no lo sería, ya que pueden ser entrenados para hacer cosas tan complicadas.

¿Algún consejo? ¡Gracias!

Aquí es donde entreno que:

//Initialize it. This will be one with 2 layers, the first having 2 Neurons and the second (output layer) having 1. 
vector<int> networkSize; 
networkSize.push_back(2); 
networkSize.push_back(1); 
NeuralNetwork myNet(networkSize,2); 

for(int i = 0; i<5000; i++){ 
    double a = randSmallNum(); 
    double b = randSmallNum(); 
    cout << "\n\n\nInputs: " << a << ", " << b << " with expected target: " << a + b; 

    vector<double> myInput; 
    myInput.push_back(a); 
    myInput.push_back(b); 

    vector<double> target; 
    target.push_back(a + b); 

    cout << endl << "Iteration " << i; 
    vector<double> output = myNet.backPropagate(myInput,target); 
    cout << "Output gotten: " << output[0]; 
    resultPlot << i << "\t" << abs(output[0] - target[0]) << endl; 
} 

Edición: He definido mi red y he estado siguiendo de esta guía: A pdf. Implementé "Worked example 3.1" y obtuve los mismos resultados exactos que obtuvieron, así que creo que mi implementación es correcta, al menos en lo que respecta a la suya.

+2

Dado que una red neuronal se basa en las neuronas conectadas y cada neurona es una víbora en sí con ponderada insumos, creo que el objetivo al que intenta llegar es algo erróneo. Entonces, para agregar dos números, los pesos de la red deben establecerse en "1" y la salida solo puede estar entre 0 o 1 cuando se usa una función sigmoidea estándar. –

Respuesta

3

Como @macs indica, la salida máxima de sigmoid estándar es 1, por lo tanto, si intenta agregar n números desde [0, 1], entonces su objetivo debe ser normalizado, es decir, suma (A1, A2, ... ., Ana.

+0

@macs, @vines, lo siento, debería haber sido más específico. Los dos números están entre 0 y .5, por lo que su suma siempre será alcanzable por la función sigmoide. Déjame arreglar eso en mi publicación original. – MasterZibZob

3

En un modelo como este, la función sigmoidea (tanto en la salida como en las capas intermedias) se usa principalmente para producir algo que se asemeja a un alternar 0/1 mientras sigue siendo una función continua, por lo que se usa para representar un rango de números no es lo que este tipo de red está diseñado para hacer. Esto se debe a que está diseñado principalmente teniendo en cuenta los problemas de clasificación. Existen, por supuesto, otros modelos de NN que pueden hacer ese tipo de cosas (por ejemplo, colocar el sigmoide en la salida y simplemente mantenerlo como una suma de sus hijos).

Si puede redefinir su modelo en términos de clasificación de la entrada, probablemente obtendrá mejores resultados.

Algunos ejemplos de tareas similares para las que la red va a ser más adecuado:

  1. prueba si la salida es más grande o más pequeño que una cierta constante - esto debe ser muy fácil.
  2. Salida: una serie de salidas, cada una representando un valor de potencial diferente (por ejemplo, una salida para los valores entre 0 y 10, una para 'más de 10' y otra para 'menos de 0'). Deseará que su red redondee el resultado al número entero más cercano
  3. Un truco será tratar de crear una representación booleana de la salida teniendo múltiples nodos de salida.

Ninguno de ellos le dará la precisión que es posible que desee, sin embargo, ya que por los NN naturaleza son más 'fuzzy'

+0

¡Gracias por la respuesta! Hmmm, vale, creo que puedo haber entendido mal a las ANN. Pero aún quiero descubrirlos. Así que probé su primer problema, así: 'double a = randSmallNum2(); double b = 0; if (max (a, .5) == a) { \t b = 1; } \t cout << "\ n \ n \ nInputs:" << a << "con el objetivo esperado:" << b; vector myInput; myInput.push_back (a); vector objetivo; target.push_back (b); vector output = myNet.backPropagate (myInput, target); ' Con eso dentro del bucle for, por supuesto. No me da 0 o 1 cada vez como debería, ¿verdad? Gracias! – MasterZibZob

+0

En realidad, con el ejemplo n. ° 1, quise decir si la suma de los parámetros de entrada es mayor que un cierto número (de alguna manera eliminé esa parte de la descripción). Lo que hiciste es incluso un poco más simple y debería ser muy fácil de aprender para la NN. Aún así, la función sigmoidea casi nunca le dará exactamente 0 o 1, pero debería darle números muy cercanos a ellos (por lo tanto, trate 0.95 como 1 y 0.05 como 0. Puede elegir 0.5 como umbral). – winter

+0

Hmmm ... Voy a poner algunos diagnósticos para imprimir información en cada nivel, y volver aquí con los resultados ... ¡Gracias! – MasterZibZob

Cuestiones relacionadas