Hallo liebe Leser. Es wurde viel ĂŒber neuronale Netze geschrieben und gesagt, hauptsĂ€chlich darĂŒber, wie und warum sie angewendet werden können. DarĂŒber hinaus wird zwei wichtigen Fragen nicht viel Aufmerksamkeit geschenkt: a) wie man ein neuronales Netzwerk vereinfacht und schnell berechnet (eine Berechnung des Exponenten wird durch Bibliotheksfunktionen von Programmiersprachen realisiert, normalerweise nicht weniger als 15-20 Prozessoranweisungen), b) was, Zumindest teilweise hilft die Logik des aufgebauten Netzwerks - tatsĂ€chlich helfen die riesigen Matrizen der Werte von Gewichten und Verschiebungen, die nach dem Training des Netzwerks erhalten wurden, nicht wirklich, die Muster zu verstehen, die dieses Netzwerk gefunden hat (sie bleiben verborgen und die Aufgabe, sie zu bestimmen, ist die Aufgabe der Weiden tion von - manchmal sehr wichtig). Ich werde ĂŒber einen meiner AnsĂ€tze zur Lösung dieser Probleme fĂŒr gewöhnliche neuronale Netze mit direkter Verteilung sprechen, wĂ€hrend ich versuche, mit einem Minimum an Mathematik auszukommen.
Ein bisschen Theorie
Das direkte Verteilungsnetz ist aus mathematischer Sicht eine sehr groĂe Funktion, die die Werte der Netzwerkeingaben, Gewichtskoeffizienten und Neuronenverschiebungen enthĂ€lt. In jedem Neuron der Schicht werden die Werte der Eingaben der Schicht (Vektor X) mit dem Gewicht des Neurons (Vektor) multipliziert
) mit einem Offset addieren
und Aktivierungsfunktionen eingeben
Bilden der AusgÀnge von Schichtneuronen.
Aktivierungsfunktionen sind möglicherweise nicht sehr einfach zu berechnen, beispielsweise enthalten sie hĂ€ufig Exponentiale (exponentielles Sigmoid, hyperbolische Tangente). Wenn Sie sich den Assembler-Code ansehen, der Exponenten implementiert, finden Sie zum einen viele verschiedene ĂberprĂŒfungen, die nicht immer erforderlich sind, und zum anderen erfolgt die Berechnung des Exponenten selbst normalerweise in mindestens zwei Operationen:
Wenn wir daher die Berechnung des Netzwerks beschleunigen möchten, besteht die erste Aufgabe darin, die Berechnung der Aktivierungsfunktion zu vereinfachen. Sie können versuchen, aufgrund eines Geschwindigkeitsgewinns ein wenig QualitĂ€t zu opfern, indem Sie die Berechnung der klassischen Aktivierungsfunktion ungefĂ€hr durch die Berechnung einer einfacheren Funktion ersetzen, die (anhand der verfĂŒgbaren Eingabedaten) ungefĂ€hr die gleichen Ergebnisse liefert. Im Allgemeinen ist dies ein klassisches Interpolationsproblem: Wir haben eine Reihe von Werten, die mit der ursprĂŒnglichen Funktion A (s) berechnet wurden, und wir wĂ€hlen eine einfachere Funktion aus, die sehr Ă€hnliche Werte ergibt. Solch eine einfache Funktion a (s) kann ein gewöhnliches Polynom oder ein Polynom mit negativen Potenzen oder so etwas sein. Ich habe vier Arten solcher Funktionen verwendet:
;;
;;
;;
;;
Angenommen, wir haben es fĂŒr jedes Neuron geschafft, die Aktivierungsfunktion durch eine etwas einfachere zu ersetzen - dies kann beispielsweise durch Anwendung der Methode der kleinsten Quadrate erfolgen. Eine solche Substitution an sich wird wahrscheinlich keinen groĂen Gewinn bringen. Aber hier können Sie einen anderen Trick ausprobieren:
- Schreiben Sie eine analytisch groĂe Funktion NET (X), die vom gesamten Netzwerk berechnet wird.
- Ersetzen Sie die ursprĂŒnglichen Funktionen A (s) in NET (X) durch die fĂŒr sie erhaltenen Ersetzungsfunktionen a (s).
- Vereinfachen Sie das algebraisch erhaltene NET (X) (oder verwenden Sie einen vorgefertigten Code zur symbolischen Vereinfachung von AusdrĂŒcken). Dies ist bereits möglich (zumindest viel einfacher, als wir versuchen wĂŒrden, das Netzwerk mit den ursprĂŒnglichen Funktionen zu vereinfachen, beispielsweise mit Exponenten).
Als Ergebnis erhalten wir etwas Einfacheres und vielleicht etwas mathematisch offensichtlicheres - hier können Sie bereits versuchen zu verstehen, welche Art von Funktion das Netzwerk implementiert.
Dies ist die Möglichkeit, die Logik des aufgebauten Netzwerks zu erlÀutern.
Die beschriebene Aufgabe sieht natĂŒrlich nur in Worten einfach aus. FĂŒr die Verwendung in meinen Programmen musste ich meinen eigenen Code zur symbolischen Vereinfachung von AusdrĂŒcken schreiben. AuĂerdem habe ich ein komplexeres Problem gelöst, wobei angenommen wurde, dass jedes Neuron mit Funktion A (s) mehrere Optionen fĂŒr eine alternative Aktivierungsfunktion haben kann
Daher bestand die allgemeine Aufgabe auch darin, Optionen fĂŒr solche Funktionen aufzuzĂ€hlen und das Netzwerk fĂŒr jede dieser Optionen symbolisch zu vereinfachen. Hier half nur die Parallelisierung von Berechnungen.
Ergebnis
Das Ergebnis hat mir gefallen. Ich habe ein dreischichtiges Netzwerk (mit drei EingĂ€ngen) von acht Neuronen (mit Eingangsgewichten und -verschiebungen) mit den Aktivierungsfunktionen âExponential Sigmoidâ beschleunigt. Wie Zeitmessungen zeigten, war es möglich, einen Zeitgewinn von etwa 40% ohne signifikanten QualitĂ€tsverlust zu erzielen.
Ich illustriere. Hier sind die Quellnetzwerkdaten:


