我最近不得不构造一个需要包含张量的模块。尽管使用torch.nn.Parameter
可以很好地进行反向传播,但是在打印网络对象时却没有显示。为什么不像其他类似parameter
的模块那样包含此layer
? (它的行为不应该像layer
吗?)
import torch
import torch.nn as nn
class MyNet(torch.nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.layer = nn.Linear(10, 10)
self.parameter = torch.nn.Parameter(torch.zeros(10,10, requires_grad=True))
net = MyNet()
print(net)
输出:
MyNet(
(layer): Linear(in_features=10, out_features=10, bias=True)
)
答案 0 :(得分:4)
调用print(net)
时,将调用__repr__
方法。 __repr__
给出对象的“正式”字符串表示形式。
在PyTorch的{{3}}(MyNet
模型的基类)中,__repr__
的实现方式如下:
def __repr__(self):
# We treat the extra repr like the sub-module, one item per line
extra_lines = []
extra_repr = self.extra_repr()
# empty string will be split into list ['']
if extra_repr:
extra_lines = extra_repr.split('\n')
child_lines = []
for key, module in self._modules.items():
mod_str = repr(module)
mod_str = _addindent(mod_str, 2)
child_lines.append('(' + key + '): ' + mod_str)
lines = extra_lines + child_lines
main_str = self._get_name() + '('
if lines:
# simple one-liner info, which most builtin Modules will use
if len(extra_lines) == 1 and not child_lines:
main_str += extra_lines[0]
else:
main_str += '\n ' + '\n '.join(lines) + '\n'
main_str += ')'
return main_str
请注意,上述方法返回main_str
,其中仅包含对_modules
和extra_repr
的调用,因此默认情况下仅打印模块。
PyTorch还提供了nn.Module
方法,您可以自己实现该方法以额外表示模块。
要打印自定义的其他信息,应在自己的模块中重新实现此方法。单行和多行字符串都是可以接受的。
答案 1 :(得分:1)
根据nn.Parameter
文档:
参数是:class:
~torch.Tensor
子类,它们具有 与:class:Module
一起使用时非常特殊的属性-当它们 分配为模块属性后,它们会自动添加到以下列表中 其参数,并会出现在在:meth:~Module.parameters
迭代器中。
因此您可以在net.parameters
中找到它。让我们看下面的例子:
代码:
import torch
import torch.nn as nn
torch.manual_seed(42)
class MyNet(nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.layer = nn.Linear(4, 4)
self.parameter = nn.Parameter(torch.zeros(4, 4, requires_grad=True))
self.tensor = torch.ones(4, 4)
self.module = nn.Module()
net = MyNet()
print(net)
输出:
MyNet(
(layer): Linear(in_features=4, out_features=4, bias=True)
(module): Module()
)
如您所见,没有tensor
或'parameter'对象(因为parameter
是tensor
的子类),只有Module
个。
现在让我们尝试获取我们的净参数:
代码:
for p in net.parameters():
print(p)
输出:
Parameter containing:
tensor([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]], requires_grad=True)
Parameter containing:
tensor([[ 0.3823, 0.4150, -0.1171, 0.4593],
[-0.1096, 0.1009, -0.2434, 0.2936],
[ 0.4408, -0.3668, 0.4346, 0.0936],
[ 0.3694, 0.0677, 0.2411, -0.0706]], requires_grad=True)
Parameter containing:
tensor([ 0.3854, 0.0739, -0.2334, 0.1274], requires_grad=True)
好的,所以第一个是您的net.parameter
。接下来的两个是net.layer
的权重和偏差。让我们验证一下:
代码:
print(net.layer.weight)
print(net.layer.bias)
输出:
Parameter containing:
tensor([[ 0.3823, 0.4150, -0.1171, 0.4593],
[-0.1096, 0.1009, -0.2434, 0.2936],
[ 0.4408, -0.3668, 0.4346, 0.0936],
[ 0.3694, 0.0677, 0.2411, -0.0706]], requires_grad=True)
Parameter containing:
tensor([ 0.3854, 0.0739, -0.2334, 0.1274], requires_grad=True)