Линейная алгебра

Операции с матрицами

Обучение нейросети - это миллиарды операций сложения и умножения матриц на GPU. Каждый шаг forward pass - несколько матричных умножений. Без понимания базовых операций с матрицами невозможно разобраться в архитектуре ни одной современной модели.

  • Нейросеть: каждый слой - умножение матрицы весов на батч входных векторов
  • Компьютерная графика: преобразование координат - умножение на матрицу Model-View-Projection
  • Физика: оператор поворота - матрица 3x3, применяется к каждому вектору
  • Статистика: ковариационная матрица - основа PCA и многомерного анализа
  • Оптимизация: матрица Гессе задаёт кривизну функции потерь

Операции с матрицами

Каждый проход ResNet-50 через одну картинку - это больше **25 миллионов** операций с матрицами. Каждый токен GPT-4 - умножение на матрицы размером ~12 288 × 12 288. Операции с матрицами - это не абстрактная алгебра, это буквально то, что делает GPU прямо сейчас, пока генерируется ответ ChatGPT. Разберёмся, что именно происходит.

**Три операции, которые нужно знать наизусть**: сложение матриц (residual connections в ResNet), умножение на скаляр (learning rate применяется к матрице градиентов), перемножение матриц (каждый линейный слой нейросети). Транспонирование - ключ к backprop и механизму attention.

Что главное в концепте «Операции с матрицами»?

Проверка усвоения материала концепта.

Сложение матриц: как работают residual connections

Сложение матриц: как работают residual connections

Складывать можно только матрицы **одинакового размера**. Элементы складываются поэлементно - i-й с i-м, j-й с j-м. Формула проста:

(A + B)_{ij} = a_{ij} + b_{ij} Пример: ┌ ┐ ┌ ┐ ┌ ┐ │ 1 2 │ + │ 5 6 │ = │ 6 8 │ │ 3 4 │ │ 7 8 │ │ 10 12 │ └ ┘ └ ┘ └ ┘ Одинаковые позиции складываются: 1+5=6, 2+6=8, 3+7=10, 4+8=12

Именно эта операция лежит в основе **residual connections** в ResNet. Идея Хе и соавторов (2015): вместо того чтобы слой учил полное преобразование H(x), пусть учит только остаток F(x) = H(x) - x. Тогда выход блока:

Обычный слой: y = H(x) Residual block: y = F(x) + x Где F(x) - выход двух свёрточных слоёв, x - исходный вход (shortcut connection) x (вход, shape [B, C, H, W]) │ ├──────────────────────┐ │ │ Conv → BN → ReLU │ shortcut Conv → BN │ │ │ └──────── + ───────────┘ │ output = F(x) + x ← матричное сложение! Результат: градиенты текут напрямую через shortcut. Именно это позволило обучать сети глубиной 152 слоя.

**Контр-интуитивный факт**: ResNet-50 содержит 16 таких residual-блоков. В каждом - одно матричное сложение. Это простейшая операция вида A + B, но именно она позволила обучать сети глубиной 100+ слоёв, что было невозможно до 2015 года.

Что главное в концепте «Сложение матриц: как работают residual connections»?

Проверка усвоения материала концепта.

Умножение на скаляр: learning rate в действии

Умножение на скаляр: learning rate в действии

Умножение матрицы на число - каждый элемент умножается на этот скаляр. Направление матрицы не меняется, масштаб меняется:

(k · A)_{ij} = k · a_{ij} Пример (k = 3): ┌ ┐ ┌ ┐ 3 · │ 1 2 │ = │ 3 6 │ │ 3 4 │ │ 9 12│ └ ┘ └ ┘

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

W_new = W_old - lr * grad_W Где: W_old - матрица весов до шага [768 × 3072 в BERT] lr - learning rate (скаляр, например 0.001) grad_W - матрица градиентов того же размера [768 × 3072] lr * grad_W - это умножение матрицы 768×3072 на скаляр 0.001 Для BERT: 768 × 3072 = 2 359 296 умножений за один параметр. В BERT-base таких слоёв 12, и ещё attention, embedding... → ~110 миллионов параметров обновляются за один batch.

Что главное в концепте «Умножение на скаляр: learning rate в действии»?

Проверка усвоения материала концепта.

Перемножение матриц: сердце нейросети

Перемножение матриц: сердце нейросети

~Матрица~{Прямоугольный массив чисел m строк на n столбцов} A размером m × n умножается на матрицу B размером n × p. Результат - матрица размером m × p. Внутренние размерности должны совпасть - это правило без исключений.

