5 분 소요

본 글은 [케라스 창시자에게 배우는 딥러닝] - (박해선 옮김) 책을 개인공부하기 위해 요약, 정리한 내용입니다.
전체 코드는 https://github.com/ingu627/deep-learning-with-python-notebooks에 기재했습니다.(원본 코드 fork)
뿐만 아니라 책에서 설명이 부족하거나 이해가 안 되는 것들은 외부 자료들을 토대로 메꿔 놓았습니다. 즉, 딥러닝은 이걸로 끝을 내보는 겁니다.
오타나 오류는 알려주시길 바라며, 도움이 되길 바랍니다.





5_3. 사전 훈련된 컨브넷 사용하기

  • 작은 이미지 데이터셋에 딥러닝을 적용하는 일반적이고 매우 효과적인 방법은 사전 훈련된 네트워크를 사용하는 것이다.
  • 사전 훈련된 네트워크(pretrained network) : 대규모 이미지 분류 문제를 위해 대량의 데이터셋에서 미리 훈련되어 저장된 네트워크
  • 학습된 특성을 다른 문제에 적용할 수 있는 유연성은 딥러닝의 핵심 장점이다.
  • ImageNet 데이터셋 : 1400만 개의 레이블된 이미지와 1000개의 클래스로 이루어진 데이터셋
  • VGG16 : 간단하고 ImageNet 데이터셋에 널리 사용되는 컨브넷 구조이다.
  • 사전 훈련된 네트워크를 사용하는 두 가지 방법 : 특성 추출(feature extraction) & 미세 조정(fine tuning)

image 이미지출처: 1



5_3_1. 특성 추출

  • 특성 추출 (Feature extraction) : 사전에 학습된 네트워크의 표현을 사용하여 새로운 샘플에서 흥미로운 특성을 뽑아 내는 것
    • 케라스에서 지원하는 모듈: VGG16, VGG19, Inception V3, ResNet50, Xception, MobilNet
  • 이런 특성을 사용하여 새로운 분류기를 처음부터 훈련한다.


  • 컨브넷은 이미지 분류를 위해 두 부분으로 구성된다.
  • 먼저 연속된 합성곱과 풀링 층으로 시작해서 완전 연결 분류기로 끝난다.
  • 첫 번째 부분을 합성곱 기반 층이라고 부른다.
  • 컨브넷의 경우 특성 추출은 사전에 훈련된 네트워크의 합성곱 기반 층을 선택하여 새로운 데이터를 통과시키고, 그 출력으로 새로운 분류기를 훈련한다.

cnn3

  • 합성곱 층에 의해 학습된 표현이 더 일반적이어서 재사용이 가능하다.
  • 컨브넷의 특성 맵은 사진에 대한 일반적인 콘셉트의 존재 여부를 기록한 맵
  • (완전 연결 층들은 공간 개념을 제거하지만 합성곱의 특성 맵은 객체 위치를 고려한다.)
  • 특성 합성곱 층에서 추출한 표현의 일반성(그리고 재사용성) 수준은 모델에 있는 층의 깊이에 달려 있다.
    • 모델의 하위 층은 (에지, 색깔, 질감 등) 지역적이고 매우 일반적인 특성 맵을 추출한다.
    • 모델의 상위 층은 좀 더 추상적인 개념을 추출한다.



VGG16 합성곱 기반 층 만들기

  • weights : 모델을 초기화할 가중치 체크포인트를 지정
  • include_top : 네트워크의 최상위 완전 연결 분류기를 포함할지 안 할지 지정한다.
    • 기본값은 ImageNet의 클래스 1000개에 대응되는 완전 연결 분류기를 포함한다.
  • input_shape : 네트워크에 주입할 이미지 텐서의 크기
    • 이 매개변수는 선택 사항. 이 값을 지정하지 않으면 네트워크가 어떤 크기의 입력도 처리할 수 있다.

image



데이터 증식을 사용하지 않는 빠른 특성 추출


