Фаза 01 · урок 06

Вероятность и распределения

Цель урока: Классификатор выдаёт [0.03, 0.91, 0.06] . Языковая модель выбирает следующее слово из 50 000 кандидатов. Диффузионная модель генерирует изображения, выполняя выборку из изученных распределений. Всё это — вероятность в действии.

Текущий релиз AlexBred.com: первые 100 уроков русскоязычной программы.

Курс
AI Engineering from Scratch
Фаза
Математические основы
Чтение
13 мин.
Проверено
Содержание урока
  1. Цели обучения
  2. Проблема
  3. Концепция
  4. События, пространства исходов и вероятность
  5. Условная вероятность и независимость
  6. Функции массы вероятности и функции плотности вероятности
  7. Распространённые распределения
  8. Математическое ожидание и дисперсия
  9. Совместные и маргинальные распределения
  10. Почему нормальное распределение встречается повсюду
  11. Логарифмические вероятности
  12. Softmax как распределение вероятностей
  13. Выборка
  14. Создайте это
  15. Шаг 1: Основы вероятности
  16. Шаг 2: PMF и PDF с нуля
  17. Шаг 3: Математическое ожидание и дисперсия
  18. Шаг 4: Выборка из распределений
  19. Шаг 5: Softmax и логарифмические вероятности
  20. Шаг 6: Демонстрация Центральной предельной теоремы
  21. Шаг 7: Визуализация
  22. Используйте это
  23. Упражнения
  24. Ключевые термины
  25. Дополнительные материалы

Вероятность — язык, которым ИИ выражает неопределённость.

Тип: Изучение Язык: Python Предварительные требования: Фаза 1, уроки 01–04 Время: ~75 минут

Цели обучения

  • Реализовать с нуля PMF и PDF для распределений Бернулли, категориального, Пуассона, равномерного и нормального
  • Вычислять математическое ожидание, дисперсию и использовать Центральную предельную теорему, чтобы объяснить, почему доминируют гауссовы распределения
  • Построить функции softmax и log-softmax с приёмом численной устойчивости (вычитание максимального логита)
  • Рассчитать функцию потерь кросс-энтропии по логитам и связать её с отрицательным логарифмическим правдоподобием

Проблема

Классификатор выдаёт [0.03, 0.91, 0.06]. Языковая модель выбирает следующее слово из 50 000 кандидатов. Диффузионная модель генерирует изображения, выполняя выборку из изученных распределений. Всё это — вероятность в действии.

Каждый прогноз, который делает модель, — распределение вероятностей. Каждая функция потерь измеряет, насколько предсказанное распределение далеко от истинного. Каждый шаг обучения корректирует параметры, чтобы одно распределение стало больше похоже на другое. Без вероятности нельзя прочитать ни одну статью по ML, отладить ни одну модель или понять, почему потери при обучении равны NaN.

Концепция

События, пространства исходов и вероятность

Пространство исходов S — множество всех возможных результатов. Событие — подмножество пространства исходов. Вероятность сопоставляет событиям числа от 0 до 1.

Подбрасывание монеты:
  S = {H, T}
  P(H) = 0.5,  P(T) = 0.5

Один бросок игральной кости:
  S = {1, 2, 3, 4, 5, 6}
  P(чётное) = P({2, 4, 6}) = 3/6 = 0.5

Три аксиомы определяют всю теорию вероятностей:

  1. P(A) >= 0 для любого события A
  2. P(S) = 1 (что-то обязательно происходит)
  3. P(A или B) = P(A) + P(B), когда A и B не могут произойти одновременно

Всё остальное (теорема Байеса, ожидания, распределения) следует из этих трёх правил.

Условная вероятность и независимость

P(A|B) — вероятность A при условии, что произошло B.

P(A|B) = P(A и B) / P(B)

Пример: колода карт
  P(Король | Фигурная карта) = P(Король и Фигурная карта) / P(Фигурная карта)
                              = (4/52) / (12/52)
                              = 4/12 = 1/3

Два события независимы, когда знание об одном ничего не говорит о другом:

Независимость:  P(A|B) = P(A)
Эквивалентно:   P(A и B) = P(A) * P(B)

Подбрасывания монеты независимы. Вытягивание карт без возвращения — нет.

Функции массы вероятности и функции плотности вероятности

Дискретные случайные величины имеют функцию массы вероятности (PMF). У каждого исхода есть конкретная вероятность, которую можно непосредственно прочитать.

PMF: P(X = k)

Честная игральная кость:
  P(X = 1) = 1/6
  P(X = 2) = 1/6
  ...
  P(X = 6) = 1/6

  Сумма всех вероятностей = 1

