double = NAN, obwohl ich nirgends durch NULL teilen kann?!
-
ich bekomme ein ganz merkwürdige ausgabe im programm, und frage mich wie dieser fehler auftreten kann, wenn eine division ausgeschlossen ist.
außerdem verschwindet der fehler wenn ich die ausgabe wiederhole... mir fällt irgendwie nicht ein, warum sowas auftreten könnte!TEST-Ausgabe: 0 Ausgabeneuron 0 = 9.55705e-05 Ausgabeneuron 1 = 4.47981e-07 Ausgabeneuron 2 = 0.0245569 Ausgabeneuron 3 = 2.88943e-09 Ausgabeneuron 4 = 4.79755e-10 Ausgabeneuron 5 = 8.67928e-05 Ausgabeneuron 6 = 1.489e-05 Ausgabeneuron 7 = 0.0321845 Ausgabeneuron 8 = 1.11353e-05 Ausgabeneuron 9 = 0.994252 TEST-Ausgabe: 1 Ausgabeneuron 0 = nan Ausgabeneuron 1 = nan Ausgabeneuron 2 = nan Ausgabeneuron 3 = nan Ausgabeneuron 4 = nan Ausgabeneuron 5 = nan Ausgabeneuron 6 = nan Ausgabeneuron 7 = nan Ausgabeneuron 8 = nan Ausgabeneuron 9 = nan Wiederholung: TEST-Ausgabe: 0 Ausgabeneuron 0 = 9.77298e-05 Ausgabeneuron 1 = 4.36772e-07 Ausgabeneuron 2 = 0.0251543 Ausgabeneuron 3 = 2.83783e-09 Ausgabeneuron 4 = 4.69154e-10 Ausgabeneuron 5 = 8.5453e-05 Ausgabeneuron 6 = 1.51131e-05 Ausgabeneuron 7 = 0.0315974 Ausgabeneuron 8 = 1.09645e-05 Ausgabeneuron 9 = 0.994419 TEST-Ausgabe: 1 Ausgabeneuron 0 = 0.989671 Ausgabeneuron 1 = 7.99327e-06 Ausgabeneuron 2 = 0.000325618 Ausgabeneuron 3 = 0.000418063 Ausgabeneuron 4 = 0.00302999 Ausgabeneuron 5 = 0.000308444 Ausgabeneuron 6 = 2.53812e-05 Ausgabeneuron 7 = 5.20772e-10 Ausgabeneuron 8 = 2.95479e-10 Ausgabeneuron 9 = 0.000717555
-
ich denke mal es wird dort Indizies uberschreitungen geben oder sowas.
-
ich werde das mal überprüfen, aber theoretisch dürfte es keine geben...
-
ich glaube, NAN tritt auch auf, wenn die Zahl zu groß wird (also 1/0.0000000000001) oder so was. Bin mir aber nicht sicher.
Dass sich die Ausgabe jedesmal ändert, könnte an einer nicht initialisierten Variablen liegen (9.55705e-05 --> 9.77298e-05).
-
es gibt keine zugriffe auf nicht allokierte indices!
BERECHNUNG von NEURON in Schicht: 2; Pos=8 aus: Neuron: Schicht=1; Pos=0 ;Wert=0.853248 Axon: Schicht=1; Neuron=0 ;Pos=8 ;Wert=-2.55708 WERT: nander fehler tritt zb beim multiplizieren der beiden werte auf... das kann doch nicht sein!!
ich habe hier mal nen testfall geschaffen..
-
ja zeich mal den testfall, oder sollen wir hier raten?
oder hoffst du auf hellsichtige?
-
Gugi schrieb:
ich glaube, NAN tritt auch auf, wenn die Zahl zu groß wird (also 1/0.0000000000001) oder so was. Bin mir aber nicht sicher.
Dass sich die Ausgabe jedesmal ändert, könnte an einer nicht initialisierten Variablen liegen (9.55705e-05 --> 9.77298e-05).
Ne, das gibt höchstens Inf. NaN gibts bei 0/0 oder wenn Müll im Speicher steht der keinem gültigen IEEE-Float/Double-Wert entspricht, z.B. durch nicht initialisierte Variablen. Außerdem gibts immer wieder NaN, wenn man mathematische Operationen mit NaN durchführt. Also z.B. NaN * Zahl.
-
ok, ich versuche mal möglichst ordentlich den code zu posten:
hier wird speicher angefordert...
n_of_layers = nmb_of_layers; n_of_neurons = nmb_of_neurons; n_of_axons = nmb_of_axons; //! erzeuge Layer n_annet = new layer* [nmb_of_layers]; for(int i = 0; i < nmb_of_layers; i++) { n_annet[i] = new layer(i, nmb_of_neurons[i], nmb_of_axons[i] ); } //! Verknüpfe die Layer untereinander UND //! fülle Layer mit Zufallszahlen for(int i = 0; i < nmb_of_layers; i++) { //! fülle neurone mit zufallszahlen for(int j = 0; j < n_annet[i]->size_of_layer(); j++) { n_annet[i]->getNeuAt(j)->setNeuVal(get_rand_nmb(1, 4)); //! fülle axone mit zufallszahlen for(int k = 0; k < n_annet[i]->getNeuAt(j)->nmb_of_axons(); k++) { n_annet[i]->getNeuAt(j)->setAxVal(get_rand_nmb(1, 4), k); //! Verknüpfung axon *curAxon = n_annet[i]->getNeuAt(j)->getAxon(k); curAxon->setOwner(n_annet[i]->getNeuAt(j) ); // bin noch im vorlestzen Layer, // damit verknüpfung zum nächsten Layer noch möglich ist if(i < nmb_of_layers - 1) // i + 1 ist der nächste Layer und k entspricht dem k'ten Neuron curAxon->setDest(n_annet[i+1]->getNeuAt(k) ); } } }das ist die lauffunktion mit ausgabe:
float *annet::run_annet(float *eingabe, bool ausgabe) { float *nextLayerNeurVal; if(eingabe != NULL) for(int j = 0; j < n_annet[0]->size_of_layer(); j++) { n_annet[0]->getNeuAt(j)->setNeuVal(eingabe[j]); } /*! durchlaufe das netz*/ for(int i = 0; i < n_of_layers; i++) { //! Anzahl der Axone pro Neuron entspr. der Neuronzahl im nächsten Layer int neurNextLayer = n_annet[i]->getAxonPNeu(); //! array mit den errechneten werten der neurone für die nächste schicht nextLayerNeurVal = new float[neurNextLayer]; /*! Durchlaufe die einzelnen Schichten nacheinander und ausgehend von der Ersten. Erste Schicht ist die Eingabeschicht (immer). */ /*! Lauffunktion: =SUMME(Neuron*Axon_i) = Neuron_i; i = schicht im netz j = neuron in schicht i k = axon von neuron j in schicht i */ for(int k = 0; k < neurNextLayer; k++) { memset(nextLayerNeurVal, 0, neurNextLayer); for(int j = 0; j < n_annet[i]->size_of_layer(); j++) { // std::cout<<i<<" - "<<j<<" - "<<k<<std::endl; // val_cur_neur ist das aktuelle neuron long double val_cur_neur = n_annet[i]->getNeuAt(j)->getNeuVal(); // axon nr. k von neuron: val_cur_neur long double axon_cur_neur = n_annet[i]->getNeuAt(j)->getAxVal(k); // Berechnung nextLayerNeurVal[k] += val_cur_neur * axon_cur_neur; /*! ausgabe-test */ if(ausgabe) { std::cout<<"BERECHNUNG von NEURON in Schicht: "<<i+1<<"; Pos="<<k<<" aus:"<<std::endl<< " Neuron: Schicht="<<i<<"; Pos="<<j<<" ;Wert="<<val_cur_neur<<std::endl<< " Axon: Schicht="<<i<<"; Neuron="<<j<<" ;Pos="<<k<<" ;Wert="<<axon_cur_neur<<std::endl<< "WERT: "<<nextLayerNeurVal[k]<<std::endl<<std::endl; } } // if(i+1 <= n_of_layers-1) n_annet[i+1]->getNeuAt(k)->setNeuVal(sigmoid_biasFkt(nextLayerNeurVal[k]) ); } } delete [] nextLayerNeurVal; // Ausgabe if(ausgabe) { for(int k = 0; k < n_annet[n_of_layers-1]->size_of_layer(); k++) std::cout<<"Ausgabeneuron "<<k<<" = "<<n_annet[n_of_layers-1]->getNeuAt(k)->getNeuVal()<<std::endl; } }das sind dann ein paar funkionen in der klasse neuron:
long double neuron::getNeuVal() { return val; } void neuron::setAxVal(long double v, unsigned short pos) { axone[pos]->setValue(v); } long double neuron::getAxVal(unsigned short pos) { return axone[pos]->getValue(); } axon *neuron::getAxon(unsigned short pos) { return axone[pos]; }WICHTIG: die ausgabe ändert sich nicht immer!!! lediglich das neuronen welche den wert NAN annehmnen, haben nach einen neuen durchlauf die richtigen werte... auch die speichern und laden funktion aus ner datei funktioniert....
ich spiele auch mit dem gedanken, das irgendwo eine zahl auf glatt 0 gerundet wird, aber ich dividiere ja nirgends...
wollt ihr evtl. noch die trainingsfunktion?
-
das wichtsigste vergessen:
wo der speicher schließlich allokiert wurde:layer::layer(unsigned short nmb, unsigned short nmb_of_neurons, unsigned short nmb_of_axons) { layerNmb = nmb; std::cout<<"create layer with "<<nmb_of_neurons<<" neurons"<<std::endl; l_dim = nmb_of_neurons; l_axon = nmb_of_axons; /*! erzeuge neuronen und fülle diese mit zufallszahlen*/ l_layer = new neuron* [l_dim]; for(int i = 0; i < l_dim; i++) { l_layer[i] = new neuron(this, nmb_of_axons); } }in der layer-klasse...