预期输入为4D张量,实际得到2D张量

我正在尝试使用PyTorch上的预训练网络VGG16构建神经网络。

我了解到需要调整网络的分类器部分,因此我已经冻结了参数以防止通过它们进行反向传播

代码:

%matplotlib inline%config InlineBackend.figure_format = 'retina'import matplotlib.pyplot as pltimport numpy as npimport timeimport torchfrom torch import nnfrom torch import optimimport torch.nn.functional as Ffrom torch.autograd import Variablefrom torchvision import datasets, transformsimport torchvision.models as modelsfrom collections import OrderedDictdata_dir = 'flowers'train_dir = data_dir + '/train'valid_dir = data_dir + '/valid'test_dir = data_dir + '/test'train_transforms = transforms.Compose([transforms.Resize(224),                                       transforms.RandomRotation(30),                                       transforms.RandomResizedCrop(224),                                       transforms.RandomHorizontalFlip(),                                       transforms.ToTensor(),                                       transforms.Normalize(mean=[0.485, 0.456, 0.406],                                                             std=[0.229, 0.224, 0.225])])validn_transforms = transforms.Compose([transforms.Resize(224),                                        transforms.CenterCrop(224),                                        transforms.ToTensor(),                                        transforms.Normalize((0.485, 0.456, 0.406),                                                             (0.229, 0.224, 0.225))])test_transforms = transforms.Compose([ transforms.Resize(224),                                       transforms.RandomResizedCrop(224),                                       transforms.ToTensor(),                                       transforms.Normalize((0.485, 0.456, 0.406),                                                             (0.229, 0.224, 0.225))])train_data = datasets.ImageFolder(train_dir,                                transform=train_transforms)validn_data = datasets.ImageFolder(valid_dir,                                transform=validn_transforms)test_data = datasets.ImageFolder(test_dir,                                transform=test_transforms)trainloader = torch.utils.data.DataLoader(train_data, batch_size=32, shuffle=True)validnloader = torch.utils.data.DataLoader(validn_data, batch_size=32, shuffle=True)testloader = torch.utils.data.DataLoader(test_data, batch_size=32, shuffle=True)model = models.vgg16(pretrained=True)modelfor param in model.parameters():    param.requires_grad = Falseclassifier = nn.Sequential(OrderedDict([                                      ('fc1', nn.Linear(3*224*224, 10000)),                           ('relu', nn.ReLU()),                          ('fc2', nn.Linear(10000, 5000)),                          ('relu', nn.ReLU()),                          ('fc3', nn.Linear(5000, 102)),                          ('output', nn.LogSoftmax(dim=1))                          ]))model.classifier = classifierclassifiercriterion = nn.NLLLoss()optimizer = optim.Adam(model.classifier.parameters(), lr=0.001)model.cuda()epochs = 1steps = 0training_loss = 0print_every = 300for e in range(epochs):    model.train()    for images, labels in iter(trainloader):        steps == 1        images.resize_(32,3*224*224)        inputs = Variable(images.cuda())        targets = Variable(labels.cuda())        optimizer.zero_grad()        output = model.forward(inputs)        loss = criterion(output, targets)        loss.backward()        optimizer.step()        training_loss += loss.data[0]        if steps % print_every == 0:            print("Epoch: {}/{}... ".format(e+1, epochs),                  "Loss: {:.4f}".format(training_loss/print_every))            running_loss = 0

跟踪错误

ValueError                                Traceback (most recent call last)<ipython-input-17-30552f4b46e8> in <module>()     15         optimizer.zero_grad()     16 ---> 17         output = model.forward(inputs)     18         loss = criterion(output, targets)     19         loss.backward()/opt/conda/lib/python3.6/site-packages/torchvision-0.2.0-py3.6.egg/torchvision/models/vgg.py in forward(self, x)     39      40     def forward(self, x):---> 41         x = self.features(x)     42         x = x.view(x.size(0), -1)     43         x = self.classifier(x)/opt/conda/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)    323         for hook in self._forward_pre_hooks.values():    324             hook(self, input)--> 325         result = self.forward(*input, **kwargs)    326         for hook in self._forward_hooks.values():    327             hook_result = hook(self, input, result)/opt/conda/lib/python3.6/site-packages/torch/nn/modules/container.py in forward(self, input)     65     def forward(self, input):     66         for module in self._modules.values():---> 67             input = module(input)     68         return input     69 /opt/conda/lib/python3.6/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)    323         for hook in self._forward_pre_hooks.values():    324             hook(self, input)--> 325         result = self.forward(*input, **kwargs)    326         for hook in self._forward_hooks.values():    327             hook_result = hook(self, input, result)/opt/conda/lib/python3.6/site-packages/torch/nn/modules/conv.py in forward(self, input)    275     def forward(self, input):    276         return F.conv2d(input, self.weight, self.bias, self.stride,--> 277                         self.padding, self.dilation, self.groups)    278     279 /opt/conda/lib/python3.6/site-packages/torch/nn/functional.py in conv2d(input, weight, bias, stride, padding, dilation, groups)     83     """     84     if input is not None and input.dim() != 4:---> 85         raise ValueError("Expected 4D tensor as input, got {}D tensor instead.".format(input.dim()))     86      87     f = _ConvNd(_pair(stride), _pair(padding), _pair(dilation), False,ValueError: Expected 4D tensor as input, got 2D tensor instead.

这是否是因为我在定义中使用了Linear操作?


回答:

你的网络存在两个问题 –

  1. 你创建了自己的分类器,其第一层接受大小为(3*224*224)的输入,但这并不是vgg16特征部分的输出大小。特征输出的大小为(25088)enter image description here

  2. 你将输入调整为形状为(3*224*224)的张量(对于每个批次),但vgg16的特征部分期望输入形状为(3, 224, 224)。你的自定义分类器位于特征之后,所以你需要为特征而不是分类器准备输入。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注