Непрерывные случайные величины имеют функцию плотности вероятности (PDF). Плотность в отдельной точке не является вероятностью. Вероятность получают интегрированием плотности по интервалу.

PDF: f(x)

P(a <= X <= b) = интеграл f(x) от a до b

f(x) может быть больше 1 (плотность, а не вероятность)
интеграл f(x) dx от -inf до +inf = 1

Это различие важно в ML. Выходы классификации — PMF (дискретные варианты выбора). Латентные пространства VAE используют PDF (непрерывные).

Распространённые распределения

Бернулли: одно испытание, два исхода. Моделирует бинарную классификацию.

P(X = 1) = p
P(X = 0) = 1 - p
Mean = p,  Variance = p(1-p)

Категориальное: одно испытание, k исходов. Моделирует многоклассовую классификацию (выход softmax).

P(X = i) = p_i,  where sum of p_i = 1
Пример: P(кот) = 0.7,  P(собака) = 0.2,  P(птица) = 0.1

Равномерное: все исходы равновероятны. Используется для случайной инициализации.

Дискретное: P(X = k) = 1/n для k в {1, ..., n}
Непрерывное: f(x) = 1/(b-a) для x в [a, b]

Нормальное (гауссово): колоколообразная кривая. Параметризуется средним (mu) и дисперсией (sigma^2).

f(x) = (1 / sqrt(2*pi*sigma^2)) * exp(-(x - mu)^2 / (2*sigma^2))

Стандартное нормальное: mu = 0, sigma = 1
  68% данных в пределах 1 sigma
  95% в пределах 2 sigma
  99.7% в пределах 3 sigma

Пуассона: число редких событий за фиксированный интервал. Моделирует интенсивности событий.

P(X = k) = (lambda^k * e^(-lambda)) / k!
Mean = lambda,  Variance = lambda

Математическое ожидание и дисперсия

Математическое ожидание — средний исход с учётом весов.

Дискретное: E[X] = сумма x_i * P(X = x_i)
Непрерывное: E[X] = интеграл x * f(x) dx

Дисперсия измеряет разброс вокруг среднего.

Var(X) = E[(X - E[X])^2] = E[X^2] - (E[X])^2
Стандартное отклонение = sqrt(Var(X))

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

Совместные и маргинальные распределения

Совместное распределение P(X, Y) описывает две случайные величины вместе.

Пример совместной PMF (X = погода, Y = зонтик):

Y=0 (нет зонтика) Y=1 (зонтик) Маргинальное P(X)
X=0 (солнце) 0.40 0.10 P(X=0) = 0.50
X=1 (дождь) 0.05 0.45 P(X=1) = 0.50
Маргинальное P(Y) P(Y=0) = 0.45 P(Y=1) = 0.55 1.00

Маргинальное распределение суммирует по другой переменной:

P(X = x) = сумма по всем y от P(X = x, Y = y)

Суммы строк и столбцов в таблице выше — это маргинальные распределения.

Почему нормальное распределение встречается повсюду

Центральная предельная теорема: сумма (или среднее) многих независимых случайных величин сходится к нормальному распределению независимо от исходного распределения.

Бросок 1 кости: равномерное распределение (плоское)
Среднее 2 костей: треугольное (с пиком)
Среднее 30 костей: почти идеальная колоколообразная кривая

Это работает для ЛЮБОГО исходного распределения.

Именно поэтому:

  • Ошибки измерений приблизительно нормальны (много малых независимых источников)
  • Для инициализации весов в нейронных сетях используют нормальные распределения
  • Шум градиента в SGD приблизительно нормален (сумма градиентов многих выборок)
  • Нормальное распределение — распределение максимальной энтропии при заданных среднем и дисперсии

Логарифмические вероятности

Необработанные вероятности создают численные проблемы. Произведение множества малых вероятностей быстро становится меньше наименьшего представимого числа и обращается в ноль.

P(предложение) = P(слово1) * P(слово2) * ... * P(слово_n)
               = 0.01 * 0.003 * 0.02 * ...
               -> 0.0 (потеря значимости после ~30 множителей)

Логарифмические вероятности решают эту проблему. Умножения становятся сложениями.

log P(предложение) = log P(слово1) + log P(слово2) + ... + log P(слово_n)
                    = -4.6 + -5.8 + -3.9 + ...
                    -> конечное число (без потери значимости)

Правила:

  • log(a * b) = log(a) + log(b)
  • логарифмические вероятности всегда <= 0 (так как 0 < P <= 1)
  • чем более отрицательно значение, тем оно менее вероятно
  • потери кросс-энтропии — отрицательный логарифм вероятности правильного класса

