NeuroNetworksBook/Include/about_ai/activation/activations.mqh
super.admin 4a9222852c convert
2025-05-30 16:12:34 +02:00

161 lines
13 KiB
MQL5

//+------------------------------------------------------------------+
//| activations.mqh |
//| Copyright 2021, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, MetaQuotes Ltd."
#property link "https://www.mql5.com"
//---
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' получает массив взвещенных сумм исходных данных.
//+------------------------------------------------------------------+
bool SoftMax(double& X[], double& Y[])
{
uint total = X.Size();
if(total == 0)
return false;
if(ArrayResize(Y, total) <= 0)
return false;
//--- Рассчёт экспоненты для каждого элемента массива
double sum = 0;
for(uint i = 0; i < total; i++)
sum += Y[i] = exp(X[i]);
//--- Нормализация данных в массиве
for(uint i = 0; i < total; i++)
Y[i] /= sum;
//---
return true;
}
//+------------------------------------------------------------------+
/// Производная SoftMax
/// Параметр 'Y' последнее состояние функции актвиации (результат прямого прохода),
/// Параметр 'G' градиент ошибки, полученный от последующего слоя
/// Функция возвращает массив скорректированных градиентов ошибки 'D'
//+------------------------------------------------------------------+
bool ActSoftMaxDerivative(double& Y[], double& G[], double& D[])
{
uint total = Y.Size();
if(total == 0 || ArrayResize(D, total) <= 0)
return false;
for(uint i = 0; i < total; i++)
{
double grad = 0;
for(uint j = 0; j < total; j++)
grad += Y[j] * ((int)(i == j) - Y[i]) * G[j];
D[i] = grad;
}
return true;
}
//+------------------------------------------------------------------+