2025, Oct 30 21:17
Обратный сдвиг тензора в PyTorch: roll с отрицательным смещением
Показываем, как выполнить обратный круговой сдвиг тензора в PyTorch с помощью roll: используйте отрицательное смещение по нужной оси. Примеры кода и пояснения.
При вращении элементов тензора в PyTorch с помощью roll легко подумать, что есть только одно направление. По умолчанию положительный сдвиг как будто толкает значения «вниз» или вправо. Но иногда нужна противоположная операция — сдвиг влево или вверх. Обращение через inverse — это другое: оно переворачивает всю последовательность, а не меняет направление кругового сдвига. Ниже — короткий и практичный способ прокрутить в обратную сторону без лишних шагов.
Постановка задачи
Допустим, у нас есть одномерный тензор:
import torch
vec = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
shifted = vec.roll(1, 0)
print(shifted)
Это перемещает последний элемент в начало — фактически поворот вправо:
tensor([6., 1., 2., 3., 4., 5.])
Но цель — получить противоположный порядок:
[2.0, 3.0, 4.0, 5.0, 6.0, 1.0]
В некоторых пайплайнах после поворота последний элемент затем зануляют, но ключевой момент здесь — сменить направление самого roll.
Что происходит на самом деле
roll выполняет круговой сдвиг вдоль указанного измерения. Знак смещения определяет направление: положительное значение сдвигает в одну сторону, отрицательное — в другую. inverse полностью разворачивает последовательность, что не равно направленному сдвигу.
Решение
Используйте отрицательный сдвиг, чтобы прокрутить в противоположную сторону. Этого достаточно.
import torch
src = torch.tensor([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
rotated_left = src.roll(-1, 0)
print(rotated_left)
Результат:
tensor([2., 3., 4., 5., 6., 1.])
Официальная документация показывает тот же принцип для многомерных тензоров. Например, тензор 4x2, прокрученный вверх вдоль измерения 0 со сдвигом -1:
import torch
mat = torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]).view(4, 2)
print(mat)
print(torch.roll(mat, -1, 0))
Результат:
tensor([[1, 2],
        [3, 4],
        [5, 6],
        [7, 8]])
tensor([[3, 4],
        [5, 6],
        [7, 8],
        [1, 2]])
Справка: https://docs.pytorch.org/docs/stable/generated/torch.roll.html
Почему это важно
Направление при преобразовании последовательностей — частый источник незаметных ошибок. Отрицательный сдвиг в roll делает намерение очевидным и избавляет от реверса или другого постобработчика. Этот нюанс легко упустить, когда бегло ищешь «поведение, похожее на pop», хотя такой сценарий прямо описан в документации.
Выводы
Если нужно прокрутить тензор PyTorch в обратном направлении, не переходите на inverse и не выдумывайте обходные пути. Вызовите roll с отрицательным сдвигом по нужному измерению. Так вы явно выражаете намерение, соблюдаете описанное в документации поведение и сохраняете операцию корректной и лаконичной.