PyTorch 张量的基本操作

 更新时间:2025年12月02日 09:20:39   作者:MadeInSQL  
PyTorch张量是PyTorch中核心数据结构,类似于 NumPy 的 ndarray,但具有 GPU 加速能力,下面就来详细的介绍一下PyTorch 张量的基本操作,感兴趣的可以了解一下

PyTorch 张量详解

基本概念

PyTorch 张量(Tensor)是 PyTorch 中的核心数据结构,类似于 NumPy 的 ndarray,但具有 GPU 加速能力。张量是一个多维数组,可以包含标量(0维)、向量(1维)、矩阵(2维)以及更高维度的数据。在深度学习应用中,张量通常用于表示神经网络的输入数据、权重参数和梯度信息。

张量的维度与详细示例

0维张量(标量)

0维张量是最基本的张量形式,仅包含一个数值,不包含任何维度信息。在PyTorch中创建时不需要使用方括号包裹。

  • 示例1torch.tensor(3.14) 表示一个简单的浮点数值
  • 示例2torch.tensor(True) 表示一个布尔值
  • 应用场景:神经网络中的损失值、准确率等单一指标的表示

1维张量(向量)

1维张量包含一个轴(维度),可以看作是一组有序的数值集合。通常用于表示特征向量、时间序列等。

  • 示例1torch.tensor([1, 2, 3]) 表示一个包含3个元素的行向量
  • 示例2torch.tensor([0.1, 0.5, 0.9]) 表示神经网络的输出概率
  • 形状表示(n,) 其中n是向量长度
  • 应用场景:全连接层的输入/输出、词嵌入表示等

2维张量(矩阵)

2维张量包含两个轴,通常表示为行和列的结构。在深度学习中广泛用于权重矩阵、特征矩阵等。

  • 示例1torch.tensor([[1, 2], [3, 4]]) 表示一个2×2的矩阵
  • 示例2torch.zeros((3, 4)) 创建3行4列的全零矩阵
  • 形状表示(m, n) 其中m是行数,n是列数
  • 应用场景:全连接层的权重参数、批量处理时的特征矩阵等

3维张量

3维张量在计算机视觉中特别常见,通常用于表示批量的图像数据或序列数据。

  • 典型形状(batch_size, channels, height, width)

    • batch_size:一次处理的样本数量
    • channels:颜色通道数(RGB图像为3,灰度图为1)
    • height:图像高度(像素数)
    • width:图像宽度(像素数)
  • 示例1torch.randn(16, 3, 224, 224) 表示16张224×224像素的RGB图像

  • 示例2torch.zeros(32, 1, 28, 28) 表示32张28×28像素的灰度图

  • 应用场景:卷积神经网络的输入、视频数据处理、自然语言处理中的词序列等

与 NumPy 数组的比较

与 NumPy 数组相比,PyTorch 张量具有以下独特优势:

  1. GPU 加速支持

    • 可以轻松将张量转移到 GPU 上进行高效计算
    • 使用方法:tensor.cuda() 或 tensor.to('cuda')
    • 示例:在图像分类任务中,可以将批量图像张量转移到 GPU 加速卷积运算
  2. 自动微分能力

    • 内置支持自动微分,便于神经网络训练
    • 通过设置 requires_grad=True 启用自动求导
    • 示例:在训练 CNN 时,PyTorch 会自动计算损失函数对网络参数的梯度
  3. 动态计算图

    • 支持动态构建计算图,灵活性更高
    • 计算图在每次前向传播时动态构建
    • 应用场景:在RNN处理变长序列时特别有用

实际应用场景

  • 计算机视觉:4D张量表示图像批次 (batch, channel, height, width)
  • 自然语言处理:3D张量表示文本序列 (batch, sequence_length, embedding_dim)
  • 强化学习:2D张量表示状态空间 (batch, state_dimension)

性能优化建议

  • 尽量使用矢量化操作代替循环
  • 合理使用 inplace 操作节省内存
  • 注意 CPU 和 GPU 之间的数据传输开销

