Machine learning

Questi metodi sono utilizzati nell'apprendimento automatico.

La funzione di attivazione della rete neurale determina il valore di uscita di un neurone secondo la somma ponderata degli input. La selezione della funzione di attivazione ha un grande impatto sulle prestazioni della rete neurale. Diverse parti del modello (strati) possono utilizzare diverse funzioni di attivazione.

Oltre a tutte le funzioni di attivazione note, MQL5 offre anche i loro derivati. I derivati della funzione permettono un aggiornamento efficiente dei parametri del modello basati sull'errore ricevuto nell'apprendimento.

Una rete neurale mira a trovare un algoritmo che minimizza l'errore nell'apprendimento, per il quale viene utilizzata la funzione di perdita. Il valore della funzione di perdita indica quanto il valore previsto dal modello devia da quello reale. Diverse funzioni di perdita vengono utilizzate a seconda del problema. Per esempio, Mean Squared Error (MSE) è usata per problemi di regressione, e Binary Cross-Entropy (BCE) è usata per scopi di classificazione binaria.

Funzione

Azione

Activation

Calcola i valori della funzione di attivazione e li scrive nel vettore/matrice passati

Derivative

Calcola i valori derivati della funzione di attivazione e li scrive nel vettore/matrice passato

Loss

Calcola i valori della funzione di perdita e li scrive nel vettore/matrice passati

LossGradient

Calcola un vettore o una matrice di gradienti della funzione di perdita

RegressionMetric

Calcola la metrica di regressione come errore della deviazione dalla linea di regressione costruita sull'array di dati specificato

ConfusionMatrix

Calcola la matrice della confusione. Il metodo viene applicato al vettore dei valori previsti

ConfusionMatrixMultilabel

Calcola la matrice di confusione per ogni etichetta. Il metodo viene applicato al vettore dei valori previsti

ClassificationMetric

Calcola la metrica di classificazione per valutare la qualità dei dati previsti rispetto ai dati reali Il metodo viene applicato al vettore dei valori previsti

ClassificationScore

Calcola la metrica di classificazione per valutare la qualità dei dati previsti rispetto ai dati reali

PrecisionRecall

Calcola i valori per costruire una curva di precisione-richiamo. Analogamente a ClassificationScore, questo metodo viene applicato al vettore dei valori reali.

ReceiverOperatingCharacteristic

Calcola i valori per costruire la curva ROC (Receiver Operating Characteristic). Analogamente a ClassificationScore, questo metodo viene applicato al vettore dei valori reali.

Esempio

Questo esempio dimostra l'addestramento di un modello utilizzando operazioni matriciali. Il modello è addestrato per la funzione (a + b + c)^2 / (a^2 + b^2 + c^2). Inseriamo la matrice di dati iniziale, in cui a, b e c sono contenuti in colonne differenti. Il risultato della funzione viene ottenuto all'output del modello.

matrix weights1weights2weights3;               // matrici dei pesi
matrix output1output2result;                   // output dello strato neurale delle matrici
input int layer1 = 200;                            // la dimensione del primo livello nascosto
input int layer2 = 200;                            // la dimensione del secondo livello nascosto
input int Epochs = 20000;                          //il numero dei periodi di addestramento
input double lr = 3e-6;                            // tasso di apprendimento
input ENUM_ACTIVATION_FUNCTION ac_func = AF_SWISH// funzione di attivazione
//+------------------------------------------------------------------+
//| Script start function                                            |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int train = 1000;    // dimensione del campione di addestramento
   int test = 10;       // dimensione del campione di prova
   matrix m_datam_target;
//-- generazione di un campione di addestramento
   if(!CreateData(m_datam_targettrain))  
      return;
//-- addestrare il modello
   if(!Train(m_datam_targetEpochs))      
      return;
//-- genera un campione di prova
   if(!CreateData(m_datam_targettest))   
      return;
//-- testa il modello
   Test(m_datam_target);                   
  }
//+------------------------------------------------------------------+
// Metodo di generazione del campione                                |
//+------------------------------------------------------------------+
bool CreateData(matrix &datamatrix &targetconst int count)
  {
//--- inizializza i dati iniziali e le matrici risultanti
   if(!data.Init(count3) || !target.Init(count1))
      return false;
//-- riempire la matrice dei dati iniziali con valori casuali
   data.Random(-1010);                     
//-- calcola i valori target per il campione di allenamento
   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;
//-- risultato restituito
   return true;
  }