Softmax как распределение вероятностей

Нейронные сети выдают необработанные оценки (логиты). Softmax преобразует их в корректное распределение вероятностей.

softmax(z_i) = exp(z_i) / sum(exp(z_j) for all j)

Свойства:
  - Все выходы находятся в (0, 1)
  - Сумма всех выходов равна 1
  - Сохраняет относительный порядок входов
  - exp() усиливает различия между логитами

Приём softmax: перед возведением в экспоненту вычтите максимальный логит, чтобы предотвратить переполнение.

z = [100, 101, 102]
exp(102) = переполнение

z_shifted = z - max(z) = [-2, -1, 0]
exp(0) = 1  (безопасно)

Тот же результат, без переполнения.

Log-softmax объединяет softmax и логарифм для численной устойчивости. PyTorch использует это внутри при вычислении потерь кросс-энтропии.

Выборка

Выборка означает извлечение случайных значений из распределения. В ML:

  • Dropout случайно выбирает, какие нейроны обнулить
  • Аугментация данных выбирает случайные преобразования
  • Языковые модели выбирают следующий токен из предсказанного распределения
  • Диффузионные модели выбирают шум и постепенно устраняют его

Для выборки из произвольных распределений требуются такие техники, как выборка методом обратного преобразования, выборка методом отклонения или приём репараметризации (используемый в VAE).

gaussian-pdf

Создайте это

Шаг 1: Основы вероятности

import math
import random

def factorial(n):
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result

def combinations(n, k):
    return factorial(n) // (factorial(k) * factorial(n - k))

def conditional_probability(p_a_and_b, p_b):
    return p_a_and_b / p_b

p_king_given_face = conditional_probability(4/52, 12/52)
print(f"P(King | Face card) = {p_king_given_face:.4f}")

Шаг 2: PMF и PDF с нуля

def bernoulli_pmf(k, p):
    return p if k == 1 else (1 - p)

def categorical_pmf(k, probs):
    return probs[k]

def poisson_pmf(k, lam):
    return (lam ** k) * math.exp(-lam) / factorial(k)

def uniform_pdf(x, a, b):
    if a <= x <= b:
        return 1.0 / (b - a)
    return 0.0

def normal_pdf(x, mu, sigma):
    coeff = 1.0 / (sigma * math.sqrt(2 * math.pi))
    exponent = -0.5 * ((x - mu) / sigma) ** 2
    return coeff * math.exp(exponent)

Шаг 3: Математическое ожидание и дисперсия

def expected_value(values, probabilities):
    return sum(v * p for v, p in zip(values, probabilities))

def variance(values, probabilities):
    mu = expected_value(values, probabilities)
    return sum(p * (v - mu) ** 2 for v, p in zip(values, probabilities))

die_values = [1, 2, 3, 4, 5, 6]
die_probs = [1/6] * 6
mu = expected_value(die_values, die_probs)
var = variance(die_values, die_probs)
print(f"Die: E[X] = {mu:.4f}, Var(X) = {var:.4f}, SD = {var**0.5:.4f}")

Шаг 4: Выборка из распределений

def sample_bernoulli(p, n=1):
    return [1 if random.random() < p else 0 for _ in range(n)]

def sample_categorical(probs, n=1):
    cumulative = []
    total = 0
    for p in probs:
        total += p
        cumulative.append(total)
    samples = []
    for _ in range(n):
        r = random.random()
        for i, c in enumerate(cumulative):
            if r <= c:
                samples.append(i)
                break
    return samples

def sample_normal_box_muller(mu, sigma, n=1):
    samples = []
    for _ in range(n):
        u1 = random.random()
        u2 = random.random()
        z = math.sqrt(-2 * math.log(u1)) * math.cos(2 * math.pi * u2)
        samples.append(mu + sigma * z)
    return samples

Шаг 5: Softmax и логарифмические вероятности

def softmax(logits):
    max_logit = max(logits)
    shifted = [z - max_logit for z in logits]
    exps = [math.exp(z) for z in shifted]
    total = sum(exps)
    return [e / total for e in exps]

def log_softmax(logits):
    max_logit = max(logits)
    shifted = [z - max_logit for z in logits]
    log_sum_exp = max_logit + math.log(sum(math.exp(z) for z in shifted))
    return [z - log_sum_exp for z in logits]

def cross_entropy_loss(logits, target_index):
    log_probs = log_softmax(logits)
    return -log_probs[target_index]

Шаг 6: Демонстрация Центральной предельной теоремы

