Les réseaux neuronaux. Questions des experts. - page 21

 
alsu:

4) Paramètres d'initialisation des poids - la forme de la distribution des valeurs et leur variance.

Trouvé. Il est possible de définir les paramètres d'initialisation des poids.

Il semble que j'ai utilisé les valeurs par défaut.


 
LeoV:
Formation avancée courte sur les réseaux neuronaux artificiels et les algorithmes génétiques
et algorithmes génétiques"

Les candidatures pour les cours de formation avancée de courte durée "Réseaux neuronaux artificiels et algorithmes génétiques" sont fermées.
Réseaux neuronaux artificiels et algorithmes génétiques",
menée par le département de l'éducation permanente de l'Université d'État de Moscou M.V. Lomonosov
Université d'État de Moscou V.V. Lomonosov sur la base de l'Institut de recherche nucléaire de l'Université d'État de Moscou
Université d'État de Moscou. Les personnes ayant suivi les cours reçoivent un certificat d'État de formation professionnelle avancée.
certificat d'état de formation avancée.
Les formations auront lieu deux fois par semaine, le soir à partir de 19 heures.
Les cours commencent le 25 février 2011.

Pour en savoir plus sur le programme du cours, obtenir plus d'informations et
Veuillez cliquer ici pour vous inscrire à ce cours :
http://www.neuroproject.ru/kpk.php
Je suis désolé, est-ce une publicité ou allez-vous suivre le cours vous-même ?
 
lasso:

Trouvé. Il est possible de définir les paramètres d'initialisation des balances.

Il semble que j'ai utilisé les valeurs par défaut.


Eh bien, il semble être clair que le problème est ici.

En partant de votre problème (si je comprends bien, vous avez des données unidimensionnelles que vous voulez diviser en deux classes), il s'agit de trouver un point (un seul !) sur l'ensemble des valeurs d'entrée, qui réalise de manière optimale la division spécifiée. Supposons que vous ayez un réseau 1-7-1. Ce réseau possède 21 poids (sept entrées pour la couche cachée, sept décalages pour celle-ci et sept entrées pour le neurone de sortie). Il s'avère que nous essayons de trouver un point, en prenant 21 variables. Avec une telle redondance de vingt et un pour un, il n'y a rien d'étonnant à ce que les lectures du réseau changent autant - la moindre différence dans les poids initiaux conduit à une dispersion significative des sorties après la formation. En gros, il s'avère que la tâche est trop simple pour le réseau, mais comme il ne la connaît pas, il cherche quelque chose qui n'existe pas. Techniquement, on peut probablement appeler cela du recyclage, mais en substance, cela revient à tirer sur des moineaux avec un canon.

À proprement parler, la tâche consistant à diviser des données unidimensionnelles en deux classes est exécutée avec succès par un seul neurone avec un poids d'entrée et un biais.

 
lasso:

Une dernière chose. Je suis alarmé par l'"étroitesse" de la gamme des sorties réseau actuelles. Pour clarifier :

-- le réseau MLP est 1-7-1

-- Les entrées du réseau sont distribuées uniformément dans l'intervalle [0;1], les sorties des exemples d'apprentissage sont 1 et -1.

Si, après la formation, toute la gamme des valeurs d'entrée est transmise au réseau, nous constatons que les sorties du réseau se situent dans une gamme très étroite. Par exemple :

opt_max_act=-0.50401336 opt_min_act=-0.50973881 step=0.0000286272901034

ou encore

opt_max_real=-0.99997914 opt_min_real=-0.99999908 step=0.00000010

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

Est-ce correct ou non ?


C'est difficile de dire si c'est correct... dépend de la situation

Selon votre exemple :

Ce cas signifie que le premier réseau sur toutes les entrées dit "ne sait pas" et le second sur les mêmes entrées dit "classe -1". Si les données sont les mêmes et que la différence se situe uniquement au niveau de l'initialisation des poids, il est fort probable qu'il s'agisse d'un fort mélange de classes, ce qui fait que les grilles ne peuvent pas comprendre intelligemment le modèle d'apprentissage et agissent donc "au hasard". En parlant de la façon dont cela peut se produire, je suppose que si le réseau utilise (probablement) des neurones biaisés, la grille remet simplement à zéro les poids de toutes les entrées d'information et ne laisse que les biais pour l'analyse. L'"analyse", bien sûr, n'est que nominale ; le réseau fonctionne selon le principe de l'autruche - il ne voit tout simplement pas les entrées. Pour confirmer ou infirmer cela, nous devons voir les matrices du réseau entraîné.

 

