Maschinelles Lernen

Diese Methode werden im Bereich des maschinellen Lernens verwendet

Die Aktivierungsfunktion eines neuronalen Netzes bestimmt den Ausgangswert eines Neurons in Abhängigkeit von der gewichteten Summe der Eingänge. Die Wahl der Aktivierungsfunktion hat einen großen Einfluss auf die Leistung des neuronalen Netzes. Verschiedene Modellteile (Schichten) können unterschiedliche Aktivierungsfunktionen verwenden.

Zusätzlich zu allen bekannten Aktivierungsfunktionen bietet MQL5 auch deren Ableitungen. Funktionsableitungen ermöglichen eine effiziente Aktualisierung der Modellparameter auf der Grundlage der beim Lernen erhaltenen Fehler.

Ein neuronales Netz zielt darauf ab, einen Algorithmus zu finden, der den Fehler beim Lernen minimiert, wofür die Verlustfunktion verwendet wird. Der Wert der Verlustfunktion gibt an, um wie viel der vom Modell vorhergesagte Wert vom realen Wert abweicht. Je nach Problemstellung werden unterschiedliche Verlustfunktionen verwendet. So wird beispielsweise der mittlere quadratische Fehler (MSE) für Regressionsprobleme und die binäre Kreuzentropie (BCE) für binäre Klassifikationszwecke verwendet.

Funktion

Aktion

Activation

Aktivierungsfunktionswerte berechnen und in den übergebenen Vektor oder Matrix schreiben

Derivative

Berechnet die Ableitungswerte der Aktivierungsfunktion, die dem übergebenen Vektor oder Matrix zugewiesen werden

Loss

Berechnet die Verlustfunktionswerte und schreibt sie in den übergebenen Vektor oder Matrix

LossGradient

Berechnung eines Vektors oder einer Matrix von Verlustfunktionsgradienten

RegressionMetric

Berechnet die Regressionsmetrik als Abweichung von der Regressionslinie, die auf dem angegebenen Datenarray konstruiert wurde

ConfusionMatrix

Berechnen der Wahrheitsmatrix oder auch Konfusionsmatrix: Richtige und falsche Klassifikationen. Die Methode wird auf den Vektor der vorhergesagten Werte angewendet

ConfusionMatrixMultilabel

Berechnen der Wahrheits- oder Konfusionsmatrix für jedes Label. Die Methode wird auf den Vektor der vorhergesagten Werte angewendet

ClassificationMetric

Berechnung der Klassifizierungsmetrik zur Bewertung der Qualität der vorhergesagten Daten im Vergleich zu den wahren Daten. Die Methode wird auf den Vektor der vorhergesagten Werte angewendet

ClassificationScore

Berechnung der Klassifizierungsmetrik, um die Qualität der vorhergesagten Daten im Vergleich zu den wahren Daten zu bewerten

PrecisionRecall

Berechnen der Werte, mit denen eine Precision-Recall-Kurve erstellt wird. Ähnlich wie ClassificationScore wird diese Methode auf den Vektor mit wahren Werte angewendet.

ReceiverOperatingCharacteristic

Berechnet werden die Werte, um die ROC-Kurve (Receiver Operating Characteristic) zu erstellen. Ähnlich wie ClassificationScore wird diese Methode auf den Vektor mit wahren Werte angewendet.

Beispiel

Dieses Beispiel demonstriert das Training eines Modells mit Hilfe von Matrixoperationen. Das Modell wird für die Funktion (a + b + c)^2 / (a^2 + b^2 + c^2) trainiert. Wir geben die Ausgangsdatenmatrix ein, in der a, b und c in verschiedenen Spalten enthalten sind. Das Modell gibt das Funktionsergebnis aus.

matrix weights1weights2weights3;               // Matrizen der Gewichte
matrix output1output2result;                   // Matrizen der Ausgaben der neuronalen Schicht
input int layer1 = 200;                            // die Größe der ersten verdeckten Schicht
input int layer2 = 200;                            // die Größe der zweiten verdeckten Schicht
input int Epochs = 20000;                          // die Anzahl der Trainingsepochen
input double lr = 3e-6;                            // Lernrate
input ENUM_ACTIVATION_FUNCTION ac_func = AF_SWISH// Aktivierungsfunktion
//+------------------------------------------------------------------+
//| Script start Funktion                                            |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int train = 1000;    // Größe des Trainingssatzes
   int test = 10;       // Größe der Teststichprobe
   matrix m_datam_target;
//--- generieren einer Teststichprobe
   if(!CreateData(m_datam_targettrain))  
      return;
//--- Modelltraining
   if(!Train(m_datam_targetEpochs))      
      return;
//--- generieren der Teststichprobe
   if(!CreateData(m_datam_targettest))   
      return;
//--- Test des Modells
   Test(m_datam_target);                   
  }
//+------------------------------------------------------------------+
//| Erstellen der Stichprobendaten                                   |
//+------------------------------------------------------------------+
bool CreateData(matrix &datamatrix &targetconst int count)
  {
//--- Initialisierung der Ausgangsdaten und der Ergebnismatrix
   if(!data.Init(count3) || !target.Init(count1))
      return false;
//--- Füllen der Matrix für die Anfangswerte mit Zufallszahlen
   data.Random(-1010);                     
//--- Berechnen der Zielwerte für die Trainingsstichprobe
   vector X1 = MathPow(data.Col(0) + data.Col(1) + data.Col(1), 2);
   vector X2 = MathPow(data.Col(0), 2) + MathPow(data.Col(1), 2) + MathPow(data.Col(2), 2);
   if(!target.Col(X1 / X20))
      return false;
//--- Ergebnisrückgabe
   return true;
  }
