Learning/Vision AI

05. 고급 합성곱 신경망 구조

눈떠보니 월요일 2023. 2. 17. 18:17

목차

 

5.1 CNN의 디자인 패턴

첫 번째 패턴 - 특징 추출과 분류

- 특징 추출을 맡는 부분은 일련의 합성곱 층, 분류를 맡는 부분은 일련의 전결합층으로 구성

 

두 번째 패턴 - 이미지 깊이는 증가, 크기는 감소

- 합성곱 연산을 거치며 이미지의 깊이는 증가하고 크기는 감소(높이x폭x깊이)

- 입력 때의 깊이는 색상 채널(3:컬러, 1:회색조)를 의미하지만 이후 계층에서는 추출된 특징을 나타내는 특징맵이 된다.

 

세 번째 패턴 - 전결합층

- 대부분의 경우 모든 전결합층은 유닛 수가 같거나, 이어지는 층에서 점차 유닛 수가 감소하는 패턴을 보임

- 이어지는 층에서 유닛 수가 증가하는 경우는 매우 드물다.

- 모든 전결합층의 유닛 수를 같게해도 학습 능력이 저해되는 현상은 아직 발견하지 못함

5.2 LeNet-5

논문 제목 : Gradient-Based Learning Applied to Document Recognition

논문 요약 참고 : https://arclab.tistory.com/150

5.2.1 LeNet 구조

Input Image -> C1(합성곱층) -> TANH(활성화 함수) -> S2(서브샘플링층) -> C3 -> TANH -> S4 -> C5 -> TANH

->FC6(전결합층) -> SOFTMAX7

 

5.2.2 Keras로 LeNet-5 구현하기

논문 page 6~8에 실린 구조에 따라 구현하기

  • 각 합성곱층의 필터 수 / C1 : 6, C3 : 16, C5 : 120
  • 각 합성곱층의 커널 크기 / kernel_size : 5 x 5
  • 풀링층(서브샘플링층) / average pooling(pool_size : 2x2)
  • 활성화 함수 / tanh(당시에는 대칭 함수가 sigmoid 함수에 비해 가중치가 더 빨리 수렴한다고 생각함)
from keras.models import Sequential
from keras.layers import Conv2D, AveragePooling2D, Flatten, Dense

model = Sequential()
model.add(Conv2D(filters=6, kernel_size=5, strides=1, activation='tanh', input_shape=(28,28,1), padding='same'))
model.add(AveragePooling2D(pool_size=2, strides=2, padding='valid'))
model.add(Conv2D(filters=16, kernel_size=5, strides=1, activation='tanh', padding='valid'))
model.add(AveragePooling2D(pool_size=2, strides=2, padding='valid'))
model.add(Conv2D(filters=120, kernel_size=5, strides=1, activation='tanh', padding='valid'))
model.add(Flatten())
model.add(Dense(units=84, activation='tanh'))
model.add(Dense(units=10, activation='softmax'))
model.summary()

5.2.3 하이퍼파라미터 설정하기

LeNet-5

epoch learning-rate
2 0.0005
3(3~5) 0.0002
4(6~9) 0.00005
....(9 이후) 0.00001
def lr_schedule(epoch):
    if epoch <= 2:
        lr = 5e-4
    elif epoch > 2 and epoch <= 5:
        le = 2e-4
    elif epoch >5 and epoch <= 9:
        lr = 5e-5
    else:
        lr = 1e-5
    return lr
  • lr_schedule 함수 컴파일
from keras.callbacks import ModelCheckpoint, LearningRateScheduler

lr_scheduler = LearningRateScheduler(lr_schedule)
checkpoint = ModelCheckpoint(filepath='path_to_save_file/file.hdf5',
                             monitor= 'val_ac',
                             verbose=1,
                             save_best_only=True)
callbacks = [checkpoint, lr_scheduler]
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
hist = model.fit(X_train, y_train, batch_size=32, epochs=20, validation_data=(X_test, y_test), callbacks=callbacks, verbose=2, shuffle=True)

 

5.3 AlexNet

논문 제목 : ImageNet Classification with Deep Convolutional Neural Networks  

논문 요약 참고 : https://jjuon.tistory.com/22

5.3.1 AlexNet 구조

Input Image -> CONV1 -> POOL2 -> CONV3 -> POOL4 -> CONV5 -> CONV6 -> CONV7 -> POOL8

-> FC9 -> -> FC10 -> SOFTMAX7

  • 합성곱층의 필터 크기 : 11x11, 5x5, 3x3
  • 최대 풀링 사용
  • 과적합 방지를 위한 드롭아웃 적용
  • 은닉층의 활성화 함수는 ReLU, 출력층의 활성화 함수는 소프트맥스 함수 사용

5.3.2 AlexNet에서 발전된 부분

