PyTorch中张量和模型的核心属性解析
目录
一、Tensor(张量)的常见属性
✅ 延伸:Tensor的“状态逻辑”
二、nn.Module(网络层)的常见属性
✅ 模型与参数之间的关系
三、Tensor 与 Module 的桥梁
四、用例直观展示
在 PyTorch 中,无论是张量(Tensor)还是网络层(nn.Module),都有自己的一套核心属性体系,这些属性不仅定义了数据或层的行为,也决定了模型的可训练性、设备位置、梯度传播方式等关键机制。
可以把它拆开成两个部分讲:
一、Tensor(张量)的常见属性
PyTorch 的张量是所有数据计算的基础,它既是数据容器,又是自动微分系统的一部分。
我们看一眼:
import torch
x = torch.randn(2, 3, requires_grad=True)
现在来一条条看它的重要属性:
| 属性 | 说明 | 示例值 |
|---|---|---|
.shape 或 .size() | 张量的维度结构 | torch.Size([2, 3]) |
.dtype | 数据类型(如 float32、int64) | torch.float32 |
.device | 存储设备(CPU 或 GPU) | device('cuda:0') |
.requires_grad | 是否参与反向传播 | True |
.grad | 存储反向传播的梯度 | None(初始时为空) |
.is_leaf | 是否为叶子节点张量(用于计算图判断) | True(如果是直接创建的变量) |
.data | 访问底层存储数据(不建议直接修改) | Tensor数据本身 |
.T | 转置 | 返回 [3, 2] 张量 |
.ndim | 维度数量 | 2 |
.numel() | 元素个数 | 6 |
这些属性控制了张量的“身份”与“行为”。
举例来说,requires_grad=True 就意味着它会被自动求导系统追踪,反向传播时生成 .grad。
✅ 延伸:Tensor的“状态逻辑”
一个张量其实有三种“身份”:
-
普通数据(不参与计算图)
-
可训练变量(
requires_grad=True) -
参数(当它被
nn.Module挂载为属性时)
二、nn.Module(网络层)的常见属性
PyTorch 中所有网络层(如 nn.Linear, nn.Conv2d, nn.BatchNorm2d)都继承自 nn.Module。
它们在“层”的意义上是一组可训练参数 + 前向计算逻辑 + 状态管理机制。
我们看个例子:
import torch.nn as nnlayer = nn.Linear(10, 5, bias=True)
| 属性 | 说明 | 示例值 |
|---|---|---|
.weight | 可训练参数之一(通常是核心权重矩阵) | torch.Size([5, 10]) |
.bias | 可训练偏置项(可选) | torch.Size([5]) |
.parameters() | 返回所有可训练参数的迭代器 | <generator> |
.state_dict() | 模型状态字典(用于保存/加载) | {'weight': ..., 'bias': ...} |
.training | 当前是否处于训练模式 | True 或 False |
.to(device) | 把模型参数移动到指定设备 | layer.to("cuda") |
.eval() / .train() | 切换推理或训练模式 | 控制 BatchNorm / Dropout 行为 |
.forward() | 定义前向传播逻辑 | 函数实现 |
.children() | 子模块迭代器(用于递归遍历) | 如 Sequential 子层 |
.named_parameters() | 带名称返回参数迭代器 | (“weight”, Tensor(...)) |
✅ 模型与参数之间的关系
-
参数(Parameters) 是特殊的 Tensor,具有
requires_grad=True。 -
当一个 Tensor 被赋值为
nn.Module的属性时(如self.weight = nn.Parameter(...)),它会自动注册到模型参数表中。 -
state_dict()会收集所有这些注册的参数,用于保存与加载模型。
三、Tensor 与 Module 的桥梁
在训练过程中,PyTorch 的核心机制是这样的:
-
张量承载数据与梯度
→ 它们构成计算图(Computational Graph)。 -
模块(Module) 管理参数与前向逻辑
→ 通过forward()使用张量运算构建计算图。 -
优化器(Optimizer) 更新参数
→ 基于.grad属性调整.weight/.bias。
所以你可以理解为:
Tensor 是数据单元,Module 是逻辑单元,两者通过计算图粘合在一起构成整个深度学习系统。
四、用例直观展示
张量属性代码:
'''
.shape 或 .size() 张量的维度结构 torch.Size([2, 3])
.dtype 数据类型(如 float32、int64) torch.float32
.device 存储设备(CPU 或 GPU) device('cuda:0')
.requires_grad 是否参与反向传播 True
.grad 存储反向传播的梯度 None(初始时为空)
.is_leaf 是否为叶子节点张量(用于计算图判断) True(如果是直接创建的变量)
.data 访问底层存储数据(不建议直接修改) Tensor数据本身
.T 转置 返回 [3, 2] 张量
.ndim 维度数量 2
.numel() 元素个数 6
'''import torcha = torch.tensor([[1, 2, 3], [4, 5, 6]], dtype=torch.float32, device='cuda:0', requires_grad=True)print(f"张量 a:{a}")
print(f"a.shape: {a.shape}") # 张量的维度结构
print(f"a.dtype: {a.dtype}") # 数据类型
print(f"a.device: {a.device}") # 存储设备
print(f"a.requires_grad: {a.requires_grad}") # 是否参与反向传播
print(f"a.grad: {a.grad}") # 存储反向传播的梯度
print(f"a.is_leaf: {a.is_leaf}") # 是否为叶子节点张量
print(f"a.data: {a.data}") # 访问底层存储数据
print(f"a.T: {a.T}") # 转置
print(f"a.ndim: {a.ndim}") # 维度数量
print(f"a.numel(): {a.numel()}") # 元素个数
运行结果如下:
张量 a:tensor([[1., 2., 3.],[4., 5., 6.]], device='cuda:0', requires_grad=True)
a.shape: torch.Size([2, 3])
a.dtype: torch.float32
a.device: cuda:0
a.requires_grad: True
a.grad: None
a.is_leaf: True
a.data: tensor([[1., 2., 3.],[4., 5., 6.]], device='cuda:0')
a.T: tensor([[1., 4.],[2., 5.],[3., 6.]], device='cuda:0', grad_fn=<PermuteBackward0>)
a.ndim: 2
a.numel(): 6
模型属性代码:
'''
.weight 可训练参数之一(通常是核心权重矩阵) torch.Size([5, 10])
.bias 可训练偏置项(可选) torch.Size([5])
.parameters() 返回所有可训练参数的迭代器 <generator>
.state_dict() 模型状态字典(用于保存/加载) {'weight': ..., 'bias': ...}
.training 当前是否处于训练模式 True 或 False
.to(device) 把模型参数移动到指定设备 layer.to("cuda")
.eval() / .train() 切换推理或训练模式 控制 BatchNorm / Dropout 行为
.forward() 定义前向传播逻辑 函数实现
.children() 子模块迭代器(用于递归遍历) 如 Sequential 子层
.named_parameters() 带名称返回参数迭代器 (“weight”, Tensor(...))'''import torch.nn as nnlayer = nn.Linear(10, 5, bias=True)print(f"\n线性层 layer: {layer}")
print(f"layer.weight: {layer.weight}") # 可训练参数之一
print(f"layer.bias: {layer.bias}") # 可训练偏置项
print(f"list(layer.parameters()): {list(layer.parameters())}") # 返回所有可训练参数的迭代器
print(f"layer.state_dict().keys(): {layer.state_dict().keys()}") # 模型状态字典
print(f"layer.training: {layer.training}") # 当前是否处于训练模式
layer.to("cuda") # 把模型参数移动到指定设备
print(f"layer.weight.device: {layer.weight.device}") # 查看参数所在设备
运行结果:
线性层 layer: Linear(in_features=10, out_features=5, bias=True)
layer.weight: Parameter containing:
tensor([[-0.1007, -0.2463, -0.1335, -0.2620, 0.1533, 0.2015, -0.1983, -0.1258,0.3121, 0.1384],[-0.2874, 0.2041, -0.3077, -0.0460, 0.1132, 0.1984, 0.2852, -0.2435,-0.0452, 0.2154],[ 0.2020, 0.0664, -0.1020, 0.1760, 0.1189, -0.2611, -0.2146, 0.2514,-0.0989, 0.0106],[ 0.1393, -0.0052, 0.2016, -0.1647, 0.1316, 0.2540, -0.2205, -0.0516,0.2074, 0.2260],[-0.2003, 0.2306, -0.0201, 0.2523, -0.2873, -0.2142, 0.2414, -0.0777,0.1019, 0.0299]], requires_grad=True)
layer.bias: Parameter containing:
tensor([-0.0893, 0.1224, -0.2193, -0.1323, -0.2181], requires_grad=True)
list(layer.parameters()): [Parameter containing:
tensor([[-0.1007, -0.2463, -0.1335, -0.2620, 0.1533, 0.2015, -0.1983, -0.1258,0.3121, 0.1384],[-0.2874, 0.2041, -0.3077, -0.0460, 0.1132, 0.1984, 0.2852, -0.2435,-0.0452, 0.2154],[ 0.2020, 0.0664, -0.1020, 0.1760, 0.1189, -0.2611, -0.2146, 0.2514,-0.0989, 0.0106],[ 0.1393, -0.0052, 0.2016, -0.1647, 0.1316, 0.2540, -0.2205, -0.0516,0.2074, 0.2260],[-0.2003, 0.2306, -0.0201, 0.2523, -0.2873, -0.2142, 0.2414, -0.0777,0.1019, 0.0299]], requires_grad=True), Parameter containing:
tensor([-0.0893, 0.1224, -0.2193, -0.1323, -0.2181], requires_grad=True)]
layer.state_dict().keys(): odict_keys(['weight', 'bias'])
layer.training: True
layer.weight.device: cuda:0
