python pytorch 张量 (Tensor)


前言

书接上回

张量 Tensor

PyTorch 中的 张量(Tensor) 是多维数组的核心数据结构,类似于 NumPy 的 ndarray,但具备 GPU 加速计算和自动微分(Autograd)的能力。


1. 张量的基本概念

  • 定义:张量是 PyTorch 中表示多维数据的容器,可以看作是多维数组。
    • 0维张量:标量(Scalar),如 tensor(3.14)
    • 1维张量:向量(Vector),如 tensor([1, 2, 3])
    • 2维张量:矩阵(Matrix),如 tensor([[1, 2], [3, 4]])
    • 3维及以上:高维张量,如 tensor([[[1, 2], [3, 4]]])

2. 创建张量

PyTorch 提供了多种创建张量的方式:

从 Python 列表或 NumPy 数组
import torch
import numpy as np

# 从列表创建
a = torch.tensor([1, 2, 3])          # 1维张量
b = torch.tensor([[1, 2], [3, 4]])   # 2维张量

# 从 NumPy 数组创建
np_array = np.array([1, 2, 3])
c = torch.from_numpy(np_array)       # 共享内存(修改一个会影响另一个)
生成特定形状的张量
# 全零张量
zeros = torch.zeros(2, 3)            # 2行3列的全零矩阵

# 全一张量
ones = torch.ones(2, 3)              # 2行3列的全一矩阵

# 随机张量(均匀分布)
rand = torch.rand(2, 3)              # 0~1之间的随机数

# 随机张量(正态分布)
randn = torch.randn(2, 3)            # 均值为0,标准差为1

# 等差序列
arange = torch.arange(0, 10, 2)      # tensor([0, 2, 4, 6, 8])
指定设备(CPU/GPU)
# 将张量放在 GPU 上(需有可用 GPU)
if torch.cuda.is_available():
    gpu_tensor = torch.tensor([1, 2, 3], device="cuda:0")
指定数据类型(dtype)
# 指定数据类型为 float32
float_tensor = torch.tensor([1, 2, 3], dtype=torch.float32)

3. 张量的属性

每个张量有三个核心属性:

  1. shape:张量的维度形状。
    x = torch.rand(2, 3)
    print(x.shape)  # 输出 torch.Size([2, 3])
    
  2. dtype:张量的数据类型(如 float32, int64 等)。
    print(x.dtype)  # 输出 torch.float32
    
  3. device:张量所在的设备(CPU 或 GPU)。
    print(x.device) # 输出 cpu 或 cuda:0
    

4. 张量的操作

数学运算
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])

# 加法
c = a + b          # 或 torch.add(a, b)

# 乘法(逐元素相乘)
d = a * b          # tensor([4, 10, 18])

# 矩阵乘法
mat1 = torch.rand(2, 3)
mat2 = torch.rand(3, 2)
matmul = torch.matmul(mat1, mat2)  # 或 mat1 @ mat2
形状操作
x = torch.rand(2, 3)

# 改变形状(不改变数据)
y = x.view(3, 2)      # 变为3行2列(需保证元素总数一致)

# 转置
z = x.T               # 行变列,列变行

# 增加/减少维度
x = torch.unsqueeze(x, dim=0)  # 在第0维增加一维,形状变为 [1, 2, 3]
x = torch.squeeze(x)           # 删除所有长度为1的维度
索引与切片

与 NumPy 类似:

x = torch.tensor([[1, 2, 3], [4, 5, 6]])

print(x[0, 1])     # 输出 2(第0行第1列)
print(x[:, 1:3])   # 输出所有行的第1到2列
广播机制(Broadcasting)

PyTorch 支持自动广播,允许不同形状的张量进行运算:

a = torch.tensor([[1, 2, 3]])  # 形状 [1, 3]
b = torch.tensor([4, 5, 6])    # 形状 [3]
c = a + b                      # 自动广播为 [1,3] + [3] → [1,3] + [1,3]

5. 自动微分(Autograd)

PyTorch 张量支持自动微分(通过 requires_grad=True):

x = torch.tensor([2.0], requires_grad=True)
y = x ** 2 + 3 * x + 1

y.backward()        # 计算梯度
print(x.grad)       # 输出导数 dy/dx = 2x + 3 → 7.0

6. 与 NumPy 的互操作

张量和 NumPy 数组可以互相转换:

# 张量 → NumPy 数组
tensor = torch.tensor([1, 2, 3])
numpy_array = tensor.numpy()         # 共享内存

# NumPy 数组 → 张量
new_tensor = torch.from_numpy(numpy_array)

7. 张量的存储

张量的底层数据存储在连续的内存块中,可以通过 storage() 访问:

x = torch.tensor([[1, 2], [3, 4]])
print(x.storage())  # 输出底层存储的1D数组 [1, 2, 3, 4]

你提到的 .item().tolist() 是 PyTorch 张量中常用的方法,用于将张量转换为 Python 原生的数据类型(如标量或列表)。以下是它们的详细说明和典型应用场景:


8. 其他方法

