Активации функция: виды, примеры, роль, сигмоида, ReLU, softmax

0
27

Пороговая (ступенчатая) функция активации

PPT - изображение номер один
PPT — изображение номер один

Пороговая функция активации, наверное, была применена одной из первых. И это не удивительно, ведь она повторяет действие биологического нейрона:

  • возможно только два состояния (активирован или нет);
  • нейрон активируется при достижении порогового значения θ.

Нейронные сети - презентация онлайн - изображение номер два
Нейронные сети — презентация онлайн — изображение номер два

Данная функция активации легка в понимании, но основным ее недостатком является сложность или даже невозможность обучения нейронной сети. Дело в том, что в алгоритмах обучения нейронных сетей используется производная первого порядка. А производная рассматриваемой функции равна нулю на всем протяжении, за исключением x = θ (в данной точке она не определена).

Реализовать данную функцию в виде программного кода MQL5 довольно легко. Константа theta определяет уровень, при достижении которого нейрон будет активирован. При вызове функции активации в параметрах передадим предварительно посчитанную взвешенную сумму исходных данных. Внутри функции сравним полученное в параметрах значение с уровнем активации theta и вернем значение активации нейрона.

Таблица №1

const double theta 0;
//———
double ActStep(double x)
  {
   return (>= theta ? 1 : 0);
  }

Таблица №2

theta 0
def ActStep (x):
  return 1 if >= theta else 0

Линейная функции активации

Искусственные нейронные сети - презентация онлайн - изображение номер три
Искусственные нейронные сети — презентация онлайн — изображение номер три
  • а — определяет угол наклона линии;
  • b — смещение линии по вертикале.

Как частный случай линейной функции активации, при a =1 и b =0 функция имеет вид.

Функция может генерировать значения в диапазоне от до и дифференцируема на всем протяжении. Производная функции постоянна и равна a, что облегчает процесс обучения нейронной сети. Указанные свойства позволяют широко использовать данную функцию активации при решении задач регрессии.

Следует отметить, что вычисление взвешенной суммы входов нейрона является линейной функцией. Применение линейной функции активации дает линейную функцию всего нейрона и нейронной сети. Данное свойство не позволяет использовать линейную функцию активации для решения нелинейных задач.

В то же время, создавая нелинейность на скрытых слоях нейронной сети с помощью других функций активации, мы можем использовать линейную функцию активации в нейронах выходного слоя своей модели. Такой прием позволяет решать нелинейные задачи регрессии.

Введение в нейросети - презентация онлайн - изображение номер четыре
Введение в нейросети — презентация онлайн — изображение номер четыре

Реализация линейной функции активации в виде программного кода MQL5 требует создания двух констант: a и b. По аналогии с реализацией предыдущей функции активации, при вызове функции в параметрах передадим предварительно посчитанную взвешенную сумму исходных данных. Внутри функции реализация расчетной части умещается в одну строчку.

Таблица №3

const double 1.0;
const double 0.0;
//———
double ActLinear(double x)
  {
   return (b);
  }

Таблица №4

1.0
0.0
def ActLinear (x):
  return b

Логистическая функция активации (Сигмоида) #

#1 - изображение номер пять
#1 — изображение номер пять

Логистическая функция активации, наверное, самая распространенная S -образная функция. Значения функции находятся в диапазоне от 0 до 1, они асимметричны относительно точки [0, 0.5]. График функции напоминает пороговую функцию, но с плавным переходом между состояниями.

Данная функция позволяет нормализовать выходные значений функции в диапазоне [0, 1]. Благодаря этому свойству использование логистической функции вводит понятие вероятности в практику нейронных сетей. Это свойство широко эксплуатируется в нейронах выходного слоя при решении задач классификации, когда количество нейронов выходного слоя равно количеству классов, а отнесение объекта к тому или иному классу определяется по максимальной вероятности (максимальному значению выходного нейрона).

