所以我正在尝试使用PyTorch库来训练一个CNN。模型本身没有问题(我可以无错误地进行数据的前向传播),并且我使用DataLoader函数准备了一个自定义数据集。
这是我准备数据的代码(我省略了一些不相关的变量声明等):
# 初始化模型 class neural_net_model(nn.Module): # 省略 ...# 准备数据集train_data = torchvision.datasets.ImageFolder(root = TRAIN_DATA_PATH, transform = TRANSFORM_IMG)train_data_loader = data_utils.DataLoader(train_data, batch_size = BATCH_SIZE, shuffle = True)test_data = torchvision.datasets.ImageFolder(root = TEST_DATA_PATH, transform = TRANSFORM_IMG)test_data_loader = data_utils.DataLoader(test_data, batch_size = BATCH_SIZE, shuffle = True)
但是,在训练代码中(我参考了各种在线资料),当我用以下指令进行模型的前向传播时,出现了错误:
...for step, (data, label) in enumerate(train_data_loader): outputs = neural_net_model(data) ...
这引发了一个错误:
NotImplementedError Traceback (most recent call last)<ipython-input-12-690cfa6916ec> in <module> 6 7 # 前向传播----> 8 outputs = neural_net_model(images) 9 loss = criterion(outputs, labels) 10 ~\Anaconda3\lib\site-packages\torch\nn\modules\module.py in __call__(self, *input, **kwargs) 487 result = self._slow_forward(*input, **kwargs) 488 else:--> 489 result = self.forward(*input, **kwargs) 490 for hook in self._forward_hooks.values(): 491 hook_result = hook(self, input, result)~\Anaconda3\lib\site-packages\torch\nn\modules\module.py in forward(self, *input) 83 registered hooks while the latter silently ignores them. 84 """---> 85 raise NotImplementedError 86 87 def register_buffer(self, name, tensor):NotImplementedError:
我在网上找不到类似的问题,这看起来很奇怪,因为我几乎完全按照参考资料编写了代码,而且文档中对这个错误(NotImplementedError:)的定义并不明确。
你们知道这个问题的原因和解决方案吗?
- 这是网络的代码
from torch import nn, from_numpyimport torchimport torch.nn.functional as F class DeXpression(nn.Module): def __init__(self, ): super(DeXpression, self).__init__() # 层1 self.convolution1 = nn.Conv2d(in_channels = 1, out_channels = 64, kernel_size = 7, stride = 2, padding = 3) self.pooling1 = nn.MaxPool2d(kernel_size = 3, stride = 2, padding = 0) # 层FeatEx1 self.convolution2a = nn.Conv2d(in_channels = 64, out_channels = 96, kernel_size = 1, stride = 1, padding = 0) self.convolution2b = nn.Conv2d(in_channels = 96, out_channels = 208, kernel_size = 3, stride = 1, padding = 1) self.pooling2a = nn.MaxPool2d(kernel_size = 3, stride = 1, padding = 1) self.convolution2c = nn.Conv2d(in_channels = 64, out_channels = 64, kernel_size = 1, stride = 1, padding = 0) self.pooling2b = nn.MaxPool2d(kernel_size = 3, stride = 2, padding = 0) # 层FeatEx2 self.convolution3a = nn.Conv2d(in_channels = 272, out_channels = 96, kernel_size = 1, stride = 1, padding = 0) self.convolution3b = nn.Conv2d(in_channels = 96, out_channels = 208, kernel_size = 3, stride = 1, padding = 1) self.pooling3a = nn.MaxPool2d(kernel_size = 3, stride = 1, padding = 1) self.convolution3c = nn.Conv2d(in_channels = 272, out_channels = 64, kernel_size = 1, stride = 1, padding = 0) self.pooling3b = nn.MaxPool2d(kernel_size = 3, stride = 2, padding = 0) # 全连接层 self.fc1 = nn.Linear(45968, 1024) self.fc2 = nn.Linear(1024, 64) self.fc3 = nn.Linear(64, 8) def net_forward(self, x): # 层1 x = F.relu(self.convolution1(x)) x = F.local_response_norm(self.pooling1(x), size = 2) y1 = x y2 = x # 层FeatEx1 y1 = F.relu(self.convolution2a(y1)) y1 = F.relu(self.convolution2b(y1)) y2 = self.pooling2a(y2) y2 = F.relu(self.convolution2c(y2)) x = torch.zeros([y1.shape[0], y1.shape[1] + y2.shape[1], y1.shape[2], y1.shape[3]]) x[:, 0:y1.shape[1], :, :] = y1 x[:, y1.shape[1]:, :, :] = y2 x = self.pooling2b(x) y1 = x y2 = x # 层FeatEx2 y1 = F.relu(self.convolution3a(y1)) y1 = F.relu(self.convolution3b(y1)) y2 = self.pooling3a(y2) y2 = F.relu(self.convolution3c(y2)) x = torch.zeros([y1.shape[0], y1.shape[1] + y2.shape[1], y1.shape[2], y1.shape[3]]) x[:, 0:y1.shape[1], :, :] = y1 x[:, y1.shape[1]:, :, :] = y2 x = self.pooling3b(x) # 全连接层 x = x.view(-1, x.shape[0] * x.shape[1] * x.shape[2] * x.shape[3]) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = F.log_softmax(self.fc3(x), dim = None) return x
回答:
你的网络类实现了一个net_forward
方法。然而,nn.Module
期望其派生类实现forward
方法(没有net_
前缀)。
只需将net_forward
重命名为forward
,你的代码应该就可以正常运行了。
你可以在这里了解更多关于继承和重载方法的信息。
旧答案:你运行的代码和发布的代码并不相同。
你发布的代码是:
for step, (data, label) in enumerate(train_data_loader): neural_net_model(data)
而你运行的代码(如错误信息中显示的)是:
# 前向传播outputs = model(images)
你得到的错误表明,你向其输入images
的model
是nn.Module
类的一个实例,而不是从nn.Module
派生的实际实现。因此,你尝试使用的实际model
没有明确实现forward
方法。请确保你使用的是你实现的实际模型。