当我想要对一个初始化的 model = nn.Sequential
对象进行前向传递时,我只需使用:
out = model(X)# ORout = 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() # 输入层和中间层的定义: for i in range(n_layers - 2): modules[f'fc{i}'] = nn.Linear(layers[i], layers[i+1]) modules[f'relu{i}'] = nn.ReLU() # 输出层的定义: 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'
回答:
问:既然我只是扩展了这个类,为什么会这样?
实际上,你确实做了改变。你选择了“错误”的基类。nn.Sequential
的 forward
方法只是遍历所有模块,当你定义:
self.criterion = nn.NLLLoss()
你将损失函数注册为一个模块。因此,当你调用 self(x)
时,你实际上在某个时刻调用了 self.criterion(x)
,因此引发了 TypeError
错误。