#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. спасибо.. теперь все работает нормально