张量创建方式

从 Python 列表创建

import torch

# 创建一维张量(向量)
tensor1d = torch.tensor([1.0, 2.0, 3.0])  # 浮点型向量
tensor1d_int = torch.tensor([1, 2, 3])     # 整型向量

# 创建二维张量(矩阵)
tensor2d = torch.tensor([[1, 2, 3], [4, 5, 6]])  # 2x3矩阵
tensor2d_float = torch.tensor([[1., 2.], [3., 4.]])  # 2x2浮点矩阵

# 创建三维张量
tensor3d = torch.tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])  # 2x2x2张量

特殊张量创建

# 创建全零张量(常用于初始化)
zeros = torch.zeros(3, 4)  # 3行4列的全零矩阵
zeros_3d = torch.zeros(2, 3, 4)  # 2x3x4的三维零张量

# 创建全一张量
ones = torch.ones(2, 3)    # 2行3列的全一矩阵
ones_like = torch.ones_like(zeros)  # 创建与zeros形状相同的全一张量

# 创建随机张量(常用于权重初始化)
rand_tensor = torch.rand(5, 5)  # 5x5的随机矩阵,值在[0,1)之间均匀分布
randn_tensor = torch.randn(3, 3)  # 3x3的正态分布随机矩阵,均值0,方差1

# 创建单位矩阵(常用于线性变换初始化)
eye_matrix = torch.eye(4)  # 4x4的单位矩阵
eye_with_offset = torch.eye(3, 4, k=1)  # 3x4的矩阵,对角线偏移1位

# 创建等差数列张量
arange_tensor = torch.arange(0, 10, 2)  # [0, 2, 4, 6, 8]
linspace_tensor = torch.linspace(0, 1, 5)  # [0.0, 0.25, 0.5, 0.75, 1.0]

张量属性

每个张量都有以下重要属性,这些属性决定了张量的行为和计算方式:

tensor = torch.rand(3, 4)

# 数据类型 - 决定张量存储的数值类型
print(tensor.dtype)    # 如torch.float32、torch.int64等
# 常用类型:torch.float32, torch.float64, torch.int32, torch.int64

# 存储设备 - 决定张量存储在CPU还是GPU上
print(tensor.device)   # 如'cpu'或'cuda:0'
# 可以通过.to(device)方法在设备间移动张量

# 形状 - 描述张量的维度信息
print(tensor.shape)    # 如torch.Size([3, 4])
print(tensor.size())   # 同shape的另一种访问方式
print(tensor.ndim)     # 张量的维度数,这里是2

# 梯度计算标志 - 决定张量是否需要计算梯度
print(tensor.requires_grad)  # 默认为False
# 当设置为True时,PyTorch会跟踪对此张量的所有操作以计算梯度

# 其他属性
print(tensor.is_leaf)  # 是否为叶节点(用户直接创建的张量)
print(tensor.is_cuda)  # 是否存储在GPU上
print(tensor.grad)     # 存储的梯度值(如果有)

张量操作

算术运算

a = torch.tensor([1, 2, 3], dtype=torch.float32)
b = torch.tensor([4, 5, 6], dtype=torch.float32)

# 加法(逐元素相加)
c = a + b          # 直接运算符
c = torch.add(a, b)  # 函数形式
c = a.add(b)       # 方法形式

# 原地加法(不创建新张量)
a.add_(b)  # 等价于 a += b

# 乘法(逐元素相乘)
d = a * b          # [1*4, 2*5, 3*6] = [4, 10, 18]
d = torch.mul(a, b)
d = a.mul(b)

# 除法(逐元素相除)
e = a / b          # [1/4, 2/5, 3/6]
e = torch.div(a, b)

# 矩阵乘法
mat_a = torch.rand(3, 4)  # 3x4矩阵
mat_b = torch.rand(4, 5)  # 4x5矩阵
mat_prod = torch.matmul(mat_a, mat_b)  # 3x5结果矩阵
mat_prod = mat_a @ mat_b  # Python 3.5+支持的运算符

