Линейная алгебра
Тензоры: от матриц к батчам изображений
Батч из 32 изображений RGB 224x224 в PyTorch - это тензор размерности (32, 3, 224, 224). Каждая операция свёрточного слоя - тензорное сокращение. Без понимания тензоров невозможно правильно писать код на PyTorch/NumPy: ошибки в shapes и broadcasting - самые частые баги в ML-коде.
- PyTorch: батч изображений (N, C, H, W) - 4D-тензор, основа всего компьютерного зрения
- NLP: батч последовательностей (batch, seq_len, d_model) - 3D-тензор в трансформере
- Physics simulation: тензор напряжений - 3x3 матрица в каждой точке 3D-тела
- Видео: (T, C, H, W) - 4D-тензор для видеоклассификации в Video Transformers
- Multi-head attention: веса (batch, n_heads, seq, seq) - 4D-тензор
Определение тензора и его ранг
**PyTorch. TensorFlow. TensorRT.** Все три названы в честь одного объекта. Батч из 32 изображений 224x224 RGB - это не «три матрицы», это один четырёхмерный тензор формы (32, 3, 224, 224). Attention в трансформере - контракция трёхмерных тензоров Q, K, V. Веса свёрточной сети хранятся как тензор (out_channels, in_channels, kH, kW). Всё современное deep learning - это тензорная алгебра на GPU.
**Два смысла слова «тензор»**: физики понимают под ним многолинейное отображение с законами преобразования координат (метрический тензор, тензор напряжений). ML-инженеры - просто многомерный массив. Урок про второе; первое упоминается, чтобы не путаться при чтении литературы.
Ранг тензора: от числа до 4D массива
**Ранг (rank)** тензора - количество индексов (осей). Не путать с рангом матрицы. Четыре ранга, которые встречаются в ML каждый день:
| Ранг | Форма | Что это в ML | Пример |
|---|---|---|---|
| 0 (скаляр) | () | Loss, learning rate, accuracy | loss = 0.3451 |
| 1 (вектор) | (d,) | Embedding, bias, 1D сигнал | emb = (1536,) для ada-002 |
| 2 (матрица) | (n, m) | Весовая матрица слоя, attention mask | W = (768, 3072) в FFN BERT |
| 3 (куб) | (B, T, D) | Батч токенов в трансформере | (32, 128, 512) - batch x seq x embed |
| 4 (гиперкуб) | (B, C, H, W) | Батч изображений в CNN | (32, 3, 224, 224) - ImageNet батч |
Что в ML понимается под «рангом тензора»?
В ML «ранг тензора» (PyTorch, TF) - это количество осей: скаляр имеет ранг 0, вектор 1, матрица 2, RGB-изображение 3, батч изображений 4. Математически это число индексов. Не путать с «тензорным рангом» из CP-разложения, который означает минимальное число слагаемых вида a⊗b⊗c.
Операции: einsum, broadcasting, reshape
Einstein summation: один синтаксис для всего
**Einstein notation** - компактный способ записывать операции с тензорами: повторяющийся индекс означает суммирование. В numpy и PyTorch это реализовано через `einsum`. Половина операций в deep learning записывается одной строкой этого синтаксиса.
ВЕКТОРНОЕ СКАЛЯРНОЕ ПРОИЗВЕДЕНИЕ: a·b = Σᵢ aᵢ bᵢ → 'i,i->' МАТРИЧНОЕ ПРОИЗВЕДЕНИЕ: C[i,k] = Σⱼ A[i,j] B[j,k] → 'ij,jk->ik' ТРАНСПОНИРОВАНИЕ: B[j,i] = A[i,j] → 'ij->ji' СЛЕД МАТРИЦЫ (контракция): tr(A) = Σᵢ A[i,i] → 'ii->' BATCHED МАТРИЧНОЕ ПРОИЗВЕДЕНИЕ (трансформер): Y[b,t,h] = Σd X[b,t,d] * W[d,h] → 'btd,dh->bth' ATTENTION SCORES: S[b,t,s] = Σd Q[b,t,d] * K[b,s,d] → 'btd,bsd->bts' ВНЕШНЕЕ ПРОИЗВЕДЕНИЕ ВЕКТОРОВ: M[i,j] = aᵢ * bⱼ → 'i,j->ij'
**В PyTorch**: `torch.einsum('btd,bsd->bts', Q, K)` - полный аналог numpy. Плюс есть `torch.bmm` (batched matrix multiply) и `torch.matmul`, которые автоматически применяют einsum-семантику для 3D+ тензоров.
Multi-head attention: тензорная картина
Multi-head attention в трансформерах (BERT, GPT, T5) - это одновременное вычисление H независимых attention механизмов. Реализация через reshape и einsum делает это без циклов.
Тензорное произведение и внешнее произведение
Тензорное произведение a ⊗ b двух векторов - матрица, каждый элемент которой (i,j) = a[i] * b[j]. Rank тензорного произведения двух rank-1 тензоров - 2. Это фундаментальная операция, лежащая в основе и attention, и свёрток.
a ∈ R^m, b ∈ R^n → a ⊗ b ∈ R^(m×n) a = [1, 2, 3] (shape: (3,)) b = [4, 5] (shape: (2,)) a ⊗ b = [ 1*4 1*5 ] = [ 4 5 ] [ 2*4 2*5 ] [ 8 10 ] [ 3*4 3*5 ] [ 12 15 ] shape: (3, 2) = (3,) x (2,) Обобщение: T ∈ R^(d1) ⊗ R^(d2) ⊗ ... ⊗ R^(dk) shape: (d1, d2, ..., dk) dim = d1 * d2 * ... * dk
**LoRA (Low-Rank Adaptation)** - техника дообучения LLM из статьи Hu et al. 2021. Вместо обновления полной весовой матрицы W добавляется delta_W = A @ B, где rank << d. Это буквально тензорное произведение двух маленьких матриц. На этом принципе работают все PEFT методы: LoRA, QLoRA, DoRA.
Что вычисляет выражение torch.einsum("btd,bsd->bts", Q, K)?
Einstein summation: индекс d суммируется (повторяется в обоих входах, отсутствует на выходе); индексы b,t,s - свободные. Это сердце attention: батчированный матричный продукт между Q (shape B,T,D) и K^T (shape B,D,S) даёт scores (shape B,T,S).
Тензорные разложения: Tucker, CP, TT
Tucker decomposition: сжатие весов нейросетей
SVD разлагает матрицу на произведение трёх. Tucker decomposition - обобщение SVD на тензоры произвольного ранга. Применяется для сжатия весов свёрточных и трансформерных слоёв.
Тензор T ∈ R^(I x J x K) раскладывается: T ≈ G ×₁ U₁ ×₂ U₂ ×₃ U₃ где: G ∈ R^(R1 x R2 x R3) - ядровой тензор (core tensor) U₁ ∈ R^(I x R1), U₂ ∈ R^(J x R2), U₃ ∈ R^(K x R3) - факторные матрицы R1 << I, R2 << J, R3 << K - ранги усечения Степень сжатия: Исходно: I*J*K параметров После Tucker: R1*R2*R3 + I*R1 + J*R2 + K*R3 параметров Пример (свёрточный слой ResNet): T: (256, 256, 9) → Tucker с рангами (64, 64, 9): 256*256*9 = 589,824 → 64*64*9 + 256*64 + 256*64 + 9*9 = 36,864 + 32,768 + 81 = 69,713 Сжатие в ~8.5 раз при минимальной потере точности
Операции с тензорами: broadcasting и reshape
Две операции, без которых не обходится ни один ML-код: **broadcasting** (неявное расширение размерности) и **reshape** (перестановка элементов без копирования).
**Тензоры в современном ML стеке** Где конкретно живут тензоры в production-системах - **PyTorch / JAX / TensorFlow**: Фундамент: все параметры, активации, градиенты - тензоры. Autograd отслеживает граф вычислений над тензорами; XLA/cuDNN оптимизирует einsum - **Transformer (BERT, GPT, T5)**: Attention = тензорная контракция (B,H,T,D) x (B,H,D,T). Flash Attention ускоряет именно эту операцию на GPU через tiling - **CNN (ResNet, EfficientNet)**: Свёртка = тензорная операция (B,C_out,H,W) x (C_out,C_in,kH,kW). cuDNN im2col + GEMM; Tucker decomposition для сжатия - **LoRA / QLoRA**: Fine-tuning через низкоранговые тензорные добавки delta_W = A @ B. Rank 4-64 вместо тысяч; PEFT библиотека Hugging Face - **TensorRT / ONNX**: Оптимизация тензорных операций для inference. Fusion операций, quantization; на выходе - тот же тензорный граф, но быстрее
Практика: RGB-изображение как 3D тензор
**Батч из 32 изображений 224x224 RGB передаётся в ResNet-50. Какова форма входного тензора и сколько памяти он занимает в float32?** Hints: PyTorch использует формат (B, C, H, W); float32 = 4 байта на элемент - Форма: (32, 3, 224, 224) - batch x channels x height x width - Элементов: 32*3*224*224 = 4,816,896 - Памяти: 4,816,896 * 4 bytes ≈ 19.3 MB только для одного батча - На GPU это умещается в VRAM; проблема начинается когда активации промежуточных слоёв суммируются --- **Чем `np.einsum('ij,jk->ik', A, B)` отличается от `A @ B`? Когда нужен einsum?** Hints: Что делает @ для 2D матриц?; Что делать если нужно перемножить не все оси? - Для 2D матриц результат идентичен; @ это частный случай einsum - einsum нужен для batched операций с нестандартным набором осей - Пример: 'btd,bsd->bts' - контракция только по d, сохраняем b,t,s - einsum читается как явное выражение суммирования - самодокументирующийся код --- **Что такое Tucker decomposition и как она применяется для сжатия нейросетей?** Hints: Как SVD разлагает матрицу?; Что если матрица - это тензор с 4 осями? - Tucker - обобщение SVD: T ≈ G ×₁ U₁ ×₂ U₂ ×₃ U₃ где G - ядровой тензор - Усечение рангов R1, R2, R3 < исходных размерностей даёт сжатие - Для свёрточного слоя (C_out, C_in, kH, kW) Tucker даёт 5-10x сжатие - Потом fine-tune для восстановления точности; библиотека tensorly
Что унести из урока
- **Ранг тензора** = число осей; rank-0 скаляр, rank-4 батч изображений (B,C,H,W)
- **einsum** записывает любую тензорную операцию через индексы: повторяющийся индекс = суммирование
- **Multi-head attention** = einsum('bhti,bhsi->bhts', Q, K) - контракция по d_head
- **LoRA** = низкоранговое тензорное произведение delta_W = A @ B, rank r << d
- **Tucker decomposition** - SVD для тензоров; сжатие весов CNN в 5-10x без потери качества
- **Broadcasting** позволяет смешивать тензоры разных форм без явного копирования
- **PyTorch/JAX** - весь стек это тензорная алгебра; понять тензоры = понять архитектуру
Куда дальше
Тензоры - язык, на котором написан весь deep learning. Дальнейшие темы используют этот язык.
- SVD — Tucker decomposition обобщает SVD; понять SVD - значит понять тензорные разложения
- Жорданова форма — Спектральная теория матриц - частный случай тензорной алгебры
- Линейная алгебра в deep learning — Практика: как именно тензорные операции реализованы в attention и свёртках