def demonstrate_clt(dist_fn, n_samples, n_averages):
    averages = []
    for _ in range(n_averages):
        samples = [dist_fn() for _ in range(n_samples)]
        averages.append(sum(samples) / len(samples))
    return averages

Шаг 7: Визуализация

import matplotlib.pyplot as plt

xs = [mu + sigma * (i - 500) / 100 for i in range(1001)]
ys = [normal_pdf(x, mu, sigma) for x, mu, sigma in ...]
plt.plot(xs, ys)

Полные реализации со всеми визуализациями находятся в code/probability.py.

Используйте это

С NumPy и SciPy всё перечисленное выше сводится к однострочным вызовам:

import numpy as np
from scipy import stats

normal = stats.norm(loc=0, scale=1)
samples = normal.rvs(size=10000)
print(f"Mean: {np.mean(samples):.4f}, Std: {np.std(samples):.4f}")
print(f"P(X < 1.96) = {normal.cdf(1.96):.4f}")

logits = np.array([2.0, 1.0, 0.1])
from scipy.special import softmax, log_softmax
probs = softmax(logits)
log_probs = log_softmax(logits)
print(f"Softmax: {probs}")
print(f"Log-softmax: {log_probs}")

Вы создали всё это с нуля. Теперь вы знаете, что делают вызовы библиотеки.

Упражнения

  1. Реализуйте выборку методом обратного преобразования для экспоненциального распределения. Проверьте её, сгенерировав 10 000 значений и сравнив гистограмму с истинной PDF.

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

  3. Вычислите потери кросс-энтропии для 5-классового классификатора, который выдаёт логиты [2.0, 0.5, -1.0, 3.0, 0.1], когда правильный класс имеет индекс 3. Затем проверьте ответ с помощью nn.CrossEntropyLoss из PyTorch.

  4. Напишите функцию, которая принимает список логарифмических вероятностей и возвращает наиболее вероятную последовательность, суммарную логарифмическую вероятность и эквивалентную необработанную вероятность. Протестируйте её на предложении из 50 слов, где вероятность каждого слова равна 0.01.

Ключевые термины

Термин Как обычно говорят Что это на самом деле означает
Пространство исходов «Все возможности» Множество S всех возможных результатов эксперимента
PMF «Функция вероятности» Функция, задающая точную вероятность каждого дискретного исхода; их сумма равна 1
PDF «Кривая вероятности» Функция плотности для непрерывных величин. Интегрируйте её по интервалу, чтобы получить вероятность
Условная вероятность «Вероятность при известном условии» P(A|B) = P(A и B) / P(B). Основа байесовского мышления и теоремы Байеса
Независимость «Они не влияют друг на друга» P(A и B) = P(A) * P(B). Знание об одном событии ничего не говорит о другом
Математическое ожидание «Среднее» Взвешенная по вероятностям сумма всех исходов. Функция потерь — это математическое ожидание
Дисперсия «Насколько велик разброс» Ожидаемое значение квадрата отклонения от среднего. Высокая дисперсия = шумные, нестабильные оценки
Нормальное распределение «Колоколообразная кривая» f(x) = (1/sqrt(2pisigma^2)) * exp(-(x-mu)^2/(2*sigma^2)). Встречается повсюду благодаря ЦПТ
Центральная предельная теорема «Средние становятся нормальными» Среднее многих независимых выборок сходится к нормальному распределению независимо от источника
Совместное распределение «Две переменные вместе» P(X, Y) описывает вероятность каждой комбинации исходов X и Y
Маргинальное распределение «Просуммировать по другой переменной» P(X) = sum_y P(X, Y). Восстанавливает распределение одной переменной из совместного
Логарифмическая вероятность «Логарифм вероятности» log P(x). Превращает произведения в суммы, предотвращая численную потерю значимости в длинных последовательностях
Softmax «Преобразовать оценки в вероятности» softmax(z_i) = exp(z_i) / sum(exp(z_j)). Преобразует вещественные логиты в корректное распределение вероятностей
Кросс-энтропия «Функция потерь» -sum(p_true * log(p_predicted)). Измеряет различие двух распределений. Чем меньше, тем лучше
Логиты «Необработанные выходы модели» Ненормированные оценки до softmax. Названы в честь логистической функции
Выборка «Извлечение случайных значений» Генерация значений в соответствии с распределением вероятностей. Так модели создают выходные данные

Дополнительные материалы


Источник: Probability and Distributions — оригинал Навигация: назад: 01.05 — Правило цепочки и автоматическое дифференцирование · Фаза 1 — Математические основы · Полный каталог · далее: 01.07 — Теорема Байеса и статистическое мышление.