참고

  1. VGG 논문, VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION
  2. torchvision VGG 구현

VGG

ICLR 2015

Abstract

convolutional network의 깊이에 따른 성능을 확인하는 것이 목적

주요한 contribution은 $3 \times 3$ 크기를 가지는 작은 convoliution 필터들을 사용하여 네트워크의 깊이를 깊게 만들어 평가

이를 통하여 16-19 개의 가중치 레이어로 확장하여 이전의 연구들 보다 좋은 성능을 가지는 것을 보임

이 모델을 사용하여 ILSVRC-2014 대회에서 localization 분야와 classification 분야에서 각각 1등과 2등을 하는 좋은 성능을 보임

ConvNet Configurations

Architecture

Screenshot from 2024-08-07 22-56-50

네트워크 깊이가 어떤 영향을 주는 지 연구 하기 위해 설계된 네트워크로 동일한 kernel size에 convolution의 개수를 늘리는 방식으로 구성됨

위의 Table에서 처럼 11 layer, 13 layer, 16 layer, 19 layer 의 네트워크를 테스트함

위의 표에서 D는 VGG-16, E는 VGG-19를 의미


Convolution layer의 stride는 1, $3 \times 3$ filter의 경우 spatial resolution을 유지하기 위해 padding은 1로 고정

Resolution의 경우 max pooling으로 줄이는데 window의 경우 $2 \times 2$ 그리고 stride는 2로 고정하여 적용


모든 hidden layer에는 ReLU 적용

VGG 이전에는 비교적 큰 Receptive Field를 가지는 $11 \times 11$, $7 \times 7$ 사용

$7 \times 7$ 한 번 사용하는 것보다 $3 \times 3$ 크기를 가지는 filter를 3번 쌓아 구현하면 ReLU 함수의 중복 사용으로 인해 비선형성이 증가하게 되어 모델의 성능이 증가함

또한, $7 \times 7$ 크기의 필터의 학습 파라미터의 수는 49 개이고 $3 \times 3$ 크기의 학습 파라미터의 수는 27개로, 학습할 파라미터의 수가 줄어듬을 확인



구현

Torchvision에 구현되어 있는 VGG 참고

VGG16, 19만 적용

Normalization 포함한 구현



cfg = {
    'vgg16': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 'M', 512, 512, 512, 'M', 512, 512, 512, 'M'],
    'vgg19': [64, 64, 'M', 128, 128, 'M', 256, 256, 256, 256, 'M', 512, 512, 512, 512, 'M', 512, 512, 512, 512, 'M']
}

class VGG(nn.Module):
    def __init__(self, features, num_classes=1000):
        super().__init__()

        self.features = features
        
        self.classifier = nn.Sequential(
            nn.Linear(512*7*7, 4096),
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, 4096), 
            nn.ReLU(inplace=True),
            nn.Dropout(),
            nn.Linear(4096, num_classes)
        )


    def forward(self, x):
        x = self.features(x)
        x = x.view(x.size(0), -1)
        out = self.classifier(x)
        return out


def make_layers(cfg):
    layers = []

    input_channel = 3

    for l in cfg:
        if l == "M":
            layers += [nn.MaxPool2d(kernel_size=2, stride=2)]
            continue

        layers += [nn.Conv2d(input_channel, l, kernel_size=3, stride=1, padding=1)]
        layers += [nn.BatchNorm2d(l)]
        layers += [nn.ReLU(inplace=True)]

        input_channel = l
    
    return nn.Sequential(*layers)


def vgg16(num_classes=1000):
    return VGG(make_layers(cfg['vgg16']), num_classes=num_classes)

def vgg19(num_classes=1000):
    return VGG(make_layers(cfg['vgg19']), num_classes=num_classes)

카테고리:

업데이트: