CNN #1

김태준·2023년 2월 11일
0

Deep-Learning

목록 보기
3/10

✅ LeNet-5

: CNN 모델의 조상 격.
구조는 다음과 같다

Input / 3개의 Convolution layer(C1, C3, C5) / 2개의 subsampling layer(S2, S4) / 1층의 fully-connected layer(F6) / Output으로 구성
< VGGNet 구조 특징 >

  • C1 ~ F6까지 tanh 활성함수 사용한 것이 특징
  • subsampling 으로 Average Pooling 사용
  • 총 파라미터 60,000개
    C.L : (가중치입력맵개수 + 바이어스)특성맵개수
    S.L : (가중치 + 바이어스)*특성맵개수

✅ AlexNet

: input image size를 (256*256)으로 고정시켜줌 (추후 FC layer의 입력 크기가 고정되어야 하기 때문)
구조는 다음과 같다.

Input / 5개의 C.L / 3개의 P.L / 2개의 N.L / 2개의 FC layer / Output으로 구성

🎈 < AlexNet 구조 특징 >

  • Max Pooling 기법 사용
    1. ReLU Nonlinearity
      : 학습속도가 sigmoid, tanh에 비해 몇배 빠름
    1. Training on Multiple GPUs
      : 네트워크를 2개의 GPU로 나누어 학습 진행 >> GPU parallelization이라 부름.
      (독립적인 학습도 가능하고 하나의 layer에서만 GPU를 통합하는 것도 가능)
    1. LRN을 사용한 Normalization Layer.

🎈 LRN (Local Response Normalization) 이란 ?

: generalization을 목적으로 함. ReLU는 non-saturation nonlinearity 함수이므로 입력 normalization을 필요로 하지 않기에 이를 예방하기 위해 등장한 함수
측면 억제의 형태로 구현됨.

    1. Overlapping Pooling
      : max pooling을 할 때 중복 되지 않는 영역만 pooling을 진행하지만, AlexNet은 겹치는 부분이 있도록 Pooling 진행해 오버피팅 개선

추가 사항 3X3 Convolution filter 활용

🎈 Reducing Overfitting

AlexNet의 경우 약 6천만 개의 Parameter가 존재해 오버피팅 없이 학습이 어려울 정도이다. 이를 방지하고자 두 가지 방안을 제안한다.

    1. Data Augmentation
      : 현재 갖고 있는 데이터를 좀 더 다양하게 만들어 CNN 모델을 학습하기 위해 만들어진 개념, 연산량이 매우 적고 CPU 내에서 이루어지기에 계산 비용 X (좌우 반전, 이미지를 다르게 잘라 여러 이미지 생성 등)
    1. Dropout

detail
momentum = 0.9, batch_size = 128, weight_decay = 0.005
weight ~ 가우시안 분포(0, 0.01^2)
bias 초기화 : C2, C4, C5와 FC1에선 1로, 나머진 0으로 초기화
learning rate : 0.01

weight decay ?
: 데이터는 단순한데 모델이 복잡하면 weight는 값이 점점 커지게 되면서 overfitting이 발생한다. 이를 방지하고자 weight 값 증가하는 것을 제한하며 모델 복잡도를 감소시킴으로 제한하는 기법.

✅ VGG-F, VGG-M, VGG-S

논문 참고 : "Return of the Devil in the Details: Delving Deep into Convolutional Nets"

각 모델은 속도와 정확도 사이의 trade-off를 고려한 모델이다.
5개의 Conv layer, 3개의 FC layer로 구성

  • VGG-F
    : 빠른 속도에 초점을 맞춘 모델
    filter(kernel) size를 크게 하고 stride를 크게 함으로써 연산량을 줄였다. (1번째 레이어)
  • VGG-M
    속도, 정확도 중간
    (2번째 레이어에서 VGG-S보다 보폭을 1더 크게함으로써 연산량 줄이고 정확도를 낮춤)
  • VGG-S
    : 느리지만 정확도에 초점을 맞춘 모델

✅ VGGNet

: 옥스포드 대학의 연구팀에 의해 개발된 모델
네트워크가 깊어짐에 따라(층이 많을수록) 어떤 영향을 미치는지 알고자 진행
16 ~ 19개의 층으로 구성된 모델을 의미하며 VGG16, VGG19로 불림
< VGGNet 구조 예시 >

0) 인풋: 224 x 224 x 3 이미지(224 x 224 RGB 이미지)를 입력받을 수 있다.

1) 1층(conv1_1): 64개의 3 x 3 x 3 필터커널로 입력이미지를 컨볼루션해준다. zero padding은 1만큼 해줬고, 컨볼루션 보폭(stride)는 1로 설정해준다. zero padding과 컨볼루션 stride에 대한 설정은 모든 컨볼루션층에서 모두 동일하니 다음 층부터는 설명을 생략하겠다. 결과적으로 64장의 224 x 224 특성맵(224 x 224 x 64)들이 생성된다. 활성화시키기 위해 ReLU 함수가 적용된다. ReLU함수는 마지막 16층을 제외하고는 항상 적용되니 이 또한 다음 층부터는 설명을 생략하겠다.

2) 2층(conv1_2): 64개의 3 x 3 x 64 필터커널로 특성맵을 컨볼루션해준다. 결과적으로 64장의 224 x 224 특성맵들(224 x 224 x 64)이 생성된다. 그 다음에 2 x 2 최대 풀링을 stride 2로 적용함으로 특성맵의 사이즈를 112 x 112 x 64로 줄인다.

*conv1_1, conv1_2와 conv2_1, conv2_2등으로 표현한 이유는 해상도를 줄여주는 최대 풀링 전까지의 층들을 한 모듈로 볼 수 있기 때문이다.

3) 3층(conv2_1): 128개의 3 x 3 x 64 필터커널로 특성맵을 컨볼루션해준다. 결과적으로 128장의 112 x 112 특성맵들(112 x 112 x 128)이 산출된다.

4) 4층(conv2_2): 128개의 3 x 3 x 128 필터커널로 특성맵을 컨볼루션해준다. 결과적으로 128장의 112 x 112 특성맵들(112 x 112 x 128)이 산출된다. 그 다음에 2 x 2 최대 풀링을 stride 2로 적용해준다. 특성맵의 사이즈가 56 x 56 x 128로 줄어들었다.

5) 5층(conv3_1): 256개의 3 x 3 x 128 필터커널로 특성맵을 컨볼루션한다. 결과적으로 256장의 56 x 56 특성맵들(56 x 56 x 256)이 생성된다.

6) 6층(conv3_2): 256개의 3 x 3 x 256 필터커널로 특성맵을 컨볼루션한다. 결과적으로 256장의 56 x 56 특성맵들(56 x 56 x 256)이 생성된다.

7) 7층(conv3_3): 256개의 3 x 3 x 256 필터커널로 특성맵을 컨볼루션한다. 결과적으로 256장의 56 x 56 특성맵들(56 x 56 x 256)이 생성된다. 그 다음에 2 x 2 최대 풀링을 stride 2로 적용한다. 특성맵의 사이즈가 28 x 28 x 256으로 줄어들었다.

8) 8층(conv4_1): 512개의 3 x 3 x 256 필터커널로 특성맵을 컨볼루션한다. 결과적으로 512장의 28 x 28 특성맵들(28 x 28 x 512)이 생성된다.

9) 9층(conv4_2): 512개의 3 x 3 x 512 필터커널로 특성맵을 컨볼루션한다. 결과적으로 512장의 28 x 28 특성맵들(28 x 28 x 512)이 생성된다.

10) 10층(conv4_3): 512개의 3 x 3 x 512 필터커널로 특성맵을 컨볼루션한다. 결과적으로 512장의 28 x 28 특성맵들(28 x 28 x 512)이 생성된다. 그 다음에 2 x 2 최대 풀링을 stride 2로 적용한다. 특성맵의 사이즈가 14 x 14 x 512로 줄어든다.

11) 11층(conv5_1): 512개의 3 x 3 x 512 필터커널로 특성맵을 컨볼루션한다. 결과적으로 512장의 14 x 14 특성맵들(14 x 14 x 512)이 생성된다.

12) 12층(conv5_2): 512개의 3 x 3 x 512 필터커널로 특성맵을 컨볼루션한다. 결과적으로 512장의 14 x 14 특성맵들(14 x 14 x 512)이 생성된다.

13) 13층(conv5-3): 512개의 3 x 3 x 512 필터커널로 특성맵을 컨볼루션한다. 결과적으로 512장의 14 x 14 특성맵들(14 x 14 x 512)이 생성된다. 그 다음에 2 x 2 최대 풀링을 stride 2로 적용한다. 특성맵의 사이즈가 7 x 7 x 512로 줄어든다.

14) 14층(fc1): 7 x 7 x 512의 특성맵을 flatten 해준다. flatten이라는 것은 전 층의 출력을 받아서 단순히 1차원의 벡터로 펼쳐주는 것을 의미한다. 결과적으로 7 x 7 x 512 = 25088개의 뉴런이 되고, fc1층의 4096개의 뉴런과 fully connected 된다. 훈련시 dropout이 적용된다.

15) 15층(fc2): 4096개의 뉴런으로 구성해준다. fc1층의 4096개의 뉴런과 fully connected 된다. 훈련시 dropout이 적용된다.

16) 16층(fc3): 1000개의 뉴런으로 구성된다. fc2층의 4096개의 뉴런과 fully connected된다. 출력값들은 softmax 함수로 활성화된다. 1000개의 뉴런으로 구성되었다는 것은 1000개의 클래스로 분류하는 목적으로 만들어진 네트워크란 뜻이다.

🎈 < VGGNet 특징 >

  • 입력은 224 X 224 X 3으로 고정
  • 컨볼루션 필터커널의 사이즈는 가장 작은 3 x 3로 고정하여(Parameter 수 줄이기 위해) 16~19의 깊은 layer를 만들어 좋은 성능을 냄
  • ReLU를 여러개 사용할 수 있다
  • FC layer가 3개나 존재해 parameter가 너무 많고, 역전파 진행 시 Conv layer의 중간 결과를 저장하기에 많은 메모리 공간을 차지하는 단점이 있다.

