Thanks for the code.
Your model works fine using your code snippets:
def Out_Size(kernel_size=1, in_size=1, padding_size=0, stride_factor=1, dilation_factor=1):
Length = int((in_size + 2*padding_size - dilation_factor*(kernel_size - 1) - 1)/stride_factor) + 1
return Length
#Input Image SIze
IMG_H = 224
IMG_W = 224
##Layer Block-1
#2D Convolution-1
#Kernel Size
CV1_K_H = 5
CV1_K_W = 5
#Number of Channels
CV1_K_C = 3
#Stride Factor
CV1_STRIDE = 2
CV1_DILATION = 1
CV1_BIAS = True
#Output Size (No-Padding)
CV1_H = Out_Size(kernel_size=CV1_K_H, in_size=IMG_H, padding_size=0, stride_factor=CV1_STRIDE, dilation_factor=CV1_DILATION)
CV1_W = Out_Size(kernel_size=CV1_K_W, in_size=IMG_W, padding_size=0, stride_factor=CV1_STRIDE, dilation_factor=CV1_DILATION)
#2D Pooling-1
#Kernel Size
PL1_K_H = 5
PL1_K_W = 5
#Stride Factor
PL1_STRIDE = 1
#Output Size (No-Padding)
PL1_H = Out_Size(kernel_size=PL1_K_H, in_size=CV1_H, padding_size=0, stride_factor=PL1_STRIDE)
PL1_W = Out_Size(kernel_size=PL1_K_W, in_size=CV1_W, padding_size=0, stride_factor=PL1_STRIDE)
##Layer Block-2
#2D Convolution-2
#Kernel Size
CV2_K_H = 3
CV2_K_W = 3
#Number of Channels
CV2_K_C = 9
#Stride Factor
CV2_STRIDE = 2
CV2_DILATION = 1
CV2_BIAS = True
#Output Size (No-Padding)
CV2_H = Out_Size(kernel_size=CV2_K_H, in_size=PL1_H, padding_size=0, stride_factor=CV2_STRIDE, dilation_factor=CV2_DILATION)
CV2_W = Out_Size(kernel_size=CV2_K_W, in_size=PL1_W, padding_size=0, stride_factor=CV2_STRIDE, dilation_factor=CV2_DILATION)
#2D Pooling-2
#Kernel Size
PL2_K_H = 3
PL2_K_W = 3
#Stride Factor
PL2_STRIDE = 1
#Output Size (No-Padding)
PL2_H = Out_Size(kernel_size=PL2_K_H, in_size=CV2_H, padding_size=0, stride_factor=PL2_STRIDE)
PL2_W = Out_Size(kernel_size=PL2_K_W, in_size=CV2_W, padding_size=0, stride_factor=PL2_STRIDE)
##Layer Block-3
#2D Convolution-3
#Kernel Size
CV3_K_H = 1
CV3_K_W = 1
#Number of Channels
CV3_K_C = 3
#Stride Factor
CV3_STRIDE = 2
CV3_DILATION = 1
CV3_BIAS = True
#Output Size (No-Padding)
CV3_H = Out_Size(kernel_size=CV3_K_H, in_size=PL2_H, padding_size=0, stride_factor=CV3_STRIDE, dilation_factor=CV3_DILATION)
CV3_W = Out_Size(kernel_size=CV3_K_W, in_size=PL2_W, padding_size=0, stride_factor=CV3_STRIDE, dilation_factor=CV3_DILATION)
#2D Pooling-3
#Kernel Size
PL3_K_H = 3
PL3_K_W = 3
#Stride Factor
PL3_STRIDE = 1
#Output Size (No-Padding)
PL3_H = Out_Size(kernel_size=PL3_K_H, in_size=CV3_H, padding_size=0, stride_factor=PL3_STRIDE)
PL3_W = Out_Size(kernel_size=PL3_K_W, in_size=CV3_W, padding_size=0, stride_factor=PL3_STRIDE)
##Layer Block-4
#Fully-Connection-1
#Input Size
FC1_SIZE_IN = (PL3_H * PL3_W * CV3_K_C)
#Output Size
FC1_SIZE_OUT = (PL3_H * PL3_W)
#Bias
FC1_BIAS = True
#Fully-Connection-2
#Input Size
FC2_SIZE_IN = (PL3_H * PL3_W)
#Output Size
FC2_SIZE_OUT = int(np.ceil(PL3_H * PL3_W / (CV3_K_C * CV3_K_C)))
#Bias
FC2_BIAS = True
#Fully-Connection-3
#Input Size
FC3_SIZE_IN = FC2_SIZE_OUT
#Output Size
FC3_SIZE_OUT = 10
#Bias
FC3_BIAS = True
class Model(nn.Module):
##Layer Composition
def __init__(self):
super(Model, self).__init__()
#Layer Block-1
self.cv1 = nn.Conv2d(kernel_size=(CV1_K_H, CV1_K_W), in_channels= CV1_K_C, out_channels=CV2_K_C, stride=CV1_STRIDE, dilation=CV1_DILATION, bias=CV1_BIAS)
self.pl1 = nn.AvgPool2d(kernel_size=(PL1_K_H, PL1_K_W), stride=PL1_STRIDE)
#Layer Block-2
self.cv2 = nn.Conv2d(kernel_size=(CV2_K_H, CV2_K_W), in_channels=CV2_K_C, out_channels=CV3_K_C, stride=CV2_STRIDE, dilation=CV2_DILATION, bias=CV2_BIAS)
self.pl2 = nn.AvgPool2d(kernel_size=(PL2_K_H, PL2_K_W), stride=PL2_STRIDE)
#Layer Block-3
self.cv3 = nn.Conv2d(kernel_size=(CV3_K_H, CV3_K_W),in_channels=CV3_K_C, out_channels=CV3_K_C, stride=CV3_STRIDE, dilation=CV3_DILATION, bias=CV3_BIAS)
self.pl3 = nn.AvgPool2d(kernel_size=(PL3_K_H, PL3_K_W), stride=PL3_STRIDE)
#Layer Block-4
self.fc1 = nn.Linear(in_features=FC1_SIZE_IN, out_features=FC1_SIZE_OUT, bias=FC1_BIAS)
self.fc2 = nn.Linear(in_features=FC2_SIZE_IN, out_features=FC2_SIZE_OUT, bias=FC2_BIAS)
self.fc3 = nn.Linear(in_features=FC3_SIZE_IN, out_features=FC3_SIZE_OUT, bias=FC3_BIAS)
def forward(self, image):
#Layer Block-1
b1_cv = torch.relu(self.cv1(image))
b1_pl = self.pl1(b1_cv)
#Layer Block-2
b2_cv = torch.relu(self.cv2(b1_pl))
b2_pl = self.pl2(b2_cv)
#Layer Block-3
b3_cv = torch.relu(self.cv3(b2_pl))
b3_pl = self.pl3(b3_cv)
#Flattening to feed into fully connection
flattened = torch.flatten(b3_pl, start_dim=1)
b4_fc1 = torch.relu(self.fc1(flattened))
b4_fc2 = torch.relu(self.fc2(b4_fc1))
b4_fc3 = torch.relu(self.fc3(b4_fc2))
return b4_fc3
model = Model()
x = torch.randn(2, 3, IMG_H, IMG_W)
out = model(x)
print(out.shape)
> torch.Size([2, 10])