Und in der dritten Ausgabeebene:

Wenn die EingÀnge als a, b und c bezeichnet sind, wird nach dem Ersetzen und Vereinfachen die Netzwerkfunktion NET wie folgt betrachtet:
double a2 = a*a; double b2 = b*b; double c2 = c*c; double a3 = a2*a; double b3 = b2*b; double c3 = c2*c; double z01 = sqrt(-1.6302e-02+7.9324e-01*a+9.65149e-01*b+5.64151e-01*c); double z06 = sqrt(1.583708e+00-8.907654e-01*a-2.844379e-01*a2+1.050942e+00*a3+1.178096e+01*b-1.865618e+00*b*a-3.145465e+00*b*a2-5.777153e+00*b2+3.138123e+00*b2*a-1.043599e+00*b3+1.32778e+00*c+5.849582e-01*c*a-3.440382e+00*c*a2+1.838371e+00*c*b+6.864703e+00*c*b*a-3.42434e+00*c*b2-3.013361e-01*c2+3.754167e+00*c2*a-3.745404e+00*c2*b-1.365524e+00*c3+1.014237e-01*z01); double NET = (-1.477593e+00)/(z06)+1.370237e+00-6.303167e-02*a-1.495051e-03*a2+2.33748e-02*a3+5.558024e-02*b+1.178189e-02*b*a-6.996071e-02*b*a2+1.837937e-02*b2+6.97974e-02*b2*a-2.321149e-02*b3+7.924241e-02*c+3.392287e-03*c*a-7.652018e-02*c*a2-1.214263e-02*c*b+1.526831e-01*c*b*a-7.616337e-02*c*b2-1.915279e-03*c2+8.349931e-02*c2*a-8.33044e-02*c2*b-3.037166e-02*c3+1.949161e-02*z01;
Gewinnen - Ich wiederhole 40% der Zeit, ohne die QualitÀt zu beeintrÀchtigen. Ich denke, dieser Ansatz kann in FÀllen angewendet werden, in denen die Geschwindigkeit der Berechnung eines neuronalen Netzwerks kritisch ist - zum Beispiel, wenn es wiederholt berechnet wird, in einem Doppel- oder Dreifachzyklus.
Ein Beispiel fĂŒr ein solches Problem : eine numerische Lösung des Aerodynamikproblems in einem Gitter, und in jedem seiner Knoten berechnet das neuronale Netzwerk eine nĂŒtzliche Vorhersage, beispielsweise fĂŒr eine genauere Berechnung der turbulenten ViskositĂ€t. Dann haben wir einen externen Zyklus in der Zeit, ein doppelter oder dreifacher Koordinatenzyklus ist darin eingebettet und bereits dort, im Inneren, gibt es eine Berechnung eines neuronalen Netzwerks. In diesem Fall ist eine Vereinfachung mehr als angemessen und nĂŒtzlich.