ReLU를 활성화함수로 사용

- 학습 시간을 크게 단축시킴

- 기울기 소실 문제 해결 : 입력에 큰 차이가 있어도 sigmoid 함수의 함숫값에는 큰 차이가 나지 않음을 해결

 

드롭아웃층

- 신경망 모델의 과적합 방지

 

데이터 강화

- 레이블 값을 변화시키지 않고 원 데이터만 변형하는 방법

- 데이터 양을 늘리는 기법도 과적합 방지에 효율적임

 

국소 응답 정규화(Local Response Nomalization)

- 가중치가 빨리 수렴되도록하는 목적

- 최근에는 배치 정규화가 많이 사용된다.

 

가중치 규제화(AlexNet은 0.0005 적용)

- L2 규제화와 같은 개념

- 과적합 억제를 통한 일반화 성능 개선

model.add(Conv2D(32, (3,3) kernel_regularizer=-l2(lambda)))

 

다중 GPU 사용

- 분산 학습 기법 적용

 

5.3.3 Keras로 AlexNet 구현하기

논문 page 4에 실린 구조에 따라 구현하기

model = Sequential()
# 첫 번째 층
model.add(Conv2D(filters=96, kernel_size=(11,11), strides=(4,4), padding='valid', input_shape=(227,227,3)))
model.add(Activation('relu'))
model.add(MaxPool2D(pool_size=(3,3), strides=(2,2)))
model.add(BatchNormalization())

# 두 번째 층
model.add(Conv2D(filters=256, kernel_size=(5,5), strides=(1,1), padding='same', kernel_regularizer=l2(0.0005)))
model.add(Activation('relu'))
model.add(MaxPool2D(pool_size=(3,3), strides=(2,2), padding='valid'))
model.add(BatchNormalization())

# 세 번째 층
model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='same', kernel_regularizer=l2(0.0005)))
model.add(Activation('relu'))
model.add(BatchNormalization())

# 네 번째 층
model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='same', kernel_regularizer=l2(0.0005)))
model.add(Activation('relu'))
model.add(BatchNormalization())

# 다섯 번째 층
model.add(Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='same', kernel_regularizer=l2(0.0005)))
model.add(Activation('relu'))
model.add(BatchNormalization())
model.add(MaxPool2D(pool_size=(3,3), strides=(2,2), padding='valid'))

model.add(Flatten()) # CNN의 출력을 1차원으로 변환해 전결합층에 입력

# 여섯 번째 층
model.add(Dense(units=4096, activation='relu'))
model.add(Dropout(0.5))

# 일곱 번째 층
model.add(Dense(units=4096, activation='relu'))
model.add(Dropout(0.5))

# 여덟 번째 층
model.add(Dense(units=1000, activation='softmax'))

model.summary()

...........Layer 정보는 생략

 

5.3.4 하이퍼파라미터 설정하기

reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=np.sqrt(0.1))
optimizer = keras.optimizers.sgd(lr=0.01, momentum=0.9)
model.compile(loss='categoriacal_crossentropy', optimizer=optimizer, metrics=['accuracy'])
model.fit(X_train, y_train, batch_size=128, epochs=90, validation_data=(X_test, y_test), verbose=2, callbacks=[reduce_lr])
top-1 오차율과 top-5 오차율
: 알고리즘의 분류 성능을 나타내기 위한 개념으로 예측 결과가 틀렸더라도 정답과 얼마나 근접한지 나타내는 지표
top-1 오차율 : 분류기가 정답 클래스에 가장 높은 확률을 부여하지 않은 비율
top-5 오차율 : 정답이 예측 확률 상위 5개 안에 들어 있지 않은 비율

5.4 VGGNet

논문 제목 : Very Deep Convolutional Networks for Large-Scale Image Recognition 

논문 요약 참고: https://medium.com/@msmapark2/vgg16-%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0-very-deep-convolutional-networks-for-large-scale-image-recognition-6f748235242a

 

5.4.1 VGGNet에서 발전된 부분

  • 동일하게 설정된 층(Conv, FC)을 사용해서 신경망 구조를 단순화 시킴
  • 전체적인 신경망 구조는 Conv층 뒤에 Pooling층이 배치
  • 모든 Conv층은 3x3 크기의 필터와 스트라이드 1, 패딩 1을 적용

      - 필터 크기를 줄인 이유는 더 세밀한 특징을 추출하기 위함

      - 논문에 따르면 커널 크기가 3x3 두층 쌀은 구조는 5x5과 동등하고 세개 쌓은 구조는 7x7과 동등) 하지만 파라미터

        억제  효과도 존재함

  • 모든 Pooling층은 2x2 크기의 풀링영역과 스트라이드 2 적용

5.4.2 VGGNet의 다양한 버전

- D와 E가 가장 일반적으로 사용된다.

