Функции потерь и градиенты

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

Представьте, что вы учитесь бросать баскетбольный мяч. После каждого броска вы наблюдаете, попал ли мяч в корзину, отклонился влево или вправо. Разрыв между этим наблюдаемым результатом и идеальным броском — это вашапотеря. Чтобы в следующий раз бросать точнее, вы корректируете свою позу и силу в соответствии с направлением и величиной этого отклонения. Этонаправление и величина корректировкиподобныградиенту。

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


I. Функции потерь: табель успеваемости модели

1.1 Что такое функция потерь?

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

  • Ключевая роль: она даёт конкретную «оценку» качеству предсказаний модели. Чем ниже эта оценка, тем точнее предсказания модели; чем выше оценка, тем больше ошибка предсказания.
  • Аналогия: как на экзамене, «оценка» функции потерь — это экзаменационная оценка модели. Наша конечная цель — делать эту оценку (потери) всё ниже и ниже с помощью «обучения» (настройки параметров модели).

1.2 Примеры распространённых функций потерь

Разные задачи требуют разныхкритериев оценки. Вот две из самых базовых функций потерь:

Среднеквадратичная ошибка- Подходит для задач регрессии (прогнозирование непрерывных значений, например цен на дома, температуры)

Среднеквадратичная ошибка вычисляетсреднее квадратов разностей между предсказанными значениями и истинными значениями по всем образцам。

Формула: MSE = (1/n) * Σ(真实值ᵢ - 预测值ᵢ)²

  • n: количество образцов
  • Σ: символ суммирования
  • True valueᵢ: истинное значение i-го образца
  • Predicted valueᵢ: предсказанное моделью значение для i-го образца

Особенности: Поскольку в ней используется возведение в квадрат, она сильнее штрафует за крупные ошибки (когда ошибка равна 2, квадратичный вклад равен 4; когда ошибка равна 10, квадратичный вклад достигает 100).

Пример кода:

Пример

import numpy as np

# Предположим, у нас есть истинные и предсказанные значения для 5 образцов
y_true = np.array([3, -0.5, 2, 7, 4])      # Истинные значения
y_pred = np.array([2.5, 0.0, 2, 8, 5])     # Предсказанные значения

# Вычислить MSE вручную
n = len(y_true)
squared_errors = (y_true - y_pred) ** 2    # Вычислить квадратичную ошибку для каждого примера
mse_manual = np.sum(squared_errors) / n    # Суммировать и взять среднее
print(f"MSE рассчитан вручную: {mse_manual}")

# Проверить с помощью функции библиотеки sklearn
from sklearn.metrics import mean_squared_error
mse_sklearn = mean_squared_error(y_true, y_pred)
print(f"MSE рассчитан с помощью Sklearn: {mse_sklearn}")

Кросс-энтропийная потеря- Подходит для задач классификации (предсказание категорий, например, является ли изображение кошкой или собакой)

Кросс-энтропия измеряет разницу междураспределением вероятностей, предсказанным модельюии истинным распределением вероятностей. В бинарной классификации истинное распределение обычно[1, 0](это категория A) или[0, 1](относится к категории B).

Формула бинарной классификации (Log Loss): Log Loss = - (1/n) * Σ [真实值ᵢ * log(预测概率ᵢ) + (1 - 真实值ᵢ) * log(1 - 预测概率ᵢ)]

Интуитивное понимание: Когда истинная метка равна 1, мы надеемся, что вероятность, предсказанная моделью, также близка к 1. Если модель предсказывает очень низкую вероятность (например, 0.1) в этот момент, тоlog(0.1)это будет очень большое отрицательное число; умножение на предшествующий знак минус приводит к тому, что значение потерь становится очень большим, что указывает на серьёзный штраф.

Пример кода:

Пример

import numpy as np
from sklearn.metrics import log_loss

# Пример бинарной классификации: истинные метки (1 обозначает "да", 0 обозначает "нет")
y_true_binary = np.array([1, 0, 0, 1]) # Истинные классы: да, нет, нет, да
# Вероятность, предсказанная моделью для класса "да"
y_pred_prob = np.array([0.9, 0.1, 0.2, 0.8]) # Предсказанные вероятности: 0.9, 0.1, 0.2, 0.8

# Используйте sklearn для вычисления кросс-энтропийной потери (log loss)
ce_loss = log_loss(y_true_binary, y_pred_prob)
print(f"Кросс-энтропийная потеря (Log Loss): {ce_loss}")

II. Градиент: «компас», указывающий направление оптимизации

Теперь мы знаем, как оценивать модель (функция потерь). Следующий важнейший вопрос:как модель улучшает себя на основе этой оценки?Ответ — черезградиент。

2.1 Что такое градиент?

В машинном обучении модель обычно состоит из множествапараметров(иливесов). Мы можем рассматриватьфункцию потерь Lкак функцию от всех этих параметров:L(w1, w2, ..., wn)。

  • Градиент— это вектор, образованныйчастными производнымиотфункции потерь по каждому параметру.
  • Математическое представление:∇L = [∂L/∂w1, ∂L/∂w2, ..., ∂L/∂wn]
  • Основное значение:
    1. Направление: направление, на которое указывает вектор градиента, — это направление, в котором функция потерьвозрастает быстрее всегов этой точке.
    2. Величина: абсолютное значение каждой частной производной отражаетчувствительность。

