#tensorflow #deep-learning #computer-vision #pytorch
#tensorflow #глубокое обучение #компьютерное зрение #pytorch
Вопрос:
Я внедряю googlenet (уменьшенную версию) с нуля в pytorch. Архитектура приведена ниже:
Для модуля понижающей выборки у меня есть следующий код:
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)
ConvBlock взят из этого модуля
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
По сути, мы создаем две ветви: модуль свертки и максимальный пул. Выходные данные этих двух ветвей затем объединяются в размер канала.
Однако у меня следующая проблема:
- Во-первых, мы вызываем
self.pool1 = DownSampleModule(in_channel=80, ch3 = 80, w=30)
. Размеры двух ветвей схожи. Это:
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)
. Размеры различны, что предотвращает их объединение.
Downsample Convolution:torch.Size([1, 96, 8, 8])
Maxpool Convolution:torch.Size([1, 144, 7, 7])
Кто-нибудь знает формулу для вычисления правильного заполнения? Спасибо.
В Keras вы можете просто установить padding=»то же самое» или «допустимый», но это не поддерживается в pytorch.
Ответ №1:
Ваши maxpool
и conv
ветви имеют одинаковые входные данные и будут выдавать выходные данные одинаковой формы, если вы зададите им одинаковые параметры для размера ядра, шага и заполнения. Так что просто замены вашего padding = 0
на padding = int(padding)
должно быть достаточно, чтобы обе ветви были совместимы с concat.
ceil_mode
также должно быть установлено значение False
. Когда результирующее измерение не является целым числом, используется округление conv2d
floor
, поэтому вы хотите maxpool
, чтобы вы тоже это делали.
Кстати, вы можете удалить свой nn.Sequential
. Ваши «последовательности» слоев состоят только из одного слоя, поэтому … не совсем последовательны 🙂
Комментарии:
1. Потрясающе! Спасибо! Вы такая большая помощь. Ранее, несмотря на добавление аналогичного заполнения, размеры не совпадали. Я только что удалил ceil_mode=True . Спасибо! <3
2. Спасибо, что указали на это, я пропустил эту деталь. Обновлен мой ответ относительно ceil_mode