181 lines
15 KiB
MQL5
181 lines
15 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| activations.mqh |
|
|
//| Copyright 2021, MetaQuotes Ltd. |
|
|
//| https://www.mql5.com |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2021, MetaQuotes Ltd."
|
|
#property link "https://www.mql5.com"
|
|
//+------------------------------------------------------------------+
|
|
//| Includes |
|
|
//+------------------------------------------------------------------+
|
|
#include <Arrays\ArrayDouble.mqh>
|
|
//---
|
|
const double theta = 0;
|
|
const double a = 1.0;
|
|
const double b = 0.0;
|
|
//+------------------------------------------------------------------+
|
|
/// Пороговая функция активации
|
|
/// Константа 'theta' определяет уровень активации нейрона.
|
|
/// Параметр 'x' получает взвещенную сумму исходных данных.
|
|
//+------------------------------------------------------------------+
|
|
double ActStep(double x)
|
|
{
|
|
return (x >= theta ? 1 : 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Линейная функция активации
|
|
/// Константа 'a' определяет уровень наклона линии,
|
|
/// Константа 'b' определяет смещени линии от начала координат
|
|
/// Параметр 'x' получает взвещенную сумму исходных данных.
|
|
//+------------------------------------------------------------------+
|
|
double ActLinear(double x)
|
|
{
|
|
return (a * x + b);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Производная линейной функции активаци
|
|
/// Константа 'a' определяет уровень наклона линии,
|
|
/// Параметр 'y' последнее состояние функции актвиации (результат прямого прохода),
|
|
/// В данном случае параметр добавлен для единства формы функции с аналогичными для других функций активации.
|
|
//+------------------------------------------------------------------+
|
|
double ActLinearDerivative(double y)
|
|
{
|
|
return a;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Логистическая функции активации (Сигмоида)
|
|
/// Константа 'a' определяет диапазон значений функции от '0' до 'a'
|
|
/// Константа 'b' определяет смещени линии от начала координат
|
|
/// Параметр 'x' получает взвещенную сумму исходных данных.
|
|
//+------------------------------------------------------------------+
|
|
double ActSigmoid(double x)
|
|
{
|
|
return (a / (1 + exp(-x)) - b);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Производная логистической функции
|
|
/// Константа 'a' определяет диапазон значений функции от '0' до 'a'
|
|
/// Константа 'b' определяет смещени линии от начала координат
|
|
/// Параметр 'y' последнее состояние функции актвиации (результат прямого прохода),
|
|
//+------------------------------------------------------------------+
|
|
double ActSigmoidDerivative(double y)
|
|
{
|
|
y = MathMax(MathMin(y + b, a), 0.0);
|
|
return (y * (1 - y / a));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Гиперболический тангенс
|
|
/// Параметр 'x' получает взвещенную сумму исходных данных.
|
|
//+------------------------------------------------------------------+
|
|
double ActTanh(double x)
|
|
{
|
|
return tanh(x);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Производная ниперболического тангенса
|
|
/// Параметр 'y' последнее состояние функции актвиации (результат прямого прохода),
|
|
//+------------------------------------------------------------------+
|
|
double ActTanhDerivative(double y)
|
|
{
|
|
y = MathMax(MathMin(y, 1.0), -1.0);
|
|
return (1 - pow(y, 2));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Функция активации PReLU
|
|
/// Константа 'a' определяет коэффициент "утечки" (пробуска отрицательных значений)
|
|
/// Параметр 'x' получает взвещенную сумму исходных данных.
|
|
//+------------------------------------------------------------------+
|
|
double ActPReLU(double x)
|
|
{
|
|
return (x >= 0 ? x : a * x);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Производная PReLU
|
|
/// Константа 'a' определяет коэффициент "утечки" (пробуска отрицательных значений)
|
|
/// Параметр 'y' последнее состояние функции актвиации (результат прямого прохода),
|
|
/// В данном случае параметр добавлен для единства формы функции с аналогичными для других функций активации.
|
|
//+------------------------------------------------------------------+
|
|
double ActPReLUDerivative(double y)
|
|
{
|
|
return (y >= 0 ? 1 : a);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Функция активации Swish
|
|
/// Константа 'b' определяет нелинейность функции.
|
|
/// Параметр 'x' получает взвещенную сумму исходных данных.
|
|
//+------------------------------------------------------------------+
|
|
double ActSwish(double x)
|
|
{
|
|
return (x / (1 + exp(-b * x)));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Производная Swish
|
|
/// Константа 'b' определяет нелинейность функции.
|
|
/// Параметр 'x' получает взвещенную сумму исходных данных.
|
|
/// Параметр 'y' последнее состояние функции актвиации (результат прямого прохода),
|
|
//+------------------------------------------------------------------+
|
|
double ActSwishDerivative(double x, double y)
|
|
{
|
|
if(x == 0)
|
|
return 0.5;
|
|
double by = b * y;
|
|
return (by + (y * (1 - by)) / x);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Функция активации SoftMax
|
|
/// Параметр 'X' получает массив взвещенных сумм исходных данных.
|
|
//+------------------------------------------------------------------+
|
|
#include <Arrays\ArrayDouble.mqh>
|
|
//---
|
|
CArrayDouble *SoftMax(CArrayDouble *X)
|
|
{
|
|
if(CheckPointer(X) == POINTER_INVALID || X.Total() <= 0)
|
|
return NULL;
|
|
CArrayDouble *result = new CArrayDouble();
|
|
if(CheckPointer(result) == POINTER_INVALID)
|
|
return NULL;
|
|
//--- Рассчёт экспоненты для каждого элемента массива
|
|
double sum = 0;
|
|
int total = X.Total();
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
if(!result.Add(exp(X.At(i))))
|
|
{
|
|
delete result;
|
|
return NULL;
|
|
}
|
|
sum += result.At(i);
|
|
}
|
|
//--- Нормализация данных в массиве
|
|
for(int i = 0; i < total; i++)
|
|
if(!result.Update(i, result.At(i) / sum))
|
|
{
|
|
delete result;
|
|
return NULL;
|
|
}
|
|
//---
|
|
return result;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
/// Производная SoftMax
|
|
/// Параметр 'Y' последнее состояние функции актвиации (результат прямого прохода),
|
|
/// Параметр 'G' градиент ошибки, полученній от последующего слоя
|
|
/// Функция возвращает массив скорректированных градиентов ошибки
|
|
//+------------------------------------------------------------------+
|
|
CArrayDouble *ActSoftMaxDerivative(CArrayDouble *Y, CArrayDouble *G)
|
|
{
|
|
CArrayDouble *result = new CArrayDouble();
|
|
if(CheckPointer(result) == POINTER_INVALID)
|
|
return NULL;
|
|
int total = Y.Total();
|
|
for(int i = 0; i < total; i++)
|
|
{
|
|
double grad = 0;
|
|
for(int j = 0; j < total; j++)
|
|
grad += Y.At(j) * ((int)(i == j) - Y.At(i)) * G.At(j);
|
|
if(!result.Add(grad))
|
|
return NULL;
|
|
}
|
|
return result;
|
|
}
|
|
//+------------------------------------------------------------------+
|