🎈 VGGNet 코드 진행

  • 라이브러리 불러오기
import torch
#신경망들 포함
import torch.nn as nn
#최적화 알고리즘 포함
import torch.optim as optim
#텐서에 초기값 부여
import torch.nn.init as init
#이미지 데이터셋 집합체
import torchvision.datasets as datasets 
#이미지 변환 툴
import torchvision.transforms as transforms
#학습 및 배치로 모델에 넣어주기 위한 툴
from torch.utils.data import DataLoader
import torch.utils.model_zoo as0 model_zoo
import numpy as np
import matplotlib.pyplot as plt
  • model url
__all__ = {
    'VGG', 'vgg11', 'vgg11_bn', 'vgg13', 'vgg13_bn', 'vgg16', 'vgg16_bn',
    'vgg19_bn', 'vgg19'}
model_urls = {
    'vgg11': 'https://download.pytorch.org/models/vgg11-bbd30ac9.pth',
    'vgg13': 'https://download.pytorch.org/models/vgg13-c768596a.pth',
    'vgg16': 'https://download.pytorch.org/models/vgg16-397923af.pth',
    'vgg19': 'https://download.pytorch.org/models/vgg19-dcbb9e9d.pth',
    'vgg11_bn': 'https://download.pytorch.org/models/vgg11_bn-6002323d.pth',
    'vgg13_bn': 'https://download.pytorch.org/models/vgg13_bn-abd245e5.pth',
    'vgg16_bn': 'https://download.pytorch.org/models/vgg16_bn-6c64b313.pth',
    'vgg19_bn': 'https://download.pytorch.org/models/vgg19_bn-c79401a0.pth',
}
  • VGG class 생성
    input : features, num_class, init_weights
    classifier : fc layer들
    features : 쌓아가야 할 VGG-net의 convolution layer
    kaiming_nomalization을 통해 weight 초기화
    cf> VGG net에서는 bias 값이 항상 0이다.
class VGG(nn.Module):
    def __init__(self, features, num_classes = 1000, init_weights = True):
        super(VGG, self).__init__()
        self.features = features  #Convolution
        self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
        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), 
        )
        if init_weights:
            self._initialize_weights()
    def forward(self, x):
        x = self.features(x)
        x = self.avgpool(x)
        x = x.view(x.size(0), -1)
        x = self.classifier(x)
        return x
    def _initialize_weights(self):
        for m in self.modules():
            if isinstance(m, nn.Conv2d):
                nn.init.kaiming_normal_(m.weight, mode = 'fan_out', nonlinearity = 'relu')
                if m.bias is not None:
                    nn.init.constant_(m.bias, 0)
                elif isinstance(m, nn.BatchNorm2d):
                    nn.init.constant_(m.weight, 1)
                    nn.init.constant_(m.bias, 0)
                elif isinstance(m, nn.Linear):
                    nn.init.normal_(m.weight, 0, 0.01)
                    nn.init.constant(m.bias, 0)
  • " features 값을 어떻게 넣어줄 수 있는가 "
    make_layer : CFG에 맞춰 make_layer 동작
    CFG : network 구성 역할
    cf> in_channels를 v로 바꿔주는 이유
    : convolution layer를 통과하고 나오면 batch_size는 그대로지만 channel 수는 변하게 됨. 다음 channel에서 변경된 수 만큼의 channel을 받아야 하므로 in_channel을 그만큼 바꿔주게 됨
def make_layers(cfg, batch_norm = False):
    layers = []
    in_channels = 3
    for v in cfg:
        if v == 'M':
            layers += [nn.MaxPool2d(kernel_size = 2, stride = 2)]
        else:
            conv2d = nn.Conv2d(in_channels, v, kernel_size = 3, padding = 1)
            if batch_norm:
                layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace=True)]
            else:
                layers += [conv2d, nn.ReLU(inplace=True)]
    return nn.Sequential(*layers)
cfg = {
    'A':[64, 'M', 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'B':[64, 64, 'M', 128, 128, 'M', 256, 256, 'M', 512, 512, 'M', 512, 512, 'M'],
    'D':[64, 64, 'M', 128, 128, 'M', 256,256,256, 'M', 512,512,512,'M',512,512,512,'M'],
    'E':[64,64,'M',128,128,'M',256,256,256,256,'M',512,512,512,512,'M',512,512,512,512,'M'],
    'custom':[64,64,64,'M',128,128,128,'M',256,256,256,'M']
}
  • 🎈 VGG 모델 생성
    feature : make_layer를 통해 내가 원하는 대로 생성 가능
    num_class : CIFAR10의 경우, 클래스가 10개이므로 10으로 설정
    +) CFG에서 custom layer를 추가한 경우, VGG class의 in_feature가 달라지므로 수정해줘야 함
    -> image size가 다른 상태에서 VGG-net을 적용하고자 하면 VGG class에서 nn.Linear() 수정해주기
CNN = VGG(make_layers(cfg['custom']), num_classes = 10, init_weights=True)
CNN
profile
To be a DataScientist

0개의 댓글