(AB)_{ij} = сумма_{k=1}^{n} a_{ik} * b_{kj} Пример: A (2×3) умножить на B (3×2) = результат (2×2) ┌ ┐ ┌ ┐ A = │ 1 2 3 │ │ 7 8 │ │ 4 5 6 │ · │ 9 0 │ = C └ ┘ │11 2 │ └ ┘ C[0,0] = 1*7 + 2*9 + 3*11 = 7 + 18 + 33 = 58 C[0,1] = 1*8 + 2*0 + 3*2 = 8 + 0 + 6 = 14 C[1,0] = 4*7 + 5*9 + 6*11 = 28+ 45 + 66 = 139 C[1,1] = 4*8 + 5*0 + 6*2 = 32+ 0 + 12 = 44 ┌ ┐ C = │ 58 14 │ │ 139 44 │ └ ┘

Элемент C[i,j] - это **скалярное произведение** i-й строки матрицы A на j-й столбец матрицы B. Весь механизм attention в трансформерах основан именно на этом: QK^T - это матричное умножение, где каждый элемент результата - сходство i-го запроса с j-м ключом.

Умножение матриц **не коммутативно**: AB не равно BA. В общем случае BA может вообще не существовать (размерности не совпадут). В нейросетях порядок матриц критичен: W @ x - это линейный слой, x @ W - это другая операция с другой семантикой.

Свойства, которые выполняются:

  • **Ассоциативность**: (AB)C = A(BC) - можно скобки переставлять
  • **Дистрибутивность**: A(B + C) = AB + AC
  • **Со скаляром**: k(AB) = (kA)B = A(kB)
  • **Единичная матрица**: AI = IA = A

Что главное в концепте «Перемножение матриц: сердце нейросети»?

Проверка усвоения материала концепта.

Транспонирование: backprop и механизм attention

Транспонирование: backprop и механизм attention

~Транспонирование~{Операция замены строк и столбцов местами: (A^T)[i,j] = A[j,i]} - отражение матрицы относительно главной диагонали. Строки становятся столбцами, размер меняется с m × n на n × m.

┌ ┐ ┌ ┐ A = │ 1 2 3 │ A^T = │ 1 4 │ │ 4 5 6 │ │ 2 5 │ └ ┘ │ 3 6 │ └ ┘ 2×3 → 3×2 Формула: (A^T)_{ij} = A_{ji}

В механизме **self-attention** трансформера вычисляется QK^T - произведение матрицы запросов Q и транспонированной матрицы ключей K. Это даёт матрицу размером [seq_len × seq_len], где каждый элемент - сходство между двумя токенами.

Q: [seq_len, d_k] - запросы (queries) K: [seq_len, d_k] - ключи (keys) K^T: [d_k, seq_len] - транспонирование QK^T: [seq_len, seq_len] - матрица сходств Пример для seq_len=4, d_k=64: Q @ K.T -> матрица 4×4 ┌ ┐ │ s00 s01 s02 s03 │ s_ij = сходство токенов i и j │ s10 s11 s12 s13 │ │ s20 s21 s22 s23 │ │ s30 s31 s32 s33 │ └ ┘ Затем softmax → attention weights → умножить на V

Свойства транспонирования - три правила, которые нужно знать:

  • $(A^T)^T = A$ - двойное транспонирование возвращает исходную матрицу
  • $(A + B)^T = A^T + B^T$ - транспонирование суммы
  • $(AB)^T = B^T A^T$ - **порядок меняется!** Это критично в backprop

Правило $(AB)^T = B^T A^T$ - это то, почему backpropagation работает именно так, как работает. При вычислении градиента по весам W приходится транспонировать матрицы активаций. Без этого правила вывод backprop не сходился бы.

Что главное в концепте «Транспонирование: backprop и механизм attention»?

Проверка усвоения материала концепта.

Специальные матрицы в ML

Специальные матрицы в ML

ТипСвойствоГде встречается в ML
СимметричнаяA = A^TКовариационная матрица в PCA; матрица Гессе в оптимизации
Диагональнаяa_ij = 0 при i != jScaling layer; диагональные аппроксимации Hessian (AdaGrad)
ОртогональнаяA^T A = IМатрицы поворота; инициализация весов (orthogonal init)
Верхнетреугольнаяa_ij = 0 при i > jLU-разложение; causal mask в autoregressive трансформерах

