PyTorch 张量操作详解:从基础运算到形状变换

PyTorch 张量操作详解:从基础运算到形状变换

张量(Tensor)是 PyTorch 的核心数据结构,而张量操作则是构建深度学习模型和进行数值计算的基础。无论是简单的加减乘除,还是复杂的形状变换,掌握这些操作对于高效使用 PyTorch 至关重要。本文将通过一段示例代码,详细解析 PyTorch 中常用的张量操作,帮助你理解它们的功能、用法和实际应用场景。

代码功能概述

让我们首先看看这段展示 PyTorch 基本张量操作的代码:

# tensor_operations.py

# Import necessary libraries
import torch


def main():
    # Create a 3x3 tensor filled with ones
    tensor = torch.ones(3, 3)
    print(tensor)

    # Resize the tensor to 9 elements (1D)
    print(tensor.view(9).shape, end="")
    print(tensor.view(9))

    # Addition
    print("Addition:", torch.add(tensor, tensor))

    # Subtraction
    print("Subtraction:", tensor.sub(tensor))

    # Element wise multiplication
    print("Element wise multiplication:", torch.mul(tensor, tensor))

    # Element wise division
    print("Element wise division:", torch.div(tensor, tensor))

    # Mean
    tensor = torch.Tensor([1, 2, 3, 4, 5])
    print("Mean:", tensor.mean().item())  # .item() converts tensor to Python scalar

    # Standart deviation (std)
    print("std:", tensor.std().item())  # .item() converts tensor to Python scalar


if __name__ == "__main__":
    main()

这段代码展示了 PyTorch 中几类常用的张量操作:

  1. 创建全 1 张量
  2. 张量形状变换(重塑)
  3. 基本算术运算(加、减、乘、除)
  4. 统计运算(均值、标准差)
  5. 张量与 Python 标量的转换

运行代码后,输出结果如下:

tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
torch.Size([9])tensor([1., 1., 1., 1., 1., 1., 1., 1., 1.])
Addition: tensor([[2., 2., 2.],
        [2., 2., 2.],
        [2., 2., 2.]])
Subtraction: tensor([[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]])
Element wise multiplication: tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
Element wise division: tensor([[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]])
Mean: 3.0
std: 1.4142135623730951

代码逐行解析

1. 导入 PyTorch 库

import torch

这行代码导入 PyTorch 库,使我们能够使用其提供的张量操作功能。torch是 PyTorch 库的标准导入名称。

2. 创建 3x3 全 1 张量

tensor = torch.ones(3, 3)
print(tensor)
  • torch.ones(3, 3):创建一个 3 行 3 列(形状为(3, 3))的二维张量,所有元素的值均为 1.0。默认数据类型为float32(单精度浮点数)。
  • 打印结果显示了一个 3x3 的矩阵,每个元素都是1.(带小数点表示浮点数)。

3. 张量形状变换(重塑)

print(tensor.view(9).shape, end="")
print(tensor.view(9))

这两行代码展示了如何使用view()方法改变张量的形状:

  • view(9):将原来 3x3 的二维张量重塑为包含 9 个元素的一维张量。view()方法需要保证新形状的元素总数与原张量相同(3×3=9),否则会报错。
  • shape属性:打印重塑后张量的形状,结果为torch.Size([9]),表示这是一个包含 9 个元素的一维张量。
  • 重塑操作不会改变张量的元素值和总数,只改变其维度结构。这在神经网络中非常有用,例如将卷积层输出的多维特征图转换为全连接层需要的一维向量。

4. 加法操作

print("Addition:", torch.add(tensor, tensor))
  • torch.add(tensor, tensor):对两个张量进行元素级加法运算。这里两个操作数都是同一个 3x3 的全 1 张量,所以结果是一个 3x3 的全 2 张量。
  • 元素级运算(Element-wise Operation)指的是两个形状相同的张量对应位置的元素进行运算,得到的结果张量形状与输入相同。
  • 也可以使用运算符简写形式:tensor + tensor,与torch.add(tensor, tensor)效果完全相同。

5. 减法操作

print("Subtraction:", tensor.sub(tensor))
  • tensor.sub(tensor):对张量进行元素级减法运算(等价于torch.sub(tensor, tensor))。一个张量减去自身,所有元素的结果都是 0,所以输出是全 0 张量。
  • 运算符简写形式:tensor - tensor

6. 乘法操作

print("Element wise multiplication:", torch.mul(tensor, tensor))
  • torch.mul(tensor, tensor):执行元素级乘法(Hadamard 积),即两个张量对应位置的元素相乘。全 1 张量与自身相乘的结果仍然是全 1 张量。
  • 注意:这与矩阵乘法(矩阵积)不同,矩阵乘法需要使用torch.matmul()@运算符。
  • 运算符简写形式:tensor * tensor

7. 除法操作

print("Element wise division:", torch.div(tensor, tensor))
  • torch.div(tensor, tensor):执行元素级除法,即两个张量对应位置的元素相除。全 1 张量除以自身的结果仍然是全 1 张量。
  • 运算符简写形式:tensor / tensor

8. 均值计算

tensor = torch.Tensor([1, 2, 3, 4, 5])
print("Mean:", tensor.mean().item())