# 广播机制示例
a = torch.rand(5, 1, 4)
b = torch.rand(  1, 3)
c = a + b  # 广播后形状为(5,3,4)

索引和切片

PyTorch 张量的索引与 NumPy 类似,支持丰富的索引操作:

tensor = torch.arange(12).reshape(3, 4)
"""
tensor([[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]])
"""

# 基本索引
print(tensor[0])       # 第一行: tensor([0, 1, 2, 3])
print(tensor[-1])      # 最后一行: tensor([ 8,  9, 10, 11])
print(tensor[:, 1])    # 第二列: tensor([1, 5, 9])
print(tensor[1:3, 2])  # 第二三行的第三列元素: tensor([6, 10])

# 高级索引
print(tensor[[0, 2], [1, 3]])  # 第0行第1列和第2行第3列: tensor([1, 11])
print(tensor[tensor > 5])      # 所有大于5的元素: tensor([6, 7, 8, 9, 10, 11])

# 修改子张量
tensor[1:, 2:] = 0  # 将第二行开始的右下2x2子矩阵置零

形状操作

# 改变形状(不改变数据)
tensor = torch.rand(4, 6)
reshaped = tensor.reshape(3, 8)  # 总元素数必须保持不变
viewed = tensor.view(2, 12)      # 与reshape类似,但对内存连续性有要求

# 转置
transposed = tensor.t()  # 仅适用于2D张量
permuted = tensor.permute(1, 0)  # 通用转置方法

# 增加/减少维度
tensor = torch.rand(3, 4)
unsqueezed = tensor.unsqueeze(0)  # 在0维增加1维,变为1x3x4
squeezed = unsqueezed.squeeze()   # 去除所有长度为1的维度

# 连接张量
a = torch.rand(2, 3)
b = torch.rand(2, 3)
cat_0 = torch.cat([a, b], dim=0)  # 沿0维连接,结果为4x3
cat_1 = torch.cat([a, b], dim=1)  # 沿1维连接,结果为2x6

# 分割张量
chunks = torch.chunk(tensor, 3, dim=0)  # 沿0维分成3块
splits = torch.split(tensor, 2, dim=1)  # 沿1维每2列分一块

张量与 NumPy 互转

PyTorch 张量和 NumPy 数组可以高效互转,因为它们共享底层内存(当张量在CPU上时):

import numpy as np

# 张量转 NumPy
tensor = torch.ones(5)
numpy_array = tensor.numpy()  # 共享内存,修改一个会影响另一个

# 注意:GPU上的张量需要先移动到CPU
gpu_tensor = torch.rand(5, device='cuda')
cpu_tensor = gpu_tensor.cpu()
numpy_array = cpu_tensor.numpy()

# NumPy 转张量
np_array = np.array([1, 2, 3])
torch_tensor = torch.from_numpy(np_array)  # 同样共享内存

# 不共享内存的创建方式
torch_tensor_copy = torch.tensor(np_array)  # 创建新副本

GPU 加速

PyTorch 张量的 GPU 加速功能可以显著提升深度学习模型的训练速度:

# 检查GPU是否可用
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(f"Using device: {device}")

# 创建张量并移动到GPU
tensor = torch.rand(10, 10).to(device)

# 直接在目标设备上创建张量
gpu_tensor = torch.rand(5, 5, device='cuda')

# 在GPU上执行运算
result = tensor * 2  # 如果tensor在GPU上,result也会在GPU上

# 将结果移回CPU
cpu_result = result.cpu()

# 多GPU示例(需要多GPU环境)
if torch.cuda.device_count() > 1:
    tensor = tensor.to('cuda:1')  # 显式指定第二个GPU

自动微分

PyTorch 的自动微分功能(autograd)是其核心特性之一,使得神经网络训练变得简单:

# 创建需要计算梯度的张量
x = torch.tensor(2.0, requires_grad=True)
w = torch.tensor(1.0, requires_grad=True)
b = torch.tensor(0.5, requires_grad=True)

