Операции над тензорами

Последнее обновление: 03.12.2025

Для тензоров доступно более 1200 операций, таких как арифметические операции, линейную алгебру, манипуляции с матрицами (транспонирование, индексирование, нарезку), выборку и т.д.. Эти операции могут выполняться на центральном или графическом процессоре. Рассмотрим некоторые самые базовые операции.

Получение элементов тензора

Используя квадратные скобки [], можно обращаться к элементам тензора (подобно тому, как это делается в списках Python):

import torch

tensor = torch.tensor([[1, 2],[3, 4]])
# получаем элементы
print(f"Первая строка: {tensor[0]}")    # [1, 2]
print(f"Второй элемент (1-я строка 2-й столбец): {tensor[0][1]}")   # 2

# изменяем элементы
tensor[0][1] = 4   # изменяем второй столбец первой строки
tensor[1] = torch.tensor([11, 12])       # изменяем вторую строку

print(tensor)

Консольный вывод:

Первая строка: tensor([1, 2])
Второй элемент (1-я строка 2-й столбец): 2
tensor([[ 1,  4],
        [11, 12]])

Для каждой размерности тензора можно использовать свою пару квадратных скобок, либо можно внутри одной пары квадратных скобок передать индексы для каждой размерности. Так, следующие выражения будут идентичны:

tensor[0][1]
tensor[0, 1]

Отрицательные значения начального и конечного индексов интерпретируются номер элемента с конца в виде n-i, где n - количество элементов в данной размерности, а i - индекс.

import torch

tensor = torch.tensor([[1, 2],[3, 4]])
tensor[0, -2] = 4   # изменяем второй столбец с конца первой строки

print(tensor)   # tensor([[ 4,  2], [11, 12]])

Для получения диапазона элементов из тензора можно использовать операцию : в виде начало:конец:шаг. Например:

import torch

tensor = torch.tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(tensor[1:4])   # tensor([1, 2, 3])
print(tensor[1:8:2])   # tensor([1, 3, 5, 7])

В первом случае (tensor[1:4]) получаем диапазон со второго элемента (индекс 1) до 5-го элемента не включая (до элемента с индексом 4)

Во второом случае (tensor[1:8:2]) получаем диапазон со второго элемента (индекс 1) до 9-го элемента не включая (до элемента с индексом 8) с шагом в 2 элемента.

Можно использовать отрицательные индексы, тогда отсчет будет идти с конца:

import torch

tensor = torch.tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(tensor[-4:-1])   # tensor([6, 7, 8])

Также можно использовать один из индексов, либо не использовать вовсе. Если оба индекса не указаны, то выбирается весь список. Если не указан начальный индекс, то в качестве начала используется самый первый элемент. Если не указан конечный индекс, то в качестве него применяется самый последний элемент:

import torch

tensor = torch.tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(tensor[:])    # tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
print(tensor[2:])   # tensor([2, 3, 4, 5, 6, 7, 8, 9])
print(tensor[:7])   # tensor([0, 1, 2, 3, 4, 5, 6])

Подобным образом мы можем выбирать диапазаоны и в многомерных тензорах. Например, если у нас двухмерный тензор (матрица), то мы можем использовать диапазон для выбора определенных строк и их определенных столбцов. Например, выберем второй столбец матрицы определенных строк:

import torch

tensor = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5], 
                    [6, 7, 8]
                ])
# выбираем второй столбец
print(tensor[:, 1])    # tensor([1, 4, 7]) - все строк
print(tensor[1:, 1])   # tensor([4, 7]) - 2 и 3 строк
print(tensor[:2, 1])   # tensor([1, 4])  - 1 и 2 строк

Еще один элемент, который можно использовать, - это многоточие .... Многоточие расширяется до количества объектов (:), необходимых для индексации всех измерений. Например:

import torch

tensor = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5], 
                    [6, 7, 8]
                ])
# выбираем первый столбец
print(tensor[..., 0])    # tensor([0, 3, 6])
# выбираем последний столбец
print(tensor[..., -1])   # tensor([2, 5, 8])

Объединение тензоров

Для объединения тензоров по определенному измерению можно использовать функцию torch.cat():

import torch

tensor1 = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5]
                ])
tensor2 = torch.tensor([
                    [6, 7, 8], 
                    [9, 10, 11]
                ])

# объединяем по первой размерности
tensor_all = torch.cat([tensor1, tensor2], dim=0)
print("dim=0\n", tensor_all)

# объединяем по второй размерности
tensor_all = torch.cat([tensor1, tensor2], dim=1)
print("dim=1\n", tensor_all)    

Первым параметром в функцию torch.cat передается массив объединяемых тензоров, а второй параметр представляет размерности, по которой ижет объединение. Так, в примере выше в первом случае с dim=0 объединяем по первой размерности (то есть все строки), а во втором случае (dim=1) объединяем столбцы внутри строк. Консольный вывод программы:

dim=0
 tensor([[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11]])
dim=1
 tensor([[ 0,  1,  2,  6,  7,  8],
        [ 3,  4,  5,  9, 10, 11]])

