参考:
- Pytorch之深入理解torch.nn.Parameter()
https://blog.csdn.net/qq_43391414/article/details/120484239
- pytorch Variable与Tensor合并后 requires_grad()默认与修改
https://blog.csdn.net/weixin_43635550/article/details/100192797
torch.tensor
使用torch.tensor
用于创建张量。
torch.nn.Parameter
使用torch.nn.Parameter
用于创建参数矩阵/向量,它和直接使用torch.tensor
来创建参数矩阵具有很大的不同。主要区别有如下:
- 梯度跟踪和更新:当使用 nn.Parameter() 函数创建参数时,PyTorch会自动将这些参数添加到模型的参数列表中,并在训练过程中跟踪和更新它们的梯度。这意味着通过 nn.Parameter() 创建的参数可以自动进行梯度下降优化。而直接使用 torch.randn() 创建的张量不会被自动添加到参数列表中,也不会自动跟踪和更新其梯度。
- 模型参数的访问:通过 nn.Parameter() 创建的参数可以通过 model.parameters() 方法访问到。这对于模型参数的初始化、保存和加载等操作非常方便。而直接使用 torch.randn() 创建的张量不会被包含在 model.parameters() 中,需要手动处理。
对于1中的不会自动更新的例子如下:使用torch.tensor或者类似的torch.zeros, torch.normal, torch.randn的函数都是创建的一个张量,而张量本身是不带有梯度且不跟踪梯度变化,即required_grad==false
默认为false。
a = torch.tensor([1,2]) # just like :: torch.tensor([1,2],dtype=torch.int64,requires_grad=False)
w = torch.tensor([1,2],dtype=torch.float32,requires_grad=True)
对于2中的模型参数的访问,即直接使用类似model.parameter()
是无法访问到参数的且类似该方法只能访问继承自nn的子类,例子如下:
import torch
import torch.nn as nn
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
self.W1 = nn.Parameter(torch.randn(3, 4)) # 使用 nn.Parameter() 创建可训练参数
self.W2 = torch.randn(3, 4) # 直接使用 torch.randn() 创建张量
model = MyModel()
# 访问模型的参数列表
parameters = list(model.parameters())
print(len(parameters)) # 输出:1
# 访问模型的成员变量
variables = list(model.__dict__.keys())
print(len(variables)) # 输出:2
在上述示例中,使用 nn.Parameter() 创建的参数 self.W1 被自动添加到模型的参数列表中,而直接使用 torch.randn() 创建的张量 self.W2 不会被添加到参数列表中。因此,通过 model.parameters() 访问模型的参数列表,只能获取到 self.W1 这个参数。
总结起来,使用 nn.Parameter() 函数可以将张量标记为模型的可训练参数,让它们自动进行梯度跟踪和更新,并方便地访问模型的参数列表。而直接使用 torch.randn() 创建的张量则没有这些功能,需要手动处理参数的梯度和访问方式。