머신 러닝

이러한 메서드들은 기계 학습에서 사용됩니다.

신경망 활성화 함수는 입력의 가중 합에 따라 뉴런의 출력 값을 결정합니다. 어떠한 활성화 함수를 선택할지 여부는 신경망 성능에 큰 영향을 미칩니다. 다른 모델 파트(레이어)는 다른 활성화 함수를 사용할 수 있습니다.

알려진 모든 활성화 기능 외에도 MQL5는 드것들의 파생 기능도 제공합니다. 도함수를 사용하면 학습에서 받은 오류를 기반으로 모델 매개변수를 효율적으로 업데이트할 수 있습니다.

신경망은 학습에서 오류를 최소화하는 알고리즘을 찾는 것을 목표로 하며 손실 함수를 사용합니다. 손실 함수의 값은 모델이 예측한 값이 실제 값과 얼마나 다른지를 나타냅니다. 문제에 따라 다른 손실 함수가 사용됩니다. 예를 들어 평균 제곱 오차(MSE)는 회귀 문제에 사용되며 Binary Cross-Entropy(기원전)는 이진 분류 목적으로 사용됩니다.

함수

액션

Activation

활성화 함수 값을 계산하고 전달된 벡터/행렬에 씁니다

Derivative

활성화 함수 도함수 값을 계산하고 이들을 전달된 벡터/행렬에 씁니다

Loss

손실 함수 값을 계산하고 전달된 벡터/행렬에 씁니다

LossGradient

손실 함수 기울기의 벡터 또는 행렬을 계산합니다

RegressionMetric

지정된 데이터 배열에 구성된 회귀선의 편차 오류로 회귀 메트릭을 계산

ConfusionMatrix

혼동 행렬 계산. 이 메서드는 예측값의 벡터에 적용됩니다

ConfusionMatrixMultilabel

각 레이블에 대한 혼동 행렬 계산. 이 메서드는 예측값의 벡터에 적용됩니다

ClassificationMetric

실제 데이터와 비교하여 예측 데이터의 품질을 평가하기 위해 분류 지표를 계산합니다. 이 방법은 예측 값의 벡터에 적용됩니다

ClassificationScore

실제 데이터와 비교하여 예측 데이터의 품질을 평가하기 위해 분류 메트릭을 계산

PrecisionRecall

값들을 계산하여 정밀도-재현율 곡선(precision-recall curve)을 구성합니다. ClassificationScore와 마찬가지로 이 메서드는 참값의 벡터에 적용됩니다

ReceiverOperatingCharacteristic

Receiver Operating Characteristic (ROC) 곡선을 구성하기 위한 값을 계산합니다. ClassificationScore와 마찬가지로 이 메서드는 참값의 벡터에 적용됩니다

이 예는 행렬 연산을 사용하여 모델을 훈련하는 방법을 보여줍니다. 모델은 (a + b + c)^2 / (a^2 + b^2 + c^2) 함수에 대해 학습됩니다. a, b 및 c가 서로 다른 열에 포함된 초기 데이터 매트릭스를 입력합니다. 함수 결과는 모델 출력에서 얻습니다.

matrix weights1weights2weights3;               // 가중치의 행렬
matrix output1output2result;                   // 신경층 출력의 행렬
input int layer1 = 200;                            // 첫 번째 은닉층의 크기
input int layer2 = 200;                            // 두 번째 은닉층의 크기
input int Epochs = 20000;                          // 훈련 에포크의 수
input double lr = 3e-6;                            // 학습률
input ENUM_ACTIVATION_FUNCTION ac_func = AF_SWISH// 활성화 함수
//+------------------------------------------------------------------+
//| Script start function                                            |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int train = 1000;    // 샘플 사이즈 훈련
   int test = 10;       // 샘플 사이즈 테스트
   matrix m_datam_target;
//--- 훈련 샘플 생성
   if(!CreateData(m_datam_targettrain))  
      return;
//--- 모델 훈련
   if(!Train(m_datam_targetEpochs))      
      return;
//--- 테스트 샘플 생성
   if(!CreateData(m_datam_targettest))   
      return;
//--- 모델 테스트
   Test(m_datam_target);                   
  }