2.2 Почему градиенты могут направлять оптимизацию?

Наша цель —минимизировать функцию потерь. Поскольку градиент указывает в направлении, где потери возрастают быстрее всего, его противоположное направление-∇Lестественно является тем, где потериубывают быстрее всего.

Процесс оптимизации (градиентный спуск) можно наглядно представить так::

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

Этот процесс можно обобщить следующей блок-схемой:

2.3 Простой пример градиентного спуска

Возьмём очень простой пример — линейную модель только с одним параметромwчтобы продемонстрировать градиентный спуск.

Предположим, наша функция потерь равнаL(w) = w². Очевидно, когдаw = 0, потери минимальны.

  • Вычисление градиента:∇L = dL/dw = 2w
  • Формула обновления параметров:w_new = w_old - η * (2 * w_old)
    • ηДаСкорость обучения, определяет, насколько велик каждый шаг.

Пример

import numpy as np
import matplotlib.pyplot as plt

# Определите функцию потерь L(w) = w^2
def loss(w):
    return w ** 2

# Определите градиент dL/dw = 2*w
def gradient(w):
    return 2 * w

# Алгоритм градиентного спуска
def gradient_descent(start_w, learning_rate, iterations):
    w = start_w
    w_history = [w]  # Записывайте историю изменений w
    loss_history = [loss(w)]  # Записывайте историю изменений потерь

    for i in range(iterations):
        grad = gradient(w)  # Вычислите градиент в текущей точке
        w = w - learning_rate * grad  # Обновите параметры вдоль направления отрицательного градиента
        w_history.append(w)
        loss_history.append(loss(w))

    return w_history, loss_history

# Запустить градиентный спуск: начать с w=5, скорость обучения 0.1, выполнить 20 итераций
w_start = 5.0
lr = 0.1
iters = 20
w_hist, loss_hist = gradient_descent(w_start, lr, iters)

print(f"Начальное w: {w_hist)
print(f"Итоговое w: {w_hist[-1]:.4f}, Итоговая потеря: {loss_hist[-1]:.4f}")

# Визуализировать процесс оптимизации
plt.figure(figsize=(12, 4))

# Рисунок 1: кривая функции потерь и путь оптимизации
plt.subplot(1, 2, 1)
w_vals = np.linspace(-6, 6, 100)
plt.plot(w_vals, loss(w_vals), label='L(w) = w²')
plt.scatter(w_hist, loss_hist, c='red', s=20, label='Шаги градиентного спуска')
plt.plot(w_hist, loss_hist, 'r--', alpha=0.5)
plt.xlabel('Параметр w')
plt.ylabel('Потеря L(w)')
plt.title('Градиентный спуск для L(w)=w²')
plt.legend()
plt.grid(True)

# Рисунок 2: кривая снижения значения потерь по итерациям
plt.subplot(1, 2, 2)
plt.plot(range(len(loss_hist)), loss_hist, 'b-o')
plt.xlabel('Итерация')
plt.ylabel('Потери')
plt.title('Снижение потерь по итерациям')
plt.grid(True)

plt.tight_layout()
plt.show()

Запустите этот код, и вы увидите:

  1. На левом рисунке показано, как параметрwстартует с 5.0 и шаг за шагом «скатывается» по параболе, постепенно приближаясь к точке минимума 0.
  2. На правом рисунке показано, как значение потерь быстро уменьшается с ростом числа итераций.

III. Ключевые моменты и сводка взаимосвязей

Концепция Метафора Ключевая роль Ключевые моменты
Функция потерь Табель успеваемости / линейка измерения ошибки Количественно оценивать, насколько хороши или плохи предсказания модели. 1. Разные типы задач (регрессия, классификация) используют разные функции потерь.
2. Чем меньше значение потерь, тем лучше качество работы модели.
Градиент Компас / направление самого крутого спуска Показывает, как следует скорректировать каждый параметр модели, чтобы быстрее всего уменьшить потери. 1. Это вектор частных производных функции потерь по всем параметрам.
2. Направление отрицательного градиента— это направление, в котором потери уменьшаются быстрее всего.
Градиентный спуск Метод спуска с горы с завязанными глазами Использует информацию о градиенте для итеративного обновления параметров с целью минимизации потерь. 1. Скорость обученияЯвляется ключевым гиперпараметром; при слишком малом значении обучение идёт медленно, при слишком большом может не сойтись.
2. Это базовый алгоритм оптимизации для обучения большинства моделей машинного обучения.

Цепочка взаимосвязей между ними такова:: Модель делает предсказания → Функция потерь вычисляет ошибку → Вычисляется градиент ошибки по каждому параметру → Параметры обновляются в направлении отрицательного градиента → Модель улучшается → Повтор...

Другие расширения