Redes neuronales. Preguntas de los expertos. - página 21

 
alsu:

4) Parámetros de inicialización de los pesos: la forma de distribución de los valores y su varianza.

Encontrado. Es posible establecer los parámetros de inicialización de los pesos.

Parece que he utilizado los valores por defecto.


 
LeoV:
Curso corto de formación avanzada sobre redes neuronales artificiales y algoritmos genéticos
y algoritmos genéticos".

Las solicitudes para los cursos de formación avanzada de corta duración "Redes neuronales artificiales y algoritmos genéticos" están cerradas
Redes neuronales artificiales y algoritmos genéticos",
realizado por el Departamento de Formación Continua de la Universidad Estatal M.V. Lomonosov de Moscú
Universidad Estatal de Moscú V.V. Lomonosov sobre la base del Instituto de Investigación Nuclear de la Universidad Estatal de Moscú
Universidad Estatal de Moscú. Los que completan los cursos reciben un certificado estatal de formación profesional avanzada.
certificado estatal de formación avanzada.
Los cursos se impartirán dos veces por semana, por la tarde, a partir de las 19:00 horas.
Las clases comienzan el 25 de febrero de 2011.

Para conocer el programa del curso, obtener más información y
Haga clic aquí para solicitar el curso:
http://www.neuroproject.ru/kpk.php
Lo siento, ¿se trata de un anuncio o va a realizar el curso usted mismo?
 
lasso:

Encontrado. Es posible establecer los parámetros de inicialización de las balanzas.

Parece que he utilizado los valores por defecto.


Bueno, parece que está claro cuál es la cuestión aquí.

Partiendo de tu problema (entiendo que tienes datos unidimensionales que quieres dividir en dos clases), se trata de encontrar un punto (¡sólo uno!) en el conjunto de valores de entrada, que realice de forma óptima la división especificada. Suponga que tiene una red 1-7-1. Esta red tiene 21 pesos (siete entradas para la capa oculta, siete compensaciones para ella y siete entradas para la neurona de salida). Resulta que estamos tratando de encontrar un punto, recogiendo 21 variables. Con una redundancia de veintiuno a uno, no es de extrañar que las lecturas de la red se desplacen tanto: cualquier mínima diferencia en los pesos iniciales conduce a una importante dispersión de las salidas después del entrenamiento. A grandes rasgos, resulta que la tarea es demasiado sencilla para la red, pero como no la conoce, busca algo que no existe. Técnicamente, esto puede llamarse reentrenamiento, pero en esencia es disparar a los gorriones con un cañón.

En sentido estricto, la tarea de dividir los datos unidimensionales en dos clases la realiza con éxito una sola neurona con un peso de entrada y un sesgo.

 
lasso:

Una cosa más. Me alarma la "estrechez" de la gama de salidas de la red actual. Para aclarar:

-- la red MLP es 1-7-1

-- Las salidas de la red están distribuidas uniformemente en el rango [0;1], las salidas en los ejemplos de entrenamiento están representadas por los valores 1 y -1.

Si después del entrenamiento se pasa todo el rango de valores de entrada por la red, vemos que las salidas de la red se encuentran en un rango muy estrecho. Por ejemplo:

opt_max_act=-0.50401336 opt_min_act=-0.50973881 step=0.0000286272901034

o incluso así

opt_max_real=-0.99997914 opt_min_real=-0.99999908 step=0.00000010

.............................

¿Es esto correcto o no?


Es difícil decir sobre la corrección... depende de la situación

Según su ejemplo:

Este caso significa que la primera red en todas las entradas dice "no sé" y la segunda en las mismas entradas dice "clase -1". Si los datos son los mismos y la diferencia está sólo en la inicialización de los pesos, lo más probable es que se trate de una fuerte mezcla de clases, debido a la cual las rejillas no pueden entender inteligentemente el patrón de aprendizaje y como resultado actúan "al azar". Hablando de cómo puede ocurrir esto, supongo que si la red (probablemente sí) utiliza neuronas sesgadas, la red simplemente pone a cero los pesos de todas las entradas de información y deja sólo el sesgo para el análisis. El "análisis", por supuesto, es sólo nominal; la red funciona según el principio del avestruz: simplemente no ve las entradas. Para confirmar o negar esto, necesitamos ver las matrices de la red entrenada.

 

Aquí está el código MLP NS generado por "Statistics":

/* ------------------------------------------------------------------------- */


#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

#ifndef FALSE
#define FALSE 0
#define TRUE 1
#endif

#define MENUCODE -999


