Mat1 and mat2 shapes can't be multiplied

Hi everyone,
I was doing some simple work until I came across this error.

  File "C:\Users\bala006\Miniconda3.8\lib\site-packages\torch\nn\functional.py", line 1753, in linear
    return torch._C._nn.linear(input, weight, bias)
RuntimeError: mat1 and mat2 shapes cannot be multiplied (50176x3 and 256x300)

The relevant code is a followed

class NN (nn.Module):
    def __init__(self, input_size, output_size):
        super(NN, self).__init__()
        self.flatten = nn.Flatten()
        self.LinearStack = nn.Sequential(
            nn.Linear(input_size, 300),
            nn.ReLU(),
            nn.Linear(300, 300),
            nn.ReLU(),
            nn.Linear(300, 256),
            nn.ReLU(),
            nn.Linear(256, 256),
            nn.ReLU(),
            nn.Linear(256, 150),
            nn.ReLU(),
            nn.Linear(150,100),
            nn.ReLU(),
            nn.Linear(100,75),
            nn.ReLU(),
            nn.Linear(75, output_size),
            nn.ReLU()
        )
    def forward (self,out):
        logits = self.LinearStack(out)
        return logits

model = NN(256,2)
y_label, imagepre = dataset.__getitem__(1)
print (y_label)
print (imagepre)

loss_func = nn.CrossEntropyLoss()
optimiser = optim.SGD(model.parameters(), lr = 0.001)
epochs = 2

def run (loss_fn, dataloader, model):
    size = dataset.__len__()
    for y_label in enumerate(dataloader):
        image = torch.from_numpy(imagepre)
        Pred = model(image)
        print (Pred)

        # Loss
        loss = loss_fn(pred, y_label)

        # Backprop
        optimiser.zero_grad()
        loss.backward()
        optimiser.step()
        
        print (loss)

for t in range(epochs):
    print ("Epoch #######################")
    run(loss_func, dataloader, model)

print ("Done") 

I got some weird errors before this that I ironed out with some compromise but am really stuck on this. Thanks for any help!

Your model works fine for a random input:

model = NN(1, 1)
x = torch.randn(2, 1)
out = model(x)
print(out.shape)
> torch.Size([2, 1])

What’s the input shape you are using which creates this issue?

Admittedly, I don’t actually know. Note for the future. I just started learning. How do i check?

You can print the shape of the input tensor via:

image = torch.from_numpy(imagepre)
print(image.shape)
Pred = model(image)

Great. I got
([224, 224, 3])
Does that mean an image of 224 pixels by 224 pixels? In that case, what is the 3?
I’m pretty new so I’m trying to get my head around this.

The three in this case is usually for the color channels of the image (RGB, or sometimes YCbCr).

Thanks. Do I have to worry about that when doing anything with the actual model or do I just keep going. I haven’t gone too far with PyTorch so I guess this is unchartered territory for me.

The issue here is that when building the model, you are specifying an input size that has to match the input that you are passing it. For an image of 224x224x3 pixels, once you flatten it for a matrix multiplication, the actual input size (dimension) is 150528 = 224x224x3.

You might want to be careful about how you reshape the input, as reshaping 224x224x3 into (50176x3) is very different from (1x150528). The first says “I have a batch of 50,176 color pixels that I want to treat separately” while the second says “I have a single image of 150528 features.”

So, do I have to flatten anything? And if so, how would I go about doing that? Could I resize the images. I really didn’t get too much on this dataset and thank you for being patent with me.
Upon editing the input size, I got this error

RuntimeError: mat1 and mat2 shapes cannot be multiplied (50176x3 and 50176x300)

If you are intending to process a single image at a time, the input shape should probably be 1x150528. You can do something like image = image.reshape(1, 150528). Then if you change the input size of the model to 150528 it should work.

Thank you for everything. With my edited code, stuff seems to working right, except for one problem.

AttributeError: 'tuple' object has no attribute 'size'

After a long list, I get this. The program works for a simple test random tensor but running it seems to give me a problem.
Following is my code (Sorry for the confusing variable names)

class NN (nn.Module):

    def __init__(self, input_size, output_size):

        super(NN, self).__init__()

        self.flatten = nn.Flatten()

        self.LinearStack = nn.Sequential(

            nn.Linear(input_size, 300),

            nn.ReLU(),

            nn.Linear(300, 300),

            nn.ReLU(),

            nn.Linear(300, 256),

            nn.ReLU(),

            nn.Linear(256, 256),

            nn.ReLU(),

            nn.Linear(256, 150),

            nn.ReLU(),

            nn.Linear(150,100),

            nn.ReLU(),

            nn.Linear(100,75),

            nn.ReLU(),

            nn.Linear(75, output_size),

            nn.ReLU()

        )

    def forward (self,out):

        logits = self.LinearStack(out)

        return logits

model = NN(150528,1)

y_label, imagepre = dataset.__getitem__(1)