Функция дифференцируема на всем промежутке допустимых значений. Значение производной легко рассчитывается через значение функции по формуле:

Нейронные сети - online presentation - изображение номер шесть
Нейронные сети — online presentation — изображение номер шесть

Иногда в практике применения нейронных сетей можно встретить немного измененную логистическую функцию:

  • a — растягивает диапазон значений функции от 0 до a;
  • b — по аналогии с линейной функцией смещает результирующее значения.

Производная такой функции также вычисляется через значение функции по формуле:

В практике наиболее часто применяют, чтобы график функции был асимметричен относительно начала координат.

Все вышеизложенные свойства добавляют популярности использованию логистической функции в качестве функции активации нейрона.

Но и она не лишена недостатков. При входных значения меньше −6 и больше 6 значение функции прижимается к границам диапазона значений функции, а производная стремится к нулю. Как следствие, градиент ошибки также стремится к нулю. Это приводит к снижению скорости обучения нейронной сети, а порой и вовсе делает сеть практически необучаемой.

Ниже предлагаю рассмотреть реализацию наиболее общего варианта логистической функции с двумя константами a и b. Экспоненту вычислим с помощью функции exp ().

Таблица №5

const double 1.0;
const double 0.0;
//———
double ActSigmoid(double x)
  {
   return (/ (exp(-x)) — b);
  }

При реализации на Python перед использованием функции экспоненты необходимо импортировать библиотеку math, в которой собраны основные математические функции. В остальном алгоритм и реализация функции аналогичны реализации на MQL5.

Таблица №6

import math

1.0
0.0
def ActSigmoid (x):
  return a / (1 + (-x)) — b

Гиперболический тангенс (tanh) #

What are - изображение номер семь
What are — изображение номер семь

Альтернативой логистической функции активации является гиперболический тангенс (Tanh). Он так же, как и логистическая функция, имеет S -образный график, а значения функции нормализованы. Но они принадлежат диапазону от −1 до 1, и изменение состояния нейрона осуществляется в 2 раза быстрее. График функции также асимметричен, но в отличие от логистической функции центр асимметрии находится в центре координат.

Функция дифференцируема на всем промежутке допустимых значений. Значение производной легко считается через значение функции по формуле:

Функция гиперболического тангенса является альтернативой логистической функции, которая довольно часто сходится быстрее.

Сверточная нейронная сеть, часть 1: структура, топология, функции активации и об - изображение номер восемь
Сверточная нейронная сеть, часть 1: структура, топология, функции активации и об — изображение номер восемь

Но и она не лишена главного недостатка логистической функции: при насыщении функции, когда значения функции приближаются к границам диапазона значений, производная функции стремится к нулю. Как следствие, градиент ошибки стремится к нулю.

Функция гиперболического тангенса уже реализована в используемых нами языках программирования, и для ее вызова достаточно вызвать функцию tanh ().

Таблица №7

double ActTanh(double x)
  {
   return tanh(x);
  }

Таблица №8

import math

def ActTanh (x):
  return (x)

Выпрямленный линейный блок (ReLU) #

Еще одна широко используемая функция активации нейронов — ReLU (выпрямленный линейный блок). При входящих значениях больше нуля функция возвращает само значение, подобно линейной функции активации. При значениях меньше или равном нулю функция всегда возвращает 0. Математически данная функция выражается формулой:

График функции представляет собой нечто среднее между пороговой и линейной функцией.

Создать мем \ - изображение номер десять
Создать мем \ — изображение номер десять

ReLU, наверное, одна из наиболее распространенных функций активации на данный момент. Такое распространение она получила благодаря своим свойствам:

  • Как и пороговая функция, работает по принципу биологического нейрона, активируется только после достижения порогового значения (0). В отличие от пороговой функции, при активации нейрон возвращает не константу, а переменное значение.
  • Область значений лежит в диапазоне от 0 до, что позволяет использовать функцию при решении задач регрессии.
  • При значении функции больше нуля ее производная равна единице.
  • При расчете функции не требуются сложные вычисления, что ускоряет процесс обучения.

