ConvNet

Weakly-Supervised localization: 뉴럴넷은 어디를 바라보고 있는가

ConvNet이 이미지를 다루는 데 강력한 성능을 보이기는 하지만, layer가 깊어지면 깊어질수록 이미지의 어떤 특징을 보고 판단을 내리는지를 파악하기란 쉽지 않다.

이미지 하나를 인풋으로 넣고 layer를 차례차례 통과하면서 activation이 어떻게 변하는지를 살펴볼 수도 있겠지만 VGG와 같은 모형처럼 레이어가 매우 깊어지거나 GoogLeNet, ResNet처럼 특수한 모듈 구조를 사용, 또는 residual connection을 사용하는 네트워크에서는 뉴럴넷이 이미지의 어느 부분을 중요하게 생각하는지의 정보를 얻기가 힘들어진다.

블랙박스인 듯 보이는 뉴럴넷(특히 ConvNet)의 내부를 조금이나마 투명하게 드러내려는 시도는 꾸준히 있어왔다. 구글에서도 최근 “Inceptionism”이라는 이름으로 재미난 연구 결과를 블로그에 공개한 바 있다.

여기서는 이보다 뉴럴넷이 “어디를 집중해서 보고 있는지”를 제시한 아주 단순하고도 유용한 방법을 살펴보고자 한다. 바로 weakly-supervised localization의 시초격 되는 방법인데, localizer 모형에게 이미지에 어떤 사물이 있는지만을 학습시키면 이미지에 어떤 사물이 있는지는 물론, 이미지의 어느 위치에 그 사물이 있는지 까지 꽤나 정확하게 예측할 수 있다.

지도학습으로 학습시키긴 했지만 학습 과정에서 알려주지 않은 사물의 위치까지 학습한다는 점에서 이러한 방식을 weakly-supervised라고 이름 붙였다. 해당 논문은 재작년에 ArXiv에 올라온 것으로 발표 당시 큰 주목을 받았었다.

 

Architecture

이 논문에서 제시한 Weakly-supervised localizer의 구조는 매우 단순하다. 어떻게 localizer를 만드는지 그 과정을 하나하나 짚어보자.

스크린샷 2018-06-17 오후 10.12.16.png

0. (Pre-trained) CNN model

CNN classifier를 가져온다. 이 classifier는 이미지를 보고 이미지에 상응하는 class label을 예측해야한다. 밑바닥부터 학습시켜도 되지만 pre-trained 모형을 사용하면 좀 더 빠르게 좋은 성능을 낼 수 있다.

가져온 CNN classifier에서 말단의 fully connected layer를 모두 제거한다. 즉 가장 깊이 있는 CONV layer가 최말단 레이어가 되도록 한다.

1. CONV layer

0.의 CNN classifier의 최말단 CONV layer 뒤에 CONV layer를 하나 추가한다. 논문에서는 1024개의 filter를 가지는 CONV layer를 추가했다. 여기서도 filter 갯수는 1024라고 가정하자.

이 레이어의 출력은 1024개의 feature map (depth=1024)이 된다.

2. Global Average Pooling (GAP)

1024개의 feature map을 크기가 1024인 벡터로 변환시킨다. 다시 말해 feature map 하나당 수치 하나로 변환시킨다.

이 과정에서 global average pooling (GAP)을 사용한다. GAP layer는 pool size가 input feature map의 크기와 같은, 즉 이미지 전체에서 딱 하나의 값(평균값)만을 pooling하는 레이어이다.

이 논문 이전에 global max pooling (GMP)를 사용한 weakly-supervised localization 방법이 공개되었었는데 GMP는 가장 activation이 강한 region의 정보만을 가져오기 때문에 사물의 경계선을 파악하는 데에 그쳤다고 한다. 사물의 위치 전체를 localization하는 데에는 모든 activation의 정보를 평균내는 GAP가 더 적합하다.

GAP layer의 출력은 각 feature map(\text{width} \times \text{height} \times 1024)의 평균값의 벡터(1 \times 1 \times 1024)가 된다.

3. Fully connected layer

fully connected layer를 GAP layer 뒤에 하나 추가한다.

