딥러닝_CNN_합성곱연산(Convnet)_4. 최신 컨브넷 아키텍처 패턴

주지윤·2022년 12월 9일
0

딥러닝

목록 보기
17/21
post-custom-banner

최신 컨브넷 아키텍처 패턴

아키텍처(architecture)

  • 아키텍처란?

    • 모델을 만드는 데 사용된 일련의 선택들
    • 가설공간을 정의
    • 사진 지식(prior knowledge)을 인코딩
      - ex: 이미지에 있는 패턴이 이동 불변성이 있음을 이미 알고 있음

  • 아키텍처 공식: MHR

    • 모듈화(=블록): 반복되는 층 그룹
    • 계층화: 모듈의 계층화, 대부분의 컨브넷은 피라미드 계층
    • 재사용(=추상화): 모듈을 적절한 곳에 재사용

  • 아케텍처 모범사례

    • 잔차연결(residual connection)
    • 배치 정규화(batch normalization)
    • 분리 합성곱(seaprable convolution)

잔차연결(residual connection)

  • 개발 배경

    • 필터 개수는 층이 깊어질수록 늘어나고, 특성 맵의 크기는 줄어든다.
    • 역전파가 전달될 때 층이 너무 깊으면, 각 함수의 일정 잡음들의 영향으로 그레이디언트 정보가 소실되고 역전파가 동작하지 않게 된다.: 그래이디언트 소실(vanishing gradient)
    • 이를 해결하기 위해 개발: 잔차연결
    • ResNet모델과 함께 소개됨
  • 잔차연결의 방식

    • 이전 입력에 담긴 잡음이 없는 정보를 따로 저장하여 유지시킴
    • 층의 입력을 출력에 더함

🔸 간단한 컨브넷 잔차연결 예시

  • 입력을 출력에 더하기 위해서는 출력크기가 입력과 같아야함
  • Conv층: 입력값을 더하기 위해 Conv층에padding='same'으로 다운샘플링을 방지
  • MaxPooling층: MaxPooling층의 입력 값을 저장할 때 strides=2로 다운샘플링을 맞춤
inputs = keras.Input(shape=(32, 32, 3))
x = layers.Rescaling(1./255)(inputs)

#--------------------------------------------------------------#

def residual_block(x, filters, pooling=False):
    
    residual = x
    x = layers.Conv2D(filters, 3, activation="relu", padding="same")(x)
    x = layers.Conv2D(filters, 3, activation="relu", padding="same")(x)
    
    if pooling:
        x = layers.MaxPooling2D(2, padding="same")(x)    
        residual = layers.Conv2D(filters, 1, strides=2)(residual)
    
    # 최대 풀링을 사용하지 않을 때 채널 수가 바뀐 경우에만 잔차 투영
    elif filters != residual.shape[-1]:
        residual = layers.Conv2D(filters, 1)(residual)
    
    x = layers.add([x, residual])
    
    return x
    
#-------------------------------------------------------------#  

x = residual_block(x, filters=32, pooling=True)
x = residual_block(x, filters=64, pooling=True)
x = residual_block(x, filters=128, pooling=False)
 
x = layers.GlobalAveragePooling2D()(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.summary()



배치 정규화(batch normalization)

  • 정규화: 샘플들을 균일하게 만드는 방법, 일반화에 도움
  • 미리 정규화된 데이터 샘플: Conv층에서 출력되는 데이터가 동일한 분포를 가질것이라고 예상하기 어려움
  • 배치정규화(BatchNormalization): 훈련하는 동안 평균과 분산이 바뀌더라도 이에 적응하여 데이터를 정규화 → 현재 배치 데이터의 평균과 분산을 사용
  • 효과: 매우 깊은 네트워크에서 그레이디언트의 전파를 도움

  • 배치정규화의 사용
    • 편향 벡터를 사용하지 않음
      • 이유: 정규화 단계는 출력의 평균을 0에 맞추기 때문
      • layers.Conv2D(32,3,use_bias=False)(x)
    • 활성화 함수 이전에 배치 정규화를 함
      x = layers.Conv2D(32, 3, use_bias=False)(x)
      x = layers.BatchNormalization()(x)
      x = layers.Activation("relu")(x)
    • 추론 시: 훈련에서 사용한 평균과 분산의 지수 이동 평균 사용


깊이별 분리 합성곱

  • 깊이별 분리 합성곱(depthwise separable convolution):
    • 케라스에서 SeparableConv2D
    • 입력채널별로 따로 공간방향의 합성곱을 연산 → 점별 합성곱(pointwise convolution)(1x1합성곱)을 통해 출력채널을 합침
    • 공간상의 위치는 높은 상관관계를 가지고, 채널간은 독립적
    • ex: 3x3 윈도우, 입력채널 64개, 출력채널 64개의 경우
      • 일반 합성곱: 336464=36,8643*3*64*64=36,864
      • 깊이별 분리 합성곱: (3364)+(6464)=4,672(3*3*64)+(64*64)=4,672

  • 훨씬 적은 개수의 파라미터 사용, 더 적은 수의 연산 수행
  • 수렴이 빠리고 쉽게 과대 적합 되지 않음


아키텍처 원칙정리

  • 모듈화(블록): 일반적으로 여러개의 합성곱, 최대풀링층
  • 피라미드계층(좁고 깊은 아키텍처): 특성맵의 공간 방향크기 ↓, 필터 개수 ↑
  • 블록에 잔차연결을 추가/합성곱 층 다음에 배치정규화 추가 시 깊은 네트워크에 도움
  • 파라미터 효율이 좋은 SeparableConv2D층이 도움될 수 있음

Xception 유사모델

  • 아키텍처의 원칙을 잘 반영한 Xception의 유사모델을 코드화
inputs = keras.Input(shape=(180, 180, 3))
x = data_augmentation(inputs)
 
x = layers.Rescaling(1./255)(x)
x = layers.Conv2D(filters=32, kernel_size=5, use_bias=False)(x)
 
for size in [32, 64, 128, 256, 512]:
    residual = x
 
    x = layers.BatchNormalization()(x)
    x = layers.Activation("relu")(x)
    x = layers.SeparableConv2D(size, 3, padding="same", use_bias=False)(x)
  
    x = layers.BatchNormalization()(x)
    x = layers.Activation("relu")(x)
    x = layers.SeparableConv2D(size, 3, padding="same", use_bias=False)(x)
  
    x = layers.MaxPooling2D(3, strides=2, padding="same")(x)
  
    residual = layers.Conv2D(
        size, 1, strides=2, padding="same", use_bias=False)(residual)
    x = layers.add([x, residual])
  
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
  • cat vs dog 데이터 적용시: 90.8% 정확도 달성
post-custom-banner

0개의 댓글