pytorch api文档:torch.nn.Parameter可训练参数的封装类

介绍

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 的核心用法:

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 只是普通张量:

# 直接创建的 nn.Parameter 不会被注册
isolated_param = nn.Parameter(torch.ones(1))
print("孤立参数是否属于模型?", isolated_param in model.parameters())  # False

支持梯度计算与优化更新

nn.Parameter 是反向传播的核心载体,优化器会自动更新其值:

# 模拟:前向计算 → 计算损失 → 反向传播 → 优化器更新参数
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):

# 自定义线性层
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 不会被自动注册:

# 错误示例:不继承 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 官方初始化策略:

# 推荐: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:

# 冻结偏置参数
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 实现自动注册和梯度更新。

原文出处:/show_1GW2c5QMXmqt.html