В литературе приводятся примеры, когда нейронные сети с ReLU обучаются до 6 раз быстрее сетей с использованием TANH.

Для минимизации эффекта мертвых нейронов при использовании ReLU было предложено несколько вариаций данной функции, но все они сводились к одному — применению некоего коэффициента a для взвешенной суммы меньше нуля.

Таблица №9

LReLU

Leaky ReLU — ReLU с утечкой

a = 0,01

PReLU

Parametric ReLU — параметрическая ReLU

Параметр a подбирается в процессе обучения нейронной сети

RReLU

Randomized ReLU — рандомизированный ReLU

Параметр a задается случайным образом при создании нейронной сети

Классический вариант ReLU удобно реализовать с помощью функции max (). Реализация ее вариантов потребует создания константы или переменной a. Вариант инициализации будет зависеть от выбранной функции (LReLU / PReLU / RReLU). А внутри нашей функции активации создадим логическое разветвление, в зависимости от значение получаемого параметра.

Таблица №10

const double 0.01;
//———
double ActPReLU(double x)
  {
   return (>= 0 ? x : a * x);
  }

Таблица №11

0.01
def ActPReLU (x):
  return x if >= 0 else a * x

Softmax #

neural network - изображение номер одиннадцать
neural network — изображение номер одиннадцать

Если выше рассмотренные функции рассчитывались на данных исключительно отдельно взятого нейрона, то функция Softmax применяется ко всем нейронам отдельного слоя сети (как правило, последнего). Наряду с сигмоидой, вводится понятие вероятности в нейронные сети. Диапазон значений функции лежит между 0 и 1, а сумма всех выходных значений нейронов взятого слоя равна 1.

Функция дифференцируема на всем промежутке значений, и ее производная легко вычисляется через значение функции:

Функция широко применяется в последнем слое нейронной сети при решении задач классификации. Считается, что выходное значение нейрона, нормализованное функцией Softmax, показывает вероятность отнесения объекта к соответствующему классу классификатора.

Стоит отметить, что вычисление Softmax трудозатратно, поэтому его применение оправдано в последнем слое нейронных сетей многоклассовой классификации.

Реализация функции Softmax на MQL5 будет немного сложнее рассмотренных выше примеров. Это связано с обработкой нейронов всего слоя. Следовательно, в параметрах функция будет получать не отдельное значение, а целый массив данных.

Надо обратить внимание, что в MQL5 массивы, в отличие от переменных, передаются в параметры функций указателями на элементы памяти, а не значениями.

Наша функция в параметрах примет указатели на два массива данных X и Y и в завершение операций вернет логический результат. Непосредственно результаты операций будут в массиве Y.

В теле функции сначала проверяем размер массива исходных данных X. Полученный массив должен быть не нулевой длины. Затем изменяем размер массива для записи результатов Y. При неудачном выполнении какой-либо из операций выходим из функции с результатом false.

Таблица №12

bool SoftMax(doubleX[], doubleY[])
  {
   uint total = X.Size();
   if(total == 0)
      return false;
   if(ArrayResize(Ytotal) <= 0)
      return false;

Далее организуем два цикла. В первом посчитаем экспоненты для каждого элемента полученного массива данных и суммируем полученные значения.

Таблица №13

//— Расчет экспоненты для каждого элемента массива
   double sum = 0;
   for(uint i = 0i < totali++)
      sum += Y[i] = exp(X[i]);

Во втором цикле нормализуем значения массива, созданного в первом цикле. Перед выходом из функции вернем полученные значения.

Таблица №14

//— Нормализация данных в массиве
   for(uint i = 0i < totali++)
      Y[i] /= sum;
//—
   return true;
  }

