Перейти к содержимому
Ступень 11.1 Линейная алгебра

Векторы, скалярное произведение, нормы

Вектор как список чисел, точка и стрелка; длина вектора, скалярное произведение и косинусное сходство — та самая математика, на которой работает поиск похожих эмбеддингов.

УРОКstage-1/1-1-linear-algebra/01-vectors.mdx1 ч 30 минУрок 1 из 3
После урока вы сможете
  • Объяснить, что вектор — это одновременно список чисел, точка и стрелка, и складывать векторы и умножать их на число
  • Считать L1- и L2-нормы, скалярное произведение и косинусное сходство — руками, на чистом Python и в NumPy
  • Объяснить, почему поиск похожих эмбеддингов сравнивает направления, а не длины, и найти ближайшие слова в словаре «слов-векторов»

Внутри языковой модели нет слов — только числа. Когда большая языковая модельбольшая языковая модель (БЯМ, LLM)EN large language model (LLM)В китайском «большая модель» («да мосин») — разговорное общее название для LLM и вообще foundation models. читает токен «кошка», она достаёт из таблицы строку из нескольких тысяч чисел. У DeepSeek-V3 таких чисел 7168 на каждый токен. Эта строка и есть эмбеддингэмбеддинг, векторное представлениеEN embedding — вектор. Дальше вся работа модели — это действия над векторами: их складывают, растягивают, сравнивают.

В этом уроке три операции, которые встретятся вам буквально в каждой теме курса:

  • длина вектора (норма) — на ней держатся нормализация слоёв и обрезка градиентов;
  • скалярное произведение — из него сделаны нейрон, внимание и выходной слой модели;
  • косинусное сходство — им ищут похожие тексты в RAGгенерация с дополнением извлечёнными данными (RAG)EN retrieval-augmented generation (RAG) (так называют схему, где модель перед ответом находит в базе документов подходящие куски текста, ступень 8) и в рекомендательных системах.
flowchart LR
A["Токен «кошка»"] --> B["Вектор<br/>из d чисел"]
B --> C["Скалярные произведения<br/>внимание, нейроны"]
B --> D["Косинусное сходство<br/>поиск похожих"]
C --> E["Логиты<br/>следующего токена"]
Векторы — «валюта» языковой модели

ВекторвекторEN vectorУпорядоченный список чисел; его же можно видеть как точку или как стрелку (направление + длина). Китайский термин буквально означает «направленная величина». — это упорядоченный набор чисел. Записывают его жирной буквой или списком в скобках: v=(3,1)\mathbf{v} = (3, 1). Числа внутри называют координатами или компонентами: v1=3v_1 = 3, v2=1v_2 = 1. Количество чисел — размерность вектора. Запись v∈Rn\mathbf{v} \in \mathbb{R}^n читается «v\mathbf{v} — вектор из nn действительных чисел». Одиночное число, в отличие от вектора, называют скаляромскалярEN scalarОдиночное число — в отличие от вектора, матрицы или тензора..

Один и тот же вектор полезно видеть тремя способами.

  1. Список чисел — взгляд программиста. В Python это [3, 1], в NumPy — np.array([3, 1]). Эмбеддинг DeepSeek-V3 — список из 7168 чисел.
  2. Точка в пространстве — взгляд аналитика данных. Квартира площадью 54 м² на 7 этаже — точка (54,7)(54, 7) на плоскости. Похожие квартиры лежат рядом. Похожие слова в пространстве эмбеддингов — тоже.
  3. Стрелка — взгляд физика. Вектор (3,1)(3, 1) — это перемещение «на 3 вправо и на 1 вверх». У стрелки есть направление и длина, а откуда её рисовать, не важно.

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

Векторы одинаковой размерности складывают покоординатно, а умножение на число растягивает каждую координату:

a+b=(a1+b1,  a2+b2),c⋅v=(c v1,  c v2)\mathbf{a} + \mathbf{b} = (a_1 + b_1, \; a_2 + b_2), \qquad c \cdot \mathbf{v} = (c\,v_1, \; c\,v_2)

Индекс у буквы — номер координаты, как в уроке 1.0.3: a1a_1 — первое число вектора a\mathbf{a}, a2a_2 — второе. Для векторов длины 3 и больше формула та же, просто координат больше.

Пример: (3,1)+(1,2)=(4,3)(3, 1) + (1, 2) = (4, 3), а 2⋅(2,1)=(4,2)2 \cdot (2, 1) = (4, 2). Геометрически сложение — это «пройти сначала по стрелке a\mathbf{a}, потом по стрелке b\mathbf{b}». Умножение на число растягивает стрелку, а умножение на отрицательное число ещё и разворачивает её.

Сложениеa + b = (4, 3)a = (3, 1)b = (1, 2)a + bУмножение на числоv = (2, 1)2vv−1 · v
Слева: чтобы сложить векторы, приставьте начало b к концу a. Справа: умножение на число растягивает вектор, а минус разворачивает его.

Сумму векторов, умноженных на числа, например 2a−0.5b2\mathbf{a} - 0.5\mathbf{b}, называют линейной комбинацией. Для наших a=(3,1)\mathbf{a} = (3, 1) и b=(1,2)\mathbf{b} = (1, 2) это (6,2)−(0.5,1)=(5.5,1)(6, 2) - (0.5, 1) = (5.5, 1). Это понятие станет главным в следующем уроке: умножение матрицы на вектор — это линейная комбинация её столбцов.

Где это в LLM. Каждый блок трансформера не заменяет вектор токена, а прибавляет к нему поправку: h←h+Attention(h)\mathbf{h} \leftarrow \mathbf{h} + \text{Attention}(\mathbf{h}). Это остаточная связьостаточная связьEN residual connection (урок 3.4.2). Среднее нескольких векторов (сложить и умножить на 1/n1/n) — простейший способ получить вектор целого предложения из векторов слов. А знаменитое «король − мужчина + женщина ≈ королева» — тоже линейная комбинация (урок 4.3.1).

import numpy as np
a = np.array([3, 1])
b = np.array([1, 2])
print(a + b) # [4 3]
print(2 * a - b) # [5 0]
print((a + b) / 2) # [2. 1.5] — среднее двух векторов

Как измерить «размер» вектора? Способов несколько, и каждый называют нормойнорма вектораEN vector norm«Размер» вектора. L2-норма — длина по Пифагору √(Σ vᵢ²), L1-норма — сумма модулей Σ |vᵢ|.. Обозначение — двойные вертикальные черты: ∥v∥\lVert \mathbf{v} \rVert.

L2-норма — обычная длина стрелки. Вспомним школьную теорему Пифагора: в прямоугольном треугольнике квадрат длинной стороны (гипотенузы) равен сумме квадратов двух коротких (катетов). Стрелка (3,4)(3, 4) — это гипотенуза треугольника с катетами 3 (вправо) и 4 (вверх), поэтому её длина — корень из 32+423^2 + 4^2:

∥v∥2=v12+v22+⋯+vn2=∑i=1nvi2,∥(3,4)∥2=9+16=5\begin{gathered} \lVert \mathbf{v} \rVert_2 = \sqrt{v_1^2 + v_2^2 + \dots + v_n^2} = \sqrt{\sum_{i=1}^{n} v_i^2}, \\ \lVert (3, 4) \rVert_2 = \sqrt{9 + 16} = 5 \end{gathered}

Теорема Пифагора работает в любой размерности: ∥(1,2,2)∥2=1+4+4=3\lVert (1, 2, 2) \rVert_2 = \sqrt{1 + 4 + 4} = 3. Когда индекс нормы не написан, почти всегда имеют в виду L2.

L1-норма — сумма модулей координат. Её называют «манхэттенской»: такси в городе с прямоугольными кварталами не может ехать по диагонали и проезжает 3+4=73 + 4 = 7 кварталов вместо 5:

∥v∥1=∑i=1n∣vi∣,∥(3,−4)∥1=3+4=7\lVert \mathbf{v} \rVert_1 = \sum_{i=1}^{n} \lvert v_i \rvert, \qquad \lVert (3, -4) \rVert_1 = 3 + 4 = 7
ВекторL1L2Что заметно
(3,4)(3, 4)75L1 всегда не меньше L2
(1,0,0,0)(1, 0, 0, 0)11вся «масса» в одной координате — нормы равны
(1,1,1,1)(1, 1, 1, 1)42«масса» размазана — L1 заметно больше

Расстояние между точками — это норма их разности: ∥a−b∥\lVert \mathbf{a} - \mathbf{b} \rVert. Расстояние, измеренное L2-нормой, называют евклидовымевклидово расстояниеEN Euclidean distanceL2-норма разности двух векторов ‖a − b‖₂ — обычное расстояние «по прямой».. На нём построен метод ближайших соседей (урок 2.3.1).

Единичный вектор. Если поделить вектор на его длину, получится единичный векторединичный векторEN unit vectorВектор длины 1. Любой ненулевой вектор v превращается в единичный делением на его длину ‖v‖ (нормировка). с тем же направлением и длиной 1: (3,4)/5=(0.6,0.8)(3, 4) / 5 = (0.6, 0.8). Эта операция — нормировка — понадобится через пару разделов.

v = np.array([3.0, 4.0])
print(np.linalg.norm(v)) # 5.0 — L2 по умолчанию
print(np.linalg.norm(v, ord=1)) # 7.0 — L1
print(v / np.linalg.norm(v)) # [0.6 0.8] — единичный вектор

Где нормы в LLM.

  • RMSNorm — нормализация в каждом слое Llama, Qwen и DeepSeek (урок 4.5.3). Она делит вектор на RMS(x)=∥x∥2/n\mathrm{RMS}(\mathbf{x}) = \lVert \mathbf{x} \rVert_2 / \sqrt{n}. RMS (root mean square) — «корень из среднего квадрата»: возвели координаты в квадрат, усреднили, взяли корень. Для (3,4)(3, 4) это (9+16)/2=5/2≈3.54\sqrt{(9 + 16)/2} = 5 / \sqrt{2} \approx 3.54, а после деления получается (0.85,1.13)(0.85, 1.13) — вектор длины 2\sqrt{2}. Как бы ни «раздувались» векторы внутри сети, после RMSNorm их длина снова n\sqrt{n} (потом каждую координату ещё умножают на обучаемый вес, но это уже отдельный шаг).
  • Обрезка градиентов (gradient clipping, урок 4.6.3). Градиент — вектор поправок ко всем весам модели на очередном шаге обучения (модуль 1.2). Если его L2-норма больше порога (обычно 1.0), все поправки уменьшают в одно и то же число раз, так чтобы норма стала равна порогу. Это страховка от слишком больших шагов обучения.
  • L2-регуляризация (её родственник в оптимизаторах — weight decay) — штраф, который не даёт весам разрастаться и мешает модели «зазубривать» обучающие данные. Он равен сумме квадратов весов, то есть квадрату L2-нормы (уроки 1.4.2 и 2.1.2).

Скалярное произведениескалярное произведениеEN dot product (inner product)a · b = Σ aᵢbᵢ = ‖a‖‖b‖cos θ. Основа нейрона, внимания (q · k) и выходного слоя LLM. двух векторов одинаковой размерности — это сумма попарных произведений координат. Результат — одно число, скаляр (отсюда и название):

a⋅b=∑i=1naibi=a1b1+a2b2+⋯+anbn\mathbf{a} \cdot \mathbf{b} = \sum_{i=1}^{n} a_i b_i = a_1 b_1 + a_2 b_2 + \dots + a_n b_n

Пример: (1,2,3)⋅(4,5,6)=4+10+18=32(1, 2, 3) \cdot (4, 5, 6) = 4 + 10 + 18 = 32. Знак Σ\Sigma из урока 1.0.3 здесь превращается в цикл:

a, b = [1, 2, 3], [4, 5, 6]
total = 0
for x, y in zip(a, b): # идём по парам координат
total += x * y
print(total) # 32
print(np.dot(a, b), np.array(a) @ np.array(b)) # 32 32 — то же в NumPy

Заметьте: скалярное произведение вектора на себя — это квадрат длины, v⋅v=∥v∥22\mathbf{v} \cdot \mathbf{v} = \lVert \mathbf{v} \rVert_2^2.

Та же величина записывается через длины и угол θ\theta («тета») между стрелками:

a⋅b=∥a∥ ∥b∥cos⁡θ\mathbf{a} \cdot \mathbf{b} = \lVert \mathbf{a} \rVert \, \lVert \mathbf{b} \rVert \cos\theta

Проверим на a=(1,0)\mathbf{a} = (1, 0) и b=(1,1)\mathbf{b} = (1, 1). По координатам: 1⋅1+0⋅1=11 \cdot 1 + 0 \cdot 1 = 1. Через угол: длины равны 11 и 2\sqrt{2}, угол между стрелками 45°, cos⁡45°≈0.707\cos 45° \approx 0.707, и 1⋅1.414⋅0.707=11 \cdot 1.414 \cdot 0.707 = 1. Сошлось.

Отсюда главное правило чтения знака:

Скалярное произведениеУголСмысл
больше 0острыйвекторы «смотрят в одну сторону»
равно 0прямойвекторы ортогональныортогональные (перпендикулярные) векторыEN orthogonal vectorsВекторы, скалярное произведение которых равно нулю. Ортогональная матрица — та, у которой столбцы единичные и попарно ортогональны. (перпендикулярны) — «не связаны»
меньше 0тупойвекторы «смотрят в разные стороны»

Ещё одна интерпретация: если b\mathbf{b} — единичный вектор, то a⋅b\mathbf{a} \cdot \mathbf{b} — длина тени (проекции) стрелки a\mathbf{a} на направление b\mathbf{b}. Скалярное произведение измеряет, «сколько в a\mathbf{a} направления b\mathbf{b}».

  • Нейрон считает w⋅x+b\mathbf{w} \cdot \mathbf{x} + b — та самая «линейная функция многих переменных» из урока 1.0.1. Выход большой, когда вход x\mathbf{x} похож на «шаблон» w\mathbf{w}. Нейрон — детектор узора.
  • Внимание (урок 4.4.2): насколько токен ii интересуется токеном jj, решает скалярное произведение запроса qi\mathbf{q}_i на ключ kj\mathbf{k}_j.
  • Выходной слой: логитлогитEN logitСтрого — логарифм шансов log(p / (1 − p)). В нейросетях логитами называют любые выходы до softmax или сигмоиды. каждого токена словаря — скалярное произведение последнего скрытого вектора на вектор этого токена. У DeepSeek-V3 словарь из 129 280 токенов, значит, на каждом шаге генерации — 129 280 скалярных произведений векторов длины 7168.

Стоимость одного скалярного произведения — nn умножений и n−1n - 1 сложений, примерно 2n2n операций. Запомните эту оценку: в уроке 5.1.1 из неё вырастет формула стоимости обучения целой модели.

Скалярное произведение зависит и от угла, и от длин. Если нас интересует только направление — «про одно и то же ли эти векторы» — длины нужно убрать. Поделим на них и получим косинусное сходствокосинусное сходствоEN cosine similarityКосинус угла между векторами — скалярное произведение, делённое на произведение длин. Для нормированных векторов равно скалярному произведению.:

cos⁡(a,b)=a⋅b∥a∥ ∥b∥\cos(\mathbf{a}, \mathbf{b}) = \frac{\mathbf{a} \cdot \mathbf{b}}{\lVert \mathbf{a} \rVert \, \lVert \mathbf{b} \rVert}

Это число всегда лежит между −1 и 1. Для (1,2,3)(1, 2, 3) и (4,5,6)(4, 5, 6): длины 14≈3.742\sqrt{14} \approx 3.742 и 77≈8.775\sqrt{77} \approx 8.775, косинус 32/(3.742⋅8.775)≈0.97532 / (3.742 \cdot 8.775) \approx 0.975, угол около 13°. Векторы почти сонаправлены, хотя второй длиннее первого больше чем вдвое.

Почти одно направлениеθ = 13°, cos ≈ 0.97Перпендикулярныθ = 90°, cos = 0Противоположныθ = 180°, cos = −1
Косинус угла θ между векторами — мера «смотрят ли они в одну сторону». Длины стрелок на него не влияют.

Почему для эмбеддингов берут косинус. Длина вектора часто несёт «посторонний» сигнал — например, зависит от частоты слова или длины текста. Нам же важно, о чём текст. Косинус сравнивает только направления: вектор (1,2)(1, 2) и вектор (10,20)(10, 20) для него одинаковы.

Трюк с нормировкой. Если заранее поделить все векторы на их длины, знаменатель станет равен 1, и косинус превратится в обычное скалярное произведение. Тогда сходство запроса со всеми документами базы считается одним матричным умножением — так работает поиск в RAG (урок 8.2.1). Иногда говорят о косинусном расстоянии 1−cos⁡1 - \cos: 0 для одинаковых направлений, 2 для противоположных.

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

СловоживоемаленькоепьютКитай
кошка0.90.80.00.1
cat (англ. «кошка»)0.850.750.050.1
собака0.90.30.00.2
чай0.00.10.90.7
tea (англ. «чай»)0.050.10.850.75
кофе0.00.00.90.2

Косинусы считаем в NumPy сразу для всех пар: нормируем строки и умножаем матрицу на её транспонированную (матричное умножение @ вы видели в уроке 0.3.2, подробно — в следующем уроке):

import numpy as np
words = ["кошка", "cat", "собака", "чай", "tea", "кофе"]
E = np.array([
[0.9, 0.8, 0.0, 0.1],
[0.85, 0.75, 0.05, 0.1],
[0.9, 0.3, 0.0, 0.2],
[0.0, 0.1, 0.9, 0.7],
[0.05, 0.1, 0.85, 0.75],
[0.0, 0.0, 0.9, 0.2],
])
En = E / np.linalg.norm(E, axis=1, keepdims=True) # каждую строку — на длину 1
S = En @ En.T # все косинусы разом: (6, 4) @ (4, 6) → (6, 6)
np.set_printoptions(precision=2, suppress=True)
print(S)
[[1. 1. 0.91 0.11 0.15 0.02]
[1. 1. 0.91 0.15 0.18 0.06]
[0.91 0.91 1. 0.15 0.2 0.04]
[0.11 0.15 0.15 1. 1. 0.9 ]
[0.15 0.18 0.2 1. 1. 0.87]
[0.02 0.06 0.04 0.9 0.87 1. ]]

Читаем таблицу: «кошка» и «cat» почти совпадают (0.999, после округления 1.0), «кошка» и «собака» близки (0.91), а «кошка» и «кофе» почти перпендикулярны (0.02). Многоязычные модели эмбеддингов устроены так же: «кошка» и «cat» у них оказываются рядом, потому что значат одно и то же.

На плоскости два случайных направления легко оказываются близкими. А в пространстве размерности 4096? Проверим:

import numpy as np
rng = np.random.default_rng(0)
for n in [2, 10, 100, 768, 4096]: # размерность векторов
a = rng.standard_normal((1000, n)) # 1000 случайных векторов — строки матрицы
b = rng.standard_normal((1000, n)) # и ещё 1000
# (a * b).sum(axis=1) — 1000 скалярных произведений пар «строка a, строка b» сразу (урок 0.3.2),
# norm(..., axis=1) — длины всех строк; делим одно на другое и получаем 1000 косинусов
cos = (a * b).sum(axis=1) / (np.linalg.norm(a, axis=1) * np.linalg.norm(b, axis=1))
print(f"n = {n:5d} средний |cos| = {np.abs(cos).mean():.3f} max |cos| = {np.abs(cos).max():.3f}")
n = 2 средний |cos| = 0.644 max |cos| = 1.000
n = 10 средний |cos| = 0.244 max |cos| = 0.818
n = 100 средний |cos| = 0.079 max |cos| = 0.292
n = 768 средний |cos| = 0.029 max |cos| = 0.124
n = 4096 средний |cos| = 0.013 max |cos| = 0.060

Чем больше размерность, тем ближе к нулю косинус случайной пары: типичное значение порядка 1/n1/\sqrt{n}. В многомерном пространстве почти все направления почти перпендикулярны друг другу. Из этого два практических вывода:

  1. Для случайных векторов размерности 1024 типичный косинус около 0.03, так что значение 0.3 для них было бы невероятным совпадением. Но у обученных моделей эмбеддингов векторы обычно сбиты в узкий «конус» (это называют анизотропией), и даже у текстов на совсем разные темы косинус часто заметно больше нуля. Поэтому абсолютное значение косинуса без контекста мало что значит: порог «похоже / не похоже» подбирают под конкретную модель, а при поиске смотрят прежде всего на порядок кандидатов.
  2. В пространстве из тысяч измерений помещается огромное число почти независимых направлений. Модель может «разложить» по ним много разных понятий, и они почти не будут мешать друг другу.

Реализуйте скалярное произведение, нормы, косинус и поиск ближайших слов на чистом Python — без NumPy, чтобы каждая формула прошла через ваши руки. Словарь «слов-векторов» уже в заготовке.

Косинусное сходство «слов-векторов»6 тестов
import math

# Игрушечные «эмбеддинги»: 4 оси с понятным смыслом
# [живое, маленькое, пьют, связано с Китаем]. Настоящие эмбеддинги — сотни осей без подписей.
# Английские слова — переводы русских: в многоязычной модели их векторы почти совпадают.
WORDS = {
    "кошка":  [0.9, 0.8, 0.0, 0.1],
    "cat":    [0.85, 0.75, 0.05, 0.1],
    "собака": [0.9, 0.3, 0.0, 0.2],
    "dog":    [0.85, 0.35, 0.0, 0.2],
    "чай":    [0.0, 0.1, 0.9, 0.7],
    "tea":    [0.05, 0.1, 0.85, 0.75],
    "кофе":   [0.0, 0.0, 0.9, 0.2],
    "дракон": [0.6, 0.0, 0.0, 0.95],
    "dragon": [0.55, 0.05, 0.0, 0.9],
}