1. .item() 方法
  • 作用
    单元素张量(即形状为 [][1] 的张量)转换为 Python 的标量(int, float, bool 等)。

  • 适用场景
    当张量中只包含一个数值时,提取该数值(例如计算损失值后提取标量结果)。

  • 示例

    import torch
    
    # 标量张量(0维)
    x = torch.tensor(3.14)
    print(x.item())  # 输出 3.14(Python float)
    
    # 单元素张量(1维)
    y = torch.tensor([5])
    print(y.item())  # 输出 5(Python int)
    
  • 注意事项

    • 如果张量包含多个元素,调用 .item() 会报错:
      z = torch.tensor([1, 2])
      # z.item()  # 报错:ValueError: only one element tensors can be converted to Python scalars
      
2. .tolist() 方法
  • 作用
    将张量转换为 Python 列表(多维张量会转换为嵌套列表)。
    所有元素会被转换为 Python 的原生数据类型(如 int, float)。

  • 适用场景
    需要将张量数据导出为 Python 原生结构(例如保存到 JSON 文件,或与其他非 PyTorch 库交互)。

  • 示例

    # 1维张量 → 列表
    a = torch.tensor([1, 2, 3])
    print(a.tolist())  # 输出 [1, 2, 3]
    
    # 2维张量 → 嵌套列表
    b = torch.tensor([[1, 2], [3, 4]])
    print(b.tolist())  # 输出 [[1, 2], [3, 4]]
    
    # 包含浮点数的张量
    c = torch.tensor([1.5, 2.7])
    print(c.tolist())  # 输出 [1.5, 2.7]
    
  • 注意事项

    • 转换后的列表与原张量 不共享内存
    • 支持任意维度的张量(会生成嵌套列表)。
.numpy() 方法
  • 作用:将张量转换为 NumPy 数组(与原张量共享内存)。
  • 示例
    x = torch.tensor([1, 2, 3])
    np_array = x.numpy()  # 转换为 NumPy 数组
    
  • 注意:如果张量在 GPU 上,需要先移动到 CPU:
    x = x.cpu().numpy()
    
.data 属性
  • 作用:获取张量的数据(返回一个无梯度的新张量)。
  • 示例
    x = torch.tensor([1.0], requires_grad=True)
    y = x.data  # y 是普通张量,无梯度信息
    
### PyTorch 张量的使用方法和操作 #### 创建张量 PyTorch 的核心数据结构是张量 (Tensor),它可以表示多维的数据数组。创建张量的方法有很多,以下是几种常见的创建方式: - **从列表或NumPy数组创建张量** 可以通过 `torch.tensor()` 函数来创建张量,传入Python列表或者NumPy数组作为输入。 ```python import torch # 从列表创建张量 tensor_from_list = torch.tensor([[1, 2], [3, 4]]) # 打印张量 print(tensor_from_list) ``` - **随机初始化张量** 使用 `torch.randn()` 来创建一个指定形状并填充有来自标准正态分布(均值为0,方差为1)随机数的张量[^3]。 ```python random_tensor = torch.randn(2, 3) # 创建一个2x3的随机张量 print(random_tensor) ``` #### 基本运算 张量支持多种算术运算和其他类型的数学操作。下面是一些常用的操作实例: - **加法** ```python t1 = torch.tensor([1., 2.]) t2 = torch.tensor([3., 4.]) result_addition = t1 + t2 print(result_addition) ``` - **乘法** - 阿达玛积(Hadamard Product) 这是指两个相同尺寸张量之间的元素级相乘[^4]。 ```python data1 = torch.tensor([[1, 2], [3, 4]]) data2 = torch.tensor([[5, 6], [7, 8]]) hadamard_product = torch.mul(data1, data2) print(hadamard_product) elementwise_multiplication = data1 * data2 print(elementwise_multiplication) ``` - **条件选择** 利用 `torch.where(condition, x, y)` 函数可以根据给定条件从两个张量中选取元素。当条件满足时取自第一个张量;否则取自第二个张量[^2]。 ```python condition = torch.tensor([[True, False], [False, True]]) choice_a = torch.tensor([[1, 2], [3, 4]], dtype=torch.float32) choice_b = torch.tensor([[9, 8], [7, 6]], dtype=torch.float32) selected_elements = torch.where(condition, choice_a, choice_b) print(selected_elements) ``` #### 数据类型转换 可以方便地在不同设备之间移动张量以及改变其数据类型: - 将CPU上的张量转移到GPU上运行(如果可用) ```python device = 'cuda' if torch.cuda.is_available() else 'cpu' gpu_tensor = some_tensor.to(device) ``` - 更改张量的数据类型 ```python float_tensor = integer_tensor.to(torch.float32) ``` #### 索引与切片 类似于NumPy,PyTorch也提供了灵活的索引机制来进行子集提取: ```python tensor_example = torch.arange(10).reshape((2, 5)) print("Original Tensor:") print(tensor_example) # 获取第二行的所有元素 row_two = tensor_example[1, :] print("\nSecond Row:", row_two) # 获取第一列的所有元素 column_one = tensor_example[:, 0] print("\nFirst Column:", column_one) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值