CNN 1d: size mismatch, m1: [64 x 8], m2: [384 x 192]

Hi,

I am using CNN 1d for my example and my data contain 12 columns and 36795 rows, Note: it is not an image it is data recorded from signals.

and I am facing this error I don’t understand the problem what exactly means. Could you explain that and suggest a solution for me.?

Thank you in advance.

My CNN model.

class CNNnet(nn.Module):
    def __init__(self):
        super(CNNnet, self).__init__()  
        self.conv1 = nn.Conv1d(in_channels=12 , out_channels=32 ,kernel_size=3, stride=1, padding = 1, bias=True)#
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool1d(kernel_size = 2)
        self.conv2 = nn.Conv1d(in_channels=32, out_channels=64 ,kernel_size=3, stride=1, padding = 1)# 36795
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool1d(kernel_size = 2)
        
        self.fc1 = nn.Linear(384, 192)
        self.dropout = nn.Dropout(p=0.5)
        self.fc2 = nn.Linear(192, 96)
        self.dropout = nn.Dropout(p=0.5)
        self.fc3 = nn.Linear(96, 8)

    def forward(self, x):  
        x = x.view(-1, 12, 32)
        x = self.conv1(x)
        x = self.relu(x)
        x = self.pool(x)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.pool(x)
        
        x = self.fc1(x)
        x = self.dropout(x)
        x = self.fc2(x)
        x = self.dropout(x)
        x = self.fc3(x)
        return x

and the error is:

RuntimeError: size mismatch, m1: [64 x 8], m2: [384 x 192] at C:\w\1\s\tmp_conda_3.7_105232\conda\conda-bld\pytorch_1579085620499\work\aten\src\TH/generic/THTensorMath.cpp:136

It means that the network was designated for a different tensor size, namely, your input size is wrong. Network works until you run the FC, as convolutions don’t require a fixed size but FC do.

So, in this case, I have 12 columns and 36795 rows (12*36795=441540‬), so in FC I have to assign 441540‬ ?? is this correct ?

or just input the columns only which 12 columns.?

The issue is telling you the dimension of x before calling x = self.fc1(x)
which is (64,8). That means your FC needs to be

  self.fc1 = nn.Linear(8, arbitrary_number)

Consider that your tensor is Nx64x8, the fully connected will apply the same kernel to all the 64 channels. You may want to reshape everything:

class CNNnet(nn.Module):
    def __init__(self):
        super(CNNnet, self).__init__()
        self.conv1 = nn.Conv1d(in_channels=12, out_channels=32, kernel_size=3, stride=1, padding=1, bias=True)  #
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool1d(kernel_size=2)
        self.conv2 = nn.Conv1d(in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=1)  # 36795
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool1d(kernel_size=2)

        self.fc1 = nn.Linear(64*8,256)
        self.dropout = nn.Dropout(p=0.5)
        self.fc2 = nn.Linear(256, 128)
        self.dropout = nn.Dropout(p=0.5)
        self.fc3 = nn.Linear(128, 8)

    def forward(self, x):
        x = x.view(-1, 12, 32)
        x = self.conv1(x)
        x = self.relu(x)
        x = self.pool(x)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.pool(x)
        x=x.view(-1,8*64)
        x = self.fc1(x)
        x = self.dropout(x)
        x = self.fc2(x)
        x = self.dropout(x)
        x = self.fc3(x)
        return x

I got this error.

RuntimeError: shape '[-1, 12, 32]' is invalid for input of size 12

I modified a bit in the net.

class CNNnet(nn.Module):
    def __init__(self):
        super(CNNnet, self).__init__()  
        self.conv1 = nn.Conv1d(in_channels=1 , out_channels=8 ,kernel_size=3, stride=1, padding = 1, bias=True)#
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool1d(kernel_size = 2)
        self.conv2 = nn.Conv1d(in_channels=8, out_channels=32 ,kernel_size=5, stride=1, padding = 2)# 36795
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool1d(kernel_size = 2)
        
        self.fc1 = nn.Linear(32*8,256)
        self.dropout = nn.Dropout(p=0.5)
        self.fc2 = nn.Linear(256, 128)
        self.dropout = nn.Dropout(p=0.5)
        self.fc3 = nn.Linear(128, 8)

    def forward(self, x):  
        x = x.view(-1, 12, 32)
        x = self.conv1(x)
        x = self.relu(x)
        x = self.pool(x)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.pool(x)
        x=  x.view(-1,32*8)
        x = self.fc1(x)
        x = self.dropout(x)
        x = self.fc2(x)
        x = self.dropout(x)
        x = self.fc3(x)
        return x

But why do you do this?

x = x.view(-1, 12, 1)

What kind of input do you have?
You need to reach a tensor with physical meaning as input. That depends on your hardware, type of data etc…

Ooh I am sorry it is 32 I modified it.

my data is recorded from a signal that has 12 signals (sensors) at the same time, for example, I have a hat that contains 12 sensors in the hat that recording some kinds of neurons in the head.

So if each sensor provide different info you will have a Bx12xT input.
You have to find the proper T depending on the sampling rate of each sensor. This is, how many elements of each signal do you want to input to the network. You can pass the entire signal, you can cut the signal int N elements etcetera… Then, adapt the code. self.fc1 = nn.Linear(32*P,256) This P will vary depending on your input size.

(what do you need x = x.view(-1, 12, 32) for?)

when I delete that x = x.view(-1, 12, 32) I am gonna face this error

RuntimeError: Given groups=1, weight of size 32 12 3, expected input[1, 1, 12] to have 12 channels, but got 1 channels instead

weight of size 32 12 3 why number 3 I dont understand what is num 3

this is the model:

class CNNnet(nn.Module):
    def __init__(self):
        super(CNNnet, self).__init__()  
        self.conv1 = nn.Conv1d(in_channels=12 , out_channels=32 ,kernel_size=3, stride=1, padding = 1, bias=True)#
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool1d(kernel_size = 2)
        self.conv2 = nn.Conv1d(in_channels=32, out_channels=64 ,kernel_size=5, stride=1, padding = 2)# 36795
        self.relu = nn.ReLU()
        self.pool = nn.MaxPool1d(kernel_size = 2)
        
        self.fc1 = nn.Linear(32*12,256)
        self.dropout = nn.Dropout(p=0.5)
        self.fc2 = nn.Linear(256, 128)
        self.dropout = nn.Dropout(p=0.5)
        self.fc3 = nn.Linear(128, 8)

    def forward(self, x):  

        x = self.conv1(x)
        x = self.relu(x)
        x = self.pool(x)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.pool(x)
        x = x.view(-1,32*12)
        x = self.fc1(x)
        x = self.dropout(x)
        x = self.fc2(x)
        x = self.dropout(x)
        x = self.fc3(x)
        return x

It depends on what’s your output from the dataset.
You should be sending something (12,32) which would become in (N,12,32) after the dataloader

Ya, thanks it worked