이미지 인식은 전자상거래 사이트의 상품인식, 디지털 카메라 및 구글 포토의 얼굴 인식, 자율 주행 자동차의 도로상황 파악 등 다양한 곳에서 사용됩니다. 또한 최근 딥러닝의 발달로 인식 성능과 처리 속도가 놀랍게 향상되어 응용범위가 확대되고 있습니다.
이 장에서는 이미지 인식의 기본 개념과 자주 사용되는 피처에 대해 알아보고, 이미지에 담긴 물체의 카테고리를 정하는 물체 분류와 이미지에 담긴 물체를 인식하는 물체인식 기법을 소개합니다. 또한 이미지 인식에서 최근 각광받고 있는 딥러닝 기법인 CNN(합성곱 신경망)에 대해서도 살펴봅니다.
7.1 이미지 처리 기본 개념
이 절에서는 이미지 처리에서 사용하는 기본 개념인 픽셀, 필터링, 합성곱에 대해 알아보겠습니다.
7.1.1 픽셀
디지털 이미지는 픽셀로 구성되어 있습니다. 화면 크기가 17인지, 해상도가 1920*1080픽셀이라는 표현에는 아마 다들 익숙할 겁니다. 픽셀은 컴퓨터 모니터에서 표시할 수 있는 가장 작은 단위라고 생각하면 됩니다. 픽셀은 밝기의 강도(intensity)와 컬러 채널값을 가집니다.
그레이스케일 이미지에서 각 픽셀은 흰색(강도 255), 검은색(강도 0), 다양한 강도의 회색(1~124)으로 채워져 있습니다. 컬러 이미지는 픽셀 하나가 R,G,B 세 채널로 구성되고 각각 0~255의 강도를 가집니다. 예를 들어 빨간색은 [255,0,0], 녹색은 [0, 255,0], 파란색은 [0, 0, 255]이런식입니다. 따라서 채널별로 높이 m픽셀과 넓이 n픽셀을 가지는 이미지를 m*n행렬로 표현할 수 있습니다. 채널이 하나인 그레이 스케일 이미지는 m*n*1행렬로, 컬러 이미지는 m*n*3 행렬로 표현할 수 있습니다.
이미지를 픽셀 좌표(x,y)의 강도값을 변환하는 함수로 볼 수도 있습니다. 즉 I(x,y) = 강도값인 함수가 됩니다. 이 함수를 이미지 강도함수 혹은 강도함수라고 합니다.
7.1.2 필터링
기존 이미지의 픽셀값을 선형적으로 조합하여 새로운 픽셀값으로 변환한 뒤 그 픽셀들로 새로운 이미지를 생성하는 것을 필터링이라고 합니다. 필터링은 결괏값이 저장될 픽셀 좌표의 +-1, +-2... 범위의 ㅍ픽셀 정보를 조합하는 방식을 사용합니다. 예를 들어 가로3개*새로3개= 9개의 픽셀 정보를 조합한다면 3*3 크기의 원도우(혹은 커널)를 사용합니다. 자주 사용되는 원도우 크기로는 3*3와 5*5가 있습니다.
대표적인 필터링 방식으로 이동평균 필터링이 있습니다. (그림 7-3). (2n+1)*(2n+1)크기의 원도우를 사용하여 이동평균 필터링을 적용할 경우, 목표 픽셀에서 +-n위치의 값을 모두 ㄷ더한 후 (2n+1)(2n+1)(원도우의 넓이)로 나누면 됩니다. 예를 들어 [그림 7-3]의 첫 번째 이미지는 새 이미지의 G의 (1,1) 픽셀값을 정하기 위해 이전 이미지 F의 (0,0), (0,1), (0,2), (1,0), (1,1), (1,2),(2,0), (2,1), (2,2) 픽셀값을 모두 더한 후 9로 나누었습니다. 이 작업을 이미지 F의 모든 픽셀에 대해 반복합니다.
하지만 이미지 G의 (0,0)픽셀을 생성하려면 이미지 F의 (-1,-1), (0,-1), (1,-1), (0,-1), (0,0), (0,0), (1,-2), (1,0), (1,1)픽셀값이 필요한데, -로 시작하는 픽셀은 존재하지 않습니다. 이와 같이 이미지의 네 가장자리 픽셀은 원도우 안의 픽셀값이 비어 있기 때문에 별도로 처리합니다. 네 가장자리의 픽셀값을 처리하는 방ㅂ버으로 이미지 바깥 값을 0으로 채우는 제로 패딩(zero-padding)과 이미지 바깥 값을 가장 가까운 가장자릿값으로 처리하는 가장자릿ㄱ밧 복제(edge value replicaiton)가 있습니다. 그림으로 나타내면 [그림 7-4]와 같습니다. 일반적으로는 제로 패딩을 많이 사용합니다. 이동평균 필터링은 픽셀을 주벼 ㄴ픽셀값의 평균으로 변환하므로 더 부드러운(스무딩된) 이미지를 생성합니다. 이동평균 외에도 원도우 안의 픽셀 주 최댓값으로 픽셀을 생성하는 최댓값필터링, 단순히 주변 값들의 편균을 구하는 대신 거리에 따라 차등을 주는 가우스 필터링(혹은 가우스 원도우), 이미지의 경계선을 얻어내는 엣지 필터링 등이 있습니다. 이러한 필터링 방식은 다음 절에서 설명하는 합성곱 원도우를 용도에 맞게 설정하여 구현할 수 있습니다.
7.1.3 합성곱
필터링 방식은 합성곱(convolution)의 특별한 경우입니다. 사실 이미지 처리에서의 필터링은 합성곱의 적용이라고 생각해도 됩니다. 합성곱은 함수와 이동한 함수의 값을 곱한 다음, 구간에 대해 적분하여 새로운 함수를 구하는 연산입니다. 연산 기호는 *입니다. 함수 f와 함수 g의 합성 곱 f*g를 식으로 표현하면 다음과같습니다.
(f*g)(t) = 적분(f(임의의값)g(함수입력값 - 암의의값)d*암의의값
함수의 이동은 함수의 그래프를 일정 방향으로 평행이동 혹은 대칭이동하는 것 입니다. 중학교에서 배운 이차함수의 이동을 떠올리면 이해하기 쉬울 겁니다. 함수 y = f(x)에 대한 이동을 식으로 표현하면 다음과 같습니다.
- p 만큼 평행이동 : y = f(x-p)
- x 축 대칭 이동 : -y = f(x)
따라서 합성곱은 함수 g를 임의의 축으로 대칭이동 하고 t마큼 평행이동한 후 , f(임의의 값)와 곱하고 그 결괏값을 적분하는 연산입니다. 여기서 적분 범위는 함수 f와 g의 범위에 따라 달라집니다. 대칭이동은 반전이라고 합니다. 합성곱은 적분을 하는 것으로 입력값 t와 적분 구간의 정보를 동시에 고려하는 값을 얻게 되므로 연속된 값으로 이루어지는 신호 처리, 시계열 분석 등 다양한 분야에 사용됩니다.
7.1 절에서 언급한 대로 이미지는 함수로 볼 수 있으므로 이미지를 합성곱 계산의 입력으로 사용할 수 있습니다. 이미지 함수는 연속함수가 아닌 이산함수이므로 적분대신 총합을 사용합니다. 또한 전 구간의 값을 더하는 것이 아니라 원도우 안의 값만 더하므로 위 식이 다음과 같이 바뀝니다.
f*g(n) = -M에서 M의 총합(f(n-m)g(n))
n: 원도우의 중심
2M: 원도우의 한변의 길이
위 식을 말로 표현하면 다음과 같습니다.
1. f로 정의된 운도우 안의 값이 x,y 좌표 반전
2. 1에서 만든 원도우로 이미지g를 흟으면([그림 7-3]의 원도우 이동 참조) 원도우 안의 값과 원도우를 적용할 이미지 g부분의 강도값의 내적을 계산
3. 2에서 생성된 값으로 새로운 픽셀값 생성
그림으로 표현하면 [그림 7-6]과 같습니다. 원도우를 반전하는 것으로 상화좌우가 바뀐 것을 볼 수 있습니다. 새 합성곱 이미지의 좌표(1,1)안에 들어갈 강도값을 계산하기 위해 원래 이미지의 좌표(1,1)이 원도우의 중심이 되도록 포갭니다. 이때 앞에서 살펴본 제로 패딩으로 가장자리 값을 채움니다. 합성곱 이미지의 (1,1)좌표의 강도값은 다음과 같습니다.
i * 5 + h * 6 + g * 0 + f * 8 + e * 9 + d * 0 + c * 0 + b * 0 + a * 0
합성곱을 이미지에 적용할 땐느 좌우대칭 필터를 사용하는 경우가 대부분이므로 반전의 영향을 미치지는 않습니다. 또한 7.4절 '딥러닝을 이용한 이미지 인식'에서 살펴볼 CNN(합성곱 신경망)도 원도우를 반전하지 않습니다. 하지만 이미지를 이동하는 필터라면 반드시 반전을 해야 원하는 결과를 얻을 수 있습니다. 원도우 안에 있는 픽섹값들을 합하여 하나의 픽셀로 만드는 이유는원래 이미지에 있던 여러 픽셀의 정보를 하나로 모으기 위해서입니다.
합성곱을 이용한 계산은 원도우를 어떻게 지정하냐에 따라 이동뿐만 아니라 블러, 샤프닝 등 다양한 효과를 이미지에 적용할 수 있습니다. GNU 이미지 편집 프로그램(GIMP)사이트 에서 다양한 원도우에 의한 합성곱 결과를 확인할 수 있습니다.
7.2 이미지 인식
이미지 인식 태스크에 대해 알아보겠습니다. 이미지 인식 태스크는 크게 다음과 같이 나뉩니다.
- 이미지 분류(image classification):이미지에 특정 물체가 존재하는지 여부를 판단합니다. 예를 들어'[그림 7-7]에 고양이가 존재하는가?'라는 물음에 '그렇다', '아니다'로 분류하는 것이죠
- 이미지 검출(image detection):이미지에 어떤 물체가 존재하며, 어디에 존재하는지 판단합니다. '[그림 7-7]'에 무엇이 있는가? 그리고 그것이 어디에 있는가?' 라는 더 구체적인 질문에 대해 답을 해야 합니다.
7.2.1 이미지 분류
어떻게 해야 위 이미지가 고양이와 관련되었다고 할 수 있을까요? 여러 개의 비슷한 고양이 이미지를 이용하여 분류기를 학습시키면 됩니다. 5장에서문서를 이루는 단어들을 이용하여 피처를 생성하고 문서를 분류하는 방법을 배웠습니다. 이미지도 마찬가지로 이미지를 이루는 픽셀을 이용하여 피처를 생성할 수 있습니다. 피처는 크게 전역 피처와 지역피처로 나눌 수 있습니다. 전역 피처는 하나의 이미지에서 한만 얻을 수 있으며 이미지의 강도 히스토그램이 그 예입니다. [그림7-8]은 이미지(왼쪽)에서 추출한 강도 히스토그램(오른쪽)을 보여주고 있습니다. 강도 히스토그램의 x축은 강도값(0~255), y축은 그 강도값을 가지는 픽셀 수 입니다.
하나의 이미지에서 얻을 수 있는 지역 피처의 종류는 다양합니다. 대표적인 지역 피처로 이미지안 물체의 코너를 들 수 있습니다. 코너에 대해서는 7.3.2 절 '코너'에서 자세히 설명할 겁니다. 이미지에서 전역 피처와 지역 피처를 추출한 뒤 이를 이용하여 이미지를 군집화하거나 분류기를 만들어 이미지 분류하게 됩니다.
7.2.2 이미지 검출
이미지 검출은 이미지에 존재하는 물체가 무엇인가, 어디에 있는지 인식합니다. 분류와 달리 어떤 물체인지에 대한 정보가 없으므로 인식하려면 우선 이미지에서 한 물체를 이루는 픽셀들을 분할해야 합니다. 이미지 분할은 이미지 내부에 있는 관련 픽셀들을 모아 그룹을 만드는 것으로, 픽셀 군집화로 생각할 수 있습니다. 그러므로 4장에서 살펴본 군집화 알고리즘을 사용할 수 있습니다. 이때 주로 사용되는 피처는 픽셀의 강도와위치 입니다.
예를 들어 파워포인트의 배경 제거 기능(그밀 7-9)은 이미지 분할의 예입니다. 파워포인트에서는 이미지의 배경을 제거하는 기능을 제고하는데 이때 그랩컷(GrabCut)기법을 이용한 이미지 분할이 사용됩니다. 그랩컷은 선택한 영역의 중앙에 사용자가 인식하고 싶은 물체가 있다고 가정하고, 그 물체 주위로 사각형을 그립니다. 그 후 사용자로부터 보조 입력을 받아 더욱 정확한 배경 범위를 찾습니다. 사용자의 보조 입력을 받기 때문에 그랩컷을 대화형 전경 추출법(interactive foreground extraction)이라고 부릅니다.
7.3 이미지 인식에 사용하는 피처
머신러닝으로 모델을 학습시킬 때 무엇을 피처로 삼아 학습해야 할지 알려줄 필요가 있습니다. 5장에서 문서를 분류할 때는 단어 빈도, TF-IDF등 텍스트와 관계된 피처를 사용했습니다. 이미지 분류에서도 이미지에 특화된 피처를 사용하는데, 이 절에서는 윤곽선, 코너, SIFT등의 이미지 인식과 검출에 사용하는 고전적인 피처에 대해 살펴보겠습니다.
7.3.1 윤곽선
흑백만화나 수묵화 등의 이미지는 색이나 질감에 대한 정보 없이 선으로만 이루어져 있는데도 사람들은 그 이미지에 있는 물체를 쉽게 판별합니다. 이는 사람이 윤곽선(edge)혹은 실루엣을 통해 물체를 인식하기 때문입니다. 그래서 이미지 안에 있는 물체를 인식하고자 이미지 안에 있는 윤곽선을 검출하는 방법에 대한 많은 연구가 있었습니다. 윤곽선을 검출하려면 이미지에서의 픽셀 강도값의 급격한 변화(혹은 불연속성)를 검출하면 됩니다.[그림 7-11]을 보면 이해하기 쉬울 겁니다.
가장 왼쪽의 이미지에서 윤과석을 찾는다고 생각해봅시다. 윤곽선은 검은 직석과 흰색 바탕의 경계선입니다. 회색 선이 지나가는 픽셀들의 강도값을 보면, 흰색(255)에서 검은색(0)이 되었다가 횐색(255)이 됩니다. 강도값을 함수로 나타낸 것이 가운데 이미지입니다. 이 강도 함수를 1차 미분하면 흰색에서 검은색이 되는 부분, 검은색에서 다시 흰색이 되는 부분에 미분의 최솟값과 최댓값(이 둘을 합쳐 극값이라고 합니다)이 나옵니다. 즉, 강도함수의 극값이 존재하는 곳에 윤곽선이 존재하고, 이 극값은 회색 선에 수직으로 존재합니다. 윤곽선 검출에 가장 널리 사용되는 캐니 윤곽선 검출기(canny edge detector)도 위 성질을 이용합니다. 1차 미분값은 노이즈에 굉장히 약하기 때문에 캐니 윤곽선 검출기는 가우스 값으로 채워진 원도우에 합성곱을 적용하여 노이즈를 줄이고, 여러 윤곽선 후보를 이용하여 최종 윤곽선을 만들때 복수의 임계치를 이용하여 검출 정확도를 높입니다. 캐니 윤곽선 검출기는 13장에서 살펴볼 이미지 라이브러리인 OpenCV를 비롯한 다양한 이미지 처리 라이브러리를 이요하여 쉽게 구현할 수 있습니다.
7.3.2 코너
[그림 7-8]에서 살펴본 이미지의 강도 히스토그램이나 [그림 7-10]의 윤곽선을 이용하면 이미지를 잘 분류할 수 있을 것 같습니다. 하지만 같은 장소를 찍은 사진이라 하더라도 시간대나 날씨에 따라 사진을 구성하는 색이 다릅니다. 윤곽선은 물체의 각도가 조금만 달라져도 완전히 바뀌므로 다양한 상황에서의 물체 인식에는 적합하지 않습니다.
그렇다면 어떻게 다양한 상황에서도 같은 물체로 인식할 수 있을까요? 이미지를 더 정확히 인식하려면 학습에 사용되는 피처가 회전 불변성(rotation invariance), 크기 불변성(scale invariance), 평행이동 불변성(translation invariance)을 만족시켜야 합니다.
- 회전 불변성: 같은 물체가 있는 이미지를 찾을 때는 (이미지 매칭)물체 방향의 변화에 영향을 받지 않아야 합니다.
- 크기 불변성: 이미지의 척도 변화에도 영향을 받지 않아야 합니다.
- 평행이동 불변성: 한 이미지 안에서 물체가 움직여도 같은 물체라고 인식할 수 있어야 합니다.
강도 히스토그램과 같이 이미지 전체에서 뽑아내는 전역 피처나 이미지 전체의 윤곽선만으로는 위 성질을 만족시키기 어렵습니다. 따라서 이미지 인식에서는 이미지의 일부분에서 뽑은 지역 피처를 많이 이용합니다.
회전 불변성과 평행이동 불변성을 만족시키면서(크기 불변성은 만족시키지 못합니다) 이미지에서 대량으로 얻을 수 있는 대표적인 지역 피처로 코너(corner)가 있습니다. 이미지에 있어서 코너는 선이 꺽이는 모든 곳에 존재하므로 많이 얻을 수 있고, 또한 한 이미지에 하나만 있는 전역 피처가 아닌 이미지의 부분에서 얻는 지역 피처이므로 물체의회전에 영향을 덜 받습니다. 다음 그림은 [그림 7-10]의 이미지에서 코너를 찾은 것입니다.
캐릭터의 눈썹 끝, 눈, 코에 코너가 존재한다는 것을 알 수 있습니다. 따라서 캐릭터가 회전하더라도 이미지에서 눈썹, 눈, 코를 검출할 수 있을 것이고 윤곽선보다는 더 강한 피처가 될 겁니다.
그럼 어떻게 코너를 검출할 수 있을까요? 7.3.1절 '윤곽선'에서 윤곽선을 찾을 때 강도의 변화를 검출했습니다. 코너도 마찬가지로 강도의 변화를 검출하는데, 여러 방향에서 강도의 변화가 일어나는 곳을 검출합니다.
[그림 7-13]에서는 이미지의 영역을 평면, 윤곽선, 코너로 나누었습니다. 작은 사각형(원도우)을 움직이면서 강도 변화를 관찰하느데, 평면인 경우는 원도우를 모든 방향으로 움직여도 강도 변화가 없습니다(상하좌우가 다 검정색입니다). 윤곽선인 경우는 윤곽선의 방향([그림 7-13]에서 수직선)을 따라 움직이면 강도 변화가 없습니다. 하지만 코너의 경우 어느 방향으로움직여도 강도 변화가 나타납니다.
이 성질을 이용하여 코너를 검출하는 대표적인 기법으로 해리스 코너 검출기(Harris corner detection)가 있습니다. 헤리스 코너 검출기는 x축 미분값, y축 미분값, 그리고 x축 미분값 * y축 미분값을 이용하여 2*2의 정방행렬을 만든 후 , 그행렬을 고윳값 분해하여 고유벡터가 고윳값을 찾습니다.
행렬의 고윳값 분해는 6.4.1절 '평균 제곱근 편차'에서 설명한 대로 행렬을 이루는 기본 요소를 찾는 방법 중 하나입니다. 특잇값 분해와 달리 고윳값 분해는 선형독립인 정방행렬에만 적용할 수 있습니다. 선형독립인 행렬 A는 간단히 말해 v가 O벡터일 경우만 Av = O를 만족하는 행렬입니다.
정방행렬 A와 A의 고유벡터 v, 고윳값 Y의 관계를 수식으로 표현하면 다음과 같습니다.
AY = Yv
즉, 고유벡터란 행렬 A가 곱해져도 그 방향(v)이 변하지 않고 크기(Y)만 변하는 벡터를 말합니다. 행렬 A가 정방행렬이고 선형 독립일 경우 다음과 같이 분해할 수 있습니다.
강도함수의 x축, y축 미분값으로 이루어진 행렬이 이미지 안의 강도값의 변화를 나타낸다는 점을 생각해보면 그 행렬을 분해한 고유벡터는 변화의 축(방향)이 되고 고윳값은 강도 변화의 크기라고 볼 수 있습니다. 그리고 앞에서 말했듯이 해리스 코너 검출기는 2*2의 정방행렬을 분해하므로 두 고유벡터와 두 고윳값이 나올 겁니다. 이 과정에서 얻은 두 고윳값을 이용하여 이미지 부분을 평명, 윤곽선, 코너 중 하나로 결정합니다. [그림 7-14]를 보면 이해하기 쉬울 겁니다. 한 고윳값이 다른 한 고윳값보다 매우 클 경우, 즉 한쪽 방향으로만 강도가 급격히 변할 경우 윤곽선이 됩니다. 두 고윳값이 모두 클 경우, 즉 모든 방향으로 강도가 급격히 변할 경우 코너, 두 고윳값이 둘 다 작으면 평면이 됩니다. 헤리스 코너 검출기로 캐니 윤곽선 겸추기와 마찬가지로 특별한 구현 없이 라이브러리로 바로 사용할 수 있습니다.
7.3.3 SIFT
SIFT(Scale-Invariant Feature Transform:크기 불변 피처 변화)는 크기 불변성, 회전 불변성, 평행이동 불변성을 동시에 만족시키는 피처를 생성하는 기법입니다. 7.3.2절 '코너'에서 회전불변성, 크기 불변성, 평행이동 불변성을 만족시키며 대랴응로 얻을 수 있는 피처가 이미지 인식에 유용하다고 언급했습니다. 그리고 코너가 크기 불변성을 만족시키지 않는다는 말도 잠깐 했습니다. 왜 그런지는 다음 그림을 보겠습니다.
[그림 7-15]는 같은 크기의 두 이미지를 보여조고 있는데, 왼쪽에는 토끼가 한 마리가 있고, 오른쪽에느 토끼가 세 마리 있습니다. 사람은 오른쪽 이미지에 있는 토끼와 왼쪽 이미지에 있는 토끼가 같다는 것을 금방 알 수 있지만, 컴퓨터로 이미지 처리를 하면 이미지 안의 물체 사이즈(혹은 이미지 척도(scale))와 상관없이 이미지 크기에 따라 원도우 크기(그림에서는 사각형으로 표시했습니다)가 정해지므로 두 이미지에서 검출하는 코너가 완전히 달라집니다.
이 문제를 해결하는 가장 쉬운 방법은 한 이미지의 확대/축소 버전을 여러개 만든 후(이를 이미지 피라미드(image pyramid)라고 합니다) 이미지를 비교하는 겁니다.[그림 7-15]의 오른쪽 이미지를 확대하다 보면(혹은 척도를 줄이다 보면)언젠가는 왼쪽 이미지에 있는 토끼와 크기가 같아지겠죠.
한편 아우스 원도우를 이용한 필터링(블러)처리 결과와 이미지의 척도(스케일)이 작아지는 효과, 즉 이미지 안의 물체가 커지는 것이 비슷한 효과를 낸다는 점에 착안하여 가우스 함수를 이용하여 각 지역마다 다른 척도를 찾는 방법이 제안되었습니다. 대표적인 방법으로 LoG(laplacian of Gaussian(가우스 라플라스)와 DoG(differece of Gaussian(가우스 차))가 있습니다.
LoG와 DoG는 모두 가우스 원도우를 이용하여 이미지에 블러효과를 준 후 그렇게 얻어진 이미지의 강도합수를 미분하여 지역 극값을 찾습니다. 지역 극값을 찾는것으로 이미지 강도의 급격한 변화가 일어나는 점을 찾을 수 있게 되고, 이 점들이 지역 피처를 추출할 후보가 됩니다. 이때 다양한 척도에서의 극값을 검출하기 위해 다른 표준편차값을 가지는 복수의 가우스 운도우를 이용합니다. [그림 7-16]은 다른 표준편차를 가지는 가우스 원도우를 이용해서 이미지를 처리한 것을 보여줍니다. 표준편차가 클수록 이미지가 흐릿해지는데, 이는 이미지가 커지는 것과 같은 효과로 생각할 수 있습니다.
이렇게 다양한 표준편차를 가지는 가우스 원도우로 생성된 여러 이미지(즉, 척도가 다른 이미지)의 특징(x, y)좌표에서 일관되게 극값이 검출된다면, 그 위치는 이미지의 척도에 영향받지 않는다고 여길 수 있습니다. 이 좌표를 특징점(keypoint)이라고 합니다. 그리고 가장 큰 극값을 얻은 이미지의 척도(즉, 가우스 원도우의 표준편차)가 그 특징점의 척도가 됩니다. 그결과 각 특징점과 그와 연결된 척도를 얻게 됩니다.
이렇게 척도에 영향받지 않는 특징점을 찾은 후에는 특징점의 방향을 찾습니다. 특징점의 방향을 고려하면 회전한 물체도 인식할 수 있게 됩니다. 특징점과 그 주변의 회전 방향을 찾기 위해 각 특징점의 척도에 해당하는 이미지를 이용하여 주변 이미지의 강도 함수를 x축 y축으로 미분한 후 변화가 가장 급격한 곳을 찾아 그 특징점의 방향으로 정합니다.[그림 7-17]에서 볼 수 있듯이 SIFT는 각 특징점에 대해 16개 주변 구역을 정한 뒤 각 구역마다 8개의 방향을 정하므로 특징점 하나는 128개의 값을 가지게 됩니다. 이러한 특징점의 주변 값들을 특징량(keypoint descriptor)이라고 합니다. 두 이미지를 비교할 때는 두 이미지 안의 특징점의 특징량을 이용해서 유사도 계산(옐르 들면 유클리드 거리 계산)을 하게 됩니다.
[그림 7-18]에서는 SIFT를 이용해 왼쪽의 기차와 개구리를 가운데 이미지에서 찾는 예를 보여줍니다. 개구리와 기차가 다른 물체 뒤에 숨어 있고 놓인 방향이 달라도 특징점(개국리 다리, 기차 바퀴 등)을 이용해서 성공적으로 찾앗습니다. 또한 각 특징짐마다 사용하는 척도가 다르므로 실제 피처를 뽑는 이미지 범위(사각형의 크기)가 다른 것도 볼 수 있습니다. SIFT기법은 2004년에 소개된 이후 많은 곳에서 사용되었지만, 특허 등록이 되어 있어 2016년 현재 상업적인 용도로는 사용할 수 없습니다. 대신 Brisk(Binary Robust Invariant Scalable Keypoints)나 Kaze 등을 사용하면 됩니다. 두 알고리즘 모두 OpenCV에 라이브러리로 구현되어 있으므로 어렵지 않게 사용할 수 있습니다.
7.3.4 주성분 분석
주성분 분석(PCA(principal component analysis))은 데이터에서 의미 있는 축을 찾아낸 후 그 축을 이용하여 고차원 데이터를 저차원으로 사영하는 방법입니다. 데이터에서 차원 수만큼 축이 존재하는데 주성분 분석 기법은 이들 중 가장 중요한 축, 즉 데이터의 특징을 가장 잘 표현할 수 있는 축부터 순서대로 찾아냅니다.
예를 들어[그림7-19]에서 데이터의 차원을 축소한다고 생각해봅시다. x축은 키, y축은 몸무게, 각 점은 해당 키와 몸무게를 가진 사람이라고 합시다. 이 데이터는 키와 나이라는 2가지 차원을 가집니다. 각 데이터는 z-점수 표준화 했습니다.
이 데이터를 검은 축과 회색 축 중 하나를 골라 사영한다고 생각해 봅시다. 회색 축 위의 점들은 떨어져 있는 반면, 검은 축 위의 점은 다닥다닥 붙어 있게 됩니다. 위 데엍에서 사람들의 키와 몸무게보다 더 다양하기 때문입니다.(즉, 키의 분산의 크기 때문입니다). 따라서 이 데이터를 1차원으로 축소할 때는 회색축을 이용해야 데이터의 특징을 더 잘 보존할 수 있습니다. 주성분 분석은 이와 같이 분산이 큰 순서대로 축을 찾아내면서 데이터의 차원을 줄여가는 방식입니다. 각 차원의 분산을 이용하기 위해 공분산행렬을 계산한 후 그 행렬을 고유벡터 분해하여 축을 찾습니다. 공분산행렬에 대해서는 4.5.2절 '마할라노비스 거리'를 차모하세요. 공분산행렬은 늘 정방행렬이고 대칭행렬입니다. 공분산행렬을 7.3.2절 '코너'에서 설명한 것처럼 고유벡터로 분해하는 것으로 데이터를 설명하는 축, 즉 성분들을 구하게 됩니다.
이미지 인식에 주성분을 이용하는 이유는 복수의 이미지에서 주성분을 뽑아내면 그 이미지들의 공통된 특징을 찾을 수 있기 때문입니다. 예를 들어 사람 얼굴의 경우, 세세한 부분은 다르지만 눈이 둘, 코가 하나, 입이 하나라는 공통점이 있습니다. 그리고 개개인의 특징은 눈 크기나 이마넓이 차이 등으로 분산할 수 있습니다.
이 아이디어를 바탕으로 한 것이 고유 얼굴 검출(eigenface detection1991)입니다. 고유 얼굴 검출은 대부분의 얼굴 이미지를 공통된 주성분으로 분해할 수있다는 가정을 바탕으로 얼굴 이미지를 설명할 수 있는 주 고유 얼굴(즉, 다양한 얼굴 데이터를 가장 잘 설명할 수 있는 주성분)을 찾아낸 후 고유 얼굴의 선형 조합을 이용하여 원래 얼굴 이미지를 나타냅니다.
고유텍터, 즉 주성분을 많이 이용할수록 차원을 덜 축소하게 되므로 고유 어굴을 조합한 이미지가 원래 이미지와 가깝게 됩니다.[그림 7-20]은 사용하는 주 성분수(K)를 4개, 128개, 256개로 바꾸었을 때 복원된 얼굴 이미지의 변화를 보여줍니다. 차이점을 확실히 알 수 있습니다.
하지만 주성분을 많이 쓴다고 좋은 것은 아닙니다. 예를 들어 이미지에서 '머그컵'이 있는지 여부를 인식하려고 할 때 주성분을 많이 사용하면 무늬가 있는 머그겁과 없는 머그겁을 구별하게 될 것이고, 그러면 일반화를 할 수 없어서 시스템의 목적에는 맞지 않게 됩니다. 분류하려는 이미지에 따라서 K값을 적절히 정하는 것이 중요합니다. PCA의 구현 방법에 대해서는 13장의 고유 얼굴 검출 예제에서 살펴봅니다.
7.4 딥러님을 이용한 이미지 인식
이 절에서는 딥러닝을 이용한 이미지 인식에 대해 알아보겠습니다. 모든 머신러닝 문제에서 그렇듯 '어떤 피처를 뽑아 학습시키느냐'가 모델의 성능을 좌우합니다. 7.3절 '이미지 인식에 사용하는 피처'에서는 이미지 인식 시스템을 만들 때이미지에서 무엇이 중요한지 고려해서 피처를 사람이 직접 하나하나 정의했습니다. 즉, 사람이 '윤곽선이 중요할 것이다', '코너가 중요할 것이다'라고 생각하고 피처를 뽑았습니다. 그런데 딥러닝을 이용하여 머신러닝을 할 때는 이렇게 수동으로 정의한 피처를 사용하지 않습니다. 학습과정에서 어느 것이 중요한 피처인지 모델이 스스로 학습합니다. 이것이 딥러닝과 전통적인 머신러닝 간의 가장 큰 차이입니다.
7.4.1 CNN 소개
CNN(convolutional netural network, 합성곱 신경망)은 딥러닝 기법 중에서도 이미지 인식에서 강력한 성능을 발휘합니다. CNN의 기본 개념은 편지봉투에 쓰인 우편번호를 인식하기 위해 1989년 레쿤에 의해 제안되었습니다. 그 후 1998년에 초기 CNN인 LeNet-5가 소개되었지만 컴퓨팅 리소스의 한계로 고해상도 이미지 분류에 좋은 성능을 보이지 못한 탓에 당시에는 주목받지 못했습니다.
그 후 컴퓨팅 하드웨어의 계산 능력 향상과 학습 데이터의 증가로 2012년 이미지넷 챌린지에서 알렛스넷(AlexNet)이 기존 모델과는 비교도 할 수 없는 놀라운 성능을 보여준 후 CNN은 이미지 인식의 표준 모델로 자리잡았습니다. 알렉스넷의 아키텍처를 살펴보면 CNN의 기본 개념에 대해 알 수 있습니다. 알렉스넷의 아키텍처는 [그림 7-21]과 같습니다.
알렉스텟은 합성곱 레이어 5개와 완전 연결(fully-connected)레이어 3개로 이루어져 있습니다. 위쪽 레이어와 아래쪽 레이어로 나눤 이유는 알렉스넷이 GPU 2개를 사용하여 만들어졌기 때문입니다. 입력은 가로 224 * 세로 224 크기 이미지입니다. 따라서 224 * 224 * 3(컬러 채널 RGB)행렬로 표현됩니다. 출력은 0부터 1사이의 실숫값 요소로 이루어지는 1000*1 크기의 벡터인데, 요소 하나가 클래스 하나에 속하는 가능성을 나타냅니다. 즉, 알렉스넷은 이미지 하나를 클래스 1000개 중 하나로 분류합니다. 기존 머신러닝과 다른 점은 합성곱 레이어를 통해 피처를 생성하는 겁니다. 즉, 이미지에서 피처를 추출하여 모델의 입력으로 사용하는ㄱ ㅔ 아니라 이미지 자체를 그대로 모델의 입력으로 사용합니다. 그리고 학습과정에서 이미지의 어떤 부분에 중점을 둘지 배우게 됩니다.
7.4.2 합성곱 레이어
합성곱 레이어는 필터를 이용해 입력값을 변형하는 레이어입니다. 7.1.2절 '필터링'에서 필터 원도우를 이미지에 적용하여 이미지를 변환한다는 것을 배웠습니다. CNN의 합성곱 레이어도 비슷한 역할을 수행하지만 7.1.2절의 필터와는 달리 이미지의 행렬을 다른 모형의 행렬로 변경합니다. 예를 들어 [그림 7-22]에서 볼수 있듯 알렉스 넷의 가장 최초의 합성곱 레이어는 11 * 11* 3 크기의 원도우를 사용해 224 * 224 * 3 크기의 이미지를 55* 55* 96 크기로 변경했습니다. 이 행렬의 넓이와 높이는 이미지의 워치와 관련된 특징을 잡아내고 깊이는 이미지의 다양한 피처를 잡아냅니다. 이렇게 하여 입력 이미지의 모든 부분의 정보를 조합한 피처를 96개(깊이의 수) 생성합니다. ConvertJS페이지의 Activation란이 이렇게 생성된 피처들을 보여줍니다. 피처 수를 정하는 데는 특별한 기준이 없습니다. CNN의 성능을 높이기 위해 피처 수, 레이어 수 및 레이어 구조를 어떻게 바꾸어야 하는지 활발하게 연구되고 있습니다.
합성곱은 7.1.2절 '필터링'에서 설명한 필터링 및 7.1.3절 '합성곱'에서 설명한 합성곱 처리와 마찬가지로 원도우를 옮겨가며 구합니다. 이때 원도우를 몇 픽셀씩 옮길 것인지 지정할 필요가 있는데 이를 스트라이드(stride)라고 합니다. [그림 7-23]에서 스트라이드 1인 경우와 2인 경우 원도우를 어떻게 옮기는지 보여줍니다. 알렉스넷은 스트라이드 4, 원도우를 4픽셀씩 옮겨가며 합성곱을 구합니다. 이미지의 가장자리는 [그림 7-4]에 살펴본 제로 패딩을 사용했습니다.
7.4.3 폴링
합성곱 레이어의 결과를 그대로 다음렝이어로 넘길 수도 있지만, 일반적으로는 샘플링으로 볼수 있는 폴링(pooling)단계를 거칩니다. 즉, 생성된 모든 정보를 사용하는게 아니라 다운샘플링된 정보를 사용하는 것으로 과학습을 막고 노이즈에 강한 피처를 생성합니다. [그림 7-24]는 원도우 크기 2 * 2, 즉 스트라이드 2를 이용한 최댓값 폴링(max pooling)과 평균값 폴링(average poooling)을 나타냅니다. 최댓값 폴링은 원도우 안의 가장 큰 값을 뽑는 것이고, 평균값 폴링은 원도우 안의 값들의 평균을 이용하는 겁니다. [그림 7-24]에서 최댓값 폴링의 결과 이미지의 (0,0) 픽셀은 (12, 20, 8, 12)의 최대값인 20으로 채워졌고, (0,1) 픽셀은 (30, 0,2,0)의 최댓값인 30으로 채워졌습니다. 평균값 폴링의 경우 (0,0) 픽셀은 (12, 20, 8, 12)의 평균값인 13으로 채워진 것을 알 수 있습니다. 이렇게 폴링을 이용해 합성곱 레이어의 정보를 압축하여 다음 레이어로 넘기게 됩니다.
그럼 평균값 폴링과 최댓값 폴링 중 어떤 것을 이용해야 할까요? 7.3절 '이미지 인식에 사용하는 피처'에서 살펴보았듯 이미지 인식에서는 이미지의 특징점을 찾은 후 그 주변의 특징량을 이용합니다. 합성곱 레이어의 결괏값이 클수록 이미지 인식에서 중요한 역할을 합니다(강도함수의 극값이 클수록 종요한 것과 마찬가지죠). 따라서 활성화된 결괏값 중 최댓값을 활용하는 최댓값 폴링이 좋은 성능을 낸다고 알려져 있습니다.
7.4.4 활성화 함수
신경망 모델에서 사용되는 비선형합수(activation function)라고 합니다. 비선형합수는 선형합수, 즉 직선으로 표현할 수 없는 데이터 사이의 관계도 표현할 수 있으므로 [그림 7-25]에서 선형함수, 대표적인 활성화 함수인 시그모이드 함수, 하이퍼볼릭 탄젠트, ReLU(rectified linear unit)함수를 볼 수 있습니다.
- 선형함수 : y = x
- 시그모이드 함수 : y = 1 / ( 1 + exp(-x))
- 하이퍼볼릭 탄젠트 함수 : y = (exp(x) - exp(-x))/(exp(x) + exp(-x))
- ReLU 함수 : y = max(0,x)
알렉스넷 이휴 합성곱 신경망 모델에서는 더 빠른 계산을 위해 ReLU를 이용합니다. ReLU는 입력값이 0보다 작을 때는 무시하고 , 0보다 클 때는 입력값을 그대로 사용하는 것으로 간단하게 비선형함수를 구현할 수 있고 괜찮은 성능을 보장하므로 자주 사용됩니다.
7.4.5 완전연결 레이어
완전연결 에이어는 일반적인 신경망과 같은 방식으로 이전 레이어의피처와 다음 레이어 사이의 모든 연결을 고려합니다. 즉, 원도우를 이용한 필터나 폴링으로 인한 변형 없이 입력 데이터를 그대로 이용합니다.
CNN은 합성곱 레이어 폴링을 반복하는데 이 과정에서 이미지의 강한 지역 피처들의 특징을 합성하여 전역적인 특징도 표현하게 됩니다. 알렉스넷에서는 하나의 이미지가 클래스 1000개의해당하는 확률을 출력하므로 최종 결과는 7.4.1절 'CNN 소개'에서 보았듯 이미지의 클래스 확률을 나타내는 1000*1 크기의 벡터입니다. [그림 7-26]에서 입력 이미지를 합성곱 레이어를 이용하여 변환한 뒤 와전연결 레이어에 통과시킨 결과 고양이 카페고리에 속할 확률이 가장 높게 나왔습니다. 따라서 이 이미지는 고양이로 분류됩니다.
7.5 마치며
이 장에서는 이미지 인식에 필요한 기본 개념과 주요 기법 및 알고리즘에 대해 고부했습니다. 특히 이미지 연구에서 좋은 성능을 보이는 CNN에 대해서도 가단히 설펴봤습니다. 이미지 인식의 필수 개념인 회전 불변성, 크기 불변성, 평행이동 불변성에 대해 이해하고 전통적인 이미지 치러체 대해 이해하여 합성곱 레이어와 폴링을 사용하는 이유를 알게 되었습니다.
이장에서 소개한 대부분의 기법은 다양한 프로그래밍 언어의 라이브러리로 구현되어 있습니다. 이에 대해서는 13장에서 살펴보겠습니다.
댓글 없음:
댓글 쓰기