static double NNCode38Thresholds[] =
{

/* layer 1 */
-0.78576109762088242, -0.23216582173469763, -1.6708808507320108, -1.525614113040888,
1.4153558659332133, -0.77276960668316319, 2.3600992937381298, 2.473963708568014,
-0.43422405325901231, 0.68546943611132893, 0.19836417975077064, 0.26461366779934564,
-0.19131682804149783, 0.24687125804149584, -0.95588612620053504, 0.25329560565058901,
-1.0054817062488075, 1.3224622867600988, 0.88115523574528376, 0.32309684489223067,
0.52538428519764313,

/* layer 2 */
-1.8292886608617505

};

static double NNCode38Weights[] =
{

/* layer 1 */
1.8660729426318707,
1.3727568288578245,
3.1175074758006374,
3.356836518157698,
3.2574311486418068,
3.2774957848884769,
1.4284147042568165,
3.534875314491805,
2.4874577673065557,
2.1516346524000403,
1.9692127720516106,
4.3440737376517129,
2.7850179803408932,
-12.654434243399631,
2.4850018642785399,
2.1683631515554227,
1.77850226182071,
2.1342779960924272,
2.8753050022428206,
3.9464397902669828,
2.5227540467556553,

/* layer 2 */
-0.041641949353302246, -0.099151657230575702, 0.19915689162090328, -0.48586373846026099,
-0.091916813099494746, -0.16863091580772138, -0.11592356639654273, -0.55874391921850786,
0.12335845466035589, -0.022300206392803789, -0.083342117374385544, 1.550222748978116,
0.10305706982775611, 3.9280003726494575, 0.12771097131123971, -0.12144621860368633,
-0.40427171889553365, -0.072652508364580259, 0.20641498115269669, 0.1519896468808962,
0.69632055946019444

};

static double NNCode38Acts[46];

/* ---------------------------------------------------------- */
/*
  NNCode38Run - run neural network NNCode38

  Input and Output variables.
  Variable names are listed below in order, together with each
  variable's offset in the data set at the time code was
  generated (if the variable is then available).
  For nominal variables, the numeric code - class name
  conversion is shown indented below the variable name.
  To provide nominal inputs, use the corresponding numeric code.
  Input variables (Offset):
  stoch

  Выход:
  res
    1=1
    2=-1

*/
/* ---------------------------------------------------------- */

void NNCode38Run( double inputs[], double outputs[], int outputType )
{
  int i, j, k, u;
  double *w = NNCode38Weights, *t = NNCode38Thresholds;

  /* Process inputs - apply pre-processing to each input in turn,
   * storing results in the neuron activations array.
   */

  /* Input 0: standard numeric pre-processing: linear shift and scale. */
  if ( inputs[0] == -9999 )
    NNCode38Acts[0] = 0.48882189239332069;
  else
    NNCode38Acts[0] = inputs[0] * 1.0204081632653061 + 0;

  /*
   * Process layer 1.
   */

  /* For each unit in turn */
  for ( u=0; u < 21; ++u )
  {
    /*
     * First, calculate post-synaptic potentials, storing
     * these in the NNCode38Acts array.
     */

    /* Initialise hidden unit activation to zero */
    NNCode38Acts[1+u] = 0.0;

    /* Accumulate weighted sum from inputs */
    for ( i=0; i < 1; ++i )
      NNCode38Acts[1+u] += *w++ * NNCode38Acts[0+i];

    /* Subtract threshold */
    NNCode38Acts[1+u] -= *t++;

    /* Now apply the logistic activation function, 1 / ( 1 + e^-x ).
     * Deal with overflow and underflow
     */
    if ( NNCode38Acts[1+u] > 100.0 )
       NNCode38Acts[1+u] = 1.0;
    else if ( NNCode38Acts[1+u] < -100.0 )
      NNCode38Acts[1+u] = 0.0;
    else
      NNCode38Acts[1+u] = 1.0 / ( 1.0 + exp( - NNCode38Acts[1+u] ) );
  }

  /*
   * Process layer 2.
   */

  /* For each unit in turn */
  for ( u=0; u < 1; ++u )
  {
    /*
     * First, calculate post-synaptic potentials, storing
     * these in the NNCode38Acts array.
     */

    /* Initialise hidden unit activation to zero */
    NNCode38Acts[22+u] = 0.0;

    /* Accumulate weighted sum from inputs */
    for ( i=0; i < 21; ++i )
      NNCode38Acts[22+u] += *w++ * NNCode38Acts[1+i];

    /* Subtract threshold */
    NNCode38Acts[22+u] -= *t++;

    /* Now calculate negative exponential of PSP
     */
    if ( NNCode38Acts[22+u] > 100.0 )
       NNCode38Acts[22+u] = 0.0;
    else
      NNCode38Acts[22+u] = exp( -NNCode38Acts[22+u] );
  }

  /* Type of output required - selected by outputType parameter */
  switch ( outputType )
  {
    /* The usual type is to generate the output variables */
    case 0:


      /* Post-process output 0, two-state nominal output */
      if ( NNCode38Acts[22] >= 0.05449452669633785 )
        outputs[0] = 2.0;
      else
        outputs[0] = 1.0;
      break;

    /* type 1 is activation of output neurons */
    case 1:
      for ( i=0; i < 1; ++i )
        outputs[i] = NNCode38Acts[22+i];
      break;

    /* type 2 is codebook vector of winning node (lowest actn) 1st hidden layer */
    case 2:
      {
        int winner=0;
        for ( i=1; i < 21; ++i )
          if ( NNCode38Acts[1+i] < NNCode38Acts[1+winner] )
            winner=i;

        for ( i=0; i < 1; ++i )
          outputs[i] = NNCode38Weights[1*winner+i];
      }
      break;

    /* type 3 indicates winning node (lowest actn) in 1st hidden layer */
    case 3:
      {
        int winner=0;
        for ( i=1; i < 21; ++i )
          if ( NNCode38Acts[1+i] < NNCode38Acts[1+winner] )
            winner=i;

        outputs[0] = winner;
      }
      break;
  }
}
 
