Wrong input size Inception_v3

I am attempting to plot the data of my neural network based on Inception_v3 using t-SNE. My issue is that my input size is wrong when passing images to the final layer of my model.

myModel = models.inception_v3(pretrained=True)


# get the number of inputs for the final layer (fc) of the network
num_ftrs = myModel.fc.in_features

myModel.fc = nn.Linear(num_ftrs, 15)

# load previously trained model

myModel.load_state_dict(torch.load('/content/gdrive/MyDrive/CNN_model.pt'))


myModel = nn.Sequential(*list(myModel.children())[:-1])

# move tensors to GPU if CUDA is available
if train_on_gpu:
    myModel.cuda()

print(myModel)

This code works fine and the final layer becomes a sequential layer.

# Visualize Sample Test Results
# define batch size
batch_size = 20

# define transforms
# training (with random flips and rotation)

transform = transforms.Compose([transforms.Resize(resizeto), # resize to 224x?
                                transforms.CenterCrop(size), # take a square (224x224) crop from the centre
                                transforms.ToTensor(), # convert data to torch.FloatTensor
                                transforms.Normalize([0.485, 0.456, 0.406],
                                                     [0.229, 0.224, 0.225])])
# choose the training, validation and test datasets
test_data = datasets.ImageFolder("output" + '/test', transform=transform)
test_loader = torch.utils.data.DataLoader(test_data, batch_size, shuffle=True,drop_last = True)
# obtain one batch of test images
dataiter = iter(test_loader)
images, labels = next(dataiter)
print(images.shape)

images.numpy()
# move model inputs to cuda, if GPU available
if train_on_gpu:
   images = images.cuda()

print(images.shape)
# get sample outputs
mushroom_feats = myModel(images)
imageNet_feats = model(images)

# put on cpu, convert to numpy array and squeeze to batchsize x 512
imageNet_feats = np.squeeze(imageNet_feats.cpu().detach().numpy())
mushroom_feats = np.squeeze(mushroom_feats.cpu().detach().numpy())

labels = labels.numpy()

print(imageNet_feats.shape)
print(mushroom_feats.shape)
print(labels)

Here when images is passed to myModel I get the error:
RuntimeError: Expected 3D (unbatched) or 4D (batched) input to conv2d, but got input of size: [20, 1000]

Your model expects its input to be [batch_size, channels, height, width] but your image input size is [20, 1000]. You have to reshape your images to the correct format prior to feeding it to your network. Try using torch.reshape().

thank you for your prompt response, my issue still remains as the input is already the correct size

print(images.shape)
# get sample outputs
mushroom_feats = myModel(images)

In the code above the printed images.shape gives a 4d tensor of (batch size, channels, height, width] yet when I try to extract the features images is read as a 2d input. This issue may be specific to inception_v3.

Here is the exact error with printed tensor shape

torch.Size([20, 3, 299, 299])

---------------------------------------------------------------------------

RuntimeError                              Traceback (most recent call last)

<ipython-input-21-35bed4452875> in <cell line: 28>()
     26 print(images.shape)
     27 # get sample outputs
---> 28 mushroom_feats = myModel(images)
     29 imageNet_feats = model(images)
     30 

9 frames

/usr/local/lib/python3.10/dist-packages/torch/nn/modules/conv.py in _conv_forward(self, input, weight, bias)
    457                             weight, bias, self.stride,
    458                             _pair(0), self.dilation, self.groups)
--> 459         return F.conv2d(input, weight, bias, self.stride,
    460                         self.padding, self.dilation, self.groups)
    461 

RuntimeError: Expected 3D (unbatched) or 4D (batched) input to conv2d, but got input of size: [20, 1000]

What happens if you create a random tensor via x = torch.rand(20, 3, 299, 299) and model it by myModel(x)?

In addition to that, can you please show a print statement of your model’s last few layers?

Thanks for your feedback again, I have tried using a random tensor and modelling it by myModel(x) as suggested. Attached below is also a screen shot of the print statement, please let me know if more information is required to help! :slight_smile:

x = torch.rand(20, 3, 299, 299)
x.numpy()
print(x.shape)
# move model inputs to cuda, if GPU available
if train_on_gpu:
   images = images.cuda()
   x = x.cuda()

print(x.shape)
# get sample outputs
mushroom_feats = myModel(x)

However this outputs the same error with both print statements shown outputting the same tensor shape

torch.Size([20, 3, 299, 299])
torch.Size([20, 3, 299, 299])

---------------------------------------------------------------------------

RuntimeError                              Traceback (most recent call last)

<ipython-input-15-0a6e59df7c48> in <cell line: 33>()
     31 print(x.shape)
     32 # get sample outputs
---> 33 mushroom_feats = myModel(x)
     34 imageNet_feats = model(x)
     35 

9 frames

/usr/local/lib/python3.10/dist-packages/torch/nn/modules/conv.py in _conv_forward(self, input, weight, bias)
    457                             weight, bias, self.stride,
    458                             _pair(0), self.dilation, self.groups)
--> 459         return F.conv2d(input, weight, bias, self.stride,
    460                         self.padding, self.dilation, self.groups)
    461 

RuntimeError: Expected 3D (unbatched) or 4D (batched) input to conv2d, but got input of size: [20, 1000]

Below is final layers of my model

Rewrapping the model into an nn.Sequential container:

myModel = nn.Sequential(*list(myModel.children())[:-1])

can easily break it since all functional API calls will be missing.
Could you explain why you are recreating the model?

I am trying to use TSNE to visualize how the data is clustered together with the goal of identifying patterns, this method worked for resnet18 but I can’t figure out how to visualize my data for inception_v3

If you want to remove the last linear layer from the model, replace it with an nn.Identity instead of rewrapping the model. As mentioned before, if you are creating an nn.Sequential block all functional API calls from the original model’s forward method will be missing and the model can easily break.