def dot(a, b):
    """Скалярное произведение: a[0]*b[0] + a[1]*b[1] + ...

    Пример: dot([1, 2, 3], [4, 5, 6]) → 1·4 + 2·5 + 3·6 = 32.
    Если длины векторов разные — бросьте ValueError.
    """
    # TODO: 1) сравните len(a) и len(b); 2) total = 0; 3) в цикле по парам zip(a, b) копите x * y; 4) return total
    ...


def norm(a, p=2):
    """Норма вектора. p=2 — длина (корень из суммы квадратов), p=1 — сумма модулей.

    Примеры: norm([3, 4]) → √(9 + 16) = 5.0,  norm([3, -4], p=1) → |3| + |−4| = 7.
    """
    # TODO: если p == 1 — сумма abs(x); иначе — math.sqrt от суммы x * x
    ...


def cosine(a, b):
    """Косинусное сходство: dot(a, b) / (|a| * |b|). Для нулевого вектора верните 0.0.

    Примеры: cosine([1, 2], [10, 20]) → 1.0 (одно направление), cosine([1, 0], [0, 5]) → 0.0.
    """
    # TODO: посчитайте обе длины через norm; если одна из них 0 — return 0.0; иначе делите dot на произведение длин
    ...


def most_similar(word, vectors, k=3):
    """k слов из словаря vectors, самых похожих на word по косинусу (по убыванию).

    Само слово word в ответ не входит. Возвращает список строк.
    Пример: most_similar("чай", WORDS, k=2) → ['tea', 'кофе'].
    """
    # TODO: соберите пары (косинус, слово) для всех слов, кроме word; отсортируйте по убыванию; верните первые k слов
    ...


# Проверьте себя кнопкой «Запустить»:
print(dot([1, 2, 3], [4, 5, 6]))            # 32
print(norm([3, 4]), norm([3, 4], p=1))      # 5.0 7
print(cosine([1, 2, 3], [4, 5, 6]))          # ≈ 0.9746
print(most_similar("кошка", WORDS))         # ['cat', 'dog', 'собака']

Задание для Jupyter (по желанию). Поменяйте в словаре вектор «кофе» на [0.0, 0.0, 0.9, 0.9] («очень китайский кофе»). Насколько вырос косинус между «кофе» и «tea»? Удалось ли «кофе» обогнать «чай» в списке ближайших к «tea»? Объясните результат, сравнив координаты векторов. Затем умножьте вектор «кошка» на 10 и убедитесь, что most_similar выдаёт те же слова, а скалярные произведения — уже нет.

Проверь себя6 вопросов
1 Посчитайте скалярное произведение (2,−1,3)⋅(4,0,−2)(2, -1, 3) \cdot (4, 0, -2).
2 Чему равна L2-норма (длина) вектора (1,2,2)(1, 2, 2)?
3 Чему равно косинусное сходство векторов a\mathbf{a} и 5a5\mathbf{a} (для ненулевого a\mathbf{a})?
4 Какие утверждения верны?Можно выбрать несколько ответов
5 Зачем эмбеддинги документов нормируют на длину 1 ещё при индексации?
6 Найдите косинус угла между (1,0)(1, 0) и (1,1)(1, 1). Округлите до трёх знаков.
  • Вектор — это список чисел, точка и стрелка одновременно. Складываем и умножаем на число покоординатно (в NumPy, а не в списках Python!).
  • L2-норма — длина по Пифагору, L1 — сумма модулей. На нормах держатся RMSNorm, обрезка градиентов и weight decay.
  • Скалярное произведение ∑aibi=∥a∥∥b∥cos⁡θ\sum a_i b_i = \lVert a \rVert \lVert b \rVert \cos\theta — основа нейрона, внимания и выходного слоя LLM.
  • Косинусное сходство сравнивает только направления. После нормировки оно равно скалярному произведению, и поиск похожих эмбеддингов становится матричным умножением.
  • В многомерном пространстве случайные векторы почти перпендикулярны: их типичный косинус порядка 1/n1/\sqrt{n}. У обученных моделей эмбеддингов шкала косинуса своя, и порог сходства подбирают под модель.

Дальше: матрицы — как одно умножение превращает вектор в другой вектор и почему линейный слой нейросети — это матрица.