# 构建计算图
y = w * x + b  # 线性函数
z = y**2       # 非线性变换

# 反向传播计算梯度
z.backward()  # 计算dz/dx, dz/dw, dz/db

# 查看梯度
print(x.grad)  # dz/dx = 2*(w*x+b)*w = 2*(1*2+0.5)*1 = 5.0
print(w.grad)  # dz/dw = 2*(w*x+b)*x = 2*(1*2+0.5)*2 = 10.0
print(b.grad)  # dz/db = 2*(w*x+b)*1 = 2*(1*2+0.5)*1 = 5.0

# 梯度清零(重要!在训练循环中需要)
x.grad.zero_()
w.grad.zero_()
b.grad.zero_()

# 禁用梯度跟踪(用于推理阶段)
with torch.no_grad():
    y = w * x + b  # 不会在计算图中记录

高级特性

内存共享

# 视图操作共享内存
a = torch.rand(4, 5)
b = a.view(20)  # b与a共享内存
c = a[1:3, 2:4]  # c与a共享内存

# clone()创建独立副本
d = a.clone()  # d与a不共享内存

稀疏张量

# 创建稀疏张量
indices = torch.tensor([[0, 1, 2], [2, 0, 1]])  # 非零元素的坐标
values = torch.tensor([3, 4, 5], dtype=torch.float32)  # 非零元素的值
shape = torch.Size([3, 3])  # 稀疏张量的形状

sparse_tensor = torch.sparse_coo_tensor(indices, values, shape)
print(sparse_tensor.to_dense())  # 转换为稠密张量

分布式张量

# 分布式训练中的张量分片
import torch.distributed as dist

if dist.is_initialized():
    # 将张量分片到不同进程
    tensor = torch.rand(10, 10)
    shard = tensor.chunk(dist.get_world_size(), dim=0)[dist.get_rank()]

PyTorch 张量(Tensor)是深度学习模型构建的核心数据结构,它本质上是一个多维数组,类似于 NumPy 的 ndarray,但具有 GPU 加速计算和自动微分等额外功能。理解张量的特性和操作对于高效使用 PyTorch 至关重要。

张量的基本特性

  1. 数据类型(dtype):PyTorch 张量支持多种数据类型,如 torch.float32、torch.int64 等
  2. 形状(shape):表示张量的维度结构,例如 (3, 224, 224) 表示一个 3 通道的 224x224 图像
  3. 设备(device):可以存储在 CPU 或 GPU 上,通过 .to('cuda') 方法可以轻松切换

张量的创建方法

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

  • 从 Python 列表创建:torch.tensor([[1, 2], [3, 4]])
  • 特殊张量创建:
    • 零张量:torch.zeros(2, 3)
    • 单位矩阵:torch.eye(3)
    • 随机张量:torch.randn(2, 2)
  • 从 NumPy 数组转换:torch.from_numpy(np_array)

张量的操作

