Ожидаемый 4-мерный ввод для 4-мерного веса [192, 768, 1, 1], но вместо этого получил 2-мерный ввод размера [50, 1000]

#python #deep-learning #pytorch #torch

Вопрос:

Я пытаюсь модифицировать Inception v3, предварительно обученный в pytorch, чтобы иметь несколько входов. ( 4 вывода точно).

Я получаю эту ошибку: Ожидаемый 4-мерный ввод для 4-мерного веса [192, 768, 1, 1], но вместо этого получил 2-мерный ввод размера [50, 1000]

Моя форма ввода : факел.Размер([50, 3, 299, 299])

Это код для моей модели,

 class CNN1(nn.Module):  def __init__(self, pretrained):  super(CNN1, self).__init__()  if pretrained is True:  self.model = models.inception_v3(pretrained=True)   modules = list(self.model.children())[:-1] # delete the last fc layer.  self.features = nn.Sequential(*modules)  self.fc0 = nn.Linear(2048, 10) #digit 0  self.fc1 = nn.Linear(2048, 10) #digit 1  self.fc2 = nn.Linear(2048, 10) #digit 2  self.fc3 = nn.Linear(2048, 10) #digit 3   def forward(self, x):  bs, _, _, _ = x.shape  x = self.features(x)  x = F.adaptive_avg_pool2d(x, 1).reshape(bs, -1)   label0 = self.fc0(x)  label1 = self.fc1(x)  label2= self.fc2(x)   label3= self.fc3(x)    return {'label0': label0, 'label1': label1,'label2':label2, 'label3': label3}  

и это часть итерации:

 for batch_idx, sample_batched in enumerate(train_dataloader):  # importing data and moving to GPU  image,label0, label1, label2, label3 = sample_batched['image'].to(device),  sample_batched['label0'].to(device),  sample_batched['label1'].to(device),  sample_batched['label2'].to(device) ,  sample_batched['label3'].to(device)      # zero the parameter gradients  optimizer.zero_grad()  output=model(image.float())  

у кого-нибудь есть предложение?

Ответ №1:

Одним из способов удаления слоев модели PyTorch является использование nn.Identity() слоя. Я думаю, вы хотите удалить последний полностью подключенный слой. Если да, то проверьте это:

 import torch  import torch.nn as nn  import torch.nn.functional as F  from torchvision import models   class CNN1(nn.Module):  def __init__(self, pretrained):  super(CNN1, self).__init__()  if pretrained is True:  self.model = models.inception_v3(pretrained=True)  else:   self.model = models.inception_v3(pretrained=False)   # modules = list(self.model.children())[:-1]   # delete the last fc layer.  self.model.fc = nn.Identity()   # # to freeze training of inception weights  # for param in self.model.parameters():  # param.requires_grad = False   self.fc0 = nn.Linear(2048, 10)   self.fc1 = nn.Linear(2048, 10)   self.fc2 = nn.Linear(2048, 10)   self.fc3 = nn.Linear(2048, 10)     def forward(self, x):  bs, _, _, _ = x.shape  x, aux_x = self.model(x)  # x = F.adaptive_avg_pool2d(x, 1).reshape(bs, -1)  label0 = self.fc0(x)  label1 = self.fc1(x)  label2= self.fc2(x)   label3= self.fc3(x)    return {'label0': label0, 'label1': label1,'label2':label2, 'label3': label3}   if __name__ == '__main__':  net = CNN1(True)  print(net)   inp = torch.randn(50, 3, 299, 299)  out = net(inp)   print('label0 shape:', out['label0'].shape)  

Примечание: если вы хотите заморозить обучение начальных слоев, заданных requires_grad = False для каждого параметра

В вашем коде вы предполагаете, что все соединения слоев являются последовательными с помощью nn.Sequential(*modules) строки, возможно, это и является причиной ошибки.

Комментарии:

1. Спасибо, все работает нормально, но у меня есть эта ошибка во время обучения: строка 188, в прямом x, aux_x = self.модель(x) Ошибка значения: слишком много значений для распаковки (ожидается 2) В первую эпоху и в третьей партии

2. @piper11 проверьте версию torchvision с помощью torchvision.__version__ . Я протестировал его на torchvision ‘0.10.0’. или же инициализируйте модель как models.inception_v3(pretrained=True/False, aux_logits=False) и используйте ее как x = self.model(x) в прямой функции

3. спасибо.. теперь все работает нормально