//+------------------------------------------------------------------+
//| Trainingsmethode des Models                                      |
//+------------------------------------------------------------------+
bool Train(matrix &datamatrix &targetconst int epochs = 10000)
  {
//--- Modell erstellen
   if(!CreateNet())
      return false;
//--- Modelltraining
   for(int ep = 0ep < epochsep++)
     {
      //--- Vorwärtsdurchlauf
      if(!FeedForward(data))
         return false;
      PrintFormat("Epoch %d, loss %.5f"epresult.Loss(targetLOSS_MSE));
      //--- Backpropagation und Update der Gewichtsmatrix
      if(!Backprop(datatarget))
         return false;
     }
//--- Ergebnisrückgabe
   return true;
  }
//+------------------------------------------------------------------+
//| Methode für die Modellerstellung                                 |
//+------------------------------------------------------------------+
bool CreateNet()
  {
//--- Initialisierung der Gewichtsmatrizen
   if(!weights1.Init(4layer1) || !weights2.Init(layer1 + 1layer2) || !weights3.Init(layer2 + 11))
      return false;
//--- Füllen der Gewichtsmatrizen mit Zufallszahlen
   weights1.Random(-0.10.1);
   weights2.Random(-0.10.1);
   weights3.Random(-0.10.1);
//--- Ergebnisrückgabe
   return true;
  }
//+------------------------------------------------------------------+
//| Feedforward-Methode                                              |
//+------------------------------------------------------------------+
bool FeedForward(matrix &data)
  {
//--- Prüfen der Größe der Ausgangsdaten
   if(data.Cols() != weights1.Rows() - 1)
      return false;
//--- Berechnen der ersten neuronalen Schicht
   matrix temp = data;
   if(!temp.Resize(temp.Rows(), weights1.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights1.Rows() - 1))
      return false;
   output1 = temp.MatMul(weights1);
//--- Berechnen der Aktivierungsfunktion
   if(!output1.Activation(tempac_func))
      return false;
//--- Berechnen der zweiten neuronalen Schicht
   if(!temp.Resize(temp.Rows(), weights2.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights2.Rows() - 1))
      return false;
   output2 = temp.MatMul(weights2);
//--- Berechnen der Aktivierungsfunktion
   if(!output2.Activation(tempac_func))
      return false;
//--- Berechnen der dritten neuronalen Schicht
   if(!temp.Resize(temp.Rows(), weights3.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights3.Rows() - 1))
      return false;
   result = temp.MatMul(weights3);
//--- Ergebnisrückgabe
   return true;
  }
//+------------------------------------------------------------------+
//| Backpropagation-Methode                                          |
//+------------------------------------------------------------------+
bool Backprop(matrix &datamatrix &target)
  {
//--- Prüfen der Größe der Matrix für die Zielwerte
   if(target.Rows() != result.Rows() ||
      target.Cols() != result.Cols())
      return false;
//--- Berechnen der Ableitung der berechneten Zielwerte
   matrix loss = (target - result) * 2;
//--- Übertragen der Gradienten zur vorherigen Schicht
   matrix gradient = loss.MatMul(weights3.Transpose());
//--- Update der Gewichtsmatrix der letzten Schicht
   matrix temp;
   if(!output2.Activation(tempac_func))
      return false;
   if(!temp.Resize(temp.Rows(), weights3.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights3.Rows() - 1))
      return false;
   weights3 = weights3 + temp.Transpose().MatMul(loss) * lr;
//--- Anpassung des Fehlergradienten durch die Ableitung der Aktivierungsfunktion
   if(!output2.Derivative(tempac_func))
      return false;
   if(!gradient.Resize(gradient.Rows(), gradient.Cols() - 1))
      return false;
   loss = gradient * temp;
//--- Übertragen der Gradienten der tieferen Schicht
   gradient = loss.MatMul(weights2.Transpose());
//--- Update der Gewichtsmatrix der zweiten verdeckten Schicht
   if(!output1.Activation(tempac_func))
      return false;
   if(!temp.Resize(temp.Rows(), weights2.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights2.Rows() - 1))
      return false;
   weights2 = weights2 + temp.Transpose().MatMul(loss) * lr;
//--- Anpassung des Fehlergradienten durch die Ableitung der Aktivierungsfunktion
   if(!output1.Derivative(tempac_func))
      return false;
   if(!gradient.Resize(gradient.Rows(), gradient.Cols() - 1))
      return false;
   loss = gradient * temp;
//--- Update der Gewichtsmatrix der ersten verdeckten Schicht
   temp = data;
   if(!temp.Resize(temp.Rows(), weights1.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights1.Rows() - 1))
      return false;
   weights1 = weights1 + temp.Transpose().MatMul(loss) * lr;
//--- Ergebnisrückgabe
   return true;
  }
//+------------------------------------------------------------------+
//| Testmethode des Models                                           |
//+------------------------------------------------------------------+
bool Test(matrix &datamatrix &target)
  {
//--- Feedforward der Testdaten
   if(!FeedForward(data))
      return false;
//--- Ausdruck der Ergebnisse der Modellberechnung und der tatsächlichen Werte
   PrintFormat("Test loss %.5f"result.Loss(targetLOSS_MSE));
   ulong total = data.Rows();
   for(ulong i = 0i < totali++)
      PrintFormat("(%.2f + %.2f + %.2f)^2 / (%.2f^2 + %.2f^2 + %.2f^2) =  Net %.2f, Target %.2f"data[i0], data[i1], data[i2],
                  data[i0], data[i1], data[i2], result[i0], target[i0]);
//--- Ergebnisrückgabe
   return true;
  }
//+------------------------------------------------------------------+