이 dense layer의 입력은 GAP layer의 출력, 즉 크기 1 \times 1 \times 1024의 벡터이고 출력은 예측하려는 class label의 갯수이다. Weight matrix W의 모양은 1024 \times \text{(\#classes)}가 된다.

4. Class Activation Map (CAM) 계산

1.의 CONV layer에서의 feature map과 3.의 dense layer에서의 weight W를 사용해서 class activation map (CAM)을 계산한다.

Label=c인 class의 activation map CAM_c는 다음과 같이 계산한다.

CAM_c = \sum_{k=1}^{1024}{w_{k, c}f_k}

여기서 w_{k, c}k번째 GAP 벡터에서 class c로 이어지는 가중치값(Wkc열 원소)이고, f_k는 1.에서 추가한 CONV layer의 k번째 feature map이다.

이렇게 구한 CAM_c는 해당 이미지가 클래스 c에 속한다고 판단내릴 때 ConvNet이 이미지의 어떤 부분을 보고있었는지의 정보를 가지고 있다.

CAM_c의 값이 큰 부분이 클래스 c에 속하는 사물의 위치라고 ConvNet이 판단내린 것이다.

 

응용

Weakly-supervised localization은 여러 방면에 응용될 수 있다. Semantic image segmentation을 위한 데이터를 만드는 데에도 사용될 수 있고, ConvNet이 보고있는 지점을 파악할 수 있다는 점에서 ConvNet이 이미지로부터 학습한 feature를 사람이 직관적으로 이해할 수 있도록 시각화하는 데에도 사용될 수 있다.

이미 학습된 모형을 사용해서 간단히 만들 수 있다는 큰 장점이 있어 여러 분야에 매우 쉽게 응용할 수 있다. 비록 localizer가 아닌 classifier에 비해서는 classification 성능이 떨어지지만 그 차이가 크지 않으며 localization 기능까지 덤으로 추가할 수 있다.

여기서는 직접 간단한 ConvNet을 만들어 두 가지 작업에 응용해보았다.

1) Facial emotion recognition

학습과 예측에 사용한 데이터는 다음과 같다. [Kaggle]

  • Feature: 48 \times 48 크기의 흑백 얼굴 사진.
  • Target: 사진 속 인물의 표정(감정). 7가지 중 하나이다(neutral, fear, happy, sad, surprise, angry, disgust).
  • train set: 25120 imgs / test set: 5382 imgs

이 데이터를 학습해서 사람 표정의 어떤 부분을 보고 감정을 유추하는지를 알아보려 했다.

모형 구조와 학습에 사용한 하이퍼 파라미터는 이 노트북[1, 2]을 참고하시길 바란다.

결과를 살펴보면 꽤 그럴듯하다.

fer-1

주로 행복한 표정은 입 모양을 보고 판단하는 듯하다. 입모양이 크고 반달 모양이면 happy라고 판단할 확률이 크게 올라간다. 놀란 표정은 눈동자의 크기를 보고 판단하고 무표정은 이목구비의 전체적 형태를 보고 판단하는 듯하다.

fer-2

이 예시에서는 True class는 FEAR로 예측에는 실패했지만  SURPRISE라고 판단하는 것도 틀린 판단은 아닐 수 있다는 것을 보여준다. ConvNet이 무엇을 보고있는지를 주의 깊게 봐야하는 이유다.

2) Chest X-Ray (Pneumonia)

의료 이미지를 분석하는 경우엔 올바르게 질병 또는 정상상태를 분류하는 것도 중요하지만, 이미지의 어떤 부분(환부)을 보고 그런 판단을 내렸는지를 살펴보는 것이 매우 중요하다. 어디까지나 최종 판단은 의료 분야의 전문 종사자가 내리는 것인 만큼 전문가가 판단을 내리는 데에 도움이 되도록 뉴럴넷이 판단한 환부의 위치까지 표시해 준다면 더욱 유용할게다.

학습과 예측에 사용한 데이터는 다음과 같다. [Kaggle]

  • Feature: 다양한 크기의 흉부 엑스레이 사진.
  • Target: 폐렴인지 정상인지. [PNEUMONIA / NORMAL]
  • train set: 5216 imgs / test set: 624 imgs