print (y_label)

print (imagepre)

imagetun = torch.from_numpy(imagepre)

print(imagetun.shape)

imagetuun = imagetun.reshape(1, 150528)

imagework = imagetuun.float() 

Pred112 = model(imagework)

print(Pred112)

loss_func = nn.CrossEntropyLoss()

optimiser = optim.SGD(model.parameters(), lr = 0.001)

epochs = 2

def run (loss_fn, dataloader, model):

    size = dataset.__len__()

    for y_label in enumerate(dataloader):

        image = torch.from_numpy(imagepre)

        imagetuun = image.reshape(1, 150528)

        imagework = imagetuun.float() 

        Pred = model(imagework)

        print (Pred)

        # Loss

        loss = loss_fn(Pred, y_label)

        # Backprop

        optimiser.zero_grad()

        loss.backward()

        optimiser.step()

        

        print (loss)

for t in range(epochs):

    print ("Epoch #######################")

    run(loss_func, dataloader, model)

print ("Done")

Thanks for everything so far, everything @eqy and @ptrblck have said seems to work. just this one problem.

Can you include the line of code that the error happens on? It is a bit difficult to see the context without that but one thing I notice is that only the label is used from the dataloader (for y_label in enumerate(dataloader):) whereas it looks like you also want to get the current image from the dataloader.

Well, I managed to get past the tuple error.
I get this:

TypeError: expected np.ndarray (got tuple)

It comes from the:

image = torch.from_numpy(imagepre)

line. Do you know how I’d go about converting a tuple to torch tensor?

usually torch.tensor(mytuple) is sufficient

Instead of that, I get

TypeError: an integer is required (got type list)

This is on the

 image = torch.tensor(imagepre)

Line.

That sounds like the type of something in imagepre is unexpected. What is contained in imagepre?

Just the image. It’s a SKImage read file. Should I use something else??

Can you check the type type(imagepre)? That seems strange as scikit-image is backed by numpy arrays which should be easy to convert to tensor.

On a test, I made it work with a PIL image and the test works. Just finding the type as followed:

print(imagepre.type) 

and got:

Traceback (most recent call last):
  File "c:\Users\bala006\OneDrive - St John's Anglican College\Desktop\Personal\Dorime\CatsDogs\cats_dogs.py", line 51, in <module>   
    print(imagepre.type)
  File "C:\Users\bala006\Miniconda3.8\lib\site-packages\PIL\Image.py", line 541, in __getattr__
    raise AttributeError(name)
AttributeError: type

When training with this code:


class NN (nn.Module):
    def __init__(self, input_size, output_size):
        super(NN, self).__init__()
        self.flatten = nn.Flatten()
        self.LinearStack = nn.Sequential(
            nn.Linear(input_size, 300),
            nn.ReLU(),
            nn.Linear(300, 300),
            nn.ReLU(),
            nn.Linear(300, 256),
            nn.ReLU(),
            nn.Linear(256, 256),
            nn.ReLU(),
            nn.Linear(256, 150),
            nn.ReLU(),
            nn.Linear(150,100),
            nn.ReLU(),
            nn.Linear(100,75),
            nn.ReLU(),
            nn.Linear(75, output_size),
            nn.ReLU()
        )
    def forward (self,out):
        logits = self.LinearStack(out)
        return logits

model = NN(150528,1)
y_label, imagepre = dataset.__getitem__(1)
print (y_label)
image1 = transforms.ToTensor()(imagepre).unsqueeze_(0)
image2 = image1.reshape(1, 150528)
image112 = image2.float() 
tunak = model(image112)
print(tunak)



loss_func = nn.CrossEntropyLoss()
optimiser = optim.SGD(model.parameters(), lr = 0.001)
epochs = 2

def run (loss_fn, dataloader, model):
    size = dataset.__len__()
    for imagepre in enumerate(dataloader):
        image = transforms.ToTensor()
        imageprepre = image.reshape(1, 150528)
        imagework = imageprepre.float() 
        Pred = model(imagework)
        print (Pred)

        # Loss
        loss = loss_fn(Pred, y_label)

        # Backprop
        optimiser.zero_grad()
        loss.backward()
        optimiser.step()
        
        print (loss)

for t in range(epochs):
    print ("Epoch #######################")

    run(loss_func, dataloader, model)

print ("Done")

I get this error:

TypeError: default_collate: batch must contain tensors, numpy arrays, numbers, dicts or lists; found <class 'PIL.JpegImagePlugin.JpegImageFile'>

Hopefully you don’t feel like I’m dumping my errors on you…
I’m pretty new and after a couple of tutorials, I’m trying this for my first time and everything else is pretty good. I’ve come against this though.

Right, you can check the type of the object with type(imagepre) rather than trying to get the type attribute. But since the error message shows the object source location we know it is a PIL image. You can convert that to a tensor via to_tensor which it looks like you have already done.