Нейронная сеть с SoftMax слоем на c#
Привет, в прошлой статье я рассказал про алгоритм обратного распространения ошибки и привел реализацию, не зависящую от функции ошибки и от функции активации нейрона. Было показано несколько простых примеров подмены этих самых параметров: минимизация квадрата Евклидова расстояния и логарифмического правдоподобия для сигмоидной функции и гиперболического тангенса. Данный пост будет логическим продолжение прошлого, в котором я рассмотрю немного нестандартный пример, а именно функцию активации Softmax для минимизации перекрестной энтропии. Эта модель актуальна при задаче классификации, когда необходимо получить на выходе нейросети вероятности принадлежности входного образа одному из не пересекающихся классов. Очевидно, что суммарный выход сети по всем нейронам выходного слоя должен равняться единице (так же как и для выходных образов обучающей выборки). Однако не достаточно просто нормализировать выходы, а нужно заставить сеть моделировать вероятностное распределение, и обучать ее именно этому. Кстати, сейчас на coursera.org идёт курс по нейросетям, именно он помог углубиться в понимание софтмакса, иначе я продолжал бы использовать сторонние реализации.
Using
Рекомендую ознакомиться с предыдущим постом, так как все обозначения, интерфейсы и сам алгоритм обучения без изменений используются и здесь.
Функция активации softmax
- сеть содержит некоторое количество скрытых слоев, все нейроны могут иметь свою собственную функцию активации;
- на последнем слое находится такое количество нейронов, которое соответствует количеству классов; все эти нейроны будут называться softmax слоем или группой.
Нейроны softmax-группы будут иметь следующую функцию активации (в этом разделе я буду опускать индекс слоя, подразумевается, что он последний и содержит n нейронов):
Реализуем эту функцию, используя интерфейс IFunction из предыдущей статьи:
Реализация softmax функции
Стоит отметить, что реализация метода double Compute(double x) вообще говоря не обязательна, так как вычисление выходных значений группы будет дешевле сделать в реализации softmax слоя. Но для полноты картины, да и на всякий случай пусть будет -)
internal class SoftMaxActivationFunction : IFunction < private ILayer _layer = null; private int _ownPosition = 0; internal SoftMaxActivationFunction(ILayer layer, int ownPosition) < _layer = layer; _ownPosition = ownPosition; >public double Compute(double x) < double numerator = Math.Exp(x); double denominator = numerator; for (int i = 0; i < _layer.Neurons.Length; i++) < if (i == _ownPosition) < continue; >denominator += Math.Exp(_layer.Neurons[i].LastNET); > return numerator/denominator; > public double ComputeFirstDerivative(double x) < double y = Compute(x); return y*(1 - y); >public double ComputeSecondDerivative(double x) < throw new NotImplementedException(); >>
Функция ошибки
На каждом обучающем примере мы будем получать выход сети, который моделирует нужное нам вероятностное распределение, а для сравнения двух вероятностных распределений необходима корректная мера. В качестве такой меры будет использоваться перекрестная энтропия:
- t — требуемые выходы для текущего обучающего примера
- y — реальные выходы нейросети
А общая ошибка сети вычисляется как:
Чтобы осознать элегантность всей модели, необходимо увидеть, как вычисляется градиент по одной из выходных размерностей или нейрону. В предыдущем посте в разделе «выходной слой» описано то, что задача сводится к вычислению dC/dz_i, продолжим с этого момента:
- , т.к. выход каждого нейрона содержит сумматор текущего, нам приходится продифференцировать всю сумму. В связи с тем, что функция стоимости зависит только от выходов нейронов, а выходы только от сумматоров, то можно разложить на две частные производные. Далее рассмотрим по отдельности каждый член суммы (главное обращать внимание на индексы, в нашем случае j пробегает по нейронам softmax группы, а i — это текущий нейрон)
Последнее преобразование получается благодаря тому, что сумма значений выходного вектора должна равняться единице, по свойству нейронов softmax-группы. Это важное требование к обучающей выборке, иначе градиент будет подсчитан не верно!
Перейдем к реализации, используя то же представление, что и раньше:
Реализация перекрестной энтропии
internal class CrossEntropy : IMetrics < internal CrossEntropy() < >/// /// \sum_i v1_i * ln(v2_i) /// public override double Calculate(double[] v1, double[] v2) < double d = 0; for (int i = 0; i < v1.Length; i++) < d += v1[i]*Math.Log(v2[i]); >return -d; > public override double CalculatePartialDerivaitveByV2Index(double[] v1, double[] v2, int v2Index) < return v2[v2Index] - v1[v2Index]; >>
Softmax слой
Вообще говоря, особый слой можно и не делать, просто в конструкторе обыкновенной сети прямого распространения создавать последний слой, с функцией активации приведенной выше, и передавать ей в конструктор ссылку на софтмакс слой, но тогда при вычислении выхода каждого нейрона каждый раз будет высчитываться знаменатель функции активации, но если реализовать метод double[] ComputeOutput(double[] inputVector) нейросети должным образом:
public double[] ComputeOutput(double[] inputVector) < double[] outputVector = inputVector; for (int i = 0; i < _layers.Length; i++) < outputVector = _layers[i].Compute(outputVector); >return outputVector; >
то из-за того, что сеть не вызывает метод Compute нейрона напрямую, а делегирует эту функцию слою, можно сделать так, чтобы знаменатель функции активации вычислялся один раз.
Softmax слой
internal class SoftmaxFullConnectedLayer : FullConnectedLayer < internal SoftmaxFullConnectedLayer(int inputDimension, int size) < _neurons = new INeuron[size]; for (int i = 0; i < size; i++) < IFunction smFunction = new SoftMaxActivationFunction(this, i); _neurons[i] = new InLayerFullConnectedNeuron(inputDimension, smFunction); >> public override double[] Compute(double[] inputVector) < double[] numerators = new double[_neurons.Length]; double denominator = 0; for (int i = 0; i < _neurons.Length; i++) < numerators[i] = Math.Exp(_neurons[i].NET(inputVector)); denominator += numerators[i]; >double[] output = new double[_neurons.Length]; for (int i = 0; i < _neurons.Length; i++) < output[i] = numerators[i]/denominator; _neurons[i].LastState = output[i]; >return output; > >
Итог
Итак, недостающие детали готовы, и можно собирать конструктор. Я, например, использую одну и ту же реализацию сети прямого распространения, просто с другим конструктором.
Пример конструктора
/// /// Creates network with softmax layer at the outlut, and hidden layes with theirs own activation functions /// internal FcMlFfNetwork(int inputDimension, int outputDimension, int[] hiddenLayerStructure, IFunction[] hiddenLayerFunctions, IWeightInitializer wi, ILearningStrategy trainingAlgorithm) < _learningStrategy = trainingAlgorithm; _layers = new ILayer[hiddenLayerFunctions.Length + 1]; _layers[0] = new FullConnectedLayer(inputDimension, hiddenLayerStructure[0], hiddenLayerFunctions[0]); for (int i = 1; i < hiddenLayerStructure.Length; i++) < _layers[i] = new FullConnectedLayer(_layers[i - 1].Neurons.Length, hiddenLayerStructure[i], hiddenLayerFunctions[i]); >//create softmax layer _layers[hiddenLayerStructure.Length] = new SoftmaxFullConnectedLayer(hiddenLayerStructure[hiddenLayerStructure.Length - 1], outputDimension); for (int i = 0; i < _layers.Length; i++) < for (int j = 0; j < _layers[i].Neurons.Length; j++) < _layers[i].Neurons[j].Bias = wi.GetWeight(); for (int k = 0; k < _layers[i].Neurons[j].Weights.Length; k++) < _layers[i].Neurons[j].Weights[k] = wi.GetWeight(); >> > >
- нейронная сеть
- обратное распространение ошибки
- softmax
- c#
- искусственный интеллект
- .net
- machine learning
- машинное обучение
Функции активации в нейронных сетях. Что это и как выбрать?
Одним из важных атрибутов глубоких нейронных сетей являются такие параметры, как функции активации. Если проводить аналогию с нейроном в организме, обработкой таких сигналов занимается мозг, и он же решает, возбудиться ли нейрону, или группе нейронов, на какой-то раздражитель или нет. В искусственных нейронных сетях за это отвечают функции активации.
Функция активации (англ. activation function) f(x) определяет выходное значение нейрона в зависимости от результата взвешенной суммы входов и порогового значения.
Простыми словами, функция активации это некий “фильтр” выходных данных текущего нейрона, который пересчитывает и пропускает важные данные — “веса” и отсеивает неактуальные данные. От функции активации напрямую зависит окончательное качество обучаемой модели и ее точность.
Проблемы при обучении нейронных сетей, которые позволяют решать функции активации
- Исчезающий градиент
- Градиентный взрыв
Проблема исчезающего градиента состоит в том, что при обучении НС, особенно в глубоких сетях, при использовании метода градиента и обратного распространения ошибки, при каждой итерации обновления весов значения стремятся к 0.
Проблема градиентного взрыва противоположна — при обучении НС, обновляемые веса получают аномально большие значения, вплоть до ошибки NaN.
Правильно подобранная функция активации поможет решить эти проблемы.
Какие функции активации существуют?
Бинарная функция активации
$$f(x) =\begin0,& x < 0 \\ 1,& x \geq 0 \end$$
Простейшая функция активации, которая сводится к логике “если больше 0 — то сигнал есть, иначе — нет”. Соответственно, нейрон активируется при значении больше 0. И остается “спящим”, если значение меньше нуля.
Чаще всего применяется в бинарной классификации, например: брак\нет брака в деталях, болеет\не болеет пациент и так далее.
Несмотря на свою простоту, может возвращать ложноположительные или ложноотрицательные результаты, что может повлечь последствия.
Бинарная функция активации не применяется для классификации нескольких классов.
Градиент в бинарной функции равен нулю, что делает практически невозможным применение метода обратного распространения ошибки (невозможно обновить веса).
Линейная функция активации
$$f(x) = x$$
По графику и формуле можно увидеть прямую зависимость y от x. Это говорит о том, что на выходе, после пересчета функцией активации, будет то же самое значение, что и на входе.
- Вся нейронная сеть, вне зависимости от количества слоев, превращается в однослойную
- Производная постоянна, а значит, мы не можем пересчитывать веса (обратное распространение)
И на этом линейные функции активации заканчиваются. Далее будут описаны нелинейные функции, которые имеют возможность пересчета весов (обратное распространение) и возможность использования нескольких слоев нейронов, наложенных друг на друга.
Нелинейные функции активации
SIgmoid
$$f(x) = \frac>$$
Функция строится в диапазоне [0; 1] и имеет S-образную линию на графике. Принцип работы сводится к логике: чем больше число на входе нейрона, тем ближе к 1 будет расположен выход. В основном используется для сетей, где необходимо предсказывать вероятность.
Дифференцируемость функции позволяет предотвратить скачки выходных значений, то есть обеспечивает более плавный градиент.
Из минусов функции можно отметить, что она склонна к проблеме исчезающего градиента (значения оси Y слабо реагируют на значения X). Это значительным образом замедляет процесс обучения нейронной сети.
Более того, выходные значения функции составляют график, который не симметричен относительно нуля. Выходные данные всех нейронов будут иметь один знак, что усложняет обучение НС.
Softmax
$$f(x) = \frac>$$
Основа функции тоже Sigmoid, выходные данные, аналогично Sigmoid, находятся в диапазоне [0; 1]. Но отличается принципом работы. Функция Softmax работает на принципе относительной вероятности и является комбинацией нескольких Sigmoid-функций. Сумма выходных данных этих комбинаций должна равняться 1, так как функция возвращает вероятность принадлежности к классу. Чаще всего используется именно для последнего слоя НС, которая работает с задачами классификации из множества классов.
$$softmax(x) = \frac)>< \sum_j )>>$$
Пример таких выходных данных:
НС обучена определять вид фрукта из 5 классов — яблоко, апельсин, киви, гранат, груша. На вход НС для предсказания класса подается изображение яблока. Результат работы функции активации Softmax будет следующим:
Класс | Результат |
---|---|
яблоко | 0,78 |
апельсин | 0,03 |
киви | 0,00 |
гранат | 0,1 |
груша | 0,09 |
Если сложить все значения вероятностей, мы получим 1.
Tahn (Гиперболический тангенс)
$$f(x) = \frac<(e^x - e^<-x>)><(e^x + e^<-x>)>$$
График функции похож на Sigmoid — имеет S-образный вид. Отличается тем, что выходные данные находятся в интервале [-1; 1]. Логика работы состоит в следующем: чем больше положительное значение подается на вход, тем ближе к 1 будет выходное значение. И наоборот, чем меньше входящее отрицательное значение, тем ближе к -1 выходное.
Так как центр проходит через 0 — это облегчает вычисление выходных значений, разделив их на нейтральные, положительные и отрицательные. Такой метод значительно упрощает обработку данных следующему слою.
Проблемной стороной функции, как и у Sigmoid, является исчезающий градиент. Но на практике предпочтение всегда отдается Tanh, из-за того, что он центрирован в точке 0.
ReLU ( Rectified Linear Unit)
$$f(x) =\max(0, x)$$
На первый взгляд похожа на линейную функцию активации, но имеет значительные отличия: позволяет использовать обратное распространение и имеет собственную производную. Нейроны активируются только в том случае, если на вход будет подано значение больше 0, в любом другом случае нейрон останется деактивированным. За счет этого ускоряется сходимость градиентного спуска к глобальному минимуму, и функция эффективнее справляется с вычислениями, в сравнении с той же Sigmoid-функцией.
Слабой стороной функции является Dying ReLU — все отрицательные значения приравниваются к нулю. Эта проблема выражается в следующем: при обратном распространении у нейронов не обновляются веса и смещения, таким образом создаются нейроны, которые никогда не активируются. И по этой же причине снижается способность модели правильно обучаться на данных.
Проблема Dying ReLU решается при помощи следующих функций активации
Leaky ReLU
$$f(x) =\max(0.1 * x, x)$$
В целом, принцип работы похож на ReLU, с единственным отличием — нейроны с отрицательными данными на входе участвуют в обучении НС. Веса для них пересчитываются.
К минусам можно отнести пару моментов, когда для отрицательных значений на входе прогнозы могут не совпадать и градиент для них будет минимален, что приводит к затруднениям при расчете параметров модели.
$$f(x) =\max(ax, x)$$
Если в предыдущей функции для отрицательных значений подавалась константа, то в этой функции активации подается дополнительная переменная a. Делается это с той же целью — избавиться от неактивных нейронов.
Из переменной a вытекает и минус — функция отрабатывает по разному для различных задач. Полная зависимость от переменной для отрицательных значений.
Функция экспоненциальных единиц (ELU)
$$f(x) =\begin x \geq 0 \Rightarrow x \\ x < 0 \Rightarrow \alpha(e^x-1) \end$$
Наиболее удачная реализация функции ReLU за счет изменения отрицательной части. Функция использует логарифмическую кривую для отрицательных значений, из чего следуют ее преимущества:
- более плавное сглаживание для выходных значений
- нет проблемы Dying ReLU. За счет этого веса и смещения движутся в нужном направлении.
Из недостатков выделяется увеличенное время вычислений из-за экспоненциальной сложности операций, и чаще всего возникает взрыв градиента.
SELU (Scaled Exponential Linear Unit)
$$f(x, \alpha) = \lambda \begin x \geq 0 \Rightarrow x \\ x < 0 \Rightarrow \alpha(e^x-1) \end$$
Расшифровка звучит как «масштабированная экспоненциальная линейная единица». Принцип работы этой функции активации заключается в том, что она обеспечивает внутреннюю нормализацию данных в слоях регулируя среднее значение и дисперсию.
В отличии от ReLU умеет работать с отрицательными значениями.
Нормализация данных происходит за счет предопределенных констант альфа α и лямбда λ, и таким образом сеть сходится быстрее.
Данная функция является относительно новой, но уже зарекомендовала себя в архитектурах CNN и RNN.
GELU (Gaussian Error Linear Unit)
Линейная единица ошибки Гаусса, GELU — сочетает в себе Dropout, Zoneout и ReLU. Активно применятся для работы с НЛП архитектурами (BERT, ROBERTa, ALBERT), а также в задачах компьютерного зрения, обработки естественного языка и распознавания речи.
Принцип работы схож с SELU, но для работы выбрана кумулятивная функция стандартного нормального распределения Бернулли, так как входные данные имеют особенность следовать нормальному распределению.
Swish
or
$$f(x) = x * sigmoid(x)$$
Функция активации разработанная специалистами Google. Используется в глубоких сетях для классификации изображений, машинного перевода.
Имеет ограничение по оси Y для отрицательных значений X. Но не обнуляет отрицательные значения, как функция ReLU. Другими словами, направление меняется плавно от 0 к значениям x
Второй положительный аспект, функция обнуляет только большие отрицательные значения, значения находящиеся ближе к 0 участвуют в расчетах.
Как правильно выбрать функцию активации?
Все зависит от решаемой задачи прогнозирования. Далее — эксперименты. Как правило, начинать можно с универсальной функции ReLU. И пробовать другие варианты, если ReLU не дает оптимальных результатов обучения НС, например процент ошибки на тестовых данных.
Краткие рекомендации по выбору функций активации:
- ReLU следует использовать только для скрытых слоев
- Sigmoid и Tahn наоборот не рекомендуются к использованию в скрытых слоях. Это приводит к проблеме исчезающего градиента
- Swish используется в сетях, где количество слоев больше 40
Для выходных слоев выбор функции активации зависит от решаемой задачи
- линейная функция — для задач регрессии
- двоичная и многоуровневая (не взаимоисключающие классы) классификации — Sigmoid
- классификация из нескольких классов (взаимоисключающие классы) — Softmax
Для скрытых слоев выбор будет зависеть от архитектуры
- CNN (сверточная сеть) — ReLU
- RNN (рекуррентная сеть) — Sigmoid и/или Tahn
ReLU — самая часто используемая функция активации.
Выбранная функция активации практически неизменна во всех скрытых слоях.
Неправильно выбранная функция активации может быть причиной исчезающего градиента или его взрыва.
Для выходного слоя выбор функции активации зависит от задачи. Регрессия — ReLU, классификация — Softmax или Sigmoid.
При написании статьи были использованы метриалы v7labs и Университет Искуственного Интеллекта
© 2023. При использовании материалов ссылка на источник будет плюсом в карму
Глубокое обучение искусственных нейронных сетей. [Часть 2]
Эти функции определяют, должен ли нейрон быть активирован или нет. Он преобразует сумму взвешенных входных данных от узла в выходное значение, которое будет передано следующему слою в качестве вывода.
Необходимость функции активации
- Добавить нелинейность нейронной сети; поскольку добавление входных данных снова и снова будет означать только линейную связь между входными данными, и обучения не будет.
- Выбор функции активации оказывает большое влияние на возможности и производительность нейронной сети, и в разных частях модели могут использоваться разные функции активации.
Типы функции активации
- Двоичная ступенчатая функция
Бинарная ступенчатая функция зависит от порогового значения, которое определяет, должен ли нейрон быть активирован или нет.
Вход, подаваемый в функцию активации, сравнивается с определенным порогом; если вход больше, чем он, то нейрон активируется, в противном случае он деактивируется, что означает, что его выход не передается на следующий скрытый слой. Градиент ступенчатой функции равен нулю, что создает помеху в процессе обратного распространения.
- Бинарная сигмовидная функция
Также известна как функция логистики/сквоша. Функция находится в диапазоне от 0 до 1, имеющей S-образную форму. Он используется в выходном слое DNN и используется для вывода на основе вероятности. Поскольку вероятность чего-либо существует только в диапазоне от 0 до 1, сигмовидная является правильным выбором из-за ее диапазона.
Также известна как функция логистики/сквоша. Функция находится в диапазоне от 0 до 1, имеющей S-образную форму. Он используется в выходном слое DNN и используется для вывода на основе вероятности. Поскольку вероятность чего-либо существует только в диапазоне от 0 до 1, сигмовидная является правильным выбором из-за ее диапазона.
Недостатки: резкие влажные градиенты во время обратного распространения, насыщение градиента, медленная сходимость и ненулевой центрированный вывод, что приводит к тому, что обновления градиента распространяются в разных направлениях.
Как видно из рисунка выше, значения градиента значимы только для диапазона от -3 до 3 , а в других областях график становится более плоским. Это означает, что для значений больше 3 или меньше -3 функция будет иметь очень маленькие градиенты. Когда значение градиента приближается к нулю, сеть перестает обучаться и страдает от проблемы исчезающего градиента .
- Биполярная сигмовидная функция
Диапазон значений сигмовидных функций может варьироваться в зависимости от приложения. Однако чаще всего используется диапазон (-1,+1).
- Функция Таня (гиперболический тангенс)
Он имеет ту же S-образную форму (сигмовидная/логистическая функция активации) с разницей в диапазоне выходных данных от -1 до 1. Чем больше входной сигнал (более положительный), тем ближе выходное значение будет к 1,0, тогда как чем меньше вход (более отрицательный), тем ближе выход будет к -1,0. Он носит биполярный характер. Это широко распространенная функция активации для особого типа нейронной сети, известной как сеть обратного распространения ошибки.
Поскольку эта функция центрирована по нулю, это упрощает моделирование входных данных, которые имеют сильно отрицательные, нейтральные и сильно положительные значения.
- Функция ReLU
Наиболее широко используемая функция активации в глубоком обучении. Он обеспечивает превосходство в производительности и обобщении, а также повышает общую скорость вычислений и связи, поскольку он не вычисляет экспоненты и деления. Его очень легко оптимизировать, поэтому на практике он всегда предпочтительнее сигмовидной функции.
Недостатки: он также сталкивается с проблемой исчезающих градиентов, аналогичной сигмовидной функции активации.
Проблема Dying ReLU: отрицательная сторона графика делает значение градиента равным нулю. По этой причине в процессе обратного распространения веса и смещения для некоторых нейронов не обновляются. Это может создать мертвые нейроны, которые никогда не активируются. Все отрицательные входные значения немедленно становятся равными нулю, что снижает способность модели правильно подбирать или обучать данные.
- Дырявая функция ReLU
Эта функция является улучшенной версией решения ReLUto, которая используется для решения проблемы Dying ReLU , поскольку она также имеет небольшой положительный наклон в отрицательной области. Он также обеспечивает обратное распространение для отрицательных значений, а также является таким же выгодным, как и у ReLU.
Сделав эту небольшую модификацию для отрицательных входных значений, градиент левой части графика оказывается ненулевым значением. Следовательно, мы больше не столкнемся с мертвыми нейронами в этой области.
- Параметрическая функция ReLU
Еще одна функция, направленная на решение проблемы Dying ReLU. Эта функция предоставляет наклон отрицательной части функции в качестве аргумента a. Выполняя обратное распространение, изучают наиболее подходящее значение a.
Параметризованная функция ReLU используется, когда дырявая функция ReLU по-прежнему не справляется с решением проблемы мертвых нейронов, и соответствующая информация не может быть успешно передана на следующий уровень.
Ограничение этой функции состоит в том, что она может работать по-разному для разных задач в зависимости от значения параметра наклона a.
- Экспоненциальные линейные единицы (ELU)
Это уменьшает смещения смещения, приближая среднюю активацию к нулю во время обучения, ELU представляет собой хорошую альтернативу ReLU. Ограничение ELU состоит в том, что ELU не центрирует значения на нуле.
ELU является сильной альтернативой ReLU из-за следующих преимуществ:
- ELU медленно сглаживается до тех пор, пока его выход не станет равным -α, тогда как RELU резко сглаживается.
- Избегает проблемы мертвого ReLU, вводя логарифмическую кривую для отрицательных значений ввода. Это помогает сети подтолкнуть веса и смещения в правильном направлении.
- Функция Софтмакс
Это функция, которая превращает вектор K действительных значений в вектор K действительных значений, сумма которых равна 1. Входные значения могут быть положительными, отрицательными, нулевыми или больше единицы, но softmax преобразует их в значения от 0 до 1, так что их можно интерпретировать как вероятности.
Если один из входных данных мал или отрицателен, softmax превращает его в маленькую вероятность, а если вход большой, то он превращает его в большую вероятность, но она всегда будет оставаться между 0 и 1. Чаще всего используется в качестве функции активации для последнего слоя нейронной сети в случае многоклассовой классификации.
Он вычисляет относительные вероятности. Подобно сигмовидной/логистической функции активации, функция SoftMax возвращает вероятность каждого класса.
Выходы softmax меньше 1, а сумма выходов функции softmax равна 1. Таким образом, можно сказать, что выход функции softmax представляет собой распределение вероятностей . Благодаря этому свойству функция Softmax считается функцией активации в нейронных сетях и алгоритмах, таких как полиномиальная логистическая регрессия. Обратите внимание, что для бинарной логистической регрессии используемой функцией активации является сигмовидная функция.
Это одна из первых составных функций активации, предложенная комбинацией сигмовидной функции активации и входной функции для достижения гибридной функции активации . К свойствам функции Swish относятся гладкость, немонотонность, ограниченность снизу и неограниченность сверху.
- Гауссовская линейная единица ошибки (GELU)
Функция активации Gaussian Error Linear Unit (GELU) совместима с BERT, ROBERTa, ALBERT и другими ведущими моделями НЛП. Эта функция активации мотивирована сочетанием свойств отсева, зонирования и ReLU.
- Масштабированная экспоненциальная линейная единица
SELU был определен в самонормализующихся сетях и обеспечивает внутреннюю нормализацию, что означает, что каждый слой сохраняет среднее значение и дисперсию по сравнению с предыдущими слоями. SELU включает эту нормализацию, регулируя среднее значение и дисперсию.
SELU имеет как положительные, так и отрицательные значения для смещения среднего значения, что было невозможно для функции активации ReLU, поскольку она не может выводить отрицательные значения.
Градиенты можно использовать для регулировки дисперсии. Для увеличения функции активации требуется область с градиентом больше единицы. SELU имеет предварительно определенные значения альфа α и лямбда λ.
Вот основное преимущество SELU перед ReLU:
- Внутренняя нормализация выполняется быстрее, чем внешняя нормализация, что означает, что сеть сходится быстрее.
- SELU является относительно новой функцией активации и нуждается в дополнительных статьях по таким архитектурам, как CNN и RNN, где она сравнительно исследуется.
Softmax
Softmax — это логистическая функция для многомерного случая. Интересно, что русскоязычного термина для этой функции так и не появилось и в русской статье википедии она так и зовётся — softmax.
Что такое “для многомерного случая”? Это означает, что функцию применяют не к отдельному значению, а к вектору. Например, её можно использовать в том случае, когда стоит задача многоклассовой классификации. Для подобной классификации сеть строят таким образом, что на последнем слое количество нейронов оказывается равным количеству искомых классов. При этом каждый нейрон должен выдавать значение вероятности принадлежности объекта к классу, то есть значение между нулём и единицей, а все нейроны в сумме должны дать единицу.
Вот так выглядит формула softmax:
большая K здесь указывает на количество классов.
Для того, чтобы было понятно, как работает эта формула, рассмотрим простой пример, в котором нужно найти принадлежность объекта к одному из пяти классов. Допустим, на последнем слое мы посчитали z по формуле:
и получили вот такой вектор значений:
Сначала посчитаем, знаменатель формулы, то есть, просуммируем все элементы вектора:
значение при этом окажется приблизительно равным 30.62:
Остаётся каждое из значений вектора поделить на получившуюся сумму, что на выходе даст вот такой вектор:
В итоге, с вероятностью 66% объект из этого примера можно отнести к третьему классу (если счёт начинать с нуля).
*Для простоты восприятия все значения в примере округлены, поэтому в сумме получается чуть-чуть больше единицы.