데이터 학습이 용이하도록 모든 사진을 가로 256 픽셀, 세로 200 픽셀로 resize한 후 모형에 입력시켰다. 모형 구조와 학습에 사용한 하이퍼 파라미터는 이 노트북을 참고하시길 바란다 (실수로 zero-padding을 하지 않아서 이미지의 가장자리 부분의 정보 손실이 일어났다).

81%의 꽤 높은 정확도로 test set을 올바르게 진단할 수 있었다.

 

xray-1

폐렴 환자의 흉부 엑스레이 사진에서는 주로 좌폐와 우폐 사이의 공간을 유심히 살펴본 것으로 보인다.

xray-2.png

 

반면 정상 환자의 사진에서는 옆구리 부분의 흉골, 양쪽 폐 아래의 공간을 중요하게 본 듯 하다.

임상 전문가라면 뉴럴넷이 살펴본 위치를 보고 더 많은 아이디어를 얻을 수 있지 않을까?

 

참고

 

 

 

 

 

 

ConvNet (CNN) 이해하기

지난 시리즈에서는 뉴럴넷 중 가장 단순한 형태인 MLP, dense (fully connected) layer만을 사용하는 뉴럴넷과 이를 학습시키는 방법에 대해서 살펴보았다. MLP를 사용하면 효과적으로 비선형 함수를 모사할 수 있었고 이 덕분에 기존의 선형함수 기반 모형에 비해 훌륭한 성능을 낼 수 있었다.

(1) 선형 분류기
(2) 퍼셉트론과 신경망
(3) 학습에는 왕도가 없다
(4) 디테일

그러나 실제 데이터를 올바르게 분류하거나 회귀할 때에는 이보다는 복잡한 구조가 필요한 경우가 있다. 다음의 몇 가지 상황을 생각해보자.

1) MLP에서는 별도의 feature engineering 없이 raw feature 곧바로 입력층에 넣었었다. 붓꽃 데이터, 또는 데이터의 차원이 크지 않은 경우에는 raw feature를 전부 사용해도 모형의 파라미터 수가 크지 않았기 때문에 학습 과정에서 문제가 생기지 않았고 성능도 좋았지만, 이미지와 같은 데이터에서는 문제가 달라진다.

이미지 데이터를 예시로 들어보자. 가로 48픽셀, 세로 48픽셀의 컬러(RGB) 이미지 데이터를 생각해보자. 이미지의 각각의 픽셀을 하나의 feature 사용해서 MLP 입력층에 넣을 있을 것이다. 이렇게 feature engineering 없이 픽셀의 raw value 전부 입력으로 넣는다면, 뉴럴넷이 감당해야 하는 feature 차원수는 48 \times 48 \times 3 = 6912 된다. 겨우 가로세로 48픽셀밖에 안되는 저화질 이미지였는데도 feature 차원이 7000 달한다. Feature 갯수가 이렇게 많아지게 되면 컴퓨팅 속도가 저하되고 오버피팅의 위험이 생길 있다.

2) MLP에서는 샘플이 등장한 맥락을 고려하지 않았다. , 샘플들이 정렬되어 있는 순서가 중요하지 않았다. 그러나 주식 일별 종가, 문장 속 단어와 같은 데이터에서는 각 샘플의 앞 뒤로 어떤 샘플들이 있었는지의 정보(‘문맥’)도 중요하다. 이 경우엔 MLP만으로는 충분히 좋은 성능을 발휘할 수 없다.

이번 시리즈에서는 전통적인 dense layer 외에 이미지 등의 데이터를 처리하기 위해 새로이 고안된 뉴럴넷의 레이어에 대해서 살펴보고자 한다. 시작은 convolutional neural network (CNN; ConvNet) 구성하는 레이어들이다.

 

  • 2-D CONV layer
    • Convolution 연산
    • 수학/신호처리학적 의미
  • RELU layer
  • POOL layer
  • 일반적인 ConvNet 구조
  • ConvNet 개선하기
    • 1×1 convolution (InceptionNet)
    • Dense CONV 표현하기
    • 변형된 convolution

 

