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()