본문 바로가기
딥러닝

컴퓨터 비전에서 딥러닝은 어떻게 활용될까?

by 볼록티 2021. 5. 5.
728x90
반응형

 

 CNN 은 이미지를 다루는데 적합한 딥러닝 알고리즘이라는 것을 배웠다. 이러한 이미지를 전문적으로 다루는 Computer vision 영역의 문제에서 딥러닝이 어떻게 활용이 될까? 

 

대표적인 task 에 대해서 살펴보도록 하자.

 

 

다룰 내용은 크게 3가지로 구분된다.

1. Transfer Learning

2. Object Detection

3. Semantic Segmentation

 

 


 

* 1. Transfer Learning

CNN 을 이용해서 이미지를 분류하면 잘 된다고 알고 있다. 그 이유증에 하나는 사람이 시각적인 정보를 처리할 때 여러 hierarchy 과정을 겪게 된다. NN 의 레이어가 사람의 그 과정을 hierarchy 하게 모사할 수 있기 때문이다. 즉, 사람은 이미지 객체 인식에 있어서 낮은 단위의 low level 의 feature 들을 인지하게 된다. 

 경계를 나타내는 엣지, 색깔 등을 뽑아내고, 이를 기반으로 작은 part 정보들을 인식한다. 이로써 추상화된 객체단위를 인식할 수 있다. 이 때, CNN 은 이러한 feature 의 hierarchy를 학습할 수 있기 때문이다.

 이미지에 들어있는 시각정보라는게 개, 고양이를 인지하는 것에 있어서 전부 공유가 되게 된다. 즉, CNN 으로 생성된 feature 가 다른 Task 에도 충분히 적용이 가능하게 된다. 대부분의 딥러닝 어플리케이션에서 활용을 하고 있다.

 

 

 

 기초적인 transfer learning 의 방법을 알아보자.

 ImageNet 이라는 CNN 모델로 학습된 게 있으면, 이 모델의 feature 를 다른 Task 에 재활용하자는 것이다.

가장 기초적인 방법은 CNN 모델 자체를 feature extractor 로 사용하는 것이다. 위의 그림의 왼쪽을 보면 1000개의 클래스를 분류하는 것을 알 수 있다. 이 때, 특정 다른 데이터셋을 가지고 분류기를 만들고 싶다면, 이미 CNN 으로 학습된 layer 들을 가져와서 즉 학습된 모델의 feature를 가져와서 사용한다(Freeze these 부분). 그리고 뒤에 위치한 분류를 하는 부분인 classifier 부분만 학습하면된다. 이것이 두번째 그림이 나타내는 것이다. 

 즉, 미리 학습한 CNN 모델의 feature 를 활용하는 것이라 할 수 있겠다.

 

 또다른 방법은 위 그림에서 3번을 나타낸다. 마찬가지로 학습된 CNN 의 low level의 feature인 부분(Freeze these 부분)은 그대로 가져오게 된다. 뒤에 해당되는 것은 랜덤하게 초기화를 시켜준다. 그런 다음에 전체 layer들에 대해서 새로운 데이터셋에 대하여 전체적으로 학습을 시키는 것이다. 이것이 finetuning 이다. 보통은 가져온 layer 에 잇는 weight 에 대해서는 Learning rate 를 작게 주고( 대충 0.001), 새로 초기화하는 부분은 0.1정도로 더 크게 줌으로써 좀 더 특화시켜서 학습을 할 수 있게 한다.

 실험적으로 큰 데이터를 토대로 학습한 모델을 가져와서 내가 가진 데이터셋에 적용을 했을 때 더 좋은 성능을 낸다는 것은 이미 많이 알려져 있다. 이미지에 대해서는 재활용이 아주 잘 활용이 된다.

 

 

 이 Transfer learning 가 중요한 이유는 고차원적인 인지기능과 같은 Task 에 대해서는 universal 한 feature 가 존재할 거라는 가정하에 존재한다. 사람이 학습하고 추상화하고 하는 과정을 생각해보면, 지도학습만으로 이뤄지는 것이 아니다. 다양한 사물을 보며 인지능력을 길러가는 학습과정을 생각해보면, 개, 고양이를 수십만장보여줘서 아는 것은 아니지 않나와 같은 이야기다. 즉 비지도 학습에 가깝다는 것이다. 관찰하는 것만으로도 이미 분류를 하는 feature 가 머리속에 박혀지게 되는 것이다.

 

 

 Transfer learning 를 먼저 설명하는 이유는 Object detection이나 Semantic segmentation Task 에서 빠르게 성장할 수 있던이유는 이미지로 학습된 Transfer learning을 적용했기에 그런 것이다.

 

 이제 Object detection에 대해서 살펴보도록하자. 지금까지 배운 것은 분류 정도였다. 아래 그림의 왼쪽 그림이다. 224x224x3 이 들어가면 1000개의 클래스에 대한 예측값을 얻게 된다. 지금까지는 이미지를 받아서 예측값 label 을 뱉는 것이었다면, 이제는 이에 그치지 않는다. 

 오른쪽 그림을 보면 첫번째, 이미지가 들어왔을 때 어떤 특정 사물을 검출하는 경우나, 같은 이미지를 갖는 객체를 분할하는 이러한 task 들이 존재한다. 그래서 첫번째가 Object detection이고, 두번째가 Semantic segmentation 이 된다. 

 

 

 그렇다면 Computer vision에서 다루고 있는 문제는 어떤게 있을까? 

 간단히 용어 정리를 하고 넘어가보자.

 먼저 첫번째로 가장 기본적인 것인데, 아래의 고양이 사진이 있는데 빨간 박스가 쳐진 부분이다. Classification + Localization 이 있는데 Object detection하고 똑같은거 같은데 이 Computer vision에서는 다르게 본다. 즉 Object Localization에서는 입력으로 들어오는 이미지에서 위치를 검출해야하는 Object가 단 하나만 존재할때를 말한다. 아래의 그림처럼 고양이만 하나 검출한 것을 알 수 있다. 

 Object detection은 이미지에 여러가지 object들이 여러개 존재할 수 있는 input 에 대해 개별적으로 검출하는 Task를 말한다.

