当扩展此类时,它的一种方法现在需要一个额外的参数。为什么?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当扩展此类时,它的一种方法现在需要一个额外的参数。为什么?相关的知识,希望对你有一定的参考价值。
[当我想对初始化的model = nn.Sequential
对象进行前向传递时,我只使用:
out = model(X)
# OR
out = model.forward(X)
但是,我尝试扩展Sequential
类,现在这两个方法突然都需要第二个参数。例如,在以下方法中记下我对self(x)
的调用:
def train(self, trainloader, epochs):
for e in range(epochs):
for x, y in trainloader:
x = x.view(x.shape[0], -1)
self.optimizer.zero_grad()
loss = self.criterion(self(x), y) # CALL OCCURS HERE
loss.backward()
self.optimizer.step()
此代码现在给了我TypeError: forward() missing 1 required positional argument: 'target'
。
我的问题:由于除了扩展类外我什么也没做,所以为什么呢?
以下完整课程的代码:
class Network(nn.Sequential):
def __init__(self, layers):
super().__init__(self.init_modules(layers))
self.criterion = nn.NLLLoss()
self.optimizer = optim.Adam(self.parameters(), lr=0.003)
def init_modules(self, layers):
n_layers = len(layers)
modules = OrderedDict()
# Layer definitions for input and inner layers:
for i in range(n_layers - 2):
modules[f'fc{i}'] = nn.Linear(layers[i], layers[i+1])
modules[f'relu{i}'] = nn.ReLU()
# Definition for output layer:
modules['fc_out'] = nn.Linear(layers[-2], layers[-1])
modules['smax_out'] = nn.LogSoftmax(dim=1)
return modules
def train(self, trainloader, epochs):
for e in range(epochs):
for x, y in trainloader:
x = x.view(x.shape[0], -1)
self.optimizer.zero_grad()
loss = self.criterion(self(x), y)
loss.backward()
self.optimizer.step()
完整堆栈跟踪:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-63-490e0b9eef22> in <module>
----> 1 model2.train(trainloader, 5, plot_loss=True)
<ipython-input-61-e173e5672f18> in train(self, trainloader, epochs, plot_loss)
32 x = x.view(x.shape[0], -1)
33 self.optimizer.zero_grad()
---> 34 loss = self.criterion(self(x), y)
35 loss.backward()
36 self.optimizer.step()
c:\program files\python38\lib\site-packages\torch\nn\modules\module.py in __call__(self, *input, **kwargs)
548 result = self._slow_forward(*input, **kwargs)
549 else:
--> 550 result = self.forward(*input, **kwargs)
551 for hook in self._forward_hooks.values():
552 hook_result = hook(self, input, result)
c:\program files\python38\lib\site-packages\torch\nn\modules\container.py in forward(self, input)
98 def forward(self, input):
99 for module in self:
--> 100 input = module(input)
101 return input
102
c:\program files\python38\lib\site-packages\torch\nn\modules\module.py in __call__(self, *input, **kwargs)
548 result = self._slow_forward(*input, **kwargs)
549 else:
--> 550 result = self.forward(*input, **kwargs)
551 for hook in self._forward_hooks.values():
552 hook_result = hook(self, input, result)
TypeError: forward() missing 1 required positional argument: 'target'
答案
问:由于我除了扩展课程外什么都没做,为什么呢?
实际上,您有。您选择了“错误的”基类。 forward
的nn.Sequential
仅遍历所有模块,并且在您定义时:
self.criterion = nn.NLLLoss()
您将损失注册为模块。因此,当您调用self(x)
时,实际上是在某个时候调用了self.criterion(x)
,因此实际上是在调用TypeError
。
另一答案
注意self.criterion
是类nn.NLLLoss
的一个实例。您需要传递一个火炬张量作为第二个参数,确保y
满足该类型要求。另外,我不确定此行loss = self.criterion(self(x), y)
为什么要呼叫self(x)
?第一个参数应该是通过激活函数传递的输入数据。
以上是关于当扩展此类时,它的一种方法现在需要一个额外的参数。为什么?的主要内容,如果未能解决你的问题,请参考以下文章
当 Python __call__ 方法获得额外的第一个参数时?