Вы подписаны на Машинное обучение доступно
Отлично! завершите оплату для полного доступа к Машинное обучение доступно
Снова приветствуем Вас! Вы успешно авторизовались
Успех! Аккаунт активирован, и Вы имеете полный доступ к контенту.
Софтмакс (Softmax)

Софтмакс (Softmax)

in

Софтмакс – функция, превращающая логиты (наборы чисел) в вероятности, причем сумма последних равна единице. Функция выводит в качестве результата вектор, представляющий распределения вероятностей списка потенциальных результатов. Это также основной элемент, используемый в задачах Классификации (Classification) Глубокого обучения (Deep Learning).

Функция превращает логиты [2.0, 1.0, 0.1] в вероятности [0.7, 0.2, 0.1]

В глубоком обучении термин "логитовый слой" обычно используется для последнего слоя Нейронной сети (Neural Network) задач классификации, которая преобразует необработанные значения прогноза в виде действительных чисел в диапазоне от [-∞, +∞]. Логиты – это необработанные результаты, полученные на последнем уровне нейронной сети до того, как произойдет активация.

Softmax превращает логиты в вероятности, получая экспоненту e каждого значения, а затем подвергая Нормализации (Normalization) каждое e, то есть разделяя на их сумму, чтобы сумма всех экспонент равнялась единице.

Как показано выше, входные данные Softmax являются выходными для Полносвязного слоя (Fully Connected Layer), непосредственно предшествующего ему, и являются выходными данными всей нейронной сети. Эти выходные данные представляют собой распределение вероятностей всех кандидатов в классы меток.

Softmax – это не черный ящик. Он состоит из двух компонентов: специальное число e для некоторой степени, деленной на определенную сумму.
y_i относится к каждому элементу в векторе логитов y. Для начала импортируем необходимые библиотеки:

import numpy as np

Создадим игрушечный логитовый слой:

logits = [2.0, 1.0, 0.1]
exps = [np.exp(i) for i in logits]

Мы используем np.exp(power), чтобы возвести число e (~2,718) к любой желаемой степени. Мы перебираем каждую степень i и вычисляем экспоненту. Результат сохраняется в списке под названием exps (экспоненты).

Почему бы просто не разделить каждый логит на их сумму? Зачем нужны экспоненты? Логиты – это логарифм шансов, он лежит в пределах от минус- до плюс-бесконечности. Когда логиты отрицательны или обладают разными знаками, правильной нормализации выполнить не удастся. Возведение в степень решает эту проблему.

print(np.exp(100))
print(np.exp(-100))
print(3.720076e-44 > 0)

Кстати, число Эйлера e также упрощает дальнейшие вычисления. Логарифм произведений можно легко превратить в суммы для удобного вычисления производной: log(a * b) = log(a) + log(b).

Замена i на logit – еще один подробный способ: exps = [np.exp (logit) for logit in logits. Обратите внимание на использование существительных во множественном и единственном числе. Это сделано намеренно.

Мы только что вычислили делимое функции Softmax. Для каждого логита мы взяли экспоненциальную степень e. Каждый преобразованный логит j необходимо нормализовать, чтобы сумма всех конечных результатов, которые являются вероятностями, была равна единице.

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

sum_of_exps = sum(exps)

Теперь мы готовы написать последнюю часть нашей функции Softmax: каждый преобразованный логит должен быть нормализован с помощью sum_of_exps:

softmax = [j/sum_of_exps for j in exps]

Мы захватываем каждый преобразованный логит, используя [j for j in exps], делим каждый j на sum_of_exps. Это нам список:

print(softmax)
print(sum(softmax))

Сумма элементов равна единице:

[0.6590011388859679, 0.2424329707047139, 0.09856589040931818]
1.0

Ноутбук, не требующий дополнительной настройки на момент написания статьи, можно скачать здесь.

Автор оригинальной статьи: Uniqtech