alsu:

Es difícil decir sobre la corrección... depende de la situación.

Según su ejemplo:

Este caso significa que la primera red en todas las entradas dice "no sabe" y la segunda en las mismas entradas dice "clase -1". Si los datos son los mismos y la diferencia está sólo en la inicialización de los pesos, lo más probable es que se trate de una fuerte mezcla de clases, debido a la cual las rejillas no pueden entender inteligentemente el patrón de aprendizaje y como resultado actúan "al azar". Hablando de cómo puede ocurrir esto, supongo que si la red (probablemente sí) utiliza neuronas sesgadas, la red simplemente pone a cero los pesos de todas las entradas de información y deja sólo el sesgo para el análisis. El "análisis", por supuesto, es sólo nominal; la red funciona según el principio del avestruz: simplemente no ve las entradas. Para confirmar o negar esto, necesitamos ver las matrices de la red entrenada.

Una cosa más: FANN aplica el cambio de sesgo en todas las capas excepto en la entrante...

Pero no he encontrado nada parecido a la parcialidad en la descripción del paquete NN de Statistics 6.

Para un principiante en NS, todos estos sesgos son realmente alucinantes...

 

Sí, muy similar a lo que dije, sólo que al revés. La red se pierde en los datos. Nota - de la arquitectura de la red se deduce que todos los pesos de la primera capa son iguales con respecto a los datos de entrada y deberían, en teoría, estar distribuidos uniformemente en torno a cero - pero como se ve en la imagen, se han disparado, lo que ha hecho que las neuronas de la capa oculta entren en saturación (tiene una función de activación logística ). Los umbrales de activación no ayudaron, porque se mantuvieron en torno a cero, al igual que la neurona de salida, que, como era de esperar, no entendió nada de lo que le dijo la primera neurona -pero ya hemos averiguado qué le pasó-.


 

¡¡¡Grandioso!!!

Los valores de las ponderaciones y los umbrales en forma de diagrama.

Y una perspectiva completamente diferente. Gracias.

 
lasso:

Aquí está el código MLP NS generado por "Statistics":

¡Buenas tardes!

¿Podría sugerir en pocas palabras, es posible aprender a compilar un archivo dll de un archivo C con una red neuronal generada por Statistica con la ayuda de un programador? Me refiero a que te expliquen el procedimiento una vez, para que luego puedas hacerlo tú mismo según el esquema. Sólo el nivel de programación en Basic en la escuela, y el modelo de NS para trabajar con Foreh, pero tengo que actualizar la red con regularidad - leer una nueva dll para generar. En el código MQL, corregirlo cada vez es un poco complicado.

 
alexeymosc:

¡Buenas tardes!

¿Es posible aprender a compilar un archivo dll a partir de un archivo C con una red neuronal generada por Statistica con la ayuda de un programador?

¡Buenas noches!

Creo que no, la única excepción es si ese programador no trabaja para la propia Statistica ))

alexeymosc:

En el código MQL, corregirlo cada vez es algo complicado.

¿Qué tipo de NS utiliza en las estadísticas?

Si se corrige algo manualmente, significa que hay un algoritmo, por lo que hay que automatizarlo....

...............................

Arriba me recomendaron usar GA, y justo hoy con la ayuda de la librería joo(UGALib) logré obtener un resultado deseable y estable.

Ahora voy a arrastrar y soltar este caso a 4...

Mi más profundo agradecimiento a Andrei (el autor). Una dirección muy prometedora y flexible.

.....................

¿Quizás merezca la pena indagar en esta dirección?

Razón de la queja: