Математика глубокого обучения
Тензоры
Многомерный массив, порядок осей — и почему математический тензор это другое
Что называют тензором здесь
В глубоком обучении тензор — это многомерный массив чисел плюс его форма. Ничего больше.
Длина
| порядок | как называют | пример |
|---|---|---|
| скаляр | значение лосса | |
| вектор | эмбеддинг токена | |
| матрица | батч эмбеддингов | |
| — | батч × позиция × канал | |
| — | батч × канал × высота × ширина |
Слово «размерность» здесь перегружено, и путаница из-за него реальна: у тензора формы
порядок равен двум, а «размерность эмбеддинга» равна . Первое — сколько
осей, второе — длина одной из них. В коде это len(x.shape) против x.shape[-1].
Математический тензор — не это
Оговорка, которая экономит недоумение при чтении физики или дифференциальной геометрии.
Там тензор — это полилинейное отображение, определённое независимо от координат, с законом преобразования компонент при замене базиса. Массив чисел — лишь его представление в выбранном базисе, и требование состоит в том, что при смене базиса компоненты меняются согласованно.
| тензор в ML | тензор в математике | |
|---|---|---|
| что это | массив с формой | полилинейное отображение |
| зависит от базиса | вопрос не ставится | нет, компоненты — да |
| индексы верх/низ | нет | различаются (ко- и контравариантность) |
| «тензор ранга 2» | форма из двух чисел | ранг как у линейного оператора |
Слово «ранг» тоже расходится: в PyTorch rank иногда означает число осей, а в линейной
алгебре (блок 1, урок 030) — размерность образа. У матрицы «ранг 2» в первом
смысле и «ранг 2» во втором — совершенно разные утверждения.
Никакой практической беды в этом нет: в машинном обучении полилинейность и законы
преобразования не используются. Знать различие нужно ровно затем, чтобы не искать в
torch того, чего там нет.
Порядок осей — это соглашение
Одни и те же данные хранят по-разному, и это источник целого класса ошибок.
| соглашение | форма | где |
|---|---|---|
| NCHW | батч, канал, высота, ширина | PyTorch по умолчанию |
| NHWC | батч, высота, ширина, канал | TensorFlow, часть ускорителей |
| batch-first | батч, позиция, признак | трансформеры обычно |
| seq-first | позиция, батч, признак | старые RNN-API, nn.Transformer по умолчанию |
Последняя строка стоит внимания: у torch.nn.Transformer параметр batch_first
исторически по умолчанию равен False. Тензор формы будет прочитан как
« позиции, батч » вместо ожидаемого. Ошибка не падает — формы сходятся, — и
проявляется только качеством.
Отсюда практическое правило: ось — это не номер, а имя. Полезно записывать формы в
комментариях или пользоваться einops, где оси называются:
# вместо x.permute(0, 2, 1, 3)
rearrange(x, 'b h n d -> b n h d')
Второе читается и, что важнее, проверяется глазами.
Форма против расположения в памяти
Тензор — это буфер плюс страйды, то есть шаги в элементах по каждой оси. Отсюда две вещи, которые обычно узнают на ошибке.
Транспонирование не копирует. x.T возвращает вид: тот же буфер, переставленные
страйды. Дёшево, но результат становится нессмежным, и часть операций (например
.view()) на нём не работает — отсюда RuntimeError про contiguous и привычка ставить
.contiguous().
view против reshape. view требует совместимости со страйдами и падает, если её
нет; reshape при необходимости копирует. То есть view — это обещание «копирования не
будет», и падение здесь полезно: оно сообщает о неожиданном копировании, а не мешает.
Разница между и тоже стоит понимания: данные те же, но вторая форма имеет ось длины , и это меняет поведение broadcasting — о чём следующий урок. Ось длины не бесполезна: она и есть способ сказать «сюда можно растянуть».
Что стоит унести
- порядок — сколько осей, размерность признаков — длина одной оси. Разные вещи;
- математический тензор — другое понятие, и искать его в фреймворке не нужно;
- порядок осей — соглашение, различающееся между библиотеками, и ошибки в нём не падают, а тихо портят результат;
- форма и расположение в памяти — не одно и то же;
viewдаёт вид,reshapeможет скопировать.
Источники
- PyTorch — Tensor semantics — Формы, страйды, представления
- Rogozhnikov — Einops tutorial — Осмысленная работа с осями
Проверки
0 из 2Что такое тензор здесь
Отметьте все верные утверждения о тензорах в глубоком обучении.
Порядок, элементы, страйды
Дана форма тензора как список
shape. Реализуйтеtensor_facts(shape)— верните[order, elements, feature_dim, stride_of_axis_0]:order— число осей (для скаляра, то есть пустого списка, это );elements— произведение всех размеров (для скаляра — : пустое произведение);feature_dim— размер последней оси, или-1.0для скаляра;stride_of_axis_0— страйд нулевой оси при построчном (row-major) размещении, то есть произведение размеров всех последующих осей. Для скаляра верните-1.0.
Страйд — это на сколько элементов нужно шагнуть в буфере, чтобы сдвинуться на единицу по данной оси. Для формы шаг по нулевой оси равен .
Загрузка редактора…
Ctrl/⌘ + Enter