사전 훈련된 합성곱 기반 층을 사용한 특성 추출하기

  • rescale = 1./255 : 값을 0과 1 사이로 변경
  • 제너레이터는 루프 안에서 무한하게 데이터를 만들어 내므로 모든 이미지를 한 번씩 처리하고 나면 중지한다. (break)
  • 추출된 크기는 (samples, 4, 4, 512)이다. 완전 연결 분류기에 주입하기 위해서 먼저 (samples, 8192) 크기로 펼친다.


완전 연결 분류기를 정의하고 훈련하기

  • 완전 연결 분류기를 정의하고(규제를 위해 드롭아웃을 사용한다) 저장된 데이터와 레이블을 사용하여 훈련한다.


결과 그래프 그리기

image


데이터 증식을 사용한 특성 추출

  • 이 방법은 훨씬 느리고 비용이 많이 들지만 훈련하는 동안 데이터 증식 기법 을 사용할 수 있다.
  • conv_base 모델을 확장하고 입력 데이터를 사용하여 엔드-투-엔드로 실행한다.


합성곱 기반 층 위에 완전 연결 분류기 추가하기

  • 모델은 층과 동일하게 작동하므로 층을 추가하듯이 Sequential 모델에 다른 모델을 추가할 수 있다.

image

  • 모델을 컴파일하고 훈련하기 전에 합성곱 기반 층을 동결하는 것이 중요하다.
    • 동결 : 훈련하는 동안 가중치가 업데이트되지 않도록 막는다는 의미
  • 이렇게 하지 않으면 합성곱 기반 층에 의해 사전에 학습된 표현이 훈련하는 동안 수정될 것이다.
  • 맨 위의 Dense 층은 랜덤하게 초기화되었기 때문에 매우 큰 가중치 업데이트 값이 네트워크에 전파될 것이다.
  • 이는 사전에 학습된 표현을 크게 훼손한다.
  • 케라스에서는 trainable 속성을 False로 설정하여 네트워크를 동결할 수 있다.
  • 이렇게 설정하면 추가한 2개의 Dense 층 가중치만 훈련된다.
  • 층마다 2개씩 총 4개의 텐서가 훈련된다.
  • 변경 사항을 적용하려면 먼저 모델을 컴파일해야 한다.
  • 컴파일 단계 후에 trainable 속성을 변경하면 반드시 모델을 다시 컴파일해야 한다.


동결된 합성곱 기반 층과 함께 모델을 엔드-투-엔드로 훈련하기

  • GPU 사용 권장

image



5_3_2. 미세 조정

  • 미세 조정 (Fine tuning) : 특성 추출에 사용했던 동결 모델의 상위 층 몇 개를 동결에서 해제하고 모델에 새로 추가한 층(여기서는 완전 연결 분류기)과 함께 훈련하는 의미.
    • 주어진 문제에 조금 더 밀접하게 재사용 모델의 표현을 일부 조정하기 때문에 미세 조정이라고 부른다.

cnn5



네트워크를 미세 조정하는 단계

  1. 사전에 훈련된 기반 네트워크 위에 새로운 네트워쿼를 추가한다.
  2. 기반 네트워크를 동결한다.
  3. 새로 추가한 네트워크를 훈련한다.
  4. 기반 네트워크에서 일부 층의 동결을 해제한다.
  5. 동결을 해제한 층과 새로 추가한 층을 함께 훈련한다.

conv_base.summary()

image

  • 마지막 3개의 합성곱 층을 미세 조정해본다.
  • 즉, block4_pool까지 모든 층은 동결되고 block5_con1, block5_conv2, block5_conv3 층은 학습 대상이 된다.



특정 층까지 모든 층 동결하기

image



GPU 사용



모델 미세 조정하기

  • 학습률을 낮춘 RMSProp 옵티마이저를 사용한다.
  • 학습률을 낮추는 이유는 미세 조정하는 3개의 층에서 학습된 표현을 조금씩 수정하기 위해서
  • 변경량이 너무 크면 학습된 표현에 나쁜 영향을 끼칠 수 있다.

image



부드러운 그래프 그리기

  • 그래프를 보기 쉽게 하기 위해 지수 이동 평균으로 정확도와 손실 값을 부드럽게 표현할 수 있다.

image

  • 그래프는 개별적인 손실 값의 평균을 그린 것. 정확도에 영향을 미치는 것은 손실 값의 분포이지 평균이 아님을 유의.



테스트 데이터로 모델 평가

image

  • 정확도 : 약 93.6%



정리

  • 컨브넷은 컴퓨터 비전 작업에 가장 뛰어난 머신 러닝 모델이다. 아주 작은 데이터셋에서도 처음부터 훈련해서 괜찮은 성능을 낼 수 있다.
  • 작은 데이터셋에서는 과대적합이 큰 문제이다. 데이터 증식은 이미지 데이터를 다룰 때 과대적합을 막을 수 있는 강력한 방법
  • 특성 추출 방식으로 새로운 데이터셋에 기존 컨브넷을 쉽게 재사용할 수 있다.
  • 특성 추출을 보완하기 위해 미세 조정을 사용할 수 있다.



5_4. 컨브넷 학습 시각화

시각화 기법

  1. 컨브넷 중간층의 출력(중간층에 있는 활성화)을 시각화하기 : 연속된 컨브넷 층이 입력을 어떻게 변형시키는지 이해하고 개별적인 컨브넷 필터의 의미를 파악하는 데 도움이 된다.
  2. 컨브넷 필터를 시각화하기 : 컨브넷의 필터가 찾으려는 시각적인 패턴과 개념이 무엇인지 상세하게 이해하는 데 도움이 된다.
  3. 클래스 활성화에 대한 히트맵을 이미지에 시각화하기 : 이미지의 어느 부분이 주어진 클래스에 속하는 데 기여했는지 이해하고 이미지에서 객체 위치를 추정(localization)하는 데 도움이 된다.



5_4_1. 중간층의 활성화 시각화하기

  • 중간층의 활성화 시각화는 어떤 입력이 주어졌을 때 네트워크에 있는 여러 합성곱과 풀링 층이 출력하는 특성 맵을 그리는 것이다.
  • 이 방법은 네트워크에 의해 학습된 필터들이 어떻게 입력을 분해하는지 보여 준다.
  • 너비, 높이, 깊이(채널) 3개의 차원에 대해 특성 맵을 시각화하는 것이 좋다.
  • 각 채널은 비교적 독립적인 특성을 인코딩하므로 특성 맵의 각 채널 내용을 독립적인 2D 이미지로 그리는 것이 방법



모델 로드

image



개별 이미지 전처리하기



테스트 사진 출력하기

image



입력 텐서와 출력 텐서의 리스트로 모델 객체 만들기

  • 확인하고 싶은 특성 맵을 추출하기 위해 이미지 배치를 입력으로 받아 모든 합성곱과 풀링 층의 활성화를 출력하는 케라스 모델을 만든다.
  • Model 클래스로 반환되는 객체는 Sequential과 같은 케라스 모델이지만 특정 입력과 특정 출력을 매핑한다.
  • Model 클래스를 사용하면 Sequential과는 달리 여러 개의 출력을 가진 모델을 만들 수 있다.
  • 이 모델은 하나의 입력과 층의 활성화마다 하나씩 총 8개의 출력을 가진다.



예측 모드로 모델 실행하기

  • 층의 활성화마다 하나씩 8개의 넘파이 배열로 이루어진 리스트를 반환한다.



20번째 채널 시각화하기

  • 32개의 채널을 가진 148x148 크기의 특성 맵이다.
  • 이 채널은 대각선 에지를 감지하도록 인코딩되었다.

Image



16번째 채널 시각화하기

  • 이 채널은 밝은 녹색 점을 감지하는 거 같아 고양이 눈을 인코딩하기 좋다.

image



중간층의 모든 활성화에 있는 채널 시각화하기