//+------------------------------------------------------------------+
//| Sample generation method                                         |
//+------------------------------------------------------------------+
bool CreateData(matrix &datamatrix &targetconst int count)
  {
//--- 초기 데이터 및 결과 행렬 초기화
   if(!data.Init(count3) || !target.Init(count1))
      return false;
//--- 임의의 값으로 초기 데이터 행렬 채우기
   data.Random(-1010);                     
//--- 학습 샘플의 목표 값을 계산
   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;
//--- 결과 반환
   return true;
  }
//+------------------------------------------------------------------+
//| Model training method                                            |
//+------------------------------------------------------------------+
bool Train(matrix &datamatrix &targetconst int epochs = 10000)
  {
//--- 모델 생성
   if(!CreateNet())
      return false;
//--- 모델 훈련
   for(int ep = 0ep < epochsep++)
     {
//--- 피드포워드 패스
      if(!FeedForward(data))
         return false;
      PrintFormat("Epoch %d, loss %.5f"epresult.Loss(targetLOSS_MSE));
//--- 가중치 행렬의 역전파 및 업데이트
      if(!Backprop(datatarget))
         return false;
     }
//--- 결과 반환
   return true;
  }
//+------------------------------------------------------------------+
//| Model creation method                                            |
//+------------------------------------------------------------------+
bool CreateNet()
  {
//--- 가중치 행렬 초기화
   if(!weights1.Init(4layer1) || !weights2.Init(layer1 + 1layer2) || !weights3.Init(layer2 + 11))
      return false;
//--- 가중치 행렬을 임의의 값으로 채웁니다.
   weights1.Random(-0.10.1);
   weights2.Random(-0.10.1);
   weights3.Random(-0.10.1);
//--- 결과 반환
   return true;
  }
//+------------------------------------------------------------------+
//| Feedforward method                                               |
//+------------------------------------------------------------------+
bool FeedForward(matrix &data)
  {
//--- 초기 데이터 크기 확인
   if(data.Cols() != weights1.Rows() - 1)
      return false;
//--- 첫 번째 신경 계층을 계산합니다.
   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);
//--- 활성화 함수 계산
   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;
   output2 = temp.MatMul(weights2);
//--- 활성화 함수 계산
   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;
   result = temp.MatMul(weights3);
//--- 결과 반환
   return true;
  }
//+------------------------------------------------------------------+
//| Backpropagation method                                           |
//+------------------------------------------------------------------+
bool Backprop(matrix &datamatrix &target)
  {
//--- 대상 값의 행렬 크기 확인
   if(target.Rows() != result.Rows() ||
      target.Cols() != result.Cols())
      return false;
//--- 목표에서 계산된 값의 편차를 결정합니다.
   matrix loss = (target - result) * 2;
//--- 그래디언트를 이전 레이어로 전파
   matrix gradient = loss.MatMul(weights3.Transpose());
//--- 마지막 레이어의 가중 행렬 업데이트
   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;
//--- 활성화 함수의 도함수로 오류 기울기를 조정합니다.
   if(!output2.Derivative(tempac_func))
      return false;
   if(!gradient.Resize(gradient.Rows(), gradient.Cols() - 1))
      return false;
   loss = gradient * temp;
//--- 기울기를 하위 레이어로 전파
   gradient = loss.MatMul(weights2.Transpose());
//--- 두 번째 은닉층의 가중치 행렬 업데이트
   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;
//--- 활성화 함수의 도함수로 오류 기울기를 조정합니다.
   if(!output1.Derivative(tempac_func))
      return false;
   if(!gradient.Resize(gradient.Rows(), gradient.Cols() - 1))
      return false;
   loss = gradient * temp;
//--- 첫 번째 은닉층의 가중치 행렬을 업데이트합니다.
   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;
//--- 결과 반환
   return true;
  }
//+------------------------------------------------------------------+
//| Model testing method                                             |
//+------------------------------------------------------------------+
bool Test(matrix &datamatrix &target)
  {
//--- 테스트 데이터에서 피드포워드
   if(!FeedForward(data))
      return false;
//--- 모델 계산 결과 및 실제 값 기록
   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]);
//--- 결과 반환
   return true;
  }
//+------------------------------------------------------------------+