PyTorch张量完全指南:从理论到源码深度解析 - 实践
目录
引言:为什么张量是PyTorch的核心?
在深度学习的世界里,PyTorch已经成为最受欢迎的框架之一,而张量(Tensor)则是PyTorch最基础、最重要的数据结构。理解张量不仅意味着掌握了PyTorch的使用方法,更是深入理解深度学习底层实现的关键。本文将带你从零开始,全面掌握PyTorch张量的核心概念、操作原理和底层实现。
一、张量基础:什么是张量?
1.1 张量的数学定义
在数学上,张量是多维数组的推广。简单来说:
- 0维张量:标量(单个数字)
- 1维张量:向量
- 2维张量:矩阵
- 3维及以上:高阶张量
1.2 PyTorch张量的核心特征
import torch
# 创建张量示例
scalar = torch.tensor(3.14) # 0维张量(标量)
vector = torch.tensor([1, 2, 3]) # 1维张量(向量)
matrix = torch.tensor([[1, 2], # 2维张量(矩阵)
[3, 4]])
tensor_3d = torch.randn(2, 3, 4) # 3维张量
print(f"标量形状: {
scalar.shape}")
print(f"向量形状: {
vector.shape}")
print(f"矩阵形状: {
matrix.shape}")
print(f"3D张量形状: {
tensor_3d.shape}")
核心特性可概括为以下几点:
- 与NumPy相似的API:使用方式类似于numpy.ndarray,学习成本低,且能与NumPy数组轻松互转。
- 动态计算图(自动微分):每个张量都有一个.grad_fn属性,用于构建动态计算图,从而实现自动求导(autograd)。这是PyTorch模型训练的核心。
- 设备无关性:可以方便地在CPU和GPU(通过.cuda())等设备间切换,只需改变device属性,以实现加速计算。
- 内存共享:通过.numpy()、.data_ptr()或切片操作(如tensor[0] = 10)创建的视图,与原始张量共享底层数据存储,高效但需注意原地操作的影响。
- 丰富的操作库:提供了涵盖线性代数、随机采样、神经网络运算等全面且高效的操作函数。
最核心的区别于其他框架的特性是第2点:动态计算图。 它使得PyTorch的代码编写(尤其是模型调试)更加直观和灵活。
import torch
import numpy as np
# 1. 类似NumPy
np_arr = np.ones((2, 3))
tensor = torch.from_numpy(np_arr) # 从NumPy创建
print(tensor + 1) # 操作类似
# 2. 动态计算图与自动微分
x = torch.tensor([1.0], requires_grad=True) # 需要追踪梯度
y = x ** 2
y.backward() # 自动计算梯度
print(x.grad) # 输出: tensor([2.]) -> dy/dx = 2x
# 3. 设备切换
if torch.cuda.is_available():
gpu_tensor = tensor.cuda() # 转移到GPU
# 4. 内存共享
a = torch.tensor([1, 2, 3])
b = a[0] # 或 a.numpy()
b += 1
print(a) # 输出: tensor([2, 2, 3]),原始数据被改变
总结来说,PyTorch张量是支持GPU加速、具备自动微分功能、类似NumPy的多维数组,是PyTorch深度学习框架的基石。
二、张量的核心属性详解
2.1 基础属性
dtype - 数据类型
tensor = torch.tensor([1, 2, 3])
print(tensor.dtype) # torch.int64
float_tensor = torch.tensor([1.0, 2.0])
print(float_tensor.dtype) # torch.float32
shape/size - 形状
tensor = torch.randn(2, 3, 4)
print(tensor.shape) # torch.Size([2, 3, 4])
print(tensor.size()) # torch.Size([2, 3, 4])
print(tensor.size(0)) # 2 - 获取第0维大小
device - 存储设备
cpu_tensor = torch.tensor([1, 2, 3])
print(cpu_tensor.device) # cpu
gpu_tensor = cpu_tensor.cuda()
print(gpu_tensor.device) # cuda:0
2.2 梯度相关属性
requires_grad - 梯度追踪标志
x = torch.tensor([1.0], requires_grad=True)
y = torch.tensor([2.0]) # 默认False
print(x.requires_grad) # True
print(y.requires_grad) # False
grad - 存储的梯度值
x = torch.tensor([2.0], requires_grad=True)
y = x ** 2
y.backward()
print(x.grad) # tensor([4.]) - dy/dx = 2x
grad_fn - 梯度计算函数
x = torch.tensor([2.0], requires_grad=True)
y = x ** 2
z = y * 3
print(z.grad_fn) # <MulBackward0 object>
print(z.grad_fn.next_functions[0][0]) # <PowBackward0 object>
is_leaf - 是否为叶子节点
x = torch.tensor([1.0], requires_grad=True) # 叶子节点
y = x ** 2 # 非叶子节点
print(x.is_leaf) # True
print(y.is_leaf) # False
2.3 内存相关属性
storage() - 底层存储
tensor = torch.tensor([[1, 2], [3, 4]])
storage = tensor.storage()
print(storage) # [1, 2, 3, 4] - 一维连续数组
stride() - 内存步长
tensor = torch.tensor([[1, 2, 3], [4, 5, 6]])
print(tensor.stride()) # (3, 1)</

浙公网安备 33010602011771号