Semantic Segmentation은 Task는 객체가 존재하는 위치가 가지는 의미 정보가 같은 영역을 분할하는 문제이다. Instance Segmentation은 Object detection과 비슷하다. 대신에 박스가 아니라 객체의 영역(boundary)를 분할하는 Task라고 생각하면 된다. 두 Segmentation의 차이를 보면, Instance Segmentation의 두 DOG는 Semantic Segmentation에서는 동일한 영역으로 묶일 것이라는 것이다..

 

 

CS231n lecture slides

 

 

* Object Localization

 Object Detection으로 가기전에 기초적인 배경지식을 짚고 넘어가보도록 하자.

이제는 Detection 에 대해서 살펴볼 것이다. 딥러닝 알고리즘들은 직관적인 방법들로 인해서 꾸준히 발전되어 왔다. 그래서 발전되는 흐름을 이해하면서 가는 것이 중요하다. 그래야 최신 논문이 나와도 흐름을 놓치지 않고 받아들일 수 있다.

 

먼저 지금까지는 Object recognition 같은 경우는 단순히 분류를 하는 문제였다. $x$는 이미지이고 $y$는 $x$의 label이다. 

 

 Object Localization에서는 단순히 이미지를 분류하는게 아니라, 아래의 그림처럼 이미지 안에 고양이가 있고, 이 위치가 여기입니다 하고 박스 좌표를 예측을 해야한다. 그러니 박스 좌표에 대해서 가르쳐줄 데이터가 필요하다.  

 그러니 아래의 $l_{i}$는 class 가 된다. 뒤에 $x,y,w,j$ 는 객체의 위치정보를 알려주는 좌표정보 label 이다. 이런 데이터를 학습시켜서 이 객체는 무엇이고, 그 위치는 어디인지를 예측할 수 있도록 모델을 만들어간다. 아래의 박스를 보면, $(x_{i}, y_{i}$ 는 왼쪽 상단 좌표를 의미하고, $w_{i}, h_{i}$는 각각 너비와 높이를 의미한다. 좌상단 우하단의 두 좌표가 주어지더라도 역시 가능하다.

 

 객체가 무엇이고, 좌표는 어디인지를 어떻게 학습을 시켜야할까?

 

 기존에는 단순히 input 주고 output 을 내고 true 랑 비교해서 loss 구해서 BP 하는 단순한 방법이었다.

 그렇다면 쉽게 생각해보면 이 Task 에서는 달라진 것은 예측해야할 label 이 더 생긴 것 뿐이다. 이제 좌표도 예측을 해야하는데 좀 디테일하게 보면, 아래의 그림처럼 고양이 이미지가 들어가고 CNN 레이어들을 거친다. 그 다음에 dense layer를 쌓아서 classification을 진행했었다. 아래의 노란 벡터가 classification 을 하는 부분이고, 이 밑에 또다른 layer를 쌓아서 좌표를 예측하도록 모델을 구성했다. 그런 다음에 실제 값과 비교해서 학습을 한다. classification 문제에 대해서는 cross-entropy loss를 활용해서 학습을 시키고, 좌표를 예측하는 부분에 대해서는 좌표는 연속적인 continuous 니까 loss 인 MSE(Gaussian log-likelihood와 동일.)를 가지고 학습을 시키면 된다.

 직관적인 방법이라는 것을 알 수 있다. !

이게 Object Localization 을 학습하기 위한 가장 직관적인 방법이었다.

CS282A lecture slide

 

 이 후에는 기본적인 접근방법에서 문제가 될만한 부분들을 해결해나가는 것이라고 생각하면 된다.

최근 연구의 결과물들을 보면 복잡하고 심오한게 들어가있는것 같지만, 방금 위에서 본 직관적인 접근에서 출발을 하게 된다.

 

 

이어서, 잘 localization 했는지 측정하는 performance measure를 측정하는 법을 알아보자. classification 은 알고 있으니 넘어가도록 하자.

 localization 모델이 잘 localization 했는지를 평가하려면 Accuracy 개념에다가 잘 localization했는지의 개념을 합친 것이라고 생각하면 된다..

 

아래의 그림처럼 고양이 이미지가 들어오고 학습모델을 거쳐서 output 이 출력되면 아래와 같이 객체 분류 예측값과 좌표 예측값이 등장한다. 좌표 예측값은 곧 bounding box라 한다. 이렇게 두 가지를 예측하게 된다.

 그러면 얼마나 잘 탐지했는가를 평가하기 위한 지표로 IOU(Intersection Over Union) 를 사용한다. 말그대로 true 의 box와 예측한 box가 있다면, 아래의 그림을 보면 빨간게 실제 box 이고, 보라색이 예측한 box이다. 그러면 이 두개가 많이 겹치면 겹칠수록 localization을 잘 한 것이 된다. 즉 교집합 면적을 합집합의 면적으로 나누는 직관적인 measure이다. 많이 겹치면 겹칠수록 1에 가까워지고, 안겹칠수록 0에 가까워지게 된다. 

 얼마나 겹쳐야 제대로 localization 잘 했다고 볼 수 있는가? 는 보통 0.5 를 기준으로 잡는다. 아래의 설명을 죽 보면은 IOU값이 0.5 보다 크면서 분류에 성공하면 correct 라고 친다. 이것이 바로 True Positive 가 된다. 

CS282A lecture slides

 

 

 

localization 을 하는 가장 나이브한 방법을 살펴보았다. 여기엔 문제가 있는데, 전체 이미지가 들어오고 나서 분류도 하고 box 좌표도 예측하는데, 전체적인 이미지를 입력으로 주면서 어떤 object가 있느냐라고 묻는것은 좀 어려운 Task이다. 왜냐하면 기존의 구조를 보면 아래의 그림처럼 Conv layer가 쌓여서 feature map을 형성한다고 치고 이거를 flatten해서 일렬로 죽나열해서 dense layer에 연결하게 되는데, 이말인 즉슨, 최종 나오는 output 들은 그냥 input 정보를 한꺼번에 취합을 해서 예측을 하겠다는 것이다. 

 classification 하는데는 상관없지만, 객체의 위치를 localization하는 경우에는 이미지의 위치정보를 하나로 뭉갠다음에 예측을 수행하면 한계가 발생하게 된다.

 

고양이가 있는지 없는지를 맞추는 문제가 있다고 해보자.  input 이미지에서 다양한 위치에 다양한 크기의 패치(patch)를 뜯는다. 그리고 그 패치를 고양이 분류기에다가 넣어준다.

아래의 그림을 보면, 첫번째 고양이 전체 이미지가 있는 이미지를 넣어서 학습하게 하지말고, 빨간 보라 box 처럼 패치를 뜯는다. 그런다음에 고양이 분류 모델에 넣어준다. 두번째 사진을 보면 분류기에서는 고양이라고 예측이 되지 않는다. 즉 아~ 여기는 고양이가 없구나. 하게 된다. 하지만 보라색 box를 분류기에 넣으면 고양이라고 예측을 하게 된다. 그러면 여기에는 고양이가 있구나~ 하게 된다. 이렇게 자연스럽게 localization 을 할 수 있다. 고양이일 확률이 가장 높게 나타나는 input의 패치가 바로 그 객체가 존재하는 영역이 된다. 이렇게 패치를 뜯어서 하는 방법을 Sliding Windows 한다고 한다. 

 

CS282A lecture

 

 

맨처음 localization 하는 방법을 제안하는 방법이 OverFeat 방법이 있다. 이 방법이 바로 위에서 설명한 방법이다. 아래의 그림처럼 box 좌표와 classification 결과를 토대로 객체의 위치를 찾게 된다. 

 cat 이라는 확률이 높은 곳의 패치가 존재하면 그 패치를 고양이가 존재하는 box라는 직관적인 아이디어이다. 

 

 

CS282A lecture

 

 

이러한 접근 방법의 문제점은 무엇일까. 

고양이가 위의 보라색 box처럼이 아니라 부분부분이상 하게 패치가 생성되서 input 으로 들어가는 경우, 혹은 패치가 너무 많아서 학습이 너무 오래걸리거나 하는 문제들이 있다. 뭐 결국 효율성의 문제이다. input 이미지에서 뜯을 수 있는 패치는 정말 많은데, 정해진 개수만큼의 rule 기반으로 뜯어야할텐데 그래도 많은 것이다. 

 

 

 

그러면 실제에서 어떻게 작동하는지 아래의 그림을 통해 살펴보자. sliding window 기반으로 input 이미지의 특정 영역에 대해서 classification모델에 넣어서 output을 계속 뽑는다. 그 특정 영역마다 output 을 다 뽑기 때문에 input 패치에 대해서 곰일 확률에 대해서 알수 있고, 그걸 가지고  아래 그림처럼 곰이라는 class에 대한 확률맵을 그릴 수 있게 된다. 그리고 overfeat 방법은 예측말고 다른쪽에서는 box 좌표를 예측하는 부분이 존재한다고 했는데, 이 부분이 약간 correction 해주는 효과가 있다. 

 

 

 

 

 입력 패치가 들어가면 곰일 확률인지를 뽑고, 다른 쪽에서는 좌표 예측값을 뽑고, 그런 다음 output을 다 그려보면 아래의 그림처럼 표현된다. 실제 곰이 위치하는 영역에서 곰이라는 확률값이 높게 나타나는 것을 알 수 있다. 그러면 실제로 곰이라고 예측한 yellow box가 많이 존재 하게 된다. 

 

 

그런 다음 후처리를 통해서 하나의 single box만을 남기게 된다. 

 

 

 

 

그런데 여기서 문제는 패치를 뜯어서 forward 하고 이것을 반복하면 너무 연산량이 많다는 것이다.

CNN 의 특성상 

이전 방법들은 똑같은 연산을 많이 반복하는 구조이다. 그래서 Window가 중첩된 부분은 input pixel 값은 다 똑같은데 왜 반복해서 계산을 하느냐. 이부분에 대해서는 연산을 재활용해보자라는 아이디어에서 나온것이 Reusing Calculation 아이디어를 내게 된다. 

 

 

 이거를 가능하게 해주는게 NN의 layer를 Conv layer로 구성을 하는 것이다. Receptive field 라는 개념을 전에 CNN에서 보았는데 상기해보도록 하자. 그리고 Conv layer가 쌓여 있으면, 마지막에 feature map을 얻게 되는데, 그 feature map과 input 이미지 간의 어떤 관계가 있는지 살펴보도록 하자.

 아래의 그림처럼 이미지가 들어오고 첫번째, 두번째, ... Conv layer를 계속 거치면 마지막에 아래의 그림의 가장 오른쪽과 같은 feature map을 얻었다고 해보자. 그러면 Conv 연산의 특성상 이 feature map에 특정 위치에 존재하는 벡터인 height, width 이 dimension에서 존재하는 특정한 위치, 그 위치에 해당되는 channel 축으로 나열된 벡터. 이 벡터는 input 의 어떤 영역을 보고 conv 한 결과인지 거꾸로 계산할 수 있다.

 그림에서 가장 오른쪽의 갈색 feature 벡터는 곧 예를 들면, 1 x 1 x Channel 가 된다. height, width에서는 단순히 하나의 위치에 해당되고, 이 위치에 channel 축으로 나열된 벡터는 곧 input 이미지의 하나의 빨간 패치 box에 해당된다. 

 좀 더 간단히 말하면 최종 output 은 자기가 맡은 input 영역의 receptive field가 딱 정해져 있다는 것이다.

 

 

 

 input 의 패치를 뜯어서 각각에 대해서 Conv 하지 말고 전체를 넣고 나오는 feature map에서 특정 위치에 해당하는 벡터를 뽑아서 그 이후에 연산을 수행하게 되면, 앞에서 뜯을때마다 forward하는 것을 한방에 처리할 수 있다는 아이디어이다.

 아래의 간단한 예를 통해서 알아보자. input 이 14x14가 들어가고 5x5 Conv가 진행되면 10x10이 되고 풀링하면 5x5되고 Conv하면 1x1 되고 conv 1x1, conv 1x1 하면 output 이 1x1이 된다. 모든 layer가 Conv layer라는 것이 좀 다른 점이긴 하다.

 만약 그 아래의 16x16을 넣는다고 해보자. 마찬가지로 Conv layer만을 모두 거치고 나면 2x2 로 나오게 된다.

이제 첫번째 14x14 를 넣어서 나오는 1x1 output은 16x16영역에 위치시킨 다음에 Network에 집어넣게 되면, 2x2 output이 나오고 2x2 output의 파란색 부분이 앞선 1x1 과 같을 수 밖에 없다는 말이다. 

 

2x2 output은 16x16 input 에 대해 아래와 같이 표현된 것이라고 생각하면 된다. 이런식으로 Conv 는 parameter 를 sharing 해서 sliding window하면서 연산하는 것으로 이해하면되니, input 의 크기에 따라서 output 이 가변적이고 output의 특정 위치의 값은 input의 특정 패치의 영역을 바라보고 있고 그곳에 대한 Conv 결과라고 생각하면된다.

16x16 이미지에서 14x14 패치를 4군데에서 뜯는다고 해보면, 14x14 input 을 넣는 연산을 4번을 수행해야한다. 그래야 2x2로 각각의 값을 얻을 수 있다. 그렇게 4번해서 나온 결과나 16x16을 한번 넣어서 나오는 결과나 같을 수 밖에 없다는 말이니 앞서 패치를 뜯어서 각각 forward시키는 일은 없게 된다는 것이다.

 마지막 output이 2x2인데 과연 이 픽셀간의 거리는 실제 input 에서는 얼마나 떨어져 있는건지는 Network 에서 stride에 따라서 결정이 되게 된다.

 

 

 


 

 

 

* 2. Object Detection

 

지금까지 이미지를 localization 하는 문제를 살펴보았다.

 

이제 Object Detection에 대해 어떤 방법들이 제안이 되었는지 살펴보도록 하자.

 

딥러닝 기반의 Object Detection 모델은 크게 두 종류로 구분한다. 첫번째가 single stage 방법이 있고, two stage 방법이 있다. 여기서는 two stage 에 대해서만 설명한다. single stage 방법은 앞선 개념의 이해로 충분히 이해가 가능하기 때문이다.

 

two stage 는 크게 두 과정으로 나뉜다. 첫번째는 이미지가 어떤 영역에 object가 있을 것 같은지 영역을 추천하는 부분. 그리고 두번째는 추천된 그 영역에 실제로 어떤 object가 있는지 분류를 하는 두 과정으로 나뉜다.

어느정도의 위치에 있을 것이다 라고 추천하는 것을 proposal 이라고 부른다. 특히나 Region proposal이라고 부르며, 이렇게 proposal 된 region에서 딥러닝 모델이 classification을 수행하게 된다.

아래의 그림을 보면 말을 탄 남자와 같은 이미지가 들어왔다면, object가 어디에 있을 것 같은지 그런 패치들을 추천하게 된다. 노란색 박스처럼 말이다. 그다음 적당히 사이즈를 조정해서 classification 모델에 집어 넣는다. 그러면 class를 알수 있게 된다. 이 과정을 통해서 객체의 위치와 종류를 검출을 할 수 있게 된다. 

 

CMP784

 

 

위와 같은 Region proposal 기반의 가장 시초가 되는 연구가 바로 R-CNN(2014) 이다. 

이미지가 들어오면, 먼저 object가 있을 것 같은 위치를 추천받는다. 어느위치에 있을 법한가는 아래의 1번에 나와있는 것 처럼 Selective search, Edge Boxes, MCG 등과 같은 이미지처리 기반의 방법을 이용해서 다음 그림과 같이 object가 있을 것 같은 위치들을 쫙 찾아내게 된다. 노란, 빨간, 초록, 보라 패치가 바로 그것이다. 그다음 이 패치들을 뜯어가지고 CNN에 넣을 수 있게 사이즈 조정한 다음에 output으로 분류를 진행한다. 여기서는 1-vs-rest SVMs 를 붙였고, 박스의 좌표를 미세조정하는 Box regressor 가 장착되어 있는 것을 알 수 있다. 이것은 앞서 보았던 프로세스랑 유사한 것을 알 수 있다. 

 입력이 들어오면 패치를 뜯고, resize한다음에 classification 모델에 집어 넣는 과정을 거치는데 여기서 !
-> 단점은 계산복잡성의 문제! 예를 들어 패치가 2000개가 나오면 그거를 다 forwarding 해야 하는 효율성의 문제이다. 

 

CMP784

 

 위의 단점은 패치를 각각 뜯어서 output을 뽑는 것으로부터 시작되는데, 이를 해결하기 위해서 등장한 것이 아래의 Fast R-CNN(2015) 이다.  위의 그림의 3번을 앞으로 보내버림으로써 해결한다. 그렇게 해서 전체가 Conv로 이뤄진것을 이미지를 한번에 집어넣는다. 그러면 적당한 크기의 feature map 이 나온다. 아래의 추가된 큰 텐서가 그림이 그것이다.

 input 패치의 하나의 output이 아래의 feature map의 한 셀이라고 생각하면 된다.

 이렇게 한번에 전체 이미지에 대한 output을 뽑아놓고, 'Selective search, Edge Boxes, MCG'로 찾은 Box(빨,초,노,보) 에 해당하는 feature 를 바로위의 feature map에서 가져오는 것이다. 이것을 뒤에서하나 앞에서하나 본질적으로는 동일하다고 할 수 있다. 그래서 RoIPooling을 통해서 이 feature map에 Box에 해당하는 부분을 가져와서 분류만 하게 된다. 이런식으로 파이프라인으로 구성하게 되면, input 이미지 하나에 대해서 object detection 결과를 뽑는데 있어서 evaluation 을 한 번만 하면 된다. 한번 딱! 하면 여러개의 object들을 한번에 detection할 수 있게 된다.

 

Fast R-CNN(2015)

 

그렇다면 위의 RoIPool 은 과연 무엇일까? 간단한 아이디어이다. 앞에서 보았듯이 먼저 Box를 찾는다. 그다음에 Box에 해당되는 input 패치를 뜯는다. 근데 그 Box가 항상 정사각형이 아니다. 이것을 같은 크기로 network에 넣기 위해서 resize를 한다. 이 resize를 feature map level에서 하는게 RoIPooling이라고 이해하면 된다.

 

 아래에는 위의 Fast R-CNN 의 RoIPool 부분을 자세히 설명한다. 

 input 이 들어오면 FCN(Fully Connected Network)를 거쳐서 feature map을 뽑았다고 해보자. 아래의 모눈종이 전체 부분(빨간색 친 부분)이 곧 위의 텐서라 말했던 feature map이다.

 그 다음에 밑에 다른 한쪽 부분에서는 Box를 찾는데, 이 Box위치를 feature map 에다가 projection할 수 있을 것이다. 어차피 feature map이 가진 special resolution은 그대로 보존하니까 이렇게 알고리즘으로 찾은 feature 넓이 그대로 투영을 시키는 것이다. 그게 바로 아래의 가운데 노란 Box가 얹어진 그림이다(Snapped RoI: 파란색으로 친 부분). 

 그런데 featuren map 은 input 이미지에 해상도에 비하면 훨씬 down sampling 이 되어있다. 그럼 input 에서 찾은 Box의 꼭지점이 feature map에 딱 맞지 않을 수 있다. 그러면 그냥 가까운대로 붙인다. 그러면 이제 파란색 부분을 feature max의 가까운 모서리에 딱 맞아떨어지게 이동을 시킨다. 

 결과를 보면, input 이미지에서 찾은 박스가 3x4 영역에 해당하는 박스라는 것을 알 수 있다. 얘를 이제 분류기에 집어넣어야한다. 분류기에 넣으려면 같은 크기로 맞춰줘야 한다. 어떻게 맞출까? input 이미지는 resize하면 되는데 feature map을 원하는 크기로 바꿔주기 위해서 어떻게 하지? 그때 사용하는 것이 RoIPooling 이 된다. RoIPooling 은 Max pooling과 똑같은 연산을 수행하는데, 앞 뒤가 바뀌었다고 생각하면 된다. 

 max pooling 은 ? x ? 를 kernel 크기로 정해줄 수 있다. 그런데, RolPooling에서는 pooling 을 통해서 만들고 싶은 output의 크기를 정해주면 알아서 만들어준다

 

R-CNN 에서 Fast R-CNN이 나오기 까지를 정리하면 Conv feature 나오는것을 앞단으로 옮겨서, 패치 level로 forward해야하는데 원샷으로 forward할 수 있게 만들어 준 것이다. 그래서 연산량이 엄청 많이 줄어들게 된다는 것이다.

 

그러면 더 빠르게 하고자하는 모델이 있다

 

Faster R-CNN

 이전에 기본 R-CNN은 Conv Net에서 연산을 하는 부분이 보틀넥이었다. 근데 이것을 Fast R-CNN으로 원샷으로 처리를 했더니, Box를 추천하는 부분이 보틀넥이 되기 시작한다. 미리 정해진 알고리즘으로 Box를 추천해주는 부분이 계산이 많이 드는 것이었다.

이를 어떻게 해결할까....

 기존의 고정된 알고리즘으로 Box를 추천받지 말고, 이것도 NN으로 바꿔버리자 라는 생각으로 시작한다. 그것이 아래의 그림에 동그라미쳐진 RPN 이라는 것이다. 정해진 개수만큼 Box를 추천해주는 Selective search 같은 방법에서 NN으로 바꿨다.

 바꾸면, 이미지를 forward하는 순간 한쪽에선 feature map을 뽑고, Box proposal을 뽑으니, 이둘을 모아서 분류를 한번에 할 수 있게 되서, 연산량을 획기적으로 줄일 수 있게 된다. 

 

Faster R-CNN

 

 위의 Box proposal 은 어떻게 할까? 아래의 그림을 통해 알아보자. 아래의 그림은 Faster R-CNN 을 나타내고 , Region Proposal Network (RPN) 를 통해서 우리가 얻어야 하는 output은 크게 두 종류가 있다. 첫번째, 해당 위치에 object가 존재할 확률이 얼마인가? 두번째, 특정 object가 존재하는 위치에 좌표는 어떻게 되는가?

Localization 에서 분류정보와 좌표 두개가 나왔어야 했는데, 마찬가지로 RPN에서도 나온다는 것이다. 차이점은 RPN은 그 object가 어떤 class인지는 맞추지 않는다. objectness에대한 score를 보여줄 뿐이다. 개, 고양이든 상관없이 object 라고 부를법한 영역인가에 대한 score를 뱉어주게 된다. 그 object가 실제로 어떤 class인지는 뒤에서 맞추게 되는 것이다. 

 

우선 output은 objectness score와 back ground 에 대한 score 가 나온다. 그리고 좌표는 4개로 구성되어 나와야 된다. 그런데 여기서 문제는 이 RPN을 하기 위해 이미지를 넣고 FCN을 통해서 feature map을 뽑아 낼건데, 이 feature map에서 특정 위치는 input 이미지의 일정영역의 패치의 conv결과라는 것을 알 수 있다. 하지만 이미지의 object의 크기는 다양하게 존재한다. 이 때 feature map에서 하나하나에 위치에 대해서 해당하는 위치에 맞는 input 이미지에 고정된 사이즈의 고정된 위치만 나타낸다는 것을 볼때 이건 말이 안된다고 할 수 있다. 그렇기 때문에 feature map의 특정 위치에서 고정된 입력크기만 보는게 아니라 더 작은 또는 더 큰 아니면 너비 높이의 비율이 다른 여러 Box의 이미지를 볼 수 있게 하기 위해서 Anchors라는 개념을 도입한다. 이것은 학습하기 전에 미리 정해주는건데, 특정 위치에서 바라보고 있는 input 영역을 conv layer, stride로 정해진 영역만 보는 것이 아니라 더 작은/큰, 높이 너비 비율이 다양한 것을 한꺼번에 볼 수 있게 미리 정해준다. 밑에 밑에 그림에 Anchors 의 그림이 나와있다. Anchors Box 에는 3개의 서로 다른 scales과 aspect ratio를 활용하게 되는데, 연구자는 k 개의 anchor를 define 할 수 있다. 그래서 k 개에 해당하는 objectness score와 좌표값을 출력을 해야하는데, RPN의 output은 2k 개의 score가 존재한다. 그리고 4k의 cordinate정보가 출력되도록 구성이 되어 있다.

 만약에 objectness 가 0.8이상인 것만 뽑는다면, 뽑힌 것들에서 cordinate를 가져와서 그 feature map영역에서 어떤 특정 영역을 봐야하는지 위치정보를 알 수 있게 된다. 이제 이부분에 대해서 RoIpooling을 진행하면 된다. 

 

 

Faster R-CNN(2015)

 

 

 

Faster R-CNN 에서는 이미지 과정 기반에 Box 추천하는 부분을 완전히 NN 로 구성을 해버린 것이라 생각하면되고, 

Faster에 이르러서 진정한 end-to-end object detection model이 된 것이다. 완전히 fully parametric 한 모델이고, 존재하는 모든 operation들은 데이터 기반으로 다 학습이 되는 애들이다.

 

 

 


 

 

* 3. Semantic Segmentation

 

 Object Detection 에서는 아래의 개와 강아지처럼 객체를 찾고 Box로 영역을 검출해냈다. Segmentation으로 넘어오면 이미지의 모든 영역에 대해서 이미지가 가진 모든 영역에 대해서 어떤 의미를 담고 있는지 알고 싶어 하는 Task라고 할 수 있다. 

 즉 Segmentation은 이미지에 존재하는 모든 픽셀들에 대해서 classification을 수행한다고 생각하면 된다.

그래서 segmentation은 input 과 output이 동일한 resolution을 가져야 한다. 그래야 input과 예측된 class를 연결시켜볼 수 있으니까.

CS282A lecture

 

 

 

 그러면 이러한 segmentation 모델은 어떻게 구성을 할 수 있는가?

 가장 직관적인 방법은 down sampling 안하고 input과 output이 같게 NN을 쌓으면 된다. 즉 width, height는 고정되고 channel만 바뀐 layer를 쌓는다는 것이다. 

 하지만 계산해야하는 양의 효율을 보면 정말 안좋다. 그래서 down sampling을 사용하면서 다시 또 W, H 를 늘려줄 수 있는 방법을 고안한다. 그것이 up sampling 이다.

아래의 그림을 보면 왼쪽 분홍색이 있는 부근의 NN은 우리가 classification할 때 사용하던 그 구조가 맞다. 그러다가 뒷쪽부분 하늘색부분을 보면, feature map을 조금씩 키워준다. 그래서 input 과 output 크기가 동일하게 해준다. 즉 input 이미지의 하나하나의 셀에 대한 classification 정보가 output 하나하나의 픽셀에 담겨있는 것이라 할 수 있다. 

 최종 결과는 즉, 가장 오른쪽의 그림처럼 나오게 된다.

 

Segmentation의 새롭게 도입된 부분은 Up-sampling이라는 방법이 추가된 것이다. 제안된 딥러닝 기반의 Segmentation 모델은 디테일은 다르지만, 공통적으로 위의 그림에서 처럼 feature를 abstract 하는 부분 그리고 원래의 input 크기로 복원하는 부분! 이 있다. 앞쪽에 abstract 하는 부분을 encoder 라고 하고, 뒷부분을 decoder라고 한다. 

 

up-sampling은 input resolution을 키우는 것이다.  첫번째 방법이 max pooling이나 average pooling과 반대되는 개념인 Un-pooling이다. un-pooling은 주의해야할 건 왼쪽에 맥스 풀링할 때는 5가 뽑혔는데 기존의 5가 있던 자리로 다시 그 값을 돌려놓는 작업이다. 즉 Max 였던 자리에다가 다시 심어주는 식이라고 생각하면 된다. 그리고 나머지 부분은 0으로 채운다는 것.!

 

 

계속해서 upsample 을 하는 방법에 대해 알아보자. 우리가 stride도 해서 down sampling도 진행했었다. 위처럼 max pooling에 반대되는 개념이 Un-pooling이었다면, stride에 대해 반대되는 개념이 바로 Transposed convolution 이라고 한다. 

 역할은 똑같다 input 의 feature map의 resolution을 키워주는 것이다. 마치 stride를 1보다 큰 값을 주고 conv를 하는 것처럼 그것의 역방향이라고 생각하면 된다. pytorch를 찾아본다면 Conv 라이브러리에 보면 transposed convolution이 있는 걸 확인가능하다.! 

 CNN이 연산되는 것이 사각형의 window가 돌아다니면서 수행하지 않고 실제로는 matrix multiplication 방식으로 fully connected 처럼 연산이 수행된다..!! 하나하나 sliding window를 가지고 하면 병렬연산이 좀 힘들기 때문이다. 

 이걸 병렬로 처리하기 좋게 행렬연산으로 쌱 바꿔주는 것이다.

 

일단 아래를 보면은 3x3 window를 가지고 연산한 결과이다. 즉 그냥 우리가 예전에 혹은 기본적으로 알고 있는 방식으로 연산이 된것을 알 수 있다. 

 

 

하지만 3x3 필터를 적당히 행렬에 arange 해놓으면 conv를 행렬로 표현이 가능하다. 

첫번째는 아래의 그림처럼 3x3 행렬을 matrix형태로 바꿔준다.  어떻게 아래의 오른쪽처럼 만들어주냐면, 저 아래의 매트릭스의 노란 부분이 처음 window를 만나서 연산이 수행되는 부분일 텐데 지정된 index를 제외한부분은 0이고 연산위치에 해당되는 값들을 첫번째 row에 쭉 나열을 해주면 된다. input 행렬의 index에 해당되는 kernel 값을 row에 나열해준다고 생각하면 된다. 

 

이렇게 구성된 4x4행렬을 죽 flatten 한 벡터와 위에서 바꾼 행렬을 곱해주기만 하면 된다. 바로 아래 처럼말이다. 한 로우 한 로우 곱하는 것이 곧 window를 옮기면서 sum 하는 것과 같은 것이 되는 것이다. 그리고 적당히 reshape해줘서 원래 나와야 하는 사이즈로 나오게 해준다.

 

 

이걸 이해하면 Transposed convolution 도 쉽게 이해할 수 있다.! 왜 Transposed convolution 이냐구? rearange한 행렬을 말그대로 Transposed 시켜주기 때문이다. 아래의 그림처럼 다시 우리가 Up sampling을 해서 사이즈를 키우는 것으로 돌아와 보자 역으로 생각해보면 우리는 기존의 아래의 하늘색 벡터처럼 4x1 을 받아서 결국 16x1로 만들고 싶은 것이니 연산이 바뀌니 행렬을 transpose 시켜줘야하기 때문인 것이다. 이런식으로 하면 결국 사이즈를 크게 해서 나오게 된다.  .

 

 

 

 

 

요새는 transposed convolution을 많이 쓰는 추세이다. 

Conv에서 stride와 pedding이 있었다는 건 알고 있었으나, 반대로 Transposed conv에서도 존재한다. Conv에서 stride와 pedding 은 original의 의미를 그대로 가져간다. Conv에서 패딩하면 boundary에 그만큼 붙여서 진행하는데 Transposed conv에서는 그렇지 않다.

 정리하자면, conv에서 input과 output크기의 관계를 유지하기 위해 parameter 를 그대로 가져간다고 생각하면 된다.

아래의 그림 왼쪽을 보면 4x4를 패딩 0, stride 1 옵션으로 2x2 행렬을 만든 것을 볼 수 있다. Transposed conv로 반대 연산을 하고 싶다? 그러면 바로 오른쪽의 그림처럼 원래의 패딩과 stride 옵션을 그대로 가져가는 것이다. 언뜻 보면 패딩이 2가 되어 있는 듯한 느낌이다. 그렇지 않고, 여기서 패딩의 의미는 conv에서의 input, output관계를 보존할 수 있는 값이다.  오른쪽의 conv, transposed conv의 예제도 같은 의미이다.

 

 

그래서 Segmentation 모델은 Region based object detection보다 이해하기는 간단하다. 인코더, 디코더를 보고 디코더 할 때 resolution을 키워줘야하는데 이 때 필요한게 un-pooling 이나 transposed convoution이 있다는 것이다. 중요한것은 conv는 실제로 행렬곱으로 연산된다는 것, 그리고 transposed conv는 행렬로 구성된 kernel이 단순히 transposed된 것이라는 것이다. 

Segmentation 에 대한 architecture는 어떤지 보자. 아래는 fully convolutional networks for semantic segmentation 아키텍처를 나타낸다. 왜 fully convolutional network인지는 위에서 언급했던 것과 같다. un-pooling, up-sampling을 하는 이유를 생각해보면 그렇다. 

 아래의 고양이 이미지를 받으면 고양이라는 확률값을 뱉어주는 분류기가 있다고 하자. 그러면 이 분류기의  모든 layer를 conv layer 로 구성했다면, 더 큰 크기의 이미지를 받을 수 있다는 것을 의미한다. 더 큰 크기를 넣었을 때, output 의 resolution이 남아있게 되고, 이런 NN에 그 아래의 더 큰 이미지를 넣게 되면은 global 패치만큼 옮겨가면서 고양이의 확률값이 결국 높은 패치에 대한 것이 고양이의 위치가 되게 된다. 

Fully convolutional networks for semantic segmentation(2014) 

 

 

아래의 아키텍처를 보면 pool을 죽죽 하다가 upsample을 하는 일련의 과정을 high resolution의 output을얻기 위한 노력이라고 보면 된다. 

Fully convolutional networks for semantic segmentation(2014)

 

아래는 SegNet(2015) 모델이다. 완전히 인코더랑 디코더가 대칭적인 segmentation 모델이다. 인코더 파트와 디코더 파트가 완벽히 대칭을 이루는 것을 볼 수 있다. 

 

 

아래는 또다른 인코더 디코더 아키텍처인데, Learning deconvolution network for semantic segmentation(2015) 이다. 위와 유사한 형태라는 것을 볼 수 있다. 

 

또다른 아키텍처인 UNet(2015) 이다. 

Neural Art. NN을 통해 학습된 filter 들로 이미지의 'style'을 잘 캡쳐할 수 있다. 특징들을 잘 파악하기 때문에 moment matching을 통해 이미지를 생성하는 것이 가능하게 된다. 

위의 아키텍처로 생성된 output !

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ref) lecture Hacettepe University

naokishibuya.medium.com/up-sampling-with-transposed-convolution-9ae4f2df52d0

 

 

728x90
반응형

댓글