또르르's 개발 Story

[31-2] VGG-11 구현 using PyTorch 본문

부스트캠프 AI 테크 U stage/실습

[31-2] VGG-11 구현 using PyTorch

또르르21 2021. 3. 8. 22:57

1️⃣ 설정

 

필요한 모듈을 import 합니다.

# Seed

import torch

import numpy as np

import random


torch.manual_seed(0)

torch.cuda.manual_seed(0)

np.random.seed(0)

random.seed(0)


# Ignore warnings

import warnings

warnings.filterwarnings('ignore')

 

2️⃣ VGG-11 Implementation

 

아래 Table은 여러 종류의 VGG 네트워크에 대한 각각의 구성을 나타낸 것입니다.

VGG-11은 A에 해당합니다.

 


MaxPool2d -> Linear로 가기 위한 작업

 

MaxPool2d의 output : tensor (channel, width, height)

Linear의 input : 2D (width, height)

 

 

따라서 MaxPool2d의 output을 Linear의 input으로 넣어주기 위해서는 vector화를 해야합니다.

vector화에는 2가지 옵션이 있습니다.

 

  • AvgPool2d : 공간 정보를 압축시켜 channel축의 정보만 남겨두는 방법
  • flatten : 하나씩 읽어 쭉 나열하는 방법

 

 

이 두가지 방법의 차이는 dimension형태가 다르다는 점입니다.


Table의 A를 가지고 Class를 구현하면 다음과 같습니다.

VGG-11 네트워크의 Input Tensor는 3 x 224 x 244-dim vector, output tensor는 1000-dim vector입니다.

import torch

import torch.nn as nn


class VGG11(nn.Module):

  def __init__(self, num_classes=1000):
  
    super(VGG11, self).__init__()


    self.relu = nn.ReLU(inplace=True)
    
    
    # Convolution Feature Extraction Part
    
    self.conv1 = nn.Conv2d(3, 64, kernel_size=3, padding=1)
    
    self.bn1   = nn.BatchNorm2d(64)
    
    self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
    

    self.conv2 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
    
    self.bn2   = nn.BatchNorm2d(128)
    
    self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
    

    self.conv3_1 = nn.Conv2d(128, 256, kernel_size=3, padding=1)
    
    self.bn3_1   = nn.BatchNorm2d(256)
    
    self.conv3_2 = nn.Conv2d(256, 256, kernel_size=3, padding=1)
    
    self.bn3_2   = nn.BatchNorm2d(256)
    
    self.pool3   = nn.MaxPool2d(kernel_size=2, stride=2)
    

    self.conv4_1 = nn.Conv2d(256, 512, kernel_size=3, padding=1)
    
    self.bn4_1   = nn.BatchNorm2d(512)
    
    self.conv4_2 = nn.Conv2d(512, 512, kernel_size=3, padding=1)
    
    self.bn4_2   = nn.BatchNorm2d(512)
    
    self.pool4   = nn.MaxPool2d(kernel_size=2, stride=2)
    

    self.conv5_1 = nn.Conv2d(512, 512, kernel_size=3, padding=1)
    
    self.bn5_1   = nn.BatchNorm2d(512)
    
    self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, padding=1)
    
    self.bn5_2   = nn.BatchNorm2d(512)
    
    self.pool5   = nn.MaxPool2d(kernel_size=2, stride=2)
    
    

    # Fully Connected Classifier Part
    
    self.fc1      = nn.Linear(512 * 7 * 7, 4096)
    
    self.dropout1 = nn.Dropout()
    
    

    self.fc2      = nn.Linear(4096, 4096)
    
    self.dropout2 = nn.Dropout()
    
    
    self.fc3      = nn.Linear(4096, 1000)



  def forward(self, x):
  
    # Convolution Feature Extraction Part
    
    x = self.conv1(x)
    
    x = self.bn1(x)
    
    x = self.relu(x)
    
    x = self.pool1(x)
    

    x = self.conv2(x)
    
    x = self.bn2(x)
    
    x = self.relu(x)
    
    x = self.pool2(x)
    

    x = self.conv3_1(x)
    
    x = self.bn3_1(x)
    
    x = self.relu(x)
    
    x = self.conv3_2(x)
    
    x = self.bn3_2(x)
    
    x = self.relu(x)
    
    x = self.pool3(x)
    

    x = self.conv4_1(x)
    
    x = self.bn4_1(x)
    
    x = self.relu(x)
    
    x = self.conv4_2(x)
    
    x = self.bn4_2(x)
    
    x = self.relu(x)
    
    x = self.pool4(x)
    

    x = self.conv5_1(x)
    
    x = self.bn5_1(x)
    
    x = self.relu(x)
    
    x = self.conv5_2(x)
    
    x = self.bn5_2(x)
    
    x = self.relu(x)
    
    x = self.pool5(x)
    

    # Fully Connected Classifier Part
    
    x = torch.flatten(x, 1)
    
    x = self.fc1(x)
    
    x = self.relu(x)
    
    x = self.dropout1(x)
    
    
    x = self.fc2(x)
    
    x = self.relu(x)
    
    x = self.dropout2(x)
    
    
    x = self.fc3(x)
    
    return x

 

 

Comments