Convolutional (CONV) layer

앞의 예시에서 이미지의 픽셀을 그대로 feature 사용하는 것은 좋지 않은 방법이라는 것을 언급했었다. 대신 이미지로부터 독특한 특성만을 뽑아내어 feature 사용한다면 좋은 성능을 있을 것이다. 과정을 feature extraction이라고 하고, 이미지에서 feature extractor 동작하는 레이어가 바로 convolutional layer이다.

Convolutional layer 가지 가정을 전제로 한다.

  1. Local connectivity: 이전 레이어의 모든 뉴런과 연결되는 MLP에서와는 달리 CONV layer는 이전 레이어의 뉴런 중 일부와만 연결된다. 즉 이미지의 모든 픽셀과 연결되는 대신 이미지 중 일부분의 픽셀과만 연결된다.
  2. Spatial invariance: 이미지의 한 부분의 데이터 분포는 다른 부분에서의 데이터 분포와 다르지 않다. , 이미지의 분포적인 특성은 어느 부위에서든 동일하다고 가정하는 것이다.

Dense layer에서 입력 샘플을 1차원의 벡터 데이터로 보았다면, Convolutional layer 입력 샘플을 3차원의 텐서(Tensor) 데이터로 인식한다. Convolutional layer 입력 3차원 데이터를 적절히 변형해서 또다른 3차원 데이터를 출력한다.

스케치

Convolutional layer 하는 일을 자세히 살펴보자.

  1. 먼저 이미지에서 특징적인 부분을 추출하는 데에 사용될 필터(또는 커널)가 정의되어야 한다. 필터 크기는 이미지 크기보다 작거나 같다. 필터는 인풋 이미지를 시작부터 끝까지 차례차례 훑으면서(마치 sliding window처럼) 이미지 픽셀 값에 필터 값을 곱해 더한 값을 출력한다.
  2. 필터가 이미지를 얼마나 자세히 훑으면서 지나갈지를 결정해야한다. 이것을 stride라고 한다. Stride 1로 정의된 경우, 필터는 이미지 위를 한 번에 한 픽셀씩 이동하면서 자세히 훑는다. Stride 10으로 정의된 경우, 필터는 이미지 위를 한 번에 10픽셀씩 이동하면서 대충 훑는다. (가로방향 stride와 세로방향 stride를 다르게 설정할 수도 있다)

스케치

f_{ij}는 필터의 ij열 값, x_{ij}는 인풋 이미지의 ij열 값이다.

convolutional layer는 필터를 일정 간격씩 이미지 위에서 이동시키면서 필터 값을 이미지 픽셀값에 곱하여 더한 값을 출력한다. 출력된 feature map의 픽셀 하나는 인풋 이미지 중 3×3만큼의 정보를 바탕으로 결정된 값이다. feature map receptive field 크기는 3×3이 된다는 뜻이다. 인풋 이미지 중 3×3만큼을보고‘ Feature map의 픽셀 하나의 값을 계산했다는 의미다.

애니메이션으로 살펴보면 이해가 쉽다. 파란색은 인풋 이미지, 초록색은 필터이다.

1*VVvdh-BUKFh2pwDD0kPeRA@2x

초록색 필터가 이미지를 칸씩(stride=1) 돌아다니면서 곱의 합을 출력하는 것을 있다. 이렇게 출력된 (convolved feature 또는 feature map; 붉은색) 추출된 이미지의 특징이라고 생각하여 feature 사용할 있다.

필터 하나 하나의 feature map 만들어지므로, 필터 n개를 사용하는 CONV layer 출력은 depth=n 갖는 텐서가 된다. 만약 32×32짜리 컬러(depth=3) 이미지 하나가 필터 10개를 사용하는 CONV layer 통과하면 출력 depth 10 된다.

1*BSLjlJf31gj98ABJMCt3-g@2x

수학/신호처리학에서의 cross-correlation

주의해야할 것은 수학에서 정의하는 convolution 연산과는 다른 연산이라는 것이다. 오히려 뉴럴넷에서의 convolution 연산은 수학/신호처리에서의 cross-correlation 같다.

