Тензор PyTorch
Тензор — это многомерный массив, который может быть скаляром, вектором, матрицей или структурой данных большей размерности.
В PyTorch тензор — это основное представление данных, аналогичное многомерным массивам NumPy, но с более мощными возможностями, такими как поддержка ускорения на GPU и автоматическое вычисление градиентов.
Тензоры поддерживают несколько типов данных (целочисленный, с плавающей запятой, логический и т. д.).
Тензоры могут храниться на CPU или GPU; тензоры GPU могут значительно ускорить вычисления.
На следующем рисунке показано, как представляются тензоры разных размерностей в PyTorch:

Пояснение:
- 1D-тензор / Вектор (одномерный тензор/вектор):Самая базовая форма тензора, которую можно рассматривать как массив. В примере на рисунке представлен вектор, содержащий 10 элементов.
- 2D-тензор / Матрица (двумерный тензор/матрица):Двумерный массив, обычно используемый для представления матрицы. В примере на рисунке показана матрица 4x5, содержащая 20 элементов.
- 3D-тензор / Куб (трёхмерный тензор/куб):Трёхмерный массив, который можно рассматривать как куб, образованный путём наложения нескольких матриц. В примере на рисунке показан куб 3x4x5, где каждая матрица размера 5x5 представляет "слой" куба.
- 4D-тензор / Вектор кубов (четырёхмерный тензор/вектор кубов):Четырёхмерный массив, который можно рассматривать как вектор, состоящий из нескольких кубов. В примере на рисунке нет конкретных значений, но его можно понимать как набор, содержащий несколько 3D-тензоров.
- 5D-тензор / Матрица кубов (пятимерный тензор/матрица кубов):Пятимерный массив, который можно рассматривать как матрицу, состоящую из нескольких 4D-тензоров. В примере на рисунке также нет конкретных значений, но его можно понимать как набор, содержащий несколько 4D-тензоров.
Создание тензоров
Существует несколько способов создания тензоров:
| Метод | Описание | Пример кода |
|---|---|---|
torch.tensor(data) | Создать тензор из списка Python или массива NumPy. | x = torch.tensor([[1, 2], [3, 4]]) |
torch.zeros(size) | Создать тензор, заполненный нулями. | x = torch.zeros((2, 3)) |
torch.ones(size) | Создать тензор, заполненный единицами. | x = torch.ones((2, 3)) |
torch.empty(size) | Создать неинициализированный тензор. | x = torch.empty((2, 3)) |
torch.rand(size) | Создать случайный тензор, подчиняющийся равномерному распределению, со значениями в[0, 1)。 | x = torch.rand((2, 3)) |
torch.randn(size) | Создать случайный тензор, подчиняющийся нормальному распределению, со средним 0 и стандартным отклонением 1. | x = torch.randn((2, 3)) |
torch.arange(start, end, step) | Создать одномерный тензор-последовательность, аналогичный таковому в Pythonrange。 | x = torch.arange(0, 10, 2) |
torch.linspace(start, end, steps) | Создать тензор-последовательность с равными интервалами в заданном диапазоне. | x = torch.linspace(0, 1, 5) |
torch.eye(size) | Создать единичную матрицу (на диагонали 1, остальные 0). | x = torch.eye(3) |
torch.from_numpy(ndarray) | Преобразовать массив NumPy в тензор. | x = torch.from_numpy(np.array([1, 2, 3])) |
Используйте функциюtorch.tensor(), чтобы преобразовать список или массив в тензор:
Пример
tensor = torch.tensor([1, 2, 3])
print(tensor)
Вывод следующий:
tensor([1, 2, 3])
Если у вас есть массив NumPy, вы можете использовать torch.from_numpy() для преобразования его в тензор:
Пример
np_array = np.array([1, 2, 3])
tensor = torch.from_numpy(np_array)
print(tensor)
Вывод следующий:
tensor([1, 2, 3])
Создание двумерного тензора (матрицы):
Пример
tensor_2d = torch.tensor([
[-9, 4, 2, 5, 7],
[3, 0, 12, 8, 6],
[1, 23, -6, 45, 2],
[22, 3, -1, 72, 6]
])
print("2D тензор (матрица):\n", tensor_2d)
print("Форма:", tensor_2d.shape) # shape
Вывод следующий:
2D Tensor (Matrix):
tensor([[-9, 4, 2, 5, 7],
[ 3, 0, 12, 8, 6],
[ 1, 23, -6, 45, 2],
[22, 3, -1, 72, 6]])
Shape: torch.Size([4, 5])
Создание других размерностей:
# 创建 3D 张量(立方体)
tensor_3d = torch.stack([tensor_2d, tensor_2d + 10, tensor_2d - 5]) # 堆叠 3 个 2D 张量
print("3D Tensor (Cube):\n", tensor_3d)
print("Shape:", tensor_3d.shape) # 形状
# 创建 4D 张量(向量的立方体)
tensor_4d = torch.stack([tensor_3d, tensor_3d + 100]) # 堆叠 2 个 3D 张量
print("4D Tensor (Vector of Cubes):\n", tensor_4d)
print("Shape:", tensor_4d.shape) # 形状
# 创建 5D 张量(矩阵的立方体)
tensor_5d = torch.stack([tensor_4d, tensor_4d + 1000]) # 堆叠 2 个 4D 张量
print("5D Tensor (Matrix of Cubes):\n", tensor_5d)
print("Shape:", tensor_5d.shape) # 形状
Атрибуты тензора
Атрибуты тензора следующие:
| Attribute | Описание | Пример |
|---|---|---|
.shape | Получить форму тензора | tensor.shape |
.size() | Получить форму тензора | tensor.size() |
.dtype | Получить тип данных тензора | tensor.dtype |
.device | Просмотреть устройство (CPU/GPU), на котором находится тензор | tensor.device |
.dim() | Получить число измерений тензора | tensor.dim() |
.requires_grad | Включено ли вычисление градиента | tensor.requires_grad |
.numel() | Получить общее число элементов в тензоре | tensor.numel() |
.is_cuda | Проверить, находится ли тензор на GPU | tensor.is_cuda |
.T | Получить транспонирование тензора (применимо к 2D-тензорам) | tensor.T |
.item() | Получить значение одноэлементного тензора | tensor.item() |
.is_contiguous() | Проверить, хранится ли тензор непрерывно | tensor.is_contiguous() |
Пример
# Создать 2D-тензор
tensor = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)
# Атрибуты тензора
print("Тензор:\n", tensor)
print("Форма:", tensor.shape) # Получить форму
print("Размер:", tensor.size()) # Получить размер (другой метод)
print("Тип данных:", tensor.dtype) # Тип данных
print("Устройство:", tensor.device) # Устройство
print("Размерности:", tensor.dim()) # Количество измерений
print("Всего элементов:", tensor.numel()) # Общее количество элементов
print("Требуется градиент:", tensor.requires_grad) # Включён ли градиент
print("Использует CUDA:", tensor.is_cuda) # Находится ли на GPU
print("Непрерывный:", tensor.is_contiguous()) # Является ли хранилище непрерывным
# Получить значение одного элемента
single_value = torch.tensor(42)
print("Значение одного элемента:", single_value.item())
# Транспонирование тензора
tensor_T = tensor.T
print("Транспонированный тензор:\n", tensor_T)
Результат вывода:
Tensor:
tensor([[1., 2., 3.],
[4., 5., 6.]])
Shape: torch.Size([2, 3])
Size: torch.Size([2, 3])
Data Type: torch.float32
Device: cpu
Dimensions: 2
Total Elements: 6
Requires Grad: False
Is CUDA: False
Is Contiguous: True
Single Element Value: 42
Transposed Tensor:
tensor([[1., 4.],
[2., 5.],
[3., 6.]])
Операции с тензорами
Методы операций с тензорами описаны ниже.
Базовые операции:
| Действие | Описание | Пример кода |
|---|---|---|
+, -, *, / |
Поэлементное сложение, вычитание, умножение и деление. | z = x + y |
torch.matmul(x, y) |
Умножение матриц. | z = torch.matmul(x, y) |
torch.dot(x, y) |
Скалярное произведение векторов (только для одномерных тензоров). | z = torch.dot(x, y) |
torch.sum(x) |
Сумма. | z = torch.sum(x) |
torch.mean(x) |
Среднее. | z = torch.mean(x) |
torch.max(x) |
Максимум. | z = torch.max(x) |
torch.min(x) |
Минимум. | z = torch.min(x) |
torch.argmax(x, dim) |
Вернуть индекс максимального значения (вдоль указанного измерения). | z = torch.argmax(x, dim=1) |
torch.softmax(x, dim) |
Вычислить softmax (вдоль указанного измерения). | z = torch.softmax(x, dim=1) |
Операции с формой
| Действие | Описание | Пример кода |
|---|---|---|
x.view(shape) |
Изменить форму тензора (без изменения данных). | z = x.view(3, 4) |
x.reshape(shape) |
Похоже наview, но более гибкий. |
z = x.reshape(3, 4) |
x.t() |
Транспонировать матрицу. | z = x.t() |
x.unsqueeze(dim) |
Добавить измерение в указанной размерности. | z = x.unsqueeze(0) |
x.squeeze(dim) |
Удалить измерение размера 1 в указанной размерности. | z = x.squeeze(0) |
torch.cat((x, y), dim) |
Конкатенировать несколько тензоров вдоль указанной размерности. | z = torch.cat((x, y), dim=1) |
Пример
# Создать 2D-тензор
tensor = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32)
print("Исходный тензор:\n", tensor)
# 1. **Операции индексирования и среза**
print("\n[Индексация и срезы]")
print("Получить первую строку:", tensor[0]) # Получить первую строку
print("Получить элемент в первой строке и первом столбце:", tensor[0, 0]) # Получить конкретный элемент
print("Получить все элементы во втором столбце:", tensor[:, 1]) # Получить все элементы во втором столбце
# 2. **Операции преобразования формы**
print("\n[Преобразование формы]")
reshaped = tensor.view(3, 2) # Изменить форму тензора на 3x2
print("Тензор после изменения формы:\n", reshaped)
flattened = tensor.flatten() # Развернуть тензор в одно измерение
print("Развёрнутый тензор:\n", flattened)
# 3. **Математические операции**
print("\n[Математические операции]")
tensor_add = tensor + 10 # Сложение тензоров
print("Тензор плюс 10:\n", tensor_add)
tensor_mul = tensor * 2 # Умножение тензоров
print("Тензор, умноженный на 2:\n", tensor_mul)
tensor_sum = tensor.sum() # Вычислить сумму всех элементов
print("Сумма элементов тензора:", tensor_sum.item())
# 4. **Операции с другими тензорами**
print("\n[Операции с другими тензорами]")
tensor2 = torch.tensor([[1, 1, 1], [1, 1, 1]], dtype=torch.float32)
print("Другой тензор:\n", tensor2)
tensor_dot = torch.matmul(tensor, tensor2.T) # Матричное умножение тензоров
print("Результат матричного умножения:\n", tensor_dot)
# 5. **Условные проверки и фильтрация**
print("\n[Условные проверки и фильтрация]")
mask = tensor > 3 # Создать булеву маску
print("Булева маска элементов, больших 3:\n", mask)
filtered_tensor = tensor[tensor > 3] # Отфильтровать элементы, удовлетворяющие условию
print("Элементы, большие 3:\n", filtered_tensor)
Результат вывода:
原始张量:
tensor([[1., 2., 3.],
[4., 5., 6.]])
【索引和切片】
获取第一行: tensor([1., 2., 3.])
获取第一行第一列的元素: tensor(1.)
获取第二列的所有元素: tensor([2., 5.])
【形状变换】
改变形状后的张量:
tensor([[1., 2.],
[3., 4.],
[5., 6.]])
展平后的张量:
tensor([1., 2., 3., 4., 5., 6.])
【数学运算】
张量加 10:
tensor([[11., 12., 13.],
[14., 15., 16.]])
张量乘 2:
tensor([[ 2., 4., 6.],
[ 8., 10., 12.]])
张量元素的和: 21.0
【与其他张量操作】
另一个张量:
tensor([[1., 1., 1.],
[1., 1., 1.]])
矩阵乘法结果:
tensor([[ 6., 6.],
[15., 15.]])
【条件判断和筛选】
大于 3 的元素的布尔掩码:
tensor([[False, False, False],
[ True, True, True]])
大于 3 的元素:
tensor([4., 5., 6.])
Ускорение тензоров на GPU
Перенос тензора на GPU:
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
x = torch.tensor([1.0, 2.0, 3.0], device=device)
Проверить, доступен ли GPU:
torch.cuda.is_available() # 返回 True или False
Взаимодействие между тензорами и NumPy
Взаимодействие между тензорами и NumPy показано в следующей таблице:
| Действие | Описание | Пример кода |
|---|---|---|
torch.from_numpy(ndarray) |
Преобразовать массив NumPy в тензор. | x = torch.from_numpy(np_array) |
x.numpy() |
Преобразовать тензор в массив NumPy (только для тензоров на CPU). | np_array = x.numpy() |
Пример
import numpy as np
# 1. Преобразование массива NumPy в тензор PyTorch
print("1. Преобразование NumPy в тензор PyTorch")
numpy_array = np.array([[1, 2, 3], [4, 5, 6]])
print("Массив NumPy:\n", numpy_array)
# Используйте torch.from_numpy() для преобразования массива NumPy в тензор
tensor_from_numpy = torch.from_numpy(numpy_array)
print(Преобразованный тензор PyTorch:\n", tensor_from_numpy)
# Измените массив NumPy и посмотрите, как изменяется тензор (общая память)
numpy_array[0, 0] = 100
print(Изменённый массив NumPy:\n", numpy_array)
print(Тензор PyTorch также изменяется соответственно:\n", tensor_from_numpy)
# 2. Преобразование тензора PyTorch в массив NumPy
print("\n2. Преобразование тензора PyTorch в массив NumPy)
tensor = torch.tensor([[7, 8, 9], [10, 11, 12]], dtype=torch.float32)
print(Тензор PyTorch:\n", tensor)
# Используйте tensor.numpy() для преобразования тензора в массив NumPy
numpy_from_tensor = tensor.numpy()
print(Преобразованный массив NumPy:\n", numpy_from_tensor)
# Измените тензор и проследите за изменением в массиве NumPy (общая память)
tensor[0, 0] = 77
print(Изменённый тензор PyTorch:\n", tensor)
print(Массив NumPy также изменяется соответственно:\n", numpy_from_tensor)
# 3. Примечание: случаи, когда память не разделяется (нужно скопировать данные)
print("\n3. Используйте clone(), чтобы обеспечить независимые данные)
tensor_independent = torch.tensor([[13, 14, 15], [16, 17, 18]], dtype=torch.float32)
numpy_independent = tensor_independent.clone().numpy() # Используйте clone для копирования данных
print(Исходный тензор:\n", tensor_independent)
tensor_independent[0, 0] = 0 # Изменить данные тензора
print(Изменённый тензор:\n", tensor_independent)
print(Массив NumPy (не изменится соответствующим образом):\n", numpy_independent)
Вывод:
1. NumPy 转为 PyTorch 张量
NumPy 数组:
[[1 2 3]
[4 5 6]]
转换后的 PyTorch 张量:
tensor([[1, 2, 3],
[4, 5, 6]])
修改后的 NumPy 数组:
[[100 2 3]
[ 4 5 6]]
PyTorch 张量也会同步变化:
tensor([[100, 2, 3],
[ 4, 5, 6]])
2. PyTorch 张量转为 NumPy 数组
PyTorch 张量:
tensor([[ 7., 8., 9.],
[10., 11., 12.]])
转换后的 NumPy 数组:
[[ 7. 8. 9.]
[10. 11. 12.]]
修改后的 PyTorch 张量:
tensor([[77., 8., 9.],
[10., 11., 12.]])
NumPy 数组也会同步变化:
[[77. 8. 9.]
[10. 11. 12.]]
3. 使用 clone() 保证独立数据
原始张量:
tensor([[13., 14., 15.],
[16., 17., 18.]])
修改后的张量:
tensor([[ 0., 14., 15.],
[16., 17., 18.]])
NumPy 数组(不会同步变化):
[[13. 14. 15.]
[16. 17. 18.]]
Другие расширения