Матрица как таблица и как преобразование

Матрица — это таблица чисел и одновременно «машина», которая берёт вектор и превращает его в другой вектор.

Матрица — прямоугольная таблица чисел размера m×n (m строк, n столбцов). В коде — список списков (строки), каждая строка — список (столбцы).

Матрица как таблица

Самый прямой взгляд: матрица — это таблица. Размер записывают как «строки×столбцы». У элемента два индекса: номер строки и номер столбца. В Python это список строк, где каждая строка — список чисел.

M = [
    [1, 2, 3],
    [4, 5, 6],
]

rows = len(M)
cols = len(M[0])
print("Размер:", rows, "x", cols)   # 2 x 3
print("Элемент [0][2] =", M[0][2])  # строка 0, столбец 2
print("Элемент [1][0] =", M[1][0])
print("Вторая строка:", M[1])

Вывод:

Размер: 2 x 3
Элемент [0][2] = 3
Элемент [1][0] = 4
Вторая строка: [4, 5, 6]

Матрица как преобразование

Куда важнее второй взгляд. Матрица — это функция над векторами: подаёшь вектор, получаешь другой вектор. Действие задаётся умножением матрицы на вектор: координата i результата — это скалярное произведение i-й строки матрицы на вектор. Так матрицы умеют растягивать, поворачивать, отражать и сдвигать пространство. Слой нейросети — это матрица: она преобразует вектор входа в вектор следующего слоя.

# Матрица на вектор: каждая координата результата — скалярное
# произведение соответствующей строки на вектор
def matvec(M, v):
    return [sum(row[j] * v[j] for j in range(len(v))) for row in M]

# Матрица, растягивающая x в 2 раза, y в 3 раза
scale = [
    [2, 0],
    [0, 3],
]
print("scale @ [1, 1] =", matvec(scale, [1, 1]))
print("scale @ [5, 2] =", matvec(scale, [5, 2]))

Вывод:

scale @ [1, 1] = [2, 3]
scale @ [5, 2] = [10, 6]

Поворот — тоже матрица

Чтобы прочувствовать «матрица = преобразование», повернём вектор на 90°. Матрица поворота против часовой стрелки на 90° равна [[0, −1], [1, 0]]. Она отправляет ось x в ось y.

def matvec(M, v):
    return [sum(row[j] * v[j] for j in range(len(v))) for row in M]

rotate90 = [
    [0, -1],
    [1,  0],
]
print("Поворот (1, 0) на 90 =", matvec(rotate90, [1, 0]))  # стала (0, 1)
print("Поворот (0, 1) на 90 =", matvec(rotate90, [0, 1]))  # стала (-1, 0)

Вывод:

Поворот (1, 0) на 90 = [0, 1]
Поворот (0, 1) на 90 = [-1, 0]

Итог

  • Матрица m×n — таблица чисел; в коде список строк (список списков).
  • Главный смысл: матрица — преобразование, превращающее вектор в другой вектор.
  • Матрица на вектор: координата i = скалярное произведение i-й строки на вектор.
  • Растяжение, поворот, отражение — всё это матрицы; слой нейросети — это матрица.
Проверьте себя
1. Каков размер матрицы [[1, 2, 3], [4, 5, 6]]?
A3×2
B2×3
C6×1
D2×2
2. Как получается i-я координата результата умножения матрицы на вектор?
AСумма всех элементов матрицы
BСкалярное произведение i-й строки матрицы на вектор
CПроизведение i-го элемента вектора на i-й столбец
DМаксимум по i-й строке
3. Что концептуально делает матрица с вектором?
AХранит его в памяти
BПреобразует его в другой вектор (растягивает, поворачивает, отражает)
CПревращает его в число
DСортирует его координаты
Поддержать проект