Что такое softmax функция?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое softmax функция?
Softmax - это математическая функция, которая преобразует вектор вещественных чисел в вероятностное распределение. Каждый элемент на выходе находится в диапазоне (0, 1), и сумма всех элементов равна 1. Softmax часто используется в задачах многоклассовой классификации как выходной слой нейронной сети.
Математическое определение
Формула softmax для вектора z:
softmax(z_i) = exp(z_i) / Σ exp(z_j) для всех j
где:
- z - входной вектор логитов (raw scores)
- i - индекс текущего элемента
- exp() - экспоненциальная функция
- Σ exp(z_j) - сумма экспонент всех элементов
Пример вычисления
Представьте, что у нас есть вектор логитов z = [1.0, 2.0, 3.0] для трех классов:
import numpy as np
def softmax(z):
exp_z = np.exp(z)
softmax_z = exp_z / np.sum(exp_z)
return softmax_z
z = np.array([1.0, 2.0, 3.0])
probs = softmax(z)
print(f"Логиты: {z}")
print(f"Вероятности: {probs}")
print(f"Сумма вероятностей: {np.sum(probs)}") # Должна быть 1.0
# Вывод:
# Логиты: [1. 2. 3.]
# Вероятности: [0.09003057 0.24472847 0.66524096]
# Сумма вероятностей: 1.0
Заметим, что самый большой логит (3.0) получил наибольшую вероятность (0.665), что имеет смысл.
Числовая стабильность
Увеличенные значения в экспоненте могут привести к переполнению (overflow). Для этого используется трюк нормализации:
import numpy as np
def softmax_stable(z):
# Вычитаем максимум для численной стабильности
z_shifted = z - np.max(z)
exp_z = np.exp(z_shifted)
softmax_z = exp_z / np.sum(exp_z)
return softmax_z
# Пример с большими числами
z_large = np.array([1000.0, 1001.0, 1002.0])
# Без стабилизации могут быть NaN
try:
probs_unstable = np.exp(z_large) / np.sum(np.exp(z_large))
print(f"Нестабильный результат: {probs_unstable}")
except:
print("Переполнение!")
# Со стабилизацией работает корректно
probs_stable = softmax_stable(z_large)
print(f"Стабильный результат: {probs_stable}")
print(f"Сумма: {np.sum(probs_stable)}")
Softmax в нейронных сетях
import tensorflow as tf
import numpy as np
# Способ 1: Явный softmax слой
model = tf.keras.Sequential([
tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),
tf.keras.layers.Dense(10, activation='softmax') # Output layer
])
# Способ 2: Использование softmax в функции потерь
model = tf.keras.Sequential([
tf.keras.layers.Dense(128, activation='relu', input_shape=(784,)),
tf.keras.layers.Dense(10) # Без активации
])
# Скомбинируем logits с softmax и cross-entropy для стабильности
model.compile(
loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
optimizer='adam',
metrics=['accuracy']
)
Softmax vs Sigmoid
Softmax используется для многоклассовой классификации (один объект -> один класс из нескольких). Sigmoid используется для бинарной классификации или multilabel классификации (объект может принадлежать нескольким классам одновременно).
import numpy as np
# SOFTMAX - для одного класса из нескольких
def softmax(z):
exp_z = np.exp(z - np.max(z))
return exp_z / np.sum(exp_z)
# SIGMOID - для вероятности
def sigmoid(z):
return 1 / (1 + np.exp(-z))
z = np.array([1.0, 2.0, 3.0])
print("Softmax:", softmax(z)) # [0.09, 0.24, 0.67] - сумма = 1.0
print("Sigmoid:", sigmoid(z)) # [0.73, 0.88, 0.95] - независимые вероятности
Softmax и Cross-Entropy Loss
Cross-entropy часто используется в качестве функции потерь с softmax для многоклассовой классификации:
import numpy as np
from scipy.special import softmax
def cross_entropy_loss(y_true, logits):
# y_true - one-hot encoded вектор
# logits - выход последнего слоя до softmax
softmax_scores = softmax(logits)
# Берем логарифм вероятности истинного класса
loss = -np.log(softmax_scores[np.argmax(y_true)])
return loss
# Пример: 3 класса, истинный класс - 0
y_true = np.array([1, 0, 0]) # One-hot: класс 0
logits = np.array([2.0, 1.0, 0.1])
loss = cross_entropy_loss(y_true, logits)
print(f"Cross-entropy loss: {loss:.4f}")
# В TensorFlow это делается проще:
import tensorflow as tf
loss_fn = tf.keras.losses.CategoricalCrossentropy()
Практический пример: классификация изображений
import tensorflow as tf
from tensorflow.keras.datasets import mnist
# Загружаем данные
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(-1, 28*28) / 255.0
X_test = X_test.reshape(-1, 28*28) / 255.0
# Преобразуем целевую переменную в one-hot
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)
# Строим модель с softmax
model = tf.keras.Sequential([
tf.keras.layers.Dense(256, activation='relu', input_shape=(784,)),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax') # Softmax для 10 классов
])
model.compile(
loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy']
)
model.fit(X_train, y_train, epochs=10, validation_split=0.2)
# Предсказания - это вероятности для каждого класса
predictions = model.predict(X_test[:5])
print("Вероятности первых 5 примеров:")
print(predictions)
print("Предсказанные классы:", np.argmax(predictions, axis=1))
Основные свойства Softmax
- Вероятностное распределение: Каждый выход находится между 0 и 1, и сумма равна 1
- Дифференцируемость: Можно вычислить градиент для backpropagation
- Чувствительность к относительным разностям: Разница между z_i и z_j важнее, чем абсолютные значения
- Усиление экстремов: Больший логит получает экспоненциально большую вероятность
Когда использовать softmax
- Многоклассовая классификация (ровно один класс из нескольких)
- Последний слой нейронной сети для задач классификации
- Attention механизмы в трансформерах
- Вероятностные модели (например, language models)
Softmax - это фундаментальный компонент современного глубокого обучения, используемый практически во всех моделях классификации.