Ein Fahrrad erfinden oder ein Perzeptron in C ++ schreiben. Teil 1 und 2

Ein Fahrrad erfinden oder ein Perzeptron in C ++ schreiben. Teil 1



Schreiben wir eine einfache Bibliothek zum Implementieren eines Perzeptrons in C ++







Einführung



Hallo allerseits, in diesem Beitrag möchte ich meine ersten Erfahrungen mit dem Schreiben neuronaler Netze mit Ihnen teilen. Es gibt viele Artikel über die Implementierung neuronaler Netze (in Zukunft neuronale Netze) im Internet, aber ich möchte nicht die Algorithmen anderer Leute verwenden, ohne die Essenz ihrer Arbeit zu verstehen, deshalb habe ich beschlossen, meinen eigenen Code von Grund auf neu zu erstellen.



In diesem Teil werde ich die Hauptpunkte des Partners beschreiben. Teile, die für uns nützlich sein werden. Die ganze Theorie stammt von verschiedenen Seiten, hauptsächlich von Wikipedia.



Link zum 3. Teil mit dem Lernalgorithmus: habr.com/ru/post/514626



Also los geht's.





Ein bisschen Theorie



Lassen Sie uns zustimmen, dass ich nicht den Titel "der beste Algorithmus für maschinelles Lernen" beanspruche, sondern nur meine Implementierung und meine Ideen zeige. Außerdem bin ich immer offen für konstruktive Kritik und Ratschläge zum Kodex. Das ist wichtig, dafür existiert die Community.



, .





. .



. :






, (1, 2, 3), u (w1, w2, w3), :

u = x1*w1 + x2*w2 + x3*w3

:







. y(u), u – . , .



, , . , , . , – (, ). :







(0; 1), . y(u) .



, . , .

, , .



, . , , ( ).



, 2 : , .



:









8 ( n1 n8), u, «y(u)» «err», (). «err» .



, , .








, .



. , , , . , .



Nun, ich habe es geschafft, die Prinzipien der Speicherung der notwendigen Werte in Neuronen zu erklären. Lassen Sie uns nun herausfinden, wie die Gewichte der Verbindungen zwischen Neuronen gespeichert werden.



Nehmen Sie zum Beispiel das folgende Netzwerk:

...





Nachdem wir bereits wissen, wie Neuronen im Speicher strukturiert werden, erstellen wir eine ähnliche Tabelle für Gewichte:









Seine Struktur ist überhaupt nicht kompliziert: Beispielsweise ist der Wert des Gewichts zwischen Neuron N1 und Neuron n1 ähnlich wie bei anderen Gewichten in Zelle w1-1 enthalten. Aber auch hier ist eine solche Matrix zum Speichern von Gewichten nur zwischen den ersten beiden Schichten geeignet, aber es gibt immer noch Gewichte im Netzwerk zwischen der zweiten und dritten Schicht. Verwenden wir den bereits bekannten Trick: Fügen Sie dem Array eine neue Dimension hinzu, jedoch mit einer Einschränkung: Lassen Sie die Zeilennamen die Neuronenschicht links relativ zum "Gewichtungsbündel" anzeigen, und die Neuronenschicht rechts passt in die Spaltennamen.



Dann erhalten wir die folgende Tabelle für das zweite "Bündel" von Gewichten:







:







«», .. , , « » , - , . )).





, .



C++. 2



, .





, . .



, !



header —



, . header — ( «neuro.h»). :





class NeuralNet {
public:
    NeuralNet(uint8_t L, uint16_t *n);
    void Do_it(uint16_t size, double *data);
    void getResult(uint16_t size, double* data);
    void learnBackpropagation(double* data, double* ans, double acs, double k);
private:
    vector<vector<vector<double>>> neurons;
    vector<vector<vector<double>>> weights;
    uint8_t numLayers;
    vector<double> neuronsInLayers;
    double Func(double in);
    double Func_p(double in);
    uint32_t MaxEl(uint16_t size, uint16_t *arr);
    void CreateNeurons(uint8_t L, uint16_t *n);
    void CreateWeights(uint8_t L, uint16_t *n);

};


, , header' ). :






//  ,       ,        
#ifndef NEURO_H
#define NEURO_H

#include <vector> //    
#include <math.h> //    ,     
#include <stdint.h> //       ,            .


:



NeuralNet(uint8_t L, uint16_t *n);


, , - .



void Do_it(uint16_t size, double *data);


)), .



void getResult(uint16_t size, double* data);


.



void learnBackpropagation(double* data, double* ans, double acs, double k);


, .



, :




    vector<vector<vector<double>>> neurons; //   ,    
    vector<vector<vector<double>>> weights; //   ,       
    uint8_t numLayers; //  
    vector<double> neuronsInLayers; //,      
/*
          ,      ,       ,          ,   
*/
    double Func(double in); //    
    double Func_p(double in); //     
    uint32_t MaxEl(uint16_t size, uint16_t *arr);//       
    void CreateNeurons(uint8_t L, uint16_t *n);//             
    void CreateWeights(uint8_t L, uint16_t *n);


header — :

#endif


header . — source — ).



source —



, .



:




NeuralNet::NeuralNet(uint8_t L, uint16_t *n) {
	CreateNeurons(L, n); //  
	CreateWeights(L, n); //  
	this->numLayers = L;
	this->neuronsInLayers.resize(L);
	for (uint8_t l = 0; l < L; l++)this->neuronsInLayers[l] = n[l]; //       
}


, :




void NeuralNet::Do_it(uint16_t size, double *data) {
	for (int n = 0; n < size; n++) { //       
		neurons[n][0][0] = data[n]; //       
		neurons[n][1][0] = Func(neurons[n][0][0]); //           
	}
	for (int L = 1; L < numLayers; L++) { //                
		for (int N = 0; N < neuronsInLayers[L]; N++) { 
			double input = 0;
			for (int lastN = 0; lastN < neuronsInLayers[L - 1]; lastN++) {//             
				input += neurons[lastN][1][L - 1] * weights[lastN][N][L - 1];
			}
			neurons[N][0][L] = input;
			neurons[N][1][L] = Func(input);
		}
	}
}


Und schließlich möchte ich als letztes über die Funktion zur Anzeige des Ergebnisses sprechen. Nun, hier kopieren wir einfach die Werte von den Neuronen der letzten Schicht in das Array, das uns als Parameter übergeben wurde:




void NeuralNet::getResult(uint16_t size, double* data) {
	for (uint16_t r = 0; r < size; r++) {
		data[r] = neurons[r][1][numLayers - 1];
	}
}


In den Sonnenuntergang gehen



Wir werden damit aufhören. Der nächste Teil ist einer einzigen Funktion gewidmet, mit der Sie das Netzwerk trainieren können. Aufgrund der Komplexität und Fülle der Mathematik habe ich beschlossen, sie in einem separaten Teil herauszunehmen, in dem wir auch die Arbeit der gesamten Bibliothek als Ganzes testen werden.



Auch hier begrüße ich Ihren Rat und Ihre Kommentare in den Kommentaren.



Vielen Dank für Ihre Aufmerksamkeit auf den Artikel, bis bald!



PS: Wie versprochen - Link zu Quellen: GitHub








All Articles