Именованные тензоры
Именованные тензоры позволяют пользователям явно присваивать имена размерностям тензоров. В большинстве случаев операции, принимающие параметры размерности, будут принимать имена размерностей, избегая необходимости отслеживать размерности по положению. Кроме того, именованные тензоры используют имена для автоматической проверки правильности использования API во время выполнения, обеспечивая дополнительную безопасность. Имена также могут использоваться для переупорядочивания размерностей, например, для поддержки «вещания по имени» вместо «вещания по положению».
Предупреждение
API именованных тензоров является прототипной функцией и может быть изменён.
Создание именованных тензоров
Функции-фабрики теперь принимают новый names аргумент, который сопоставляет имя каждой размерности.
>>> torch.zeros(2, 3, names=('N', 'C'))
tensor([[0., 0., 0.],
[0., 0., 0.]], names=('N', 'C'))
Именованные размерности, подобно обычным размерностям тензора, упорядочены. tensor.names[i] — это имя размерности i тензора tensor.
Следующие функции-фабрики поддерживают именованные тензоры:
Именованные размерности
См. names для ограничений на имена тензоров.
Используйте names для доступа к именам размерностей тензора и rename() для переименования именованных размерностей.
>>> imgs = torch.randn(1, 2, 2, 3 , names=('N', 'C', 'H', 'W'))
>>> imgs.names
('N', 'C', 'H', 'W')
>>> renamed_imgs = imgs.rename(H='height', W='width')
>>> renamed_imgs.names
('N', 'C', 'height', 'width)
Именованные тензоры могут сосуществовать с неуказанными тензорами; именованные тензоры являются экземплярами torch.Tensor. У неуказанных тензоров есть None-именованные размерности. Именованные тензоры не требуют, чтобы все размерности были именованными.
>>> imgs = torch.randn(1, 2, 2, 3 , names=(None, 'C', 'H', 'W')) >>> imgs.names (None, 'C', 'H', 'W')
Семантика распространения имён
Именованные тензоры используют имена для автоматической проверки правильности вызова API во время выполнения. Это происходит в процессе, называемом *выведением имен*. Более формально, вывод имен состоит из следующих двух шагов:
- Проверка имён: оператор может выполнять автоматические проверки во время выполнения, которые проверяют, что определённые имена размерностей должны совпадать.
- Распространение имён: вывод имен распространяет имена на выходные тензоры.
Все операции, поддерживающие именованные тензоры, распространяют имена.
>>> x = torch.randn(3, 3, names=('N', 'C'))
>>> x.abs().names
('N', 'C')
Семантика соответствия
Два имени совпадают, если они равны (равенство строк) или если хотя бы одно из них None. Значения None по существу являются специальным «подстановочным» именем.
unify(A, B) определяет, какое из имён A и B распространить на выходы. Она возвращает более *специфичное* из двух имён, если они совпадают. Если имена не совпадают, то возникает ошибка.
Примечание
На практике при работе с именованными тензорами следует избегать использования неуказанных размерностей, так как их обработка может быть сложной. Рекомендуется преобразовать все неуказанные размерности в именованные размерности, используя refine_names().
Основные правила вывода имён
Давайте посмотрим, как match и unify используются в выводе имен при сложении двух одномерных тензоров без вещания.
x = torch.randn(3, names=('X',))
y = torch.randn(3)
z = torch.randn(3, names=('Z',))
Проверка имён: проверка того, что имена двух тензоров совпадают.
Для следующих примеров:
>>> # x + y # match('X', None) is True
>>> # x + z # match('X', 'Z') is False
>>> # x + x # match('X', 'X') is True
>>> x + z
Error when attempting to broadcast dims ['X'] and dims ['Z']: dim 'X' and dim 'Z' are at the same position from the right but do not match.
Распространение имён: *объединение* имён для выбора того, какое из них распространить. В случае x + y, unify('X', None) = 'X', так как 'X' является более специфичным, чем None.
>>> (x + y).names
('X',)
>>> (x + x).names
('X',)
Полный список правил вывода имён см. в Охват операторов именованных тензоров. Вот две распространённые операции, которые могут быть полезны:
- Бинарные арифметические операции: Объединяет имена из входных данных
- Операции матричного умножения: Удаляет размерности
Явное выравнивание по именам
Используйте align_as() или align_to() для выравнивания размерностей тензора по имени до заданного порядка. Это полезно для выполнения «вещания по именам».
# This function is agnostic to the dimension ordering of `input`,
# as long as it has a `C` dimension somewhere.
def scale_channels(input, scale):
scale = scale.refine_names('C')
return input * scale.align_as(input)
>>> num_channels = 3
>>> scale = torch.randn(num_channels, names=('C',))
>>> imgs = torch.rand(3, 3, 3, num_channels, names=('N', 'H', 'W', 'C'))
>>> more_imgs = torch.rand(3, num_channels, 3, 3, names=('N', 'C', 'H', 'W'))
>>> videos = torch.randn(3, num_channels, 3, 3, 3, names=('N', 'C', 'H', 'W', 'D')
>>> scale_channels(imgs, scale)
>>> scale_channels(more_imgs, scale)
>>> scale_channels(videos, scale)
Изменение размерностей
Используйте align_to() для перестановки большого количества размерностей без упоминания всех из них, как это требуется в permute().
>>> tensor = torch.randn(2, 2, 2, 2, 2, 2)
>>> named_tensor = tensor.refine_names('A', 'B', 'C', 'D', 'E', 'F')
# Move the F (dim 5) and E dimension (dim 4) to the front while keeping
# the rest in the same order
>>> tensor.permute(5, 4, 0, 1, 2, 3)
>>> named_tensor.align_to('F', 'E', ...)
Используйте flatten() и unflatten() для сглаживания и восстановления размерностей соответственно. Эти методы более подробны, чем view() и reshape(), но имеют более понятный семантический смысл для читающего код.
>>> imgs = torch.randn(32, 3, 128, 128)
>>> named_imgs = imgs.refine_names('N', 'C', 'H', 'W')
>>> flat_imgs = imgs.view(32, -1)
>>> named_flat_imgs = named_imgs.flatten(['C', 'H', 'W'], 'features')
>>> named_flat_imgs.names
('N', 'features')
>>> unflattened_named_imgs = named_flat_imgs.unflatten('features', [('C', 3), ('H', 128), ('W', 128)])
>>> unflattened_named_imgs.names
('N', 'C', 'H', 'W')
Поддержка Autograd
В настоящее время Autograd ограниченно поддерживает именованные тензоры: Autograd игнорирует имена всех тензоров. Вычисление градиента всё ещё корректно, но мы теряем безопасность, которую обеспечивают имена.
>>> x = torch.randn(3, names=('D',))
>>> weight = torch.randn(3, names=('D',), requires_grad=True)
>>> loss = (x - weight).abs()
>>> grad_loss = torch.randn(3)
>>> loss.backward(grad_loss)
>>> weight.grad # Unnamed for now. Will be named in the future
tensor([-1.8107, -0.6357, 0.0783])
>>> weight.grad.zero_()
>>> grad_loss = grad_loss.refine_names('C')
>>> loss = (x - weight).abs()
# Ideally we'd check that the names of loss and grad_loss match but we don't yet.
>>> loss.backward(grad_loss)
>>> weight.grad
tensor([-1.8107, -0.6357, 0.0783])
В настоящее время поддерживаемые операции и подсистемы
Операторы
Полный список поддерживаемых операций torch и тензоров см. в Охват операторов именованных тензоров. Мы пока не поддерживаем следующие операции, не охваченные ссылкой:
- индексация, расширенная индексация.
Для torch.nn.functional операторов мы поддерживаем следующие:
torch.nn.functional.relu()torch.nn.functional.softmax()torch.nn.functional.log_softmax()torch.nn.functional.tanh()torch.nn.functional.sigmoid()torch.nn.functional.dropout()
Подсистемы
Поддерживается Autograd, см. Поддержка Autograd. Поскольку градиенты в настоящее время не имеют имён, оптимизаторы могут работать, но не протестированы.
Модули нейронных сетей в настоящее время не поддерживаются. Это может привести к следующим проблемам при вызове модулей с именованными тензорными входами:
- Параметры модулей нейронных сетей не имеют имён, поэтому выходы могут быть частично именованными.
- В модулях нейронных сетей есть код, не поддерживающий именованные тензоры, и он будет выдавать соответствующую ошибку.
Мы также не поддерживаем следующие подсистемы, хотя некоторые могут работать «из коробки»:
- распределения
- сериализация (
torch.load(),torch.save()) - многопроцессорная обработка
- JIT
- распределённые вычисления
- ONNX
Если это необходимо для вашего случая использования, пожалуйста, найдите уже открытый вопрос, а если нет, создайте новый.
Справочник по API именованных тензоров
В этом разделе вы найдёте документацию для API, специфичных для именованных тензоров. Для полного справочника по тому, как имена распространяются через другие операторы PyTorch, см. Охват операторов именованных тензоров.
- classtorch.Tensor
-
-
names -
Хранит имена для каждой из размерностей этого тензора.
names[idx]соответствует имени размерности тензораidx. Имена — это либо строка, если размерность имеет имя, либоNone, если размерность не имеет имени.Имена размерностей могут содержать буквы, цифры или знак подчеркивания. Кроме того, имя размерности должно быть допустимым именем переменной Python (то есть не начинаться с подчеркивания).
У тензора не может быть двух именованных размерностей с одинаковым именем.
Предупреждение
API именованных тензоров находится в стадии разработки и может быть изменен.
-
rename(*names, **rename_map)[source] -
Переименовывает имена размерностей
self.Существуют два основных способа использования:
self.rename(**rename_map)возвращает представление тензора, у которого размерности переименованы, как указано в отображенииrename_map.self.rename(*names)возвращает представление тензора, переименовывая все размерности позиционно с помощьюnames. Для удаления имен у тензора используйтеself.rename(None).Нельзя указывать как позиционные аргументы
names, так и именованные аргументыrename_map.Примеры:
>>> imgs = torch.rand(2, 3, 5, 7, names=('N', 'C', 'H', 'W')) >>> renamed_imgs = imgs.rename(N='batch', C='channels') >>> renamed_imgs.names ('batch', 'channels', 'H', 'W') >>> renamed_imgs = imgs.rename(None) >>> renamed_imgs.names (None, None, None, None) >>> renamed_imgs = imgs.rename('batch', 'channel', 'height', 'width') >>> renamed_imgs.names ('batch', 'channel', 'height', 'width')Предупреждение
API именованных тензоров находится в стадии разработки и может быть изменен.
-
rename_(*names, **rename_map)[source] -
Встроенная версия
rename().
-
refine_names(*names)[source] -
Уточняет имена размерностей
selfв соответствии сnames.Уточнение — это частный случай переименования, который «поднимает» безымянные размерности. Безымянную
Noneразмерность можно уточнить, присвоив ей любое имя; именованную размерность можно уточнить, только присвоив ей то же имя.Поскольку именованные и безымянные тензоры могут сосуществовать, уточнение имен предоставляет удобный способ написания кода, учитывающего именованные тензоры, который работает как с именованными, так и с безымянными тензорами.
namesможет содержать не более одного многоточия (...). Многоточие расширяется жадно; оно расширяется на месте, чтобы заполнитьnamesдо той же длины, что иself.dim(), используя имена из соответствующих индексовself.names.В Python 2 многоточие не поддерживается, но вместо него можно использовать строковый литерал (
'...').- Параметры
-
names (итерируемый из str) — желаемые имена размерностей выходного тензора. Может содержать не более одного многоточия.
Примеры:
>>> imgs = torch.randn(32, 3, 128, 128) >>> named_imgs = imgs.refine_names('N', 'C', 'H', 'W') >>> named_imgs.names ('N', 'C', 'H', 'W') >>> tensor = torch.randn(2, 3, 5, 7, 11) >>> tensor = tensor.refine_names('A', ..., 'B', 'C') >>> tensor.names ('A', None, None, 'B', 'C')Предупреждение
API именованных тензоров находится в стадии разработки и может быть изменен.
-
align_as(other) → Tensor -
Переставляет размерности тензора
selfв соответствии с порядком размерностей в тензореother, добавляя размерности размером 1 для любых новых имен.Эта операция полезна для явного вещания по именам (см. примеры).
Все размерности
selfдолжны быть именованы для использования этого метода. Результирующий тензор является представлением исходного тензора.Все имена размерностей
selfдолжны присутствовать вother.names.otherможет содержать именованные размерности, отсутствующие вself.names; для каждого из этих новых имен выходной тензор имеет размерность размером 1.Для выравнивания тензора по определенному порядку используйте
align_to().Примеры:
# Example 1: Applying a mask >>> mask = torch.randint(2, [127, 128], dtype=torch.bool).refine_names('W', 'H') >>> imgs = torch.randn(32, 128, 127, 3, names=('N', 'H', 'W', 'C')) >>> imgs.masked_fill_(mask.align_as(imgs), 0) # Example 2: Applying a per-channel-scale >>> def scale_channels(input, scale): >>> scale = scale.refine_names('C') >>> return input * scale.align_as(input) >>> num_channels = 3 >>> scale = torch.randn(num_channels, names=('C',)) >>> imgs = torch.rand(32, 128, 128, num_channels, names=('N', 'H', 'W', 'C')) >>> more_imgs = torch.rand(32, num_channels, 128, 128, names=('N', 'C', 'H', 'W')) >>> videos = torch.randn(3, num_channels, 128, 128, 128, names=('N', 'C', 'H', 'W', 'D')) # scale_channels is agnostic to the dimension order of the input >>> scale_channels(imgs, scale) >>> scale_channels(more_imgs, scale) >>> scale_channels(videos, scale)Предупреждение
API именованных тензоров находится в стадии разработки и может быть изменен.
-
align_to(*names)[source] -
Переставляет размерности тензора
selfв соответствии с порядком, указанным вnames, добавляя размерности размером 1 для любых новых имен.Все размерности
selfдолжны быть именованы для использования этого метода. Результирующий тензор является представлением исходного тензора.Все имена размерностей
selfдолжны присутствовать вnames.namesможет содержать дополнительные имена, отсутствующие вself.names; для каждого из этих новых имен выходной тензор имеет размерность размером 1.namesможет содержать не более одного многоточия (...). Многоточие расширяется, чтобы охватить все имена размерностейself, которые не упомянуты вnames, в порядке их появления вself.В Python 2 многоточие не поддерживается, но вместо него можно использовать строковый литерал (
'...').- Параметры
-
names (итерируемый из str) — желаемый порядок размерностей выходного тензора. Может содержать не более одного многоточия, которое расширяется до всех неупомянутых имен размерностей
self.
Примеры:
>>> tensor = torch.randn(2, 2, 2, 2, 2, 2) >>> named_tensor = tensor.refine_names('A', 'B', 'C', 'D', 'E', 'F') # Move the F and E dims to the front while keeping the rest in order >>> named_tensor.align_to('F', 'E', ...)Предупреждение
API именованных тензоров находится в стадии разработки и может быть изменен.
- flatten(dims, out_dim) Tensor
-
Сжимает
dimsв одну размерность с именемout_dim.Все размерности
dimsдолжны быть последовательными в порядке в тензореself, но не обязательно непрерывными в памяти.Примеры:
>>> imgs = torch.randn(32, 3, 128, 128, names=('N', 'C', 'H', 'W')) >>> flat_imgs = imgs.flatten(['C', 'H', 'W'], 'features') >>> flat_imgs.names, flat_imgs.shape (('N', 'features'), torch.Size([32, 49152]))Предупреждение
API именованных тензоров находится в стадии разработки и может быть изменен.
-
© 2024, PyTorch Contributors
PyTorch has a BSD-style license, as found in the LICENSE file.
https://pytorch.org/docs/2.1/named_tensor.html