Home > Back-end >  How can i solve this error with Pytorch summary?
How can i solve this error with Pytorch summary?

Time:07-06

I am trying to load a DNN pytorch model using:

from torch import nn
import torch.nn.functional as F

class myDNN(nn.Module):  
  def __init__(self):
    super(myDNN, self).__init__()

    # layers definition

    # first convolutional block
    self.conv1 = nn.Conv1d(in_channels=2, out_channels=8, kernel_size=7) 
    self.pool1 = nn.MaxPool1d(kernel_size = 2, stride=2) 

    # second convolutional block
    self.conv2 = nn.Conv1d(in_channels=8, out_channels=16, kernel_size=3) 
    self.pool2 = nn.MaxPool1d(kernel_size = 2, stride=2) 

    # third convolutional block
    self.conv3 = nn.Conv1d(in_channels=16, out_channels=32, kernel_size=3) 
    self.pool3 = nn.MaxPool1d(kernel_size = 2, stride=2) 

    # fourth convolutional block
    self.conv4 = nn.Conv1d(in_channels=32, out_channels=64, kernel_size=3) 
    self.pool4 = nn.MaxPool1d(kernel_size = 2, stride=2) 

    # fifth convolutional block
    self.conv5 = nn.Conv1d(in_channels=64, out_channels=128, kernel_size=3) 
    self.pool5 = nn.MaxPool1d(kernel_size = 2, stride=2) 

    
    self.flatten = nn.Flatten() 
    self.drop1 = nn.Dropout(p=0.5) 
    self.fc1 = nn.Linear(in_features=3200, out_features=50) #3200 is a random number, 
    probably wrong
    self.drop2 = nn.Dropout(p=0.5) #dropout 
    self.fc2 = nn.Linear(in_features=50, out_features=25)
    self.fc3 = nn.Linear(in_features=25, out_features=2)


  def forward(self, x, y):  
    x = F.relu(self.conv1(x))  
    x = self.pool1(x)
    x = F.relu(self.conv2(x)) 
    x = self.pool2(x)
    x = F.relu(self.conv3(x))
    x = self.pool3(x)
    x = F.relu(self.conv4(x))
    x = self.pool3(x)
    x = F.relu(self.conv5(x))
    x = self.pool5(x)
    
    y = F.relu(self.conv1(y))  
    y = self.pool1(y)
    y = F.relu(self.conv2(y)) 
    y = self.pool2(y)
    y = F.relu(self.conv3(y))
    y = self.pool3(y)
    y = F.relu(self.conv4(y))
    y = self.pool3(y)
    y = F.relu(self.conv5(y))
    y = self.pool5(y)

    #flatten
    x = self.flatten(x)
    y = self.flatten(y)

    w = torch.cat(x,y,1) 
    
    w = self.drop1(w) #dropout layer
    w = F.relu(self.fc1(w)) #layer fully connected with re lu
    w = self.drop2(w)
    w = F.relu(self.fc2(w)) #layer fully connected with re lu 

    w = self.fc3(w) #layer fully connected
    out = F.log_softmax(w, dim=1) 

    return out

The DNN that i am trying to reproduce is the one mentioned in this paper:

https://iopscience.iop.org/article/10.1088/2399-6528/aa83fa/pdf

I am not sure that it's correct, anyway, when I load Pytorch's summary function:

model = myDNN()
print(model)

from torchsummary import summary
if torch.cuda.is_available():
  summary(model.cuda(), input_size = [(1,892),(1,492)])
else:
  summary(model, input_size = [(1,892),(1,492)])

but i get this error:

RuntimeError                              Traceback (most recent call last)
<ipython-input-123-6846b44c144c> in <module>()
      6 from torchsummary import summary
      7 if torch.cuda.is_available():
----> 8   summary(model.cuda(), input_size = [(1,892),(1,492)]) 
      9 else:
     10   summary(model, input_size = [(1,892),(1,492)])

5 frames
/usr/local/lib/python3.7/dist-packages/torch/nn/modules/conv.py in _conv_forward(self, input, weight, bias)
    297                             _single(0), self.dilation, self.groups)
    298         return F.conv1d(input, weight, bias, self.stride,
--> 299                         self.padding, self.dilation, self.groups)
    300 
    301     def forward(self, input: Tensor) -> Tensor:

RuntimeError: Given groups=1, weight of size [8, 2, 7], expected input[2, 1, 892] to have 2 channels, but got 1 channels instead

Please any help would be grateful, thank you

CodePudding user response:

The first layer of the model expects two channels rather than one. Simply pass the correct input shape to "summary" as follows:

summary(model, ((2, dim1),(2,dim2))

Edit: In the forward function I would do the concatenation as follows (if both model's inputs have the same shape):

w = torch.cat([x,y], dim=1)
w = self.flatten(w)

Edit: Here is a working code using the correct implementation

from torch import nn
import torch.nn.functional as F
import torch

class myDNN(nn.Module):
  def __init__(self):
    super(myDNN, self).__init__()

    # layers definition

    # first convolutional block
    self.path1_conv1 = nn.Conv1d(in_channels=2, out_channels=8, kernel_size=7)
    self.path1_pool1 = nn.MaxPool1d(kernel_size = 2, stride=2)

    # second convolutional block
    self.path1_conv2 = nn.Conv1d(in_channels=8, out_channels=16, kernel_size=3)
    self.path1_pool2 = nn.MaxPool1d(kernel_size = 2, stride=2)

    # third convolutional block
    self.path1_conv3 = nn.Conv1d(in_channels=16, out_channels=32, kernel_size=3)
    self.path1_pool3 = nn.MaxPool1d(kernel_size = 2, stride=2)

    # fourth convolutional block
    self.path1_conv4 = nn.Conv1d(in_channels=32, out_channels=64, kernel_size=3)
    self.path1_pool4 = nn.MaxPool1d(kernel_size = 2, stride=2)

    # fifth convolutional block
    self.path1_conv5 = nn.Conv1d(in_channels=64, out_channels=128, kernel_size=3)
    self.path1_pool5 = nn.MaxPool1d(kernel_size = 2, stride=2)

    self.path2_conv1 = nn.Conv1d(in_channels=2, out_channels=8, kernel_size=7)
    self.path2_pool1 = nn.MaxPool1d(kernel_size = 2, stride=2)

    # second convolutional block
    self.path2_conv2 = nn.Conv1d(in_channels=8, out_channels=16, kernel_size=3)
    self.path2_pool2 = nn.MaxPool1d(kernel_size = 2, stride=2)

    # third convolutional block
    self.path2_conv3 = nn.Conv1d(in_channels=16, out_channels=32, kernel_size=3)
    self.path2_pool3 = nn.MaxPool1d(kernel_size = 2, stride=2)

    # fourth convolutional block
    self.path2_conv4 = nn.Conv1d(in_channels=32, out_channels=64, kernel_size=3)
    self.path2_pool4 = nn.MaxPool1d(kernel_size = 2, stride=2)

    # fifth convolutional block
    self.path2_conv5 = nn.Conv1d(in_channels=64, out_channels=128, kernel_size=3)
    self.path2_pool5 = nn.MaxPool1d(kernel_size = 2, stride=2)


    self.flatten = nn.Flatten()
    self.drop1 = nn.Dropout(p=0.5)
    self.fc1 = nn.Linear(in_features=2048, out_features=50) #3200 is a random number,probably wrong
    self.drop2 = nn.Dropout(p=0.5) #dropout
    self.fc2 = nn.Linear(in_features=50, out_features=25)
    self.fc3 = nn.Linear(in_features=25, out_features=2)


  def forward(self, x, y):
    x = F.relu(self.path1_conv1(x))
    x = self.path1_pool1(x)
    x = F.relu(self.path1_conv2(x))
    x = self.path1_pool2(x)
    x = F.relu(self.path1_conv3(x))
    x = self.path1_pool3(x)
    x = F.relu(self.path1_conv4(x))
    x = self.path1_pool3(x)
    x = F.relu(self.path1_conv5(x))
    x = self.path1_pool5(x)

    y = F.relu(self.path2_conv1(y))
    y = self.path2_pool1(y)
    y = F.relu(self.path2_conv2(y))
    y = self.path2_pool2(y)
    y = F.relu(self.path2_conv3(y))
    y = self.path2_pool3(y)
    y = F.relu(self.path2_conv4(y))
    y = self.path2_pool3(y)
    y = F.relu(self.path2_conv5(y))
    y = self.path2_pool5(y)

    #flatten
    x = self.flatten(x)
    y = self.flatten(y)

    w = torch.cat([x,y],dim=1)
    print(w.shape)
    w = self.drop1(w) #dropout layer
    w = F.relu(self.fc1(w)) #layer fully connected with re lu
    w = self.drop2(w)
    w = F.relu(self.fc2(w)) #layer fully connected with re lu

    w = self.fc3(w) #layer fully connected
    out = F.log_softmax(w, dim=1)

    return out

def main():
    model = myDNN()
    print(model)
    from torchsummary import summary
    if torch.cuda.is_available():
        summary(model.cuda(), input_size = [(2,246),(2,447)])
    else:
        summary(model, input_size = [(2,246),(2,447)])
if __name__ == '__main__':
    main()

  • Related