pytorch api文档:torch.nn.Parameter可训练参数的封装类 作者:马育民 • 2026-01-18 09:01 • 阅读:10001 # 介绍 `torch.nn.Parameter` 是 **可训练参数的封装类**,继承自 `torch.Tensor`,是构建自定义可训练模型参数的核心工具——它本质是一种特殊的张量,会被自动注册到模型的参数列表中,参与反向传播和优化更新 ### 特点 - 特殊的张量,默认开启 `requires_grad=True`(可求梯度); - 当把它赋值给 `nn.Module` 的属性时,会被自动注册到模型的 `parameters()`/`named_parameters()` 列表中; - 优化器(如 `Adam`/`SGD`)能识别并更新这些参数,普通张量则不会。 简单来说:**普通张量是“数据”,`torch.nn.Parameter` 是“模型可训练的权重/偏置”**。 # 语法 ``` torch.nn.Parameter(data=None, requires_grad=True) ``` #### 核心参数 | 参数 | 作用 | 说明 | |------------|----------------------------------------------------------------------|--------------------------------------------------------------------------| | `data` | 初始化参数的张量(必填)| 通常用 `torch.randn()`/`torch.zeros()` 等初始化,数据类型建议为 float32 | | `requires_grad` | 是否开启梯度计算(默认 True)| 设为 False 时,该参数不会被优化器更新(变为“冻结参数”)| # 例子 先通过极简的自定义模型示例,理解 `nn.Parameter` 的核心用法: ```python import torch import torch.nn as nn # 示例1:定义一个含可训练参数的简单模型 class MyModel(nn.Module): def __init__(self): super().__init__() # 定义可训练参数:权重 w(2×3 矩阵)、偏置 b(3维向量) self.w = nn.Parameter(torch.randn(2, 3)) # 默认 requires_grad=True self.b = nn.Parameter(torch.zeros(3)) # 全零初始化的偏置 # 定义普通张量(不会被注册为模型参数) self.not_a_param = torch.randn(2, 3) # 无 requires_grad,也不注册 # 初始化模型 model = MyModel() # 查看模型的可训练参数(仅 nn.Parameter 会被列出) print("模型可训练参数:") for name, param in model.named_parameters(): print(f"名称:{name},形状:{param.shape},是否可求梯度:{param.requires_grad}") # 输出: # 名称:w,形状:torch.Size([2, 3]),是否可求梯度:True # 名称:b,形状:torch.Size([3]),是否可求梯度:True # 普通张量不会出现在参数列表中 print("\n普通张量是否在参数列表中?", "not_a_param" in [n for n, _ in model.named_parameters()]) # 输出:False ``` # 特性 ### 自动注册到模型参数列表 只有赋值给 `nn.Module` 实例属性的 `nn.Parameter` 才会被注册,直接创建的 `nn.Parameter` 只是普通张量: ```python # 直接创建的 nn.Parameter 不会被注册 isolated_param = nn.Parameter(torch.ones(1)) print("孤立参数是否属于模型?", isolated_param in model.parameters()) # False ``` ### 支持梯度计算与优化更新 `nn.Parameter` 是反向传播的核心载体,优化器会自动更新其值: ```python # 模拟:前向计算 → 计算损失 → 反向传播 → 优化器更新参数 optimizer = torch.optim.SGD(model.parameters(), lr=0.1) # 前向计算 x = torch.randn(4, 2) # 输入:4个样本,2维特征 output = x @ model.w + model.b # 线性计算 # 计算损失(模拟) loss = output.sum() # 反向传播 loss.backward() # 查看梯度 print("\n参数w的梯度:\n", model.w.grad) print("参数b的梯度:\n", model.b.grad) # 优化器更新参数 optimizer.step() # 清空梯度(必须步骤) optimizer.zero_grad() print("\n更新后参数w的前两个值:\n", model.w[:2, :2]) # 数值已更新 ``` # 与普通张量的核心区别 | 特性 | `torch.nn.Parameter` | 普通 `torch.Tensor` | |---------------------|--------------------------------|------------------------------------| | 自动注册到模型参数 | ✅(赋值给 Module 属性时)| ❌ | | 默认 `requires_grad` | ✅(True)| ❌(False)| | 被优化器更新 | ✅ | ❌(除非手动设 `requires_grad=True` 且加入优化器) | # 实战场景:自定义层/模型 `nn.Parameter` 最常用的场景是**自定义层(nn.Module)**,比如实现一个简单的线性层(替代 `nn.Linear`): ```python # 自定义线性层 class MyLinear(nn.Module): def __init__(self, in_features, out_features): super().__init__() # 初始化权重:遵循 PyTorch 官方初始化策略(Kaiming 正态分布) self.weight = nn.Parameter(torch.randn(out_features, in_features) * 0.01) # 初始化偏置:全零 self.bias = nn.Parameter(torch.zeros(out_features)) def forward(self, x): # 前向计算:y = x @ weight.T + bias return x @ self.weight.T + self.bias # 使用自定义线性层 linear_layer = MyLinear(in_features=5, out_features=3) x = torch.randn(4, 5) # 4个样本,5维特征 output = linear_layer(x) print("自定义线性层输出形状:", output.shape) # torch.Size([4, 3]) # 查看层的参数 print("\n自定义层参数:") for name, param in linear_layer.named_parameters(): print(f"{name}: {param.shape}") # 输出: # weight: torch.Size([3, 5]) # bias: torch.Size([3]) ``` # 常见易错点 ### 忘记继承 `nn.Module` 如果自定义类不继承 `nn.Module`,`nn.Parameter` 不会被自动注册: ```python # 错误示例:不继承 nn.Module class BadModel: def __init__(self): self.w = nn.Parameter(torch.randn(2,3)) bad_model = BadModel() # 无法调用 parameters() 方法 # print(list(bad_model.parameters())) # 报错:'BadModel' object has no attribute 'parameters' ``` ### 参数初始化不当 直接用 `torch.randn()` 初始化大维度参数时,数值过大会导致训练不稳定,建议遵循 PyTorch 官方初始化策略: ```python # 推荐:Kaiming 初始化(适用于线性层/卷积层) self.weight = nn.Parameter(torch.nn.init.kaiming_normal_(torch.empty(out_features, in_features))) # 或简单缩放 self.weight = nn.Parameter(torch.randn(out_features, in_features) * 0.01) ``` ### 冻结参数(设 `requires_grad=False`) 如果想冻结部分参数(不更新),可手动设置 `requires_grad=False`: ```python # 冻结偏置参数 linear_layer.bias.requires_grad = False # 优化器仅更新未冻结的参数 optimizer = torch.optim.SGD( [p for p in linear_layer.parameters() if p.requires_grad], lr=0.1 ) ``` # 总结 1. `torch.nn.Parameter` 是**封装可训练参数的特殊张量**,赋值给 `nn.Module` 实例属性时会自动注册到模型参数列表,默认开启梯度计算。 2. 核心区别:普通张量不会被模型注册、不会被优化器更新;`torch.nn.Parameter` 是模型的“可训练权重/偏置”。 3. 实战用法:自定义层/模型时,用 `torch.nn.Parameter` 定义权重、偏置等可训练参数,配合 `torch.nn.Module` 实现自动注册和梯度更新。 原文出处:http://malaoshi.top/show_1GW2c5QMXmqt.html