Neuronale Netze. Fragen an die Experten. - Seite 21

 
alsu:

4) Initialisierungsparameter für die Gewichte - die Form der Verteilung der Werte und ihre Varianz.

Gefunden. Es ist möglich, die Initialisierungsparameter für die Gewichte festzulegen.

Es sieht so aus, als hätte ich die Standardwerte verwendet.


 
LeoV:
Künstliche Neuronale Netze und Genetische Algorithmen - Kurzlehrgang für Fortgeschrittene
und genetische Algorithmen"

Bewerbungen für Kurzzeit-Fortbildungskurse "Künstliche Neuronale Netze und Genetische Algorithmen" sind geschlossen
Künstliche neuronale Netze und genetische Algorithmen",
durchgeführt von der Abteilung für Weiterbildung der Staatlichen M.V. Lomonossow-Universität Moskau
Staatliche V.V. Lomonosov-Universität Moskau auf der Grundlage des Kernforschungsinstituts der Staatlichen Universität Moskau
Staatliche Universität Moskau. Die Absolventinnen und Absolventen der Kurse erhalten ein staatliches Zertifikat über die berufliche Fortbildung.
staatlicher Fortbildungsnachweis.
Die Schulungen finden zweimal pro Woche abends ab 19:00 Uhr statt.
Der Unterricht beginnt am 25. Februar 2011.

Um mehr über das Kursprogramm zu erfahren, erhalten Sie weitere Informationen und
Bitte klicken Sie hier, um sich für den Kurs zu bewerben:
http://www.neuroproject.ru/kpk.php
Entschuldigung, ist dies eine Werbung oder werden Sie den Kurs selbst besuchen?
 
lasso:

Gefunden. Es ist möglich, die Initialisierungsparameter für die Skalen einzustellen.

Ich scheine die Standardwerte verwendet zu haben.


Nun, es scheint klar zu sein, worum es hier geht.

Ausgehend von Ihrem Problem (so wie ich es verstehe, haben Sie eindimensionale Daten, die Sie in zwei Klassen aufteilen wollen), geht es darum, einen Punkt (nur einen!) auf der Menge der Eingabewerte zu finden, der die angegebene Aufteilung optimal durchführt. Angenommen, Sie haben ein 1-7-1-Netz. Dieses Netz hat 21 Gewichte (sieben Eingänge für die verborgene Schicht, sieben Offsets für sie und sieben Eingänge für das Ausgangsneuron). Es stellt sich heraus, dass wir versuchen, einen Punkt zu finden, indem wir 21 Variablen aufnehmen. Bei einer solchen Redundanz von einundzwanzig zu eins ist es nicht verwunderlich, dass sich die Werte des Netzes so stark verschieben - jeder noch so kleine Unterschied in den Anfangsgewichten führt nach dem Training zu einer erheblichen Streuung der Ergebnisse. Grob gesagt, stellt sich heraus, dass die Aufgabe für das Netz zu einfach ist, aber da es sie nicht kennt, sucht es nach etwas, das nicht existiert. Technisch gesehen kann man das wohl als Umschulung bezeichnen, aber im Grunde genommen wird mit Kanonen auf Spatzen geschossen.

Streng genommen wird die Aufgabe, eindimensionale Daten in zwei Klassen aufzuteilen, von einem einzigen Neuron mit einem Eingangsgewicht und einem Bias erfolgreich durchgeführt.

 
lasso:

Noch eine Sache. Ich bin beunruhigt über die "Enge" des Spektrums der derzeitigen Netzausgänge. Zur Klarstellung:

-- das MLP-Netz ist 1-7-1

-- Die Eingaben in das Netz sind gleichmäßig im Bereich [0;1] verteilt, die Ausgaben in den Trainingsbeispielen sind 1 und -1.

Wenn nach dem Training der gesamte Bereich der Eingabewerte durch das Netz geleitet wird, sehen wir, dass die Ausgänge des Netzes in einem sehr engen Bereich liegen. Zum Beispiel:

opt_max_act=-0.50401336 opt_min_act=-0.50973881 step=0.0000286272901034

oder sogar so

opt_max_real=-0.99997914 opt_min_real=-0.99999908 step=0.00000010

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

Ist das richtig oder nicht?


Es ist schwer zu sagen, ob es korrekt ist... hängt von der jeweiligen Situation ab

Nach Ihrem Beispiel:

In diesem Fall sagt das erste Netz auf allen Eingängen "weiß nicht" und das zweite Netz auf denselben Eingängen "Klasse -1". Wenn die Daten die gleichen sind und der Unterschied nur in der Initialisierung der Gewichte besteht, handelt es sich höchstwahrscheinlich um eine starke Vermischung der Klassen, aufgrund derer die Raster das Lernmuster nicht intelligent verstehen können und folglich "zufällig" handeln. Wenn ich darüber spreche, wie dies geschehen kann, gehe ich davon aus, dass, wenn das Netz (wahrscheinlich) voreingenommene Neuronen verwendet, das Netz einfach die Gewichte aller Informationseingänge auslöscht und nur die Voreingenommenheit für die Analyse übrig lässt. Die "Analyse" ist natürlich nur nominell; das Netz arbeitet nach dem Vogel-Strauß-Prinzip - es sieht die Eingaben einfach nicht. Um dies zu bestätigen oder zu verneinen, müssen wir uns die Matrizen des trainierten Netzes ansehen.

 