//+------------------------------------------------------------------+
//| Metodo del modello di addestramento                              |
//+------------------------------------------------------------------+
bool Train(matrix &datamatrix &targetconst int epochs = 10000)
  {
//-- creare il modello
   if(!CreateNet())
      return false;
//-- addestrare il modello
   for(int ep = 0ep < epochsep++)
     {
      //--- feedforward pass
      if(!FeedForward(data))
         return false;
      PrintFormat("Epoch %d, loss %.5f"epresult.Loss(targetLOSS_MSE));
      //--- backpropagation e aggiornamento della matrice del peso
      if(!Backprop(datatarget))
         return false;
     }
//-- risultato restituito
   return true;
  }
//+------------------------------------------------------------------+
//| Metodo del modello della creazione                               |
//+------------------------------------------------------------------+
bool CreateNet()
  {
//--- inizializza le matrici del peso 
   if(!weights1.Init(4layer1) || !weights2.Init(layer1 + 1layer2) || !weights3.Init(layer2 + 11))
      return false;
//-- riempire le matrici del peso con valori casuali
   weights1.Random(-0.10.1);
   weights2.Random(-0.10.1);
   weights3.Random(-0.10.1);
//-- risultato restituito
   return true;
  }
//+------------------------------------------------------------------+
//| Metodo Feedforward                                               |
//+------------------------------------------------------------------+
bool FeedForward(matrix &data)
  {
//-- verifica la dimensione dei dati iniziali
   if(data.Cols() != weights1.Rows() - 1)
      return false;
//-- calcola il primo strato neurale
   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);
//-- calcola la funzione di attivazione
   if(!output1.Activation(tempac_func))
      return false;
//-- calcola il secondo strato neurale
   if(!temp.Resize(temp.Rows(), weights2.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights2.Rows() - 1))
      return false;
   output2 = temp.MatMul(weights2);
//-- calcola la funzione di attivazione
   if(!output2.Activation(tempac_func))
      return false;
//-- calcola il terzo strato neurale
   if(!temp.Resize(temp.Rows(), weights3.Rows()) ||
      !temp.Col(vector::Ones(temp.Rows()), weights3.Rows() - 1))
      return false;
   result = temp.MatMul(weights3);
//-- risultato restituito
   return true;
  }
//+------------------------------------------------------------------+
//| Metodo Backpropagation                                           |
//+------------------------------------------------------------------+
bool Backprop(matrix &datamatrix &target)
  {
//-- controllare la dimensione della matrice dei valori target
   if(target.Rows() != result.Rows() ||
      target.Cols() != result.Cols())
      return false;
//-- determinare la deviazione dei valori calcolati dall'obiettivo
   matrix loss = (target - result) * 2;
//-- propagare il gradiente al livello precedente
   matrix gradient = loss.MatMul(weights3.Transpose());
//-- aggiornare la matrice del peso dell'ultimo livello
   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;
//--- regola il gradiente di errore in base alla derivata della funzione di attivazione
   if(!output2.Derivative(tempac_func))
      return false;
   if(!gradient.Resize(gradient.Rows(), gradient.Cols() - 1))
      return false;
   loss = gradient * temp;
//-- propagare il gradiente ad uno strato inferiore
   gradient = loss.MatMul(weights2.Transpose());
//-- aggiornare la matrice di peso del secondo livello nascosto
   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;
//--- regola il gradiente di errore in base alla derivata della funzione di attivazione
   if(!output1.Derivative(tempac_func))
      return false;
   if(!gradient.Resize(gradient.Rows(), gradient.Cols() - 1))
      return false;
   loss = gradient * temp;
//-- aggiornare la matrice di peso del primo livello nascosto
   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;
//-- risultato restituito
   return true;
  }
//+------------------------------------------------------------------+
//| Metodo di prova del modello                                      |
//+------------------------------------------------------------------+
bool Test(matrix &datamatrix &target)
  {
//-- feedforward sui dati di prova
   if(!FeedForward(data))
      return false;
//-- registra i risultati del calcolo del modello e i valori reali
   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]);
//-- risultato restituito
   return true;
  }
//+------------------------------------------------------------------+