Spec-Zone.ru › PyTorch 1

Именованные тензоры

Именованные тензоры позволяют пользователям явно задавать имена размерностям тензора. В большинстве случаев операции, принимающие параметры размерности, будут принимать имена размерностей, избегая необходимости отслеживать размерности по положению. Кроме того, именованные тензоры используют имена для автоматической проверки правильности использования 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.

Следующие функции-фабрики поддерживают именованные тензоры:

  • torch.empty()
  • torch.rand()
  • torch.randn()
  • torch.ones()
  • torch.tensor()
  • torch.zeros()

Именованные размерности

См. 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_imgs = imgs.view(32, 3, 128, 128)
>>> unflattened_named_imgs = named_flat_imgs.unflatten(
        'features', [('C', 3), ('H', 128), ('W', 128)])

Поддержка 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. Поскольку градиенты в настоящее время не именованные, оптимизаторы могут работать, но не протестированы.

Модули NN в настоящее время не поддерживаются. Это может привести к следующему при вызове модулей с именованными тензорными входами:

  • Параметры модуля NN не именованные, поэтому выходы могут быть частично именованными.
  • Функции forward модулей NN не поддерживают именованные тензоры и будут выводить соответствующую ошибку.

Мы также не поддерживаем следующие подсистемы, хотя некоторые из них могут работать «из коробки»:

  • распределения
  • сериализация (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() используется метод 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/1.13/named_tensor.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API