Hier ist der von "Statistics" generierte MLP NS-Code:

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


#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 ist schwer zu sagen, ob es korrekt ist... hängt von der jeweiligen Situation ab.

Nach Ihrem Beispiel:

In diesem Fall sagt das erste Netz auf allen Eingängen "weiß nicht" und das zweite Netz auf denselben Eingängen "Klasse -1". Wenn die Daten die gleichen sind und der Unterschied nur in der Initialisierung der Gewichte besteht, handelt es sich höchstwahrscheinlich um eine starke Vermischung der Klassen, aufgrund derer die Raster das Lernmuster nicht intelligent verstehen können und folglich "zufällig" handeln. Wenn ich darüber spreche, wie dies geschehen kann, gehe ich davon aus, dass, wenn das Netz (wahrscheinlich) voreingenommene Neuronen verwendet, das Netz einfach die Gewichte aller Informationseingänge auslöscht und nur die Voreingenommenheit für die Analyse übrig lässt. Die "Analyse" ist natürlich nur nominell; das Netz arbeitet nach dem Vogel-Strauß-Prinzip - es sieht die Eingaben einfach nicht. Um dies zu bestätigen oder zu verneinen, müssen wir uns die Matrizen des trainierten Netzes ansehen.

Und noch etwas: FANN wendet die Bias-Verschiebung in jeder Schicht an, außer in der eingehenden Schicht...

In der Beschreibung des NN-Pakets von Statistics 6 habe ich jedoch nichts gefunden, was einer Verzerrung ähnelt.

Für einen NS-Anfänger sind all diese Vorurteile wirklich verwirrend...

 

Ja, ganz ähnlich wie ich es gesagt habe, nur andersherum. Das Netz geht einfach in den Daten unter. Hinweis: Aus der Architektur des Netzes geht hervor, dass alle Gewichte der ersten Schicht in Bezug auf die Eingabedaten gleich sind und theoretisch gleichmäßig um Null herum verteilt sein sollten. Wie Sie jedoch im Bild sehen, wurden sie nach oben verschoben, was dazu führte, dass die Neuronen der versteckten Schicht in die Sättigung gingen (Sie haben eine logistische Aktivierungsfunktion). Die Aktivierungsschwellen halfen nicht, denn sie blieben bei Null, ebenso wie das Ausgangsneuron, das erwartungsgemäß nichts von dem verstand, was das erste Neuron ihm sagte - aber wir haben bereits herausgefunden, was mit ihm geschah.


 

Toll!!!

Die Werte der Gewichte und Schwellenwerte in Form eines Diagramms.

Und eine ganz andere Perspektive. Ich danke Ihnen.

 
lasso:

Hier ist der von "Statistics" generierte MLP NS-Code:

Guten Tag!

Könnten Sie kurz vorschlagen, ob es möglich ist, mit Hilfe eines Programmierers zu lernen, wie man eine dll-Datei aus einer C-Datei mit einem von Statistica generierten neuronalen Netz kompiliert? Ich meine, dass man sich das Verfahren einmal erklären lassen soll, damit man es anschließend selbst nach dem Schema machen kann. Nur das Niveau der Programmierung in Basic in der Schule, und NS-Modell, um mit Foreh arbeiten, aber ich brauche, um das Netzwerk regelmäßig zu aktualisieren - lesen Sie eine neue dll zu generieren. Im MQL-Code ist es etwas kompliziert, dies jedes Mal zu korrigieren.

 
alexeymosc:

Guten Tag!

Ist es möglich, mit Hilfe eines Programmierers zu lernen, wie man eine dll-Datei aus einer C-Datei mit einem von Statistica generierten neuronalen Netz kompiliert?

Gute Nacht!

Ich denke nicht, die einzige Ausnahme ist, wenn der Programmierer nicht für Statistica selbst arbeitet ))

alexeymosc:

Bei MQL-Code ist es ziemlich kompliziert, dies jedes Mal zu korrigieren.

Welche Art von NS verwenden Sie in der Statistik?

Wenn Sie etwas manuell korrigieren, bedeutet dies, dass es einen Algorithmus gibt, der automatisiert werden muss....

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

Oben wurde mir die Verwendung von GA empfohlen, und gerade heute ist es mir mit Hilfe der joo-Bibliothek(UGALib) gelungen, ein wünschenswertes und stabiles Ergebnis zu erzielen.

Jetzt werde ich diesen Fall per Drag & Drop auf 4...

Mein tief empfundener Dank gilt Andrei (dem Autor). Eine sehr vielversprechende und flexible Richtung.

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

Vielleicht lohnt es sich, in dieser Richtung zu graben?