- 가중치를 포함하는 층수를 붙여 각각 VGG16, VGG19라고 부른다.

신경망 유형 A, A-LRN B C D E
파라미터 수 133 133 134 138 144

※ Keras 코드 구현은 생략,,(너무 길어요..)

5.5 인셉션과 GoogLeNet

GoogleNet : 신경망 내부적으로 계산 자원의 효율을 높여 신경망의 층수를 늘린 인셉션 신경망 구조를 구현

논문 제목 : Going deeper with convolutions

논문 요약 참고:

https://phil-baek.tistory.com/entry/3-GoogLeNet-Going-deeper-with-convolutions-%EB%85%BC%EB%AC%B8-%EB%A6%AC%EB%B7%B0

5.5.1 인셉션 구조에서 발전된 부분

인셉션 모듈 : 합성곱층의 커널 크기, 풀링층의 배치를 직접 결정하는 대신 블록 전체에 똑같은 설정을 적용

  • 기존 방식에서는 Conv층과 Pooling층을 번갈아 쌓아올리는 방식으로 특징 추출기를 구성하고, 뒤에 전결합층으로 구성된 분류기를 배치
  • 인셉션 구조는 Conv층과 Pooling층으로 인셉션 모듈을 구성한 다음 이 인셉션 모듈과 풀링층을 쌓아 측징 추출디를 구성하고, 뒤에 전결합층으로 구성

5.5.2 단순 인셉션 모듈

- 입력을 4개의 층에 동시 입력하고 출력

5.5.3 차원 축소가 적용된 인셉션 모듈

: 단순 인셉션 모듈은 5x5 Conv층과 같은 크기의 큰 필터를 포함하기 때문에 계산 비용이 큼

  그러므로 차원 축소층을 도임하여 계산 부하를 낮춤.(Conv 1x1 층 사용)

 

차원 축소가 적용된 단순한 인셉션 구조

 

5.5.4 인셉션 구조

GoogleNet 구조

  • A 블록 : Conv층과 Pooling층이 번갈아 배치된 Alexnet이나 LeNet과 같은 구조
  • B 블록 : 9개의 인셉션 모듈이 인셉션 모듈 2개 + Pooling층 + 인셉션 모듈 5개 + Pooling층 + 인셉션 모듈 2개 순으로 서로 쌓인 구조
  • C 블록 : 전결합측와 소프트맥스층으로 구성된 신경망의 분류기 부분

※ Keras 코드 구현은 생략,,(너무 길어요..)

5.6 ResNet

논문 제목 : deep residual learning for image recognition

논문 요약 참고 : https://jxnjxn.tistory.com/22

 

5.6.1 ResNet에서 발전된 부분

: 층수를 대폭 늘려보자라는 컨셉(50층, 100층, 150층..)

-> 과적합을 dropout, L2 규제화, 배치 정규화를 통해 해결

 

스킵 연결 : 기울기 소실 문제를 해결하기 위해 뒤쪽 층의 기울기를 앞쪽 층에 직접 전달하는 별도의 경로를 추가

직관적인 코드 구현

X_shortcut = X
X = Conv2D(filters=F1, kernel_size=(3,3), strides=(1,1))(X)
X = Activation('relu')(X)
X = Conv2D(filters=F1, kernel_size=(3,3), strides=(1,1))(X)

X = ADD()(X, X_shortcut])

X = Activation('relu)(X)

 

5.6.2 잔차 블록

: Conv층에 스킵 연결을 추가한 구조

  • 지름길 경로 : 입력을 주 경로의 ReLU 입력 전으로 전달
  • 주 경로 : [CONV -> BN -> ReLU] x 3

- 잔차 블록에는 Pooling층이 없다. 대신 인셉션 구조와 비슷하게 1x1 Conv층을 사용한 다운샘플링을 적용

- 잔차 블록 처음에 1x1 Conv층을 배치하고, 출력에는 3x3 Conv층과 1x1 Conv층을 하나씩 배치해서 두 번에 걸쳐 차원 축소

- 이렇게 차원 축소가 적용된 블록을 병목 잔차 블록(bottleneck residual block)이라 한다.

- 잔차 블록을 배치하면 블록마다 입출력의 차원이 달라지는데, 이 문제를 해결하기 위해 지름길 경로 역시 주 경로의 값과 더하기 전에 다운 샘플링을 적용한다. -> 병목층(1x1 Conv층 + BN) 추가를 통해 

- 이러한 구조를 축소 지름길 경로(reduce shortcut)이라고 한다.

 

※ Keras 코드 구현은 생략,,(너무 길어요..)


참고 : 비전 시스템을 위한 딥러닝(모하메드 엘겐디)

전체 코드 : https://github.com/moelgendy/deep_learning_for_vision_systems