**Causal mask в GPT** - это верхнетреугольная матрица из -inf, которая добавляется к матрице scores в attention перед softmax. Токен не должен смотреть в будущее - нижний треугольник заблокирован. Формально: ещё одна операция сложения матриц.

Что главное в концепте «Специальные матрицы в ML»?

Проверка усвоения материала концепта.

GPU как машина матричных умножений

GPU как машина матричных умножений

NVIDIA A100 выполняет **312 TFLOPS** операций с матрицами (tensor cores, FP16). Это 312 триллионов умножений в секунду. Весь дизайн современных GPU оптимизирован под одну операцию - **GEMM** (General Matrix Multiplication). Pytorch, TensorFlow, JAX - всё это в конечном счёте вызывает cuBLAS GEMM.

Где матричные операции работают прямо сейчас

Каждая из этих систем - это матричные операции под капотом

КомпонентРольДетали
GPT-4 / ClaudeLinear layers + attention (QK^T)Каждый токен - умножение на матрицы [12288 x 12288]. Сотни миллиардов параметров.
ResNet / YOLO / CLIPConv + residual connections (F(x) + x)ResNet-50: 25M параметров, 4.1 GFLOPs на одну картинку
Stable DiffusionU-Net + cross-attentionКаждый denoising step: сотни матричных умножений в U-Net и attention
Gradient descent (Adam, SGD)W = W - lr * grad_WСкалярное умножение матрицы градиентов - происходит на каждом batch

Что главное в концепте «GPU как машина матричных умножений»?

Проверка усвоения материала концепта.

Практика: Instagram sepia-фильтр

Практика: Instagram sepia-фильтр

Вопросы для собеседования

Почему в residual connections используется именно сложение матриц (F(x) + x), а не, например, конкатенация?

- При сложении градиент течёт напрямую через shortcut без затухания - это решает проблему vanishing gradients - Конкатенация удваивает размерность - нужен дополнительный слой чтобы вернуть исходный размер - Сложение не добавляет параметров, конкатенация требует дополнительный Linear слой - DenseNet использует конкатенацию - это другой подход с другими компромиссами

Матрица Q имеет форму [seq_len, d_k], матрица K имеет форму [seq_len, d_k]. Почему в attention вычисляется Q @ K.T, а не Q @ K?

- Q @ K невозможно: [seq_len, d_k] @ [seq_len, d_k] - внутренние размерности не совпадают - Q @ K.T: [seq_len, d_k] @ [d_k, seq_len] = [seq_len, seq_len] - матрица попарных сходств - Элемент [i,j] результата = скалярное произведение i-го запроса и j-го ключа = сходство токенов i и j - Масштабирование на 1/sqrt(d_k) нужно чтобы dot products не становились слишком большими при большом d_k

Почему порядок в правиле (AB)^T = B^T A^T меняется?

- A: [m, n], B: [n, p] -> AB: [m, p] -> (AB)^T: [p, m] - B^T: [p, n], A^T: [n, m] -> B^T A^T: [p, m] - размерности совпадают - A^T B^T: [n, m] @ [p, n] - умножение невозможно, размерности не совпадают - Это правило прямо применяется в backprop: grad_input = W^T @ grad_output

Что главное в концепте «Практика: Instagram sepia-фильтр»?

Проверка усвоения материала концепта.

Что унести из урока

  • **Сложение** A + B: поэлементно, только одинаковые размеры - основа residual connections в ResNet
  • **Скалярное умножение** k*A: каждый элемент на k - именно так learning rate применяется к градиентам
  • **Матричное умножение** AB: внутренние размерности должны совпасть; [m,n]@[n,p]=[m,p] - основа Linear слоёв
  • **Транспонирование** A^T: строки и столбцы меняются местами; (AB)^T = B^T A^T с переворотом порядка
  • **AB не равно BA** - порядок матриц имеет значение; в нейросетях это всегда так
  • **QK^T** в attention - транспонирование K обязательно для правильных размерностей матрицы сходств
  • **GPU = машина GEMM** - весь deep learning сводится к одной операции матричного умножения

Куда дальше

Операции с матрицами - строительный блок для более сложных концепций

  • Матрицы: что они делают? — Геометрический смысл матрицы как трансформации пространства
  • Обратная матрица — Операция, обратная умножению - нормальное уравнение в линейной регрессии
  • Собственные векторы и SVD — Что происходит с матрицей при многократном умножении - PCA и LoRA

Связанные уроки

  • ml-06-linear-regression
  • stats-21
Операции с матрицами

0

1

Войти