我正在尝试使用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操作?
回答:
你的网络存在两个问题 –