我正在使用PyTorch进行深度学习来进行图像分类。每当我尝试训练我的模型时,前向函数就会失败。有人能解释一下输入大小错误的原因以及如何修复这个问题吗?
这是我的模型代码,以及我的训练损失和优化器:
model.fc = nn.Sequential( nn.Conv2d(1, 6, 9, padding=0), # 64040 nn.ReLU(), # nn.AvgPool2d(2, stride=2), # max 62020 nn.Conv2d(6, 16, 11, padding=0), # 161010 nn.ReLU(), # 161010 nn.AvgPool2d(2, stride=2), # 1655 = 400 nn.Flatten(), nn.Linear(400, 200), nn.ReLU(), nn.Linear(200, 100), nn.ReLU(), nn.Linear(100, 3), nn.LogSoftmax(dim=1))criterion = nn.NLLLoss()optimizer = optim.Adam(model.fc.parameters(), lr=0.003)model.to(device)
这是验证函数:
def validation(model, val_dataloader, criterion):val_loss = 0accuracy = 0for images, labels in iter(val_dataloader): images, labels = images.to('cuda'), labels.to('cuda') output = model.forward(images) val_loss += criterion(output, labels).item() probabilities = torch.exp(output) equality = (labels.data == probabilities.max(dim=1)[1]) accuracy += equality.type(torch.FloatTensor).mean()return val_loss, accuracy
最后,这是我的训练函数:
def train_classifier(): epochs = 10 steps = 0 print_every = 40 model.to('cuda') for e in range(epochs): model.train() running_loss = 0 for images, labels in iter(train_dataloader): images = images.view(images.shape[0], -1) #this flattens it? steps += 1 images, labels = images.to('cuda'), labels.to('cuda') optimizer.zero_grad() # training output = model.forward(images) loss = criterion(output, labels) loss.backward() optimizer.step() running_loss += loss.item() if steps % print_every == 0: model.eval() # Turn off gradients for validation, saves memory and computations with torch.no_grad(): validation_loss, accuracy = validation(model, validate_loader, criterion) print("Epoch: {}/{}.. ".format(e+1, epochs), "Training Loss: {:.3f}.. ".format(running_loss/print_every), "Validation Loss: {:.3f}.. ".format(validation_loss/len(validate_loader)), "Validation Accuracy: {:.3f}".format(accuracy/len(validate_loader))) running_loss = 0 model.train() train_classifier()
错误代码:
---------------------------------------------------------------------------RuntimeError Traceback (most recent call last)<ipython-input-32-60a435d940e1> in <module>() 49 model.train() 50 ---> 51 train_classifier()5 frames/usr/local/lib/python3.7/dist-packages/torch/nn/modules/conv.py in _conv_forward(self, input, weight, bias) 438 _pair(0), self.dilation, self.groups) 439 return F.conv2d(input, weight, bias, self.stride,--> 440 self.padding, self.dilation, self.groups) 441 442 def forward(self, input: Tensor) -> Tensor:RuntimeError: Expected 4-dimensional input for 4-dimensional weight [64, 3, 7, 7], but got 2-dimensional input of size [32, 1728] instead
任何帮助都将不胜感激!谢谢!
回答:
你的网络既包含Conv2d
层,也包含全连接的Linear
层——这是问题的根源:Conv2d
期望其输入是4维的:批次-通道-高度-宽度。另一方面,nn.Linear
处理的是“扁平化”的特征:批次-通道。因此,你需要在网络处理的过程中“扁平化”你的数据,而不是在应用网络之前,而是在你有一个Flattening
层的地方进行扁平化处理。