Почему VGG-16 принимает размер входа 512 * 7 * 7?

Согласно https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py

Я не понимаю, почему модели VGG берут 512 * 7 * 7 input_size полностью связного слоя. Последний слой свертки

  • nn.Conv2d (512, 512, размер_ядра = 3, отступ = 1),
  • nn.ReLU (Истина),
  • nn.MaxPool2d (размер_ядра = 2, шаг = 2, расширение = 1)

Коды в ссылке выше.

class VGG(nn.Module):

    def __init__(self, features, num_classes=1000, init_weights=True):
        super(VGG, self).__init__()
        self.features = features
        self.classifier = nn.Sequential(
            nn.Linear(512 * 7 * 7, 4096),
            nn.ReLU(True),
            nn.Dropout(),
            nn.Linear(4096, 4096),
            nn.ReLU(True),
            nn.Dropout(),
            nn.Linear(4096, num_classes),
        )

person Nazzzz    schedule 13.02.2018    source источник


Ответы (2)


Чтобы понять это, вы должны знать, как работает оператор свертки для CNN. nn.Conv2d(512, 512, kernel_size=3, padding=1) означает, что входное изображение для этой свертки имеет 512 каналов и что на выходе после свертки также будет 512 каналов. Входное изображение будет свернуто с ядром размером 3x3, которое перемещается как скользящее окно. Наконец, padding=1 означает, что перед применением свертки мы симметрично добавляем нули к краям входной матрицы.

В приведенном вами примере вы можете подумать, что 512 - это глубина, а 7x7 - это ширина и высота, полученные путем применения нескольких сверток. Представьте, что у нас есть изображение с некоторой шириной и высотой, и мы скармливаем его свертке, в результате размер будет

owidth  = floor(((width  + 2*padW - kW) / dW) + 1) 
oheight = floor(((height + 2*padH - kH) / dH) + 1)

где height и width - исходные размеры, padW и padH - высота и ширина (по горизонтали и вертикали) отступы, kW и kH - размеры ядра, а dW и dH - ширина и высота (по горизонтали и вертикали) пикселей, которые перемещает ядро ​​( т.е. если это dW=1, сначала ядро ​​будет в пикселе (0,0), а затем переместится в (1,0))

Обычно первый оператор свертки в CNN выглядит так: nn.Conv2d(3, D, kernel_size=3, padding=1), потому что исходное изображение имеет 3 входных канала (RGB). Предполагая, что входное изображение имеет размер 256x256x3 пикселей, если мы применим оператор, как определено ранее, результирующее изображение будет иметь ту же ширину и высоту, что и входное изображение, но его глубина теперь равна D. Аналогично, если мы определим свертку как c = nn.Conv2d(3, 15, kernel_size=25, padding=0, stride=5) с kernel_size=25 , без заполнения во входном изображении и с stride=5 (dW=dH=5, что означает, что ядро ​​перемещается на 5 пикселей каждый раз, если мы находимся в (0,0), тогда оно перемещается в (5,0), пока мы не дойдем до конца изображения по оси x, затем он перемещается в (0,5) -> (5,5) -> (5,15), пока снова не достигнет конца) результирующее выходное изображение будет иметь размер 47x47xD

person Manuel Lagunas    schedule 13.02.2018

Нейронная сеть VGG имеет два раздела слоев: слой «признаков» и слой «классификатор». Входными данными для векторного слоя всегда является изображение размером 224 x 224 пикселей.

Векторный слой имеет 5 nn.MaxPool2d(kernel_size=2, stride=2) сверток. См. Указанную строку исходного кода 76: каждый символ «M» в конфигурациях устанавливает одну свертку MaxPool2d.

Свертка MaxPool2d с этими конкретными параметрами уменьшает размер тензора вдвое. Итак, у нас есть 224 -> 112 -> 56 -> 28 -> 14 -> 7, что означает, что выходной сигнал векторного слоя представляет собой тензор 512 каналов * 7 * 7. Это вход для слоя «классификатор».

person nn4l    schedule 25.12.2018