//+------------------------------------------------------------------+ //| activations.mqh | //| Copyright 2021, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2021, MetaQuotes Ltd." #property link "https://www.mql5.com" //+------------------------------------------------------------------+ //| Includes | //+------------------------------------------------------------------+ #include //--- 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 //--- 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; } //+------------------------------------------------------------------+