Paper : https://arxiv.org/abs/1409.1556
VGGNet
VGGNet은 옥스포드 대학의 연구팀 VGG에 의해 개발된 모델로써, 2014년 이미지넷 이미지 인식 대회에서 준우승을 한 모델이며, 특히 VGG-16 모델은 ImageNet Challenge에서 Top-5 테스트 정확도를 92.7% 달성했습니다. 딥러닝 역사적으로 보았을 때 신경망의 깊이가 이 때 부터 깊어졌다고 하네요. VGG 뜻은 Visual Geometry Group이며, 논문 명은 "Very Deep Convolutional Networks for Large-Scale Image Recognition" 입니다. vgg 관련 pytorch 공식 문서에서 보시면 VGG16 외에 VGG11, 13, 19 등이 있습니다.
VGG 모델 구조
논문에 나와있는 모델 구조는 다음과 같습니다. 이 논문에서는 시사하는 바는, VGG 모델 이전에 Conv layer를 활용하여 image classification task에서 좋은 성능을 보였던 모델들이 비교적 큰 receptive field를 갖는 11x11 filter 또는 7x7 filter를 포함하는 반면 vgg 모델은 오로지 3x3 크기의 filter 만 사용했는데도 정확도를 크게 개선시켰다고 합니다. 또한 10x10 크기의 이미지가 있다고 가정했을 때, 3x3 filter로 3번 conv 연산을 수행한 것과 7x7 filter로 1번 conv를 수행한 것과 같은 크기의 영역을 수용할 수 있게 됩니다. 이 때 다음과 같은 장점을 갖게 됩니다.
1. 유용한 feature extraction 가능
각 conv 연산은 ReLU 함수를 포함하고 있기 때문에, layer가 증가할 수록 비선형성이 증가하게 되고, 이는 모델의 특징을 잘 식별할 수 있도록 해줍니다.
2. 학습 파라미터 감소
7x7필터 1개에 대한 학습 파라미터 수는 49이고 3x3 필터 3개에 대한 학습 파라미터 수는 27(3x3x3)개가 되므로, 학습 파라미터가 감소하게 됩니다.
논문에는 그림이 없어서, 다른 곳에서 가져왔습니다. 🙂
torchsummary로 나타내면 다음과 같습니다. 역시 이렇게 보는게 편합니다.
PyTorch Implementation
아래와 같이 간단히 실험해 볼 수 있으며,
import torch
import torchvision
from torchvision import models, transforms
from torchsummary import summary
use_pretrained = True
vggnet = models.vgg16(pretrained=use_pretrained)
vggnet.eval()
summary(vggnet, (3, 224, 224))
자세한 구현은 아래와 같습니다.
import torch
import torch.nn as nn
import torchvision
from torchvision import models, transforms
from torchsummary import summary
class VGG16(nn.Module):
def __init__(self, num_classes: int = 1000, init_weights: bool = True):
super(VGG16, self).__init__()
self.conv = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, padding=1, stride=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, padding=1, stride=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(in_channels=128, out_channels=256, kernel_size=3, padding=1, stride=1),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=256, out_channels=256, kernel_size=3, padding=1, stride=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(in_channels=256, out_channels=512, kernel_size=3, padding=1, stride=1),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1, stride=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1, stride=1),
nn.ReLU(inplace=True),
nn.Conv2d(in_channels=512, out_channels=512, kernel_size=3, padding=1, stride=1),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
)
self.fc_layer = nn.Sequential(
nn.Linear(512 * 7 * 7, 4096),
nn.ReLU(inplace=True),
nn.Dropout(p=0.5),
nn.Linear(4096, 4096),
nn.ReLU(inplace=True),
nn.Dropout(p=0.5),
nn.Linear(4096, num_classes)
)
def forward(self, x:torch.Tensor):
x = self.conv(x)
x = torch.flatten(x, 1)
x = self.fc_layer(x)
return x
summary(VGG16(), (3, 224, 224))
참고자료 1 : https://wolfy.tistory.com/240
'AI Research Topic > Backbone' 카테고리의 다른 글
[Backbone] VanillaNet: the Power of Minimalism in Deep Learning (6) | 2023.05.26 |
---|---|
[Backbone] ResNet (7) | 2023.04.14 |
[Backbone] AlexNet (0) | 2023.04.14 |
[Backbone] LeNet-5 (0) | 2023.04.13 |
[Paper Review] MobileOne: An Improved One millisecond Mobile Backbone (0) | 2023.04.06 |