Линейная алгебра
Линейная алгебра в ML: синтез
GPT-4 за один forward pass выполняет более 1.8 триллиона матричных умножений. Внимание трансформера, embedding-слои, PCA для анализа данных, PageRank для поиска - каждый из этих инструментов есть прямое применение концепций линейной алгебры из предыдущих уроков.
- Трансформер: Attention(Q,K,V) = softmax(QKᵀ/√d)V - три матричных умножения на head
- Embeddings: токен → строка матрицы E размером vocab × d_model
- PCA: центрирование + SVD; 30 компонент объясняют 95% вариации лиц в датасете AT&T
- PageRank: собственный вектор матрицы 50B страниц - найден степенной итерацией за ~50 шагов
- GPU GEMM: всё обучение ML сводится к операции C = A·B на Tensor Cores
**Нейросеть на 4 слоя - это ровно 4 матричных умножения с нелинейностями между ними.** Attention в трансформере - это три матрицы (Q, K, V), скалярное произведение и softmax. PCA - это SVD с одним вызовом. Embeddings - это строки матрицы весов. Весь современный ML - это один большой курс линейной алгебры, запущенный на GPU. Этот урок - не новые концепции, а финальная сборка: где именно каждая идея курса живёт в реальных системах.
**Цель урока**: не пересказ применений, а понимание структуры. После этого урока любая ML-статья с формулами читается как знакомый текст, а не как иностранный язык.
Нейросеть: цепочка линейных слоёв
Каждый линейный слой нейросети - это умножение входного вектора на матрицу весов. Нелинейность (ReLU, GELU) вставлена между слоями - иначе произведение любого числа матриц осталось бы одной матрицей, и вся глубина сети была бы бесполезной.
**Почему нужны нелинейности**: произведение двух линейных отображений - линейное отображение. Три матрицы W₃W₂W₁ = одна матрица W. Без ReLU/GELU вся "глубина" нейросети - иллюзия, один эффективный слой. Нелинейность ломает это равенство и делает глубину реальной.
Attention: матричное произведение в сердце трансформера
GPT, BERT, LLaMA, Claude - все работают на механизме attention. Под капотом - три матрицы весов, два матричных умножения и softmax. Это буквально несколько строк линейной алгебры.
**Q·Kᵀ - это матрица скалярных произведений**: элемент [i,j] - насколько запрос i-го токена совпадает с ключом j-го. Это в точности cosine similarity (без нормировки), которое разбиралось в уроке про скалярное произведение. Трансформеры буквально строятся на скалярных произведениях.
Embeddings: матрица весов как словарь векторов
Embedding-слой - это просто большая матрица E размером (vocab_size x d_model). Каждому токену соответствует одна строка. «Поиск embedding» - это умножение one-hot вектора на матрицу, что эквивалентно простой индексации строки.
PCA: полный pipeline за 10 строк
**PCA (Principal Component Analysis)** - главный инструмент снижения размерности. Под капотом - центрирование данных и SVD. Математически: найти ортогональный базис, в котором дисперсия данных максимальна по первым осям.
**Eigenfaces** - классическое применение PCA: матрица лиц (n_images x n_pixels), SVD даёт «главные лица» - линейные комбинации, объясняющие максимум вариативности. Распознавание лиц в AT&T Database работало на 40 eigenfaces. Современные методы заменили линейную PCA на нелинейные автоэнкодеры, но идея та же.
PageRank: поиск Google как задача на собственный вектор
PageRank Ларри Пейджа и Сергея Брина (1998) - это нахождение собственного вектора матрицы переходов по веб-графу. Страница важна, если на неё ссылаются важные страницы - круговая логика, которая разрешается через собственный вектор с λ = 1.
**Спектральная кластеризация** - родственный метод: взять граф похожести между объектами, собственные векторы матрицы Лапласа графа дают кластеризацию. Используется в обработке изображений, анализе социальных сетей, биоинформатике. Та же математика - другое приложение.
Матричные операции на GPU: почему так быстро
Обучение GPT-4 заняло ~100 дней на тысячах A100. Это не потому что нейросети «сложные» - это потому что **GEMM (General Matrix Multiply)** на GPU работает в тысячи раз быстрее CPU. Вся производительность ML упирается в одну операцию.
**Batch processing**: вместо умножения W · x по одному вектору за раз - умножение W · X, где X содержит целый batch. Это та же GEMM, но больше - и GPU это любит. Поэтому batch size влияет на скорость так сильно: маленький batch не загружает GPU полностью.
3D-графика: MVP как произведение матриц
Каждый кадр в игре или нейрорендере - это прогон всех вершин через цепочку матричных преобразований. На GPU это происходит параллельно для миллионов вершин.
Практика: ковариационная матрица и дисперсия
Нейросеть и трансформер: что происходит внутри математически
Каждый слой нейросети - это одна операция: $h = \text{activation}(Wx + b)$. Матрица $W \in \mathbb{R}^{m \times n}$ задаёт линейное отображение из $n$-мерного пространства в $m$-мерное. Без нелинейности между слоями произведение любого числа матриц осталось бы одной матрицей: $W_3 W_2 W_1 = W_{\text{eff}}$. ReLU/GELU ломают это тождество.
**Attention в трансформере** - это матричное произведение в три шага: $Q = XW_q$, $K = XW_k$, $V = XW_v$, затем $\text{Attention}(Q,K,V) = \text{softmax}(QK^\top / \sqrt{d_k}) \cdot V$. Матрица $QK^\top$ содержит скалярные произведения всех пар токенов - буквально cosine similarity без нормировки.
Backprop через транспонирование
Почему backward pass требует $W^\top$
Forward: $h = Wx$. Дано $\partial L / \partial h$. Тогда $\partial L / \partial x = W^\top \cdot \partial L / \partial h$ и $\partial L / \partial W = (\partial L / \partial h) \cdot x^\top$ (внешнее произведение). Транспонирование из урока 7 - именно здесь оно живёт в каждом шаге обучения.
Почему нейросеть без нелинейных активаций между слоями эквивалентна одному линейному слою?
$W_3(W_2(W_1 x)) = (W_3 W_2 W_1)x$ - три слоя без нелинейности это один слой с матрицей $W_{\text{eff}} = W_3 W_2 W_1$. Глубина теряет смысл.
PCA, embeddings и PageRank: SVD и собственные векторы в действии
PCA - это SVD данных после центрирования. Если $\tilde{X} = U\Sigma V^\top$, то столбцы $V$ - направления максимальной дисперсии, а $\sigma_i^2/(n-1)$ - дисперсия вдоль $i$-й компоненты. Проекция на $k$ главных компонент: $X_{\text{red}} = \tilde{X} V_{:k}$.
**Embedding-слой** - это матрица $E \in \mathbb{R}^{\text{vocab} \times d}$. Поиск embedding токена $i$ - это умножение one-hot вектора на $E$, то есть просто взятие $i$-й строки. Cosine similarity двух токенов = скалярное произведение нормированных строк: $\text{sim}(i,j) = E[i] \cdot E[j] / (\|E[i]\| \|E[j]\|)$.
Какую операцию линейной алгебры выполняет PCA для нахождения главных компонент?
$\tilde{X} = U\Sigma V^\top$, столбцы $V$ - главные компоненты. Объяснённая дисперсия $i$-й компоненты: $\sigma_i^2 / \sum_j \sigma_j^2$.
ОДИН СЛОЙ: h = activation(W · x + b) x - входной вектор (n,) W - матрица весов (m, n) b - вектор смещений (m,) h - выходной вектор (m,) ВСЯ СЕТЬ (4 слоя MNIST): x₀ = изображение 28×28 → вектор (784,) h₁ = ReLU(W₁ · x₀ + b₁) W₁ ∈ ℝ^(256×784) 200K параметров h₂ = ReLU(W₂ · h₁ + b₂) W₂ ∈ ℝ^(128×256) 33K параметров h₃ = ReLU(W₃ · h₂ + b₃) W₃ ∈ ℝ^(64×128) 8K параметров y = softmax(W₄ · h₃ + b₄) W₄ ∈ ℝ^(10×64) 640 параметров Итого: ~242K параметров, 99%+ - в матрицах W. BACKPROP: ∂L/∂W = ∂L/∂h · xᵀ (внешнее произведение) ∂L/∂x = Wᵀ · ∂L/∂h (транспонирование!) Транспонирование из урока 7 - вот где оно живёт.
ДАНО: последовательность токен-векторов X ∈ ℝ^(n×d) ШАГ 1 - проецируем в Q, K, V: Q = X · Wq (n×d) · (d×dₖ) = (n×dₖ) «Запросы» K = X · Wk (n×d) · (d×dₖ) = (n×dₖ) «Ключи» V = X · Wv (n×d) · (d×dᵥ) = (n×dᵥ) «Значения» ШАГ 2 - считаем веса внимания: scores = Q · Kᵀ / √dₖ (n×n) - матрица совместимостей A = softmax(scores) (n×n) - нормированные веса ШАГ 3 - взвешиваем значения: output = A · V (n×dᵥ) - итоговые представления ПОЛНАЯ ФОРМУЛА: Attention(Q,K,V) = softmax(Q·Kᵀ / √dₖ) · V Q·Kᵀ - скалярные произведения всех пар токенов! Каждый токен смотрит на все остальные через dot product.
EMBEDDING МАТРИЦА: E ∈ ℝ^(vocab × d) - например, 50 000 × 768 (BERT-base) Параметров: 50 000 × 768 = 38 400 000 Это ~40% всех параметров BERT! ПОИСК EMBEDDING ТОКЕНА i: one_hot ∈ ℝ^(vocab,) - вектор с 1 на позиции i, остальное 0 emb_i = one_hot · E = i-я строка E (матричное умножение!) COSINE SIMILARITY МЕЖДУ ТОКЕНАМИ: sim(i, j) = E[i] · E[j] / (||E[i]|| · ||E[j]||) - «кот» и «котёнок» → высокая схожесть - «кот» и «экскаватор» → низкая схожесть GPT-2 WEIGHT TYING: В GPT-2 матрица embedding = матрица проекции выхода (транспонированная) Экономия: 50 257 × 768 = 38.5M параметров используются дважды
ДАНО: X ∈ ℝ^(n×d) - n объектов, d признаков 1. ЦЕНТРИРОВАНИЕ: X̃ = X - mean(X, axis=0) вычесть среднее по каждому признаку 2. SVD: X̃ = U · Σ · Vᵀ 3. ГЛАВНЫЕ КОМПОНЕНТЫ: V = правые сингулярные векторы = направления максимальной дисперсии Σ²/(n-1) = дисперсия вдоль каждой компоненты 4. ПРОЕКЦИЯ на k компонент: X_reduced = X̃ · V[:, :k] (n×k) 5. ВОССТАНОВЛЕНИЕ (приближённое): X_approx = X_reduced · V[:, :k]ᵀ + mean(X, axis=0) PROCENT ОБЪЯСНЁННОЙ ДИСПЕРСИИ: explained_ratio = σᵢ² / Σσⱼ² Стандартно выбирают k, дающий ≥ 95% дисперсии
МАТРИЦА ПЕРЕХОДОВ M: M[i,j] = 1/out_degree(j) если j ссылается на i M[i,j] = 0 иначе PAGERANK ВЕКТОР r: M · r = r (собственный вектор с λ = 1) НА ПРАКТИКЕ добавляют damping factor d ≈ 0.85: M' = d · M + (1-d)/n · 1·1ᵀ Смысл: с вероятностью 0.15 пользователь переходит на случайную страницу ПОВЕР ИТЕРАЦИЯ: r₀ = (1/n, 1/n, ..., 1/n) равномерное начало rₜ₊₁ = M' · rₜ → сходится к собственному вектору Перрона-Фробениуса СХОДИМОСТЬ: |rₜ₊₁ - r*| ≤ d · |rₜ - r*| За 50-100 итераций точность достаточная для веб-поиска
РАЗМЕРЫ В РЕАЛЬНОЙ ТРЕНИРОВКЕ (GPT-2 medium): Batch size = 32, seq_len = 1024, d_model = 1024 Один attention: Q,K,V проекции: X · Wq: (32·1024, 1024) · (1024, 1024) = (32768, 1024) FLOPS: 2 · 32768 · 1024 · 1024 ≈ 69 GFLOPS Всего forward pass одного transformer block: ~550 GFLOPS 16 блоков GPT-2: ~8.8 TFLOPS - именно то, что выдаёт A100 ПАРАЛЛЕЛЬНОСТЬ: C[i,j] = Σₖ A[i,k] · B[k,j] - каждый элемент независим! GPU: 6912 CUDA-ядер считают разные C[i,j] одновременно Tensor Cores (A100): 312 TFLOPS для FP16 matrix multiply CUDAS ПОД КАПОТОМ: cuBLAS (NVIDIA), rocBLAS (AMD), XLA (Google TPU) PyTorch вызывает их автоматически при @, matmul, einsum
ПАЙПЛАЙН: v_clip = P · V · M · v_local M (Model matrix): локальные координаты → мировые (масштаб, поворот, сдвиг) V (View matrix): мировые → координаты камеры (обратное преобразование камеры) P (Projection matrix): координаты камеры → clip (перспективное деление) ОПТИМИЗАЦИЯ: M, V, P не меняются в пределах одного draw call → предвычисляем MVP = P · V · M один раз на CPU → на GPU: v_clip = MVP · v_local Экономия: 3 матричных умножения → 1 ДЛЯ 60 FPS, 1M ВЕРШИН: 60 · 1 000 000 умножений 4x4 · 4-вектора = 1.44 GFLOPS GPU справляется за миллисекунды
- **Нейросеть (любая)**: y = activation(Wx + b) на каждом слое
- **Трансформер / Attention**: Attention(Q,K,V) = softmax(QKᵀ/√d)V
- **Embeddings**: Токен → строка матрицы E
- **PCA / SVD**: Снижение размерности, шумоподавление
- **Рекомендации**: R ≈ UVᵀ (matrix factorization)
- **GPU / Hardware**: GEMM - General Matrix Multiply
Упражнения
- Почему произведение любого числа линейных слоёв без нелинейностей - это тоже линейный слой? — Линейное отображение f(x) = Wx сохраняет сложение и умножение на скаляр; Произведение двух линейных отображений - линейное: W₂(W₁x) = (W₂W₁)x; W₃W₂W₁ - одна матрица. Три слоя без нелинейностей = один слой; ReLU/GELU ломают линейность и делают глубину сети реально необходимой
- Как работает механизм attention в трансформере с точки зрения линейной алгебры? — Q, K, V - линейные проекции входных токенов (умножение на обученные матрицы Wq, Wk, Wv); Q·Kᵀ - матрица попарных скалярных произведений: насколько каждый запрос совпадает с каждым ключом; Softmax нормирует веса, A·V - взвешенная сумма значений по этим весам; Multi-head attention = несколько attention параллельно с разными матрицами проекций
- Полный PCA pipeline: от сырых данных до двух главных компонент - какие шаги линейной алгебры нужны? — 1. Центрирование: X̃ = X - mean(X, axis=0) - вычесть среднее каждого признака; 2. SVD: X̃ = UΣVᵀ - правые сингулярные векторы V = направления макс. дисперсии; 3. Проекция: X_2d = X̃ · V[:, :2] - умножение на первые два столбца V; Объяснённая дисперсия = σᵢ² / Σσⱼ² - помогает выбрать число компонент
Финальный синтез курса
- **Нейросеть = цепочка Wx + b**: каждый слой - матрица; backprop = транспонирование и внешние произведения
- **Attention = QKᵀ + softmax + V**: скалярное произведение пар токенов определяет, кто на кого смотрит
- **Embeddings = строки матрицы E**: cosine similarity = dot product нормированных строк
- **PCA = SVD**: центрируем данные, берём правые сингулярные векторы - это и есть главные компоненты
- **PageRank = собственный вектор**: рейтинг страницы сходится через степенную итерацию к Perron-вектору
- **GPU = быстрый GEMM**: всё ML-ускорение сводится к одной операции - умножению матриц на Tensor Cores
Откуда пришли эти идеи
Каждое применение - финал одного из уроков курса
- SVD — LoRA, LSA, PCA, псевдообратная - всё из сингулярного разложения
- Скалярное произведение — Cosine similarity, attention scores - основа поиска и трансформеров
- Собственные векторы — PageRank, PCA, спектральная кластеризация - три разных приложения