Арифметические операции

В PyTorch арифметические операции над тензорами включают сложение, вычитание, умножение и деление. Эти операции можно выполнять поэлементно между тензорами или между тензорами и скалярами, автоматически применяя операцию к каждому элементу, что упрощает математические вычисления с многомерными данными. Рассмотрим некоторые из этих операций. Операции со скалярным значением:

import torch

tensor1 = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5]
                ])

# сложение со скаляром
tensor2 = tensor1 + 1
print(tensor2)  
# Результат: 
#  tensor([[1, 2, 3],
#        [4, 5, 6]])

# вычитание скалярного значения
tensor3 = tensor1 - 1
print(tensor3)  
# Результат: 
#  tensor([[-1,  0,  1],
#        [ 2,  3,  4]])

# умножение на скаляр
tensor4 = tensor1 * 2
print(tensor4)  
# Результат: 
#  tensor([[ 0,  2,  4],
#        [ 6,  8, 10]])

Аналогичные операции между тензорами:

import torch

tensor1 = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5]
                ])

# создаем единичную матрицу с числами типа int
tensor2 = torch.ones((2, 3), dtype= torch.int)

print(tensor2)
# tensor([[1, 1, 1],
#        [1, 1, 1]], dtype=torch.int32)


# сложение тензоров
tensor3 = tensor1 + tensor2
print(tensor3)  
# Результат: 
#  tensor([[1, 2, 3],
#        [4, 5, 6]])

# вычитание тензоров
tensor4 = tensor1 - tensor2
print(tensor4)  
# Результат: 
#  tensor([[-1,  0,  1],
#        [ 2,  3,  4]])

# умножение тензоров
tensor5 = tensor1 * tensor2
print(tensor5)  
# Результат: 
#  tensor([[0, 1, 2],
#          [3, 4, 5]])

Отдельно стоит сказать про умножение. Стандартная операция * представляет поэлементное умножение тензоров. И в качестве альтернативы этой операции можно использовать функцию mul():

import torch

tensor1 = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5]
                ])

tensor2 = torch.tensor([
                    [1, 2, 1], 
                    [1, 1, 1]
                ])

# поэлементное умножение тензоров
tensor5 = tensor1 * tensor2
print(tensor5)  
# Результат: 
#  tensor([[0, 2, 2],
#          [3, 4, 5]])

tensor6 = tensor1.mul(tensor2)
print(tensor6)  
# Результат: 
#  tensor([[0, 2, 2],
#          [3, 4, 5]])

Если же нам надо осуществить умножение матриц, то для этого применяется операция @ или функция matmul():

import torch

tensor1 = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5]
                ])

tensor2 = torch.tensor([
                    [1, 2], 
                    [1, 2],
                    [1, 2]
                ])

# умножение матриц
tensor3 = tensor1.matmul(tensor2)
print(tensor3)  
# Результат: 
#  tensor([[ 3,  6],
#        [12, 24]])

tensor4 = tensor1 @ tensor2
print(tensor4)  
# Результат: 
#  tensor([[ 3,  6],
#        [12, 24]])

Ряд операций представлены специальными функциями. Например, функция sum() вычисляет сумму всех элементов тензора, а функция dot() - скалярное произведение двух одномерных векторов:

import torch

tensor = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5]
                ])
tensor_sum = tensor.sum()
print(tensor_sum)    # tensor(15)

# умножаем вектор [2, 3] на [2, 1]
tensor_dot = torch.dot(torch.tensor([2, 3]), torch.tensor([2, 1]))
print(tensor_dot)           # tensor(7)

Причем некоторые операции, как рассмотренные выше sum() и dot(), возвращают тензор с одним элементом. С помощью функции item() подобный тензор можно преобразовать в скалярное значение языка Python:

import torch

tensor = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5]
                ])
tensor_sum = tensor.sum()
print(tensor_sum)    # tensor(15)

value_sum = tensor_sum.item()
print(value_sum)    # 15

# умножаем вектор [2, 3] на [2, 1]
tensor_dot = torch.dot(torch.tensor([2, 3]), torch.tensor([2, 1]))
print(tensor_dot)           # tensor(7)
print(tensor_dot.item())    # 7

Транспонирование матрицы

С помощью свойства T можно получить транспонированную матрицу:

import torch

tensor1 = torch.tensor([
                    [0, 1, 2], 
                    [3, 4, 5]
                ])

print(tensor1.T)
# tensor([[0, 3],
#        [1, 4],
#        [2, 5]])


tensor2 = tensor1 @ tensor1.T
print(tensor2)  

Перемещение тензора

По умолчанию тензоры создаются на центральном процессоре. Если необходимо задействовать графический процессор для повышения производительности во время обучения модели и вывода, то надо явно переместить тензоры на графический процессор с помощью метода to() после проверки доступности графического процессора. Пример перемещения тензора на граф. процессор:

if torch.accelerator.is_available():
    tensor = tensor.to(torch.accelerator.current_accelerator())

Обратите внимание, что перемещение тензора происходит только, если в системе доступен графический процессор с поддержкой CUDA.

Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850