image

  • 상위 층으로 갈수록 활성화는 점점 더 추상적으로 되고 시각적으로 이해하기 어려워 진다.
  • 비어 있는 활성화가 층이 깊어짐에 따라 늘어난다. 첫 번째 층에서는 모든 필터가 입력 이미지에 활성화되었지만 층을 올라가면서 활성화되지 않는 필터들이 생긴다.
    • 필터에 인코딩된 패턴이 입력 이미지에 나타나지 않았다는 것을 의미한다.



5_4_2. 컨브넷 필터 시각화하기

  • 컨브넷이 학습한 필터를 조사하는 또 다른 간편한 방법은 각 필터가 반응하는 시각적 패턴을 그려 보는 것이다.
  • 빈 입력 이미지에서 시작해서 특정 필터의 응답을 최대화하기 위해 컨브넷 입력 이미지에 경사 상승법을 적용한다.
  • 결과적으로 입력 이미지는 선택된 필터가 최대로 응답하는 이미지가 될 것이다.
  • 경사 상승법을 적용하여 이미지의 필터가 무엇을 인식하고 있는지 보는 것


  • 전체 과정
    1. 특정 합성곱 층의 한 필터 값을 최대화하는 손실 함수를 정의한다.
    2. 이 활성화 값을 최대화하기 위해 입력 이미지를 변경하도록 확률적 경사 상승법을 사용한다.



피터 시각화를 위한 손실 텐서 정의하기



그래이던트 정규화하기

  • 경사 하강법 과정을 부드럽게 하기 위해 사용하는 한 가지 기법은 그래디언트 텐서를 L2 노름으로 나누어 정규화하는 것.
  • 이렇게 하면 입력 이미지에 적용할 수정량의 크기를 항상 일정 범위 안에 놓을 수 있다.



입력 값에 대한 넘파이 출력 값 추출하기

  • iterate는 넘파이 텐서(크기가 1인 텐서의 리스트)를 입력으로 받아 손실과 그래디언트 2개의 넘파이 텐서를 반환한다.



확률적 경사 상승법을 사용한 손실 최대화하기

  • 이미지 텐서는 (1, 150, 150, 3) 크기의 부동 소수 텐서이다.



텐서를 이미지 형태로 변환하기 위한 유틸리티 함수

  • numpy.clip(a, a_min, a_max, out=None, **kwargs) : min ~ max 범위 이외의 값은 모두 자른다. (범위에 맞춰준다.)



필터 시각화 이미지를 만드는 함수

  • 위의 코드들을 모아서 층의 이름과 필터 번호를 입력으로 받는 함수를 만든다.

image

  • block3_conv1 층의 필터 0은 물방울 패턴에 반응했다.



층에 있는 각 필터에 반응하는 패턴 생성하기 (수정)

image

  • 에러가 났다. (이부분)

  • 컨브넷의 각 층은 필터의 조합으로 입력을 표현할 수 있는 일련의 필터를 학습한다.



5_4_3. 클래스 활성화의 히트맵 시각화하기

  • 클래스 활성화 맵(Class Activation Map, CAM) : ‘입력 이미지가 각 채널을 활성화하는 정도’에 대한 공간적인 맵을 ‘클래스에 대한 각 채널의 중요도’로 가중치를 부여하여 ‘입력 이미지가 클래스를 활성화하는 정도’에 대한 공간적인 맵을 만드는 것
    • 입력 이미지가 주어지면 합성곱 층에 있는 특성 맵의 출력을 추출한다.
    • 그다음 특성 맵의 모든 채널 출력에 채널에 대한 클래스의 그래디언트 평균을 곱한다.



사전 훈련된 가중치로 VGG16 네트워크 로드하기



VGG16을 위해 입력 이미지 전처리하기

image

  • 이 이미지에서 사전 훈련된 네트워크를 실행하고 예측 벡터를 이해하기 쉽게 디코딩한다.
  • 아프리카 코끼리 (90%), 코끼리 (7%), 인도 코끼리 (0.4%) 예측
  • 예측 벡터에서 최대로 활성화된 항목은 ‘아프리카 코끼리’클래스에 대한 것으로 386번 인덱스이다.



Grad-CAM 알고리즘 설정하기

image



원본 이미지에 히트맵 덧붙이기

image



References

댓글남기기