Reputation: 85
I am implementing googlenet (smaller version) from scratch in pytorch. The architecture is below:
For the Downsample Module I have the following code:
class DownSampleModule(nn.Module):
def __init__(self, in_channel, ch3, w):
super(DownSampleModule, self).__init__()
kernel_size = 3
padding = (kernel_size-1)/2
self.branch1 = nn.Sequential(
ConvBlock(in_channel, ch3, kernel_size = 3,stride=2, padding=int(padding))
)
self.branch2 = nn.Sequential(
nn.MaxPool2d(3, stride=2, padding=0, ceil_mode=True)
)
def forward(self, x):
branch1 = self.branch1(x)
branch2 = self.branch2(x)
return torch.cat([padded_tensor, branch2], 1)
The ConvBlock is from this module
class ConvBlock(nn.Module):
def __init__(self, in_channels, out_channels, kernel_size, stride, padding):
super(ConvBlock, self).__init__()
#padding = (kernel_size -1 )/2
#print(padding)
self.conv = nn.Conv2d(in_channels, out_channels, kernel_size, stride, padding)
self.bn = nn.BatchNorm2d(out_channels)
self.act = nn.ReLU()
def forward(self, x):
x = self.conv(x)
x = self.bn(x)
x = self.act(x)
return x
Basically, we are creating two branches: a convolution module and a max pool. The output of these two branches are then concatenated on the channel dimension.
However, I have the following problem:
self.pool1 = DownSampleModule(in_channel=80, ch3 = 80, w=30)
. The dimensions of the two branches are similar. These are:Downsample Convolution:torch.Size([1, 80, 15, 15])
Maxpool Convolution:torch.Size([1, 80, 15, 15])
self.pool2 = DownSampleModule(in_channel = 144, ch3 = 96, w=15)
. The dimensions are different which prevents it from being concatenated.Downsample Convolution:torch.Size([1, 96, 8, 8])
Maxpool Convolution:torch.Size([1, 144, 7, 7])
Does anyone know the formula to compute the correct padding? Thank you.
In Keras, you can just set the padding="same" or "valid" but it's not supported on pytorch.
Upvotes: 0
Views: 203
Reputation: 3553
Your maxpool
and conv
branches have the same input, and will produce identically-shaped output if you give them the same parameters for kernel size, stride and padding. So just replacing your padding = 0
with padding = int(padding)
should be enough to make both branches be concat-compatible.
ceil_mode
should also be set to False
. When the resulting dimension is not an integer, the rounding behavior of conv2d
is to use floor
, so you want your maxpool
to do that as well.
By the way, you can remove your nn.Sequential
. Your "sequences" of layers are made of only one layer, so... not really sequential :)
Upvotes: 1