Рассмотрим сверточную нейронную сеть (два сверточных слоя):
class ConvNet(nn.Module):
def __init__(self, num_classes=10):
super(ConvNet, self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(1, 16, kernel_size=5, stride=1, padding=2),
nn.BatchNorm2d(16),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2))
self.layer2 = nn.Sequential(
nn.Conv2d(16, 32, kernel_size=5, stride=1, padding=2),
nn.BatchNorm2d(32),
nn.ReLU(),
nn.MaxPool2d(kernel_size=2, stride=2))
self.fc = nn.Linear(7*7*32, num_classes)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = out.reshape(out.size(0), -1)
out = self.fc(out)
return out
Полностью связанный слой fc
состоит в том, чтобы fc
в него 7*7*32
Выше:
out = out.reshape(out.size(0), -1)
приводит к тензору с размером (32, 49)
. Это не кажется правильным, поскольку размеры ввода для плотного слоя различны. Что мне здесь не хватает?
[Обратите внимание, что в Pytorch вход имеет следующий формат: [N, C, W, H], так что нет. каналов идет до ширины и высоты изображения]
Если вы посмотрите на выход каждого слоя, вы можете легко понять, чего не хватает.
def forward(self, x):
print ('input', x.size())
out = self.layer1(x)
print ('layer1-output', out.size())
out = self.layer2(out)
print ('layer2-output', out.size())
out = out.reshape(out.size(0), -1)
print ('reshape-output', out.size())
out = self.fc(out)
print ('Model-output', out.size())
return out
test_input = torch.rand(4,1,28,28)
model(test_input)
OUTPUT:
('input', (4, 1, 28, 28))
('layer1-output', (4, 16, 14, 14))
('layer2-output', (4, 32, 7, 7))
('reshape-output', (4, 1568))
('Model-output', (4, 10))
Слой Conv2d не изменяет высоту и ширину тензора. только изменяет канал тензора из-за шага и заполнения. Уровень MaxPool2d уменьшает высоту и ширину тензора.
inpt = 4,1,28,28
conv1_output = 4,16,28,28
max_output = 4,16,14,14
conv2_output = 4,32,14,14
max2_output = 4,32,7,7
reshapeutput = 4,1585 (32*7*7)
fcn_output = 4,10
padding=2
работает такsame
заполнение в TensorFlow?