신호처리에서 cross-correlation은 두 신호간의 유사성을 잴 때에 사용되는 연산이라고 한다. 때문에 뉴럴넷에서의 convolution convolution filter input image 사이의 유사성을 측정해서 출력하는 연산이라고 생각할 수 있다. 필터와 이미지의 패턴이 유사하다면 절대값이 큰 값을, 그렇지 않다면 작은 값을 반환하는 것이다.

예를 들어, 아래처럼 우상에서 좌하로 향하는 사선 모양의 convolution filter는 이미지 내에서 사선 모양이 있는 부분(주로 이미지의 윤곽선)을 보면 큰 값을 출력한다. 아래 돌고래 이미지에서 우상좌하 사선 모양의 윤곽선이 도드라지게 추출된 것을 확인할 수 있다.

실제 ConvNet에서는 필터를 우리가 직접 정해주지 않고 알고리즘이 데이터를 바탕으로 문제 해결에 적합한 형태가 되도록 학습해나간다.

Zero padding

이미지에 필터를 적용할 때, 아무리 촘촘히(stride=1) convolution을 해도 출력된 feature map의 가로세로 크기는 원본 이미지에 비해 반드시 작아질 수 밖에 없다. 원본 이미지와 가로세로 크기가 같은 feature map을 얻기 위해서는 필터를 적용하기 전에 입력 이미지에 처리를 해주어야 한다.

1*W2D564Gkad9lj3_6t9I2PA@2x

단순하고도 널리 사용되는 방법이 바로 zero padding, 즉 원본 이미지의 상하좌우를 0값으로 둘러싸는(padding) 방법이다. 아무 정보가 없는 0값으로 이미지를 패딩함으로써 feature map의 가로세로 크기를 인풋과 같게 유지하면서 convolution layer를 깊게 쌓을 수 있다.

 

ReLU layer

CONV layer 통해서 이미지로부터 추출한 feature map에서 양의 값만을 활성화시키는 레이어다. ReLU layer에서는 feature map에서 특히나 두드러지는 특징을 다시 추출한다.

사실 별도의 layer라고 칭하기는 뭣하고, CONV layer activation function으로 ReLU 사용한 것이라 이해하면 쉽다.

output_19_0

ReLU activation 적용 후 우상좌하 사선 모양의 윤곽선이 매우 잘 추출되었다.

 

POOL layer

수많은 이미지를 처리하는 과정에서 필연적으로 맞딱뜨릴 수 밖에 없는 것이 바로 메모리 문제다. 특히나 CONV layer는 원본 이미지의 가로세로 크기를 유지하면서 depth를 수백~수천 수준으로 키우기 때문에 메모리를 많이 먹는 레이어다. 이때문에 이미지와 feature map의 가로세로 크기를, 특징은 유지하되 적절한 수준으로 다운샘플링하여 메모리를 절약할 필요가 있다. 다운샘플링 방법 중 ConvNet에서는 pooling을 사용한다.

가장 빈번히 사용되는 풀링은 max pooling이다. Max pooling pool region 내에서 가장 수치가 위치의 값만을 가져온다.

1*GksqN5XY8HPpIddm5wzm7A

2×2 pool size, stride 2 max pooling 적용한 모습이다. 2×2 pool region 내에서 가장 수치가 값만을 샘플링한 것을 있다.

Weakly-supervised localization 등의 문제를 해결할 때에는 average pooling 사용하기도 한다. Average pooling 해당 pool region 내의 모든 값을 평균내어 가져온다.

돌고래 이미지의 예시에 2×2 max pooling (stride 2) 적용한 결과, 아래와 같이 feature map 특징은 유지하면서 이미지 크기를 1/4 축소할 있었다.

output_20_0

 

ConvNet 일반적인 구조

일반적으로 ConvNet의 구조는 다음과 같이 표현할 수 있다.

\{(CONV + RELU) \times n + POOL \} \times m + (Dense \times k)

여기서 CONV + RELU + POOL feature extractor 역할을 하고 Dense layer classifier 또는 regressor 역할을 한다. 이미지 분류 문제를 예시로 들자면, CONV + RELU + POOL 인풋 이미지로부터 분류에 사용할만한 특징적인 feature 추출하고 Dense layer 추출된 feature 입력받아 이미지를 적당한 카테고리로 분류한다.