PyTorch 支持丰富的张量操作:

  1. 数学运算:加减乘除、矩阵乘法(@torch.matmul()
  2. 形状操作
    • 改变形状:view()reshape()
    • 转置:t()transpose()
  3. 索引和切片:与 NumPy 类似的索引方式
  4. 归约操作sum(), mean(), max()

设备管理

PyTorch 允许张量在 CPU 和 GPU 之间轻松切换:

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
x = x.to(device)  # 将张量移动到指定设备

自动微分

PyTorch 的核心特性之一是自动微分(autograd):

x = torch.tensor(2.0, requires_grad=True)
y = x**2
y.backward()  # 自动计算梯度
print(x.grad)  # 输出梯度值 4.0

实际应用场景

  1. 图像处理领域
  • 格式转换:将BGR/RGB格式的原始图像(H, W, C)转换为PyTorch标准格式(C, H, W)张量
    • 示例:处理224x224的RGB图像时,转换后得到(3, 224, 224)形状的张量
  • 预处理流水线:可结合torchvision.transforms模块实现
    • 标准化操作:使用Normalize将像素值从[0,255]转换到[0,1]范围
    • 数据增强:随机裁剪、水平翻转等操作都通过张量运算实现
  1. 自然语言处理领域
  • 文本向量化:通过词嵌入层将单词转换为固定维度的词向量
    • 典型流程:文本分词→构建词汇表→创建词向量矩阵
    • 示例:使用300维GloVe词向量时,每个单词表示为(300,)的张量
  • 序列处理:使用pack_padded_sequence处理变长文本序列
    • 有效处理批量中不同长度的文本序列
  1. 模型训练过程
  • 批量处理:将数据组织为(N, C, H, W)或(N, L, D)形式的批量张量
    • N为批量大小,L为序列长度,D为特征维度
  • 自动微分:通过backward()自动计算梯度
    • 示例:损失函数的梯度自动传播到各层参数
  • GPU加速:使用.to('cuda')将张量转移到GPU
    • 典型加速比:相比CPU可实现5-50倍的训练速度提升
  1. 优化技巧
  • 内存优化:使用torch.no_grad()减少验证时的内存占用
  • 计算优化:利用torch.jit对模型进行编译优化
  • 并行计算:通过DataParallel实现多GPU训练

通过这些张量操作和优化技术,开发者可以:

  • 构建端到端的深度学习流水线
  • 实现高效的模型训练和推理
  • 充分利用现代GPU的计算能力
  • 快速迭代模型结构和超参数
  • 部署高性能的深度学习应用

到此这篇关于PyTorch 张量的基本操作的文章就介绍到这了,更多相关PyTorch 张量内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python 包实现 time 时间管理操作

    python 包实现 time 时间管理操作

    这篇文章主要介绍了python包实现time时间管理操作,文章通过获取当前时间戳,即当前系统内表示时间的一个浮点数,下文更多相关内容需要的小伙伴可以参考一下
    2022-04-04
  • 关于Python面向对象编程的知识点总结

    关于Python面向对象编程的知识点总结

    Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。下面这篇文章将详细给大家介绍关于Python面向对象编程的知识点,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-02-02
  • 关于torch.scatter与torch_scatter库的使用整理

    关于torch.scatter与torch_scatter库的使用整理

    这篇文章主要介绍了关于torch.scatter与torch_scatter库的使用整理,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Pandas 按索引合并数据集的方法

    Pandas 按索引合并数据集的方法

    今天小编就为大家分享一篇Pandas 按索引合并数据集的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-11-11
  • Python中断多重循环的思路总结

    Python中断多重循环的思路总结

    在本文里小编给大家整理的是关于Python中断多重循环的思路以及相关知识点,有需要的朋友们可以学习下。
    2019-10-10
  • 关于fastapi异步框架操作的理解

    关于fastapi异步框架操作的理解

    这篇文章主要介绍了关于fastapi异步框架的操作,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-06-06
  • 详解python中的生成器、迭代器、闭包、装饰器

    详解python中的生成器、迭代器、闭包、装饰器

    这篇文章主要介绍了python中的生成器、迭代器、闭包、装饰器的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • Python实现html转换为pdf报告(生成pdf报告)功能示例

    Python实现html转换为pdf报告(生成pdf报告)功能示例

    这篇文章主要介绍了Python实现html转换为pdf报告功能,结合实例形式分析了Python使用pdfkit实现HTML转换为PDF的相关操作技巧与注意事项,需要的朋友可以参考下
    2019-05-05
  • python使用epoll实现服务端的方法

    python使用epoll实现服务端的方法

    今天小编就为大家分享一篇python使用epoll实现服务端的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • Python开发游戏之井字游戏的实战步骤

    Python开发游戏之井字游戏的实战步骤

    最近正在学习Python,所以最近做了一个关于Python的实例,下面这篇文章主要给大家介绍了关于Python开发游戏之井字游戏的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-02-02

最新评论