ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [9주차 - Day3] Deep Learning 기초
    교육/프로그래머스 인공지능 데브코스 2021. 7. 1. 14:17
    728x90

    Deep Learning: 신경망의 기초 - 심층학습기초 I

    1. 심층학습(deep learning)

    다층 퍼셉트론(multilayer perceptron)에 은닉층(hidden layer)을 여러개 추가하면 깊은 신경망이 됨

    경사소멸문제(gradient vanishing problem)+작은 훈련집합+과다한 연산과 시간 소요

    1.1. 심층학습의 성공 배경

    1. 혁신적 알고리즘 등장
      • 합성곱 신경망(Convolutional Neural Networks, CNN)구조 : 부분연결, 가중치 공유
      • 경사 소멸 문제 해결을 위한 ReLU활성함수
      • 과잉 적합을 방지하는데 효과적인 다양한 규제기법
      • 층별 예비학습(pretraining) 기법 개발
    2. 값싼 GPGPU의 등장
    3. 학습 데이터 양과 질의 향상

    1.2. 표현학습의 부각

    전통적인 다층 퍼셉트론

    은닉층은 특징 추출기, 얕은 구조(제한적 특징 추출)이므로 가공하지 않은 원래 패턴을 그대로 입력하면 낮은 성능을 내므로 사람이 수작업으로 특징을 선택(feature selection)하거나 추출(feature extration)하여 신경망에 입력

    패턴->특징 추출->분류(얕은 신경망)->부류

    현대 기계학습(심층 학습)

    학습에 의해 자동으로 데이터로부터 특징(data driven features)추출≒표현 학습(representation learning)

    특징 벡터를 신경망의 입력->종단간 학습(end to end learning)

    패턴->특징+분류(깊은 신경망)->부류

    깊은 신경망의 표현학습(representation learning)(또는 특징학습(feature learning))

    낮은 단계 은닉층은 간단한(저급) 특징 추출->높은 단계 은닉층은 추상적인 형태(abstractive representation)의 복잡한(고급) 특징 추출

    2. 깊은 다층 퍼셉트론(깊은 신경망)

    2.1. 구조와 동작

    깊은 다층 퍼셉트론(DMLP, deep MLP)의 구조 : 입력(d+1차원의 특징벡터)과 출력(c개 분류)

    L-1개의 은닉층(입력층은 0번째 은닉층, 출력층은 L번째 은닉층으로 간주)

    동작

    전방계산(forward pass)

    2.2. 학습

      퍼셉트론 다층 퍼셉트론 깊은 다층 퍼셉트론
    활성함수 계단함수 시그모이드함수 ReLU와 변형들
    목적함수 평균제곱오차 평균제곱오차 교차 엔트로피/로그우도

    층간의 모든 영역이 완전 연결->가중치가 많아짐(파라미터의 양이 증가)->과적합 확률도 증가->완전 연결이 아닌 부분 연결을 하는 합성곱 신경망(Convolutional Neural Network, CNN)등장

    6. 심층학습은 왜 강력한가?

    1. 종단간(end-to-end)최적화된 학습가능
      • 고전적 방법은 사람의 직관에 따르므로 성능에 한계가 생김, 인식대상이 달라지면 새로 설계해야함
      • 심층학습은 전체 신경망을 동시에 최적화(종단간 학습)
    2. 깊이(depth)의 중요성
      • 더 정교하게 분할할 수 있음
    3. 계층적 특징(hierarchical feature)

    Deep Learning: 신경망의 기초 - 실습IV PT-TF CNN

    -DMLP

    완전 연결 구조로 높은 복잡도->학습이 매우 느리고 과잉적합이 발생할 가능성이 존재

    -컨볼루션 신경망(Convolutional Neural Network, CNN)

    격자 구조를 갖는 데이터에 적합, 영상 분류나 문자 인식등 인식 문제에 높은 성능

    컨볼루션 연산을 수행하여 특징 추출

    컨볼루션(Convolution)연산?

    해당하는 요소끼리 곱해서 결과를 모두 더하는 선형 연산

    보폭(Stride) : 커널을 다음 컨볼루션 연산을 위해 이동시키는 칸 수

    패딩(Padding) : 컨볼루션 결과의 크기를 조정하기 위해 입력 배열의 둘레를 확장하고 0으로 채우는 연산

    풀링(Pooling) : 일정 크기의 블록을 통합하여 하나의 대푯값으로 대체하는 연산

    ex)최대값 풀링(Max Pooling), 평균값 풀링(Average Pooling)

    컨볼루션 신경망 구조

    • 특징추출
      • 컨볼루션 연산을 하는 Conv층
      • ReLU연산을 하는 ReLU
      • 풀링 연산을 하는 Pool
    • 추출된 특징을 통해 분류나 회귀를 수행하는 다층 퍼셉트론
      • 전체 연결된(Fully connected) FC층 반복
      • 분류의 경우 마지막 층에 Softmax연산 수행

    CNN구조

    import torch
    import torch.nn as nn
    from .utils import load_state_dict_from_url
    from typing import Any
    
    
    __all__ = ['AlexNet', 'alexnet']
    
    
    model_urls = {
        'alexnet': 'https://download.pytorch.org/models/alexnet-owt-4df8aa71.pth',
    }
    
    #AlexNet은 5개의 Convolution layer+3개의 Fully Connected layer로 구성
    class AlexNet(nn.Module):
    
        def __init__(self, num_classes: int = 1000) -> None:
            super(AlexNet, self).__init__()
            #특징추출
            self.features = nn.Sequential(
                #Conv1
                #input channel : 3(RGB channel) , output channel : 64, kernel_size : 11, stride : 4, padding : 2
                nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),
                nn.ReLU(inplace=True), # inplace=True 하면, inplace 연산을 수행함, inplace 연산은 결과값을 새로운 변수에 값을 저장하는 대신 기존의 데이터를 대체하는것을 의미
                #Max Pool1
                nn.MaxPool2d(kernel_size=3, stride=2),
                #Conv2
                nn.Conv2d(64, 192, kernel_size=5, padding=2),
                nn.ReLU(inplace=True),
                #Max Pool2
                nn.MaxPool2d(kernel_size=3, stride=2),
                #Conv3
                nn.Conv2d(192, 384, kernel_size=3, padding=1),
                nn.ReLU(inplace=True),
                ##Conv4
                nn.Conv2d(384, 256, kernel_size=3, padding=1),
                nn.ReLU(inplace=True),
                #Conv5
                nn.Conv2d(256, 256, kernel_size=3, padding=1),
                nn.ReLU(inplace=True),
                #Max Pool3
                nn.MaxPool2d(kernel_size=3, stride=2),
            )
            self.avgpool = nn.AdaptiveAvgPool2d((6, 6))
            #분류층
            self.classifier = nn.Sequential(
                #드롭아웃 
                nn.Dropout(),
                nn.Linear(256 * 6 * 6, 4096),
                #nn.Linear()를 통해 첫번째 fully connected layer 생성
                nn.ReLU(inplace=True),
                nn.Dropout(),
                nn.Linear(4096, 4096),
                #nn.Linear()를 통해 두번째 fully connected layer 생성
                nn.ReLU(inplace=True),
                nn.Linear(4096, num_classes),
                #nn.Linear()를 통해 세번째 fully connected layer(최종 분류층) 생성
            )
    
        def forward(self, x: torch.Tensor) -> torch.Tensor:
            #특징 추출 부분
            x = self.features(x)
           
            x = self.avgpool(x)
            #output shape : (batch size * 256(channel), 6, 6)
            #Flatten
            x = torch.flatten(x, 1)
            #output shape (batch_size, 256 * 6* 6)
            #분류 분류 
            x = self.classifier(x)
            return x
    
    #pretrained : 이미지넷으로 사전학습된 모델을 가지고 올지 말지
    def alexnet(pretrained: bool = False, progress: bool = True, **kwargs: Any) -> AlexNet:
        r"""AlexNet model architecture from the
        `"One weird trick..." <https://arxiv.org/abs/1404.5997>`_ paper.
        Args:
            pretrained (bool): If True, returns a model pre-trained on ImageNet
            progress (bool): If True, displays a progress bar of the download to stderr
        """
        #모델에 AlexNet이라는 객체를 생성해서 넣어줌
        model = AlexNet(**kwargs)
        if pretrained:
            state_dict = load_state_dict_from_url(model_urls['alexnet'],
                                                  progress=progress)
            model.load_state_dict(state_dict)
        return model
    import tensorflow as tf
    
    def AlexNet(
      input_shape=None,
      weights=None,
      classes=1000,
      classifier_activation='softmax'):
      
      model = tf.keras.Sequential([
          #특징 추출 부분 
          #Conv 1
          tf.keras.layers.Conv2D(filters=96,
                                  kernel_size=(11, 11),
                                  strides=4,
                                  padding="valid",
                                  activation=tf.keras.activations.relu,
                                  input_shape=input_shape),
          #Max Pool 1
          tf.keras.layers.MaxPool2D(pool_size=(3, 3),
                                    strides=2,
                                    padding="valid"),
          tf.keras.layers.BatchNormalization(),
          #Conv 2
          tf.keras.layers.Conv2D(filters=256,
                                  kernel_size=(5, 5),
                                  strides=1,
                                  padding="same",
                                  activation=tf.keras.activations.relu),
          #Max Pool 2
          tf.keras.layers.MaxPool2D(pool_size=(3, 3),
                                    strides=2,
                                    padding="same"),
          tf.keras.layers.BatchNormalization(),
          #Conv 3
          tf.keras.layers.Conv2D(filters=384,
                                  kernel_size=(3, 3),
                                  strides=1,
                                  padding="same",
                                  activation=tf.keras.activations.relu),
          #Conv 4
          tf.keras.layers.Conv2D(filters=384,
                                  kernel_size=(3, 3),
                                  strides=1,
                                  padding="same",
                                  activation=tf.keras.activations.relu),
          #Conv 5
          tf.keras.layers.Conv2D(filters=256,
                                  kernel_size=(3, 3),
                                  strides=1,
                                  padding="same",
                                  activation=tf.keras.activations.relu),
          #Max Pool 3
          tf.keras.layers.MaxPool2D(pool_size=(3, 3),
                                    strides=2,
                                    padding="same"),
          tf.keras.layers.BatchNormalization(),
          
          tf.keras.layers.Flatten(),
          
          #분류 층 부분
          #Fully connected layer 1 
          tf.keras.layers.Dense(units=4096,
                                activation=tf.keras.activations.relu),
          tf.keras.layers.Dropout(rate=0.2),
          #Fully connected layer 2
          tf.keras.layers.Dense(units=4096,
                                activation=tf.keras.activations.relu),
          tf.keras.layers.Dropout(rate=0.2),
          
          #Fully connected layer 3
          tf.keras.layers.Dense(units=classes,
                                activation=tf.keras.activations.softmax)
      ])
    
      return model

    댓글

Designed by Tistory.