На Python реализация выглядит намного проще, т.к. функция Softmax уже реализована в библиотеке Scipy.

Таблица №15

from scipy.special import softmax
def ActSoftMax (X):
  return softmax(X)

Swish #

swish activation function self gated activation function - изображение номер двенадцать
swish activation function self gated activation function — изображение номер двенадцать

В октябре 2017 года команда исследователей из Google Brain провела работу по автоматическому поиску функций активации. Результаты этой работы были представлены в статье Searching for Activation Functions. В статье приведены результаты тестирования целого ряда функций в сравнении с ReLU. Наилучшие показатели были достигнуты в нейросетях с функцией активации Swish. Только замена ReLU на Swish (без переобучения) позволила улучшить показатели нейронных сетей.

Параметр β влияет на нелинейность функции и может быть принят константой при проектировании сети или подбираться в процессе обучения. При β =0 функция сводится к масштабируемой линейно функции.

При β =1 график функции Swish приближается к ReLU. Но в отличие от последней, функция дифференцируема на всем промежутке значений.

Функция дифференцируема на всем протяжении, и ее производная вычисляется через значение функции. Но в отличие от сигмоиды, для вычисления производной требуется еще и входящее значение. Математическая формула производной имеет вид:

Реализация функции в программном коде MQL5 аналогична представленной выше Сигмоиде. Параметр a заменяется полученным значением взвешенной суммы и добавляется параметр нелинейности β.

Таблица №16

const double b=1.0;
//———
double ActSwish(double x)
  {
   return (x / (exp(-b * x)));
  }

Таблица №17

import math

b=1.0
def ActSwish (x):
  return x / (1 + (-b * x))

Стоит отметить, что это далеко не полный список возможных функций активации. Возможны как вариации к приведенным выше функциям, так и использование иных функций. Выбор функции активации и пороговых значений лежит на архитекторе нейронной сети. Далеко не всегда все нейроны в сети имеют одинаковую функцию активации. В практике широко используются нейронные сети, в которых функция активации меняется от слоя к слою. Такие сети называют гетерогенными.

Позже будет показано, что для реализации нейронных сетей гораздо удобнее использовать векторные и матричные операции, которые реализованы в MQL5. В частности это касается и функций активации, ведь в функционале матричных и векторных операций создана функция Activation, которая позволяет одной строкой кода вычислять функции активации для целого массива данных. В нашем случае — для всего нейронного слоя. Реализация функции имеет нижеследующий вид.

Таблица №18

bool vector::Activation(
  vector&                   vect_out,      // вектор для получения значений
  ENUM_ACTIVATION_FUNCTION  activation     // тип функции
   );
 
 
bool matrix::Activation(
  matrix&                   matrix_out,    // матрица для получения значений
  ENUM_ACTIVATION_FUNCTION  activation     // тип функции
   );

В параметрах функция принимает указатель на вектор или матрицу (в зависимости от источника данных) для записи результатов и тип используемой функции активации. Стоит отметить, что спектр функций активации в векторных/матричных операциях MQL5 гораздо шире описанных выше. Их полный список приводится в таблице.

Таблица №19

Идентификатор

Описание

AF_ELU

Экспоненциальная линейная единица

AF_EXP

Экспоненциальная

AF_GELU

Линейная единица ошибки Гаусса

AF_HARD_SIGMOID

Жесткий сигмоид

AF_LINEAR

Линейная

AF_LRELU

Линейный выпрямитель с «утечкой» (Leaky ReLU)

AF_RELU

Усеченное линейное преобразование ReLU

AF_SELU

Масштабированная экспоненциальная линейная функция (Scaled ELU)

AF_SIGMOID

Сигмоид

AF_SOFTMAX

Softmax

AF_SOFTPLUS

Softplus

AF_SOFTSIGN

Softsign

AF_SWISH

Swish-функция

AF_TANH

Гиперболический тангенс

AF_TRELU

Линейный выпрямитель с порогом

End-to-End - изображение номер четырнадцать
End-to-End — изображение номер четырнадцать

Часто задаваемые вопросы о функциях активации

Вопрос: Можно ли обойтись без функции активации в нейросети?
Ответ: Нет, без функции активации нейронная сеть, независимо от количества слоев, будет эквивалентна простой линейной модели и не сможет решать сложные нелинейные задачи.

Вопрос: Какая функция активации считается самой популярной и почему?
Ответ: ReLU (Rectified Linear Unit) — из-за простоты вычисления, эффективности в борьбе с затухающим градиентом и хорошей производительности в глубоких сетях.

Вопрос: В чем главный недостаток сигмоиды и tanh?
Ответ: Их производные на краях насыщаются, принимая значения близкие к нулю, что приводит к проблеме затухающего градиента при обучении глубоких сетей.

Вопрос: Всегда ли ReLU лучше сигмоиды?
Ответ: Не всегда. Для выходного слоя в задачах бинарной классификации сигмоида более уместна. Также ReLU может «умирать» (переставать обучаться) при отрицательных входах.

Вопрос: Где именно применяется функция Softmax?
Ответ: Почти исключительно в выходном слое нейросетей для задач многоклассовой классификации, так как она преобразует выходы в вероятностное распределение по классам.

Вопрос: Что такое «умирающий ReLU»?
Ответ: Это ситуация, когда нейрон с функцией ReLU постоянно выдает ноль (например, из-за слишком большого отрицательного смещения), его градиент становится нулевым, и он перестает обучаться.

Вопрос: Можно ли использовать разные функции активации в разных слоях одной сети?
Ответ: Да, это распространенная практика. Например, ReLU в скрытых слоях для скорости обучения, а сигмоида или softmax в выходном слое для интерпретации результата.

Вопрос: Зачем нужна нелинейность функции активации?
Ответ: Именно нелинейность позволяет сети аппроксимировать сколь угодно сложные зависимости между входными и выходными данными, что является основой ее мощности.

Вопрос: Что такое параметрическая функция активации (например, PReLU)?
Ответ: Это функции, которые имеют обучаемые параметры (например, коэффициент наклона для отрицательных значений в PReLU), что позволяет сети адаптировать форму функции под конкретную задачу.

Вопрос: Как выбрать функцию активации для своего проекта?
Ответ: Начать стоит с ReLU или ее модификаций (Leaky ReLU) для скрытых слоев. Для выходного слоя выбор зависит от задачи: сигмоида для бинарной классификации, softmax для многоклассовой, линейная функция для регрессии.

Краткая памятка по выбору и использованию функций активации

  1. Функция активации — обязательный компонент нейрона, вносящий нелинейность.
  2. Без нелинейной функции активации глубокая сеть вырождается в один линейный слой.
  3. Для скрытых слоев современных нейросетей чаще всего используют ReLU и ее модификации (Leaky ReLU, ELU).
  4. Сигмоида (логистическая функция) хорошо подходит для выходного слоя в задачах бинарной классификации.
  5. Функция Softmax используется исключительно в выходном слое для задач классификации с несколькими классами.
  6. Гиперболический тангенс (tanh) центрирован вокруг нуля, что иногда делает обучение более стабильным по сравнению с сигмоидой.
  7. Проблема «затухающего градиента» характерна для сигмоиды и tanh, но не для ReLU.
  8. Ступенчатая функция исторически важна, но в современных сетях на основе градиентного спуска не используется.
  9. Чисто линейная функция активации делает сеть бесполезной для моделирования сложных зависимостей.
  10. Функция Swish (x * sigmoid(x)) может показывать результаты лучше ReLU в некоторых глубоких архитектурах.
  11. При возникновении проблемы «умирающих нейронов» в ReLU стоит попробовать Leaky ReLU.
  12. Выбор функции активации — это гиперпараметр, который можно и нужно тестировать экспериментально.