这两行代码首先创建了一个新的一维张量,然后计算其均值:

  • torch.Tensor([1, 2, 3, 4, 5]):创建一个包含 5 个整数的一维张量,元素值分别为 1 到 5。
  • tensor.mean():计算张量所有元素的平均值。对于张量[1,2,3,4,5],均值为(1+2+3+4+5)/5 = 3.0
  • .item():将只包含一个元素的张量转换为 Python 标量(普通的 Python 数值类型)。这在需要获取计算结果的具体数值时非常有用。

9. 标准差计算

print("std:", tensor.std().item())
  • tensor.std():计算张量所有元素的标准差(Standard Deviation),衡量数据的离散程度。对于张量[1,2,3,4,5],标准差的计算过程如下:
    1. 均值为 3.0
    2. 每个元素与均值的差的平方:(1-3)²=4(2-3)²=1(3-3)²=0(4-3)²=1(5-3)²=4
    3. 方差为这些平方的平均值:(4+1+0+1+4)/5 = 10/5 = 2
    4. 标准差为方差的平方根:√2 ≈ 1.4142
  • 同样使用.item()将结果转换为 Python 标量。

关键概念解析

1. 张量形状变换:view()方法

view()是 PyTorch 中重塑张量形状的核心方法,其工作原理和重要特性包括:

  • 元素总数守恒:新形状的元素总数必须与原张量相同,例如 3x3 的张量可以重塑为 9x1、1x9 或 1x3x3 等,但不能重塑为 2x5(元素总数 10≠9)。
  • 内存共享view()返回的新张量与原张量共享底层数据,修改一个会影响另一个(不复制数据,高效)。
  • -1 的特殊用法:可以用 - 1 表示 "自动计算该维度的大小",例如tensor.view(-1, 3)会将 3x3 的张量重塑为 3x3(-1 自动计算为 3),tensor.view(3, -1)同样得到 3x3。

示例:

x = torch.ones(2, 4)
print(x.view(8))        # 形状: (8)
print(x.view(-1, 2))    # 形状: (4, 2)(-1自动计算为4)
print(x.view(2, 2, -1)) # 形状: (2, 2, 2)

2. 元素级运算(Element-wise Operations)

代码中展示的加减乘除都属于元素级运算,其核心特点是:

  • 要求参与运算的张量具有相同的形状(或可广播为相同形状)
  • 运算在对应位置的元素之间进行,不改变张量形状
  • 支持运算符重载(+-*/)和函数调用两种方式
  • 效率高,底层由 C++ 实现,无需 Python 循环

广播(Broadcasting)是元素级运算的重要扩展,允许形状不同但兼容的张量进行运算,例如:

a = torch.ones(3, 3)
b = torch.tensor([1, 2, 3])
print(a + b)  # b会被广播为3x3的张量,每一行都是[1,2,3]

3. 张量与标量的转换:item()方法

item()方法用于将只包含一个元素的张量转换为 Python 标量,具有以下特点:

  • 仅适用于包含单个元素的张量(0 维张量或形状为(1,)的 1 维张量)
  • 返回值是 Python 的基本数据类型(如floatint
  • 常用于提取损失值、准确率等标量指标的具体数值
  • numpy()方法的区别:numpy()返回 NumPy 数组,item()返回 Python 标量

示例:

scalar_tensor = torch.tensor(3.14)
print(type(scalar_tensor))  # <class 'torch.Tensor'>
print(type(scalar_tensor.item()))  # <class 'float'>

4. 统计运算

代码中展示的mean()(均值)和std()(标准差)是常用的统计运算,PyTorch 还提供了其他统计函数:

  • sum():计算元素总和
  • max()/min():计算最大值 / 最小值
  • var():计算方差
  • median():计算中位数
  • argmax()/argmin():返回最大值 / 最小值的索引

这些函数默认对张量所有元素进行计算,也可以通过dim参数指定在某个维度上计算:

x = torch.tensor([[1, 2], [3, 4]])
print(x.mean(dim=0))  # 按列计算均值: tensor([2., 3.])
print(x.sum(dim=1))   # 按行计算总和: tensor([3., 7.])

实际应用场景

这些基础张量操作是构建复杂深度学习模型的基石,在实际应用中无处不在:

  1. 神经网络前向传播

    # 简单的线性层计算: output = input × weight + bias
    output = torch.matmul(input_tensor, weight_tensor) + bias_tensor
    
  2. 损失函数计算

    # 计算预测值与真实值的均方误差
    loss = torch.mean((predictions - targets) **2)
    

    3. 数据预处理 :

# 标准化数据: (x - mean) / std
mean = data.mean()
std = data.std()
normalized_data = (data - mean) / std

   4.形状适配 :

# 将卷积特征图展平为全连接层输入
conv_output = torch.rand(16, 32, 7, 7)  # 16个样本,32个通道,7x7特征图
fc_input = conv_output.view(16, -1)    # 展平为16x(32×7×7)的张量

总结

通过这段代码,我们学习了 PyTorch 中几类最基础也最常用的张量操作,包括形状变换(view())、基本算术运算(加、减、乘、除)和统计运算(均值、标准差),以及张量与标量的转换(item())。

这些操作看似简单,却是构建复杂深度学习模型和进行数值计算的基础。掌握它们的工作原理和使用场景,能够帮助你更高效地编写 PyTorch 代码,理解神经网络的计算过程。

在实际应用中,这些操作通常会组合使用,形成更复杂的计算流程。随着学习的深入,你还会遇到更多高级张量操作,但它们的设计理念与这些基础操作是一致的 —— 高效、直观且面向深度学习任务优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值