Voici le code MLP NS généré par "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:

C'est difficile de dire si c'est correct... dépend de la situation.

Selon votre exemple :

Ce cas signifie que le premier filet sur toutes les entrées dit "ne sait pas" et le second sur les mêmes entrées dit "classe -1". Si les données sont les mêmes et que la différence se situe uniquement au niveau de l'initialisation des poids, il est fort probable qu'il s'agisse d'un fort mélange de classes, ce qui fait que les grilles ne peuvent pas comprendre intelligemment le modèle d'apprentissage et agissent donc "au hasard". Pour ce qui est de la façon dont cela peut se produire, je suppose que si le réseau utilise (probablement) des neurones biaisés, alors la grille annule simplement les poids de toutes les entrées d'information et ne laisse que les biais pour l'analyse. L'"analyse", bien sûr, n'est que nominale ; le réseau fonctionne selon le principe de l'autruche - il ne voit tout simplement pas les entrées. Pour confirmer ou infirmer cela, nous devons voir les matrices du réseau entraîné.

Une dernière chose : FANN applique le décalage de biais dans toutes les couches sauf la couche entrante...

Mais je n'ai rien trouvé de semblable à un parti pris dans la description du paquet NN de Statistics 6.

Pour un débutant en SN, tous ces préjugés sont vraiment ahurissants...

 

Oui, très similaire à ce que j'ai dit, mais à l'envers. Le réseau se perd dans les données. Remarque - d'après l'architecture du réseau, il s'ensuit que tous les poids de la première couche sont égaux par rapport aux données d'entrée et devraient, en théorie, être répartis uniformément autour de zéro - mais comme vous le voyez sur l'image, ils ont été poussés vers le haut, ce qui a entraîné la saturation des neurones de la couche cachée (vous avez une fonction d'activation logistique ). Les seuils d'activation n'ont pas aidé, car ils sont restés autour de zéro, tout comme le neurone de sortie, qui, comme prévu, n'a rien compris à ce que le premier neurone lui a dit - mais nous avons déjà compris ce qui lui est arrivé.


 

Super ! !!

Les valeurs des pondérations et des seuils sous forme de diagramme.

Et une perspective très différente. Merci.

 
lasso:

Voici le code MLP NS généré par "Statistics" :

Bonjour !

Pourriez-vous me dire en quelques mots s'il est possible d'apprendre à compiler un fichier dll à partir d'un fichier C avec un réseau de neurones généré par Statistica avec l'aide d'un programmeur? Je veux dire que la procédure doit être expliquée une fois, pour que vous puissiez ensuite la faire vous-même selon le schéma. Juste le niveau de programmation en Basic à l'école, et le modèle NS pour travailler avec Foreh, mais je dois mettre à jour le réseau régulièrement - lire une nouvelle dll pour le générer. Dans le code MQL, le corriger à chaque fois est un peu compliqué.

 
alexeymosc:

Bonjour !

Est-il possible d'apprendre à compiler un fichier dll à partir d'un fichier C avec un réseau neuronal généré par Statistica avec l'aide d'un programmeur ?

Bonne nuit !

Je ne pense pas, la seule exception est si ce programmeur ne travaille pas pour Statistica lui-même ;))

alexeymosc:

Dans le code MQL, le corriger à chaque fois est un peu compliqué.

Quel type de SN utilisez-vous pour les statistiques ?

Si vous corrigez quelque chose manuellement, cela signifie qu'il y a un algorithme, donc qu'il doit être automatisé.....

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

Plus haut, on m'a recommandé d'utiliser GA, et juste aujourd'hui, avec l'aide de la bibliothèque joo(UGALib), j'ai réussi à obtenir un résultat souhaitable et stable.

Maintenant je vais glisser et déposer cette affaire à 4...

Ma plus profonde gratitude à Andrei (l'auteur). Une direction très prometteuse et flexible.

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

Peut-être cela vaut-il la peine de creuser dans cette direction ?