이 때 얕은(입력층에 가까운) CONV layer일수록 단순한 특성윤곽선, 음영 등을 추출하고 깊은(출력층에 가까운) CONV layer일수록 복잡한 특성동물 모양, 특정 색상 조합 등을 추출한다.

2012 ILSVRC에서 우승한 AlexNet이 유행시킨 구조라 할 수 있겠다. 딥러닝을 사용해서 효과적으로 이미지를 분석할 수 있다는 것을 보여준 첫 사례다.

1*qyc21qM0oxWEuRaj-XJKcw

그림에서 있듯, 5개의 CONV layer 3개의 dense layer 사용하여 최종적으로 1000 카테고리에 대한 softmax 값을 출력한다. AlexNet 대해서는 이후 기회가 자세히 다루도록 한다.

 

ConvNet 개선하기

1×1 convolution

어느 모형에서나 파라미터 수가 지나치게 많아지는 것은 overfitting 컴퓨팅 속도 저하를 의미하기에 좋지 않다. convolution 연산에 사용되는 파라미터 (필터값 ) 줄이기 위해서 1×1, 1xn 또는 nx1 convolution 사용할 있다.

n \times n \times 3 형태의 인풋 이미지에 receptive field 3×3 되도록, 128개의 필터를 사용해서 convolution 한다고 가정해보자. 단순히 3×3 filter 사용할 수도 있다. 경우 필요한 파라미터 수는 3 \times 3 \times 3 \times 128 = 3456개이다.

반면 1×1 > 1×3 > 3×1 순서로 convolution 한다면? 필요한 파라미터 수는 (3 \times 1 \times 1 \times 128) + (1 \times 1 \times 3 \times 128) + (1 \times 3 \times 1 \times 128) = 384 + 384 + 384 = 1152 뿐이다. 같은 크기의 receptive field 유지하면서 파라미터 수를 거의 1/3 수준으로 줄였다!

inception-v4-fig-5

구글에서 개발한 GoogLeNet에서 바로 이 방법을 활용한 Inception 구조를 사용한다.

Dense layer CONV layer 표현하기

Dense layer CONV layer 차이점은 local connection 뿐이다. Dense layer에서는 이전 레이어의 모든 뉴런이 다음 레이어의 모든 뉴런과 연결되어 있는 반면(그래서 fully connected layer라고도 불린다), CONV layer에서는 이전 레이어의 일부분만이 다음 레이어의 뉴런과 연결되어 있다.

그럼 CONV layer에서 이전 레이어의 모든 뉴런을 다음 레이어와 연결시킨다면? 즉 인풋 이미지의 일부분에만 필터를 적용시키지 않고 이미지 전체에 이미지와 동일한 크기의 필터를 적용시킨다면? Dense layer와 동일한 연산을 하는 CONV layer를 만들 수 있다. 계산해보면 파라미터 수도 일치한다.

스케치

Dense layer CONV layer로 대체함으로써 인풋 이미지 크기를 고정하지 않아도 된다는 이익을 얻을 수 있다. 사전에 정의된 크기의 이미지를 인풋하지 않으면 오류를 뿜는 Dense layer와는 달리, CONV layer는 사전 정의된 것보다 큰 이미지를 인풋해도 오류 없이 연산을 해낸다. (다만 3차원 텐서 형태로 출력하기는 한다)

1*wRkj6lsQ5ckExB5BoYkrZg

Fully Convolutional Network (FCN)이 바로 이 구조를 처음 제안한 모형이다.

특수한 Convolution

외에도 위에서 정의한 것과는 다른, 서로다른 문제에 특화된 특수한 convolution 사용할 수도 있다. 예를 들어 atrous convolution 구멍이 숭숭 뚫린 듯한 모양의 필터를 사용해서 receptive field 더욱 향상시킨다. Deconvolution Convolution 연산을 역으로 수행해 추출된 feature map 원본 이미지에 가까운 형태로 되돌린다.

특수한 convolution 연산들에 대해서는  페이지를 참고하면 좋다.

 

참고