본문 바로가기

Deep Learning for Computer Vision

EECS 498-007 / 598-005 Lecture 2 : Image Classification

강의 링크

https://www.youtube.com/watch?v=0nqvO3AM2Vw&list=PL5-TkQAfAZFbzxjBHtzdVCWE0Zbhomg7r&index=2

 

강의 슬라이드

https://web.eecs.umich.edu/~justincj/slides/eecs498/498_FA2019_lecture02.pdf

 

=====================================================================

Image Classification은 Computer Vision의 핵심 요소 중 하나로, 이미지를 입력으로 받아서 그 이미지가 속한

카테고리를 출력으로 반환하는 작업을 지칭하는데

이 작업을 사람이 한다면 무척 간단한 작업이지만 컴퓨터가 하기에는 상당히 어려운 작업이다

이러한 사람과 컴퓨터간의 차이를 Semantic Gap이라고 지칭한다.

 

 

 

사람이 고양이 이미지를 보고 고양이라고 바로 판단하는 것처럼 컴퓨터가 고양이 이미지를 보고, 즉 raw pixel grid를 보고 고양이와 연관시킬 수 있는 명확한 방법은 없으며

 

심지어 같은 고양이에 대한 이미지라도 고양이에 대한 카메라의 각도가 달라지면 각 이미지마다의 pixel grid는 각 이미지마다 제각기 다르다. 그래서 이런 경우에도 대처할 수 있는 robust한 알고리즘이 필요하다.

 

 

Image Classification 하는 것에 있어 어려움은 각도 뿐만이 아니다.

 

세상에 사람이라고 모두 똑같이 생긴 것이 아닌 것처럼, 같은 카테고리에 속하더라도 약간씩의 차이점은 존재한다.

위 이미지만 보더라도 모두 같은 고양이라는 카테고리로 묶이지만 색깔이나 무늬 등 각 개체별로 차이점을 볼 수 있다.

 

또한 위와 같이 고양이라는 super class에 속하지만 품종이라는 sub class는 모두 다르다. 이런 경우 고양이가 나타내는 공통적인 특징은 무시하고 각 품종간의 차이점으로 이미지를 분류해야 한다.

 

그뿐만이 아니라 이미지별로 제각기 다른 배경도 처리해야하며

 

조명이 다른 것도 해결해야 한다.

 

심지어 이미지 속의 object가 항상 같은 자세만 취하는 것도 아니며

 

일부가 가려진 경우도 있다

 

그럼에도 이러한 어려움을 극복한다면 Image Classification은 천문학, 의학, 생물학 등 넓은 분야에서 매우 유용하게 사용될 수 있다.

 

 

 

 

 

Image Classification은 단독으로 쓰이는 경우도 많지만 다른 작업의 구성하는 하나의 블록형태로 쓰이기도 한다.

 

Object Detection을 수행할 때에는 이미지 속의 각 물체가 어디에 위치해 있는 지를 박스를 그려서 표현하는데, 이때

 

박스를 옮겨 가면서 매번 박스에 대해서 Image Classification을 수행하는 Sliding Window라고 불리우는 작업을 

수행하며 물체를 탐지한다.

 

Object Detection 말고도 Image를 설명하는 Image Captioning도 Image Classification을 이용하여 구현된다고 한다.

 

컴퓨터 게임에서의 AI 시스템도 Image Classification이 사용된다.

위의 바둑 게임에서는 AI는 Image Classification을 통해 현재 바둑돌이 놓인 위치를 인식한다.

 

 

이처럼 여러 복잡한 문제들도 Image Classification을 통해 구현할 수 있다.

그러므로 강력한 Image Classification 알고리즘을 만든다면 이런 문제들을 해결하는 것은 그다지 어려운일이

아닐 것이다.

 

하지만 숫자를 정렬할 때와 같이 어떤 이미지가 주어던지, 어떤 방식으로 분류해야 하던지 항상 강력하게 작동하는

알고리즘을 구현하는 마법 같은 방법은 없다.

 

위와 같이 사람이 직접 고양이를 인식하는 프로그램을 만든다고 하자. 그런데 만약에 고양이의 각도가 달라진다면, 조명이 달라진다면, 무늬가 달라진다면? '크다', '작다', '같다'만 고려하면 되는 숫자 정렬 프로그램과는 달리 고양이 이미지의 경우의 수는 무한하다. 그래서 사람이 이런 무한한 경우의 수를 고려해서 프로그램을 만들기란 불가능에 가깝다.

 

반면에 머신러닝을 사용하는 경우, 컴퓨터에 데이터와 그에 대한 레이블만 학습시킨다면 머신은 그 레이블만의

feature을 추출해내고, 나중에 학습하지 않은 이미지가 주어진다 하더라도 알아서 이미지 속의 feature를 찾아서

적절히 분류해낼 수 있다.

이 과정에서 사람이 해야하는 것은 어떻게 학습 시킬지, 그리고 학습된 결과를 가지고 어떻게 이미지를 분류해낼지만

프로그래밍 해주면 된다. 이미지 속의 object의 각도, 배경, 조명 등을 고려할 필요가 없기에 부담은 훨씬 덜하다.

또한 머신러닝을 사용한다면 일종의 Generic Program을 만들 수 있는데, 고양이를 분류하고 싶으면 고양이 데이터를 

학습시키고, 비행기를 분류하고 싶으면 비행기 데이터를 학습시키기만 하면 고양이를 분류하는 프로그램, 비행기를

분류하는 프로그램이 만들어지게 된다.

 

Image Classification을 머신러닝을 통해 구현할 때에는 데이터로 구현이 완성되는 특성 상, 그에 따른 데이터가

필요하다.  그래서 이를 위해 누구나 이용할 수 있는 여러 Data Set들이 제공되고 있다.

 

MNIST는 0부터 9까지의 숫자들로 이루어진 Data Set으로 8,90년대 Computer Vision이 주로 사용된 글자 인식(OCR)

프로그램을 테스트 할때에 실제로 사용된 데이터이다. 하지만 MNIST는 현대의 Computer Vision에서 사용되기에는 

상대적으로 단순하기에 머신러닝 모델이 MNIST에서 좋은 결과가 나왔다 하더라도 실제 현장에서도 좋은 결과가 

나올 것이라고는 확신 할 수는 없다.

 

CIFAR 또한 MNIST보다는 복잡하지만 그래도 머신러닝 모델을 증명하기에는 부족하다. 하지만 toy project에 대해서는 유의미하므로 과제에서는 CIFAR10을 사용한다고 한다.

 

Image Classification에서 표준 데이터라 할 수 있을 정도로 머신러닝 모델의 성능을 보여줄려면 필수로 사용해야 한다고 볼 수 있을 정도이다. 이미지 크기는 인터넷에서 자유롭게 원하는 크기의 이미지를 받을 수 있지만

보통 256 X 256 크기를 사용한다.

그리고 이미지에서 보통 1개의 object만 존재하는 경우는 거의 없어서 보통 top 5 accuracy라는 방식을 이용한다.

또한 22k class의 Data Set도 있지만 그다지 사용하지는 않는다.

 

ImageNet이 Object에 집중했다면 MIT Places는 이름처럼 scene type에 집중한 Data Set이다.

 

 

MNIST부터 MIT Places까지 DataSet은 크기가 점점 커졌지만, 모든 DataSet이 그런 것은 아니다

 

Omniglot은 각 카테고리별로 20개 밖에 되지 않을 정도로 크기가 작다. 이 Data Set은 머신러닝 모델이

적은 수의 데이터에 대해서도 잘 작동하는지 확인하기 위해 사용된다.

 

Image Classification에서 사용되는 머신러닝 알고리즘 중에는 'Nearest Neighbor'란 것이 있다.

Train 과정에서는 train data를 저장하고 predict 과정에서는 예측할 이미지를 입력으로 받아서 사전에 저장한 

train data에서 가장 유사한 이미지를 찾고 해당 이미지의 레이블을 리턴한다.

 

이 과정에서 이미지 간의 유사성을 알려면 distance metric을 선택해서 계산해야하는데

 

보통 L1 distance 혹은 Manhattan distance라고 불리는 것을 많이 사용한다.

 

Nearest Neighbor의 시간 복잡도의 경우 train과정에서는 포인터와 같은 메커니즘을 사용한다면 O(1), test 과정에서는 

모든 데이터를 살펴봐야 하기에 O(N) 만큼 걸린다.

 

머신러닝을 사용할 때에는 대부분의 경우 train할 데이터보다 predict할 데이터가 많다. 그렇기에 predict 과정에서 

많은 시간이 소요되는 brute force 방식의 Nearest Neighbor Classifier는 그다지 좋은 모델이 아니다.

꼭 Nearest Neighbor 모델을 써야한다면 brute force 방식보다 빠른 방식을 사용한 다음 링크의 모델을 사용하는 것을

추천한다.   https://github.com/facebookresearch/faiss

 

위 결과는 Image Classification에 L1 distance를 적용한 Nearest Neighbor를 사용한 결과로 이미지의 유사도를

distance metric으로 구하는 Nearest Neighbor 특성상 semantical하게 의미있는 이미지로 제대로 분류하지 못하였다.

10개 중 겨우 4개만이 제대로 분류가 되었음을 알 수 있다.

 

 

Nearest Neighbor를 활용한 모델에는 Nearest Negibor를 직접적으로 사용하는 모델만이 있는 것은 아니다

 

 

위 모델은 Nearest Neighbor를 찾아서 같은 카테고리에 속하는 것끼리 묶는다. 그리고 그 집합간의 Boundary를 긋고

predict할 데이터가 주어졌을 때 해당 데이터가 속한 Boundary의 카테고리가 곧 그 데이터의 카테고리가 된다.

이러한 방식으로 그은 Boundary를 Decision Boundary라고 부른다.

 

Decisoin Boundary에서는 위와 같이 특정 영역에서 튀어나오거나 동떨어진 것과 같은 노이즈가 존재할 수 있다. 

 

 

그러한 노이즈는 Decision Boundary를 그을 때 사용하는 Neighbor의 수를 증가시키면 튀어나온 부분을 완화할 수 있다.

또한 다른 데이터들과 동떨어져 존재하는 이상치의 영향도 완화할 수 있다.

 

하지만 그에 대한 반대급부로 어떠한 카테고리로도 정해지지 않는 공백 지역이 생길 수 있다.

 

Decision Boundary는 Distance Metric에 따라서도 달라지는데 2차원 데이터에서 L1을 사용하는 경우 boundary는 수직 혹은 수평과 평행하거나 45도 각도를 이루며 L2를 사용할 경우에는 아무런 제약없이 자유롭게 형성된다.

 

 

Distance Metric을 선택하는 것에 있어 절대적인 공식 같은 것은 없다. 하지만 적절한 metric을 선택한다면 어떠한 

데이터가 주어지든지 K-Nearest Neighbors를 적용해서 좋은 결과를 얻을 수 있다.

 

Hyperparameter는 학습 데이터를 통해 학습하는 것이 아니라 사전에 미리 정하는 parameter를 말한다. 

예를 들어 K-Nearest Neighbor의 경우 K 값과 distance metric이다. Hyperparameter는 모든 경우를 포괄하는

최적해가 존재하지 않기에 일반적으로는 Hyperparameter를 정할 때에는 가능한 경우를 모두 수행해본 후에 그 중 최고의 parameter를 선택할 필요가 있다.

 

 

Hyperparameter를 선택하는 방법으로는

 

첫째로 주어진 데이터에 가장 적합한 hyperparameter를 정하는 것이 있다. 하지만 이 경우 겉보기에는 

그럴듯해 보이지만 추후에 predict할 상황에서 train data에 없던 data가 주어지는 경우에도 잘 작동한다는 보장이

없다.  K-Nearest Neighbor만 보아도 K=1이면 train data에 대해서는 항상 완벽한 결과가 나온다. 하지만 이 경우

사전에 학습되지 않은 데이터를 입력으로 받거나,  노이즈로 인해 생기는 문제에는 속수무책으로 당할 수 밖에 없다.

 

두번째로 데이터를 train과 test로 나누고 train data로 모델을 학습시켰을 때에 test data를 예측했을 때 최고의 결과를

만들어내는 hyperparameter를 찾는 방법이 있다. 이 방법은 이전보다는 낫지만 hyperparameter를 뽑을 때 test data에 적합한 hyperparameter를 뽑는 것과 같아서 test data에 overfit된 모델을 만들 수 있다는 문제를 내재한다.

 

세번째 방법으로는 데이터를 train, validation, test로 나누는 방법이 있다.

모델을 먼저 train으로 학습시키고 validation data로 최적의 hyperparmeter를 정하고 마지막으로 test data에 대해서도

잘 작동하는지 확인함으로써 최종 점검을 한다. 이렇게 하면 이전의 방식에서의 잠재적인 overfit 문제를 피할 수 있다.

 

마지막으로  data set을 train과 test로 쪼개고 train을 다시 한번 더 여러 개의 fold로 쪼갠다. 그리고 fold를 번갈아가며

validation data로 정하고 세번째 방법과 동일한 방식으로 hyperparmeter를 정한다. 이 경우 이론적으로는 가장 좋은

방법이지만 그만큼 요구되는 계산량이 크기에 데이터와 모델을 고려해서 적용해야한다. 그래서 기본적으로 대규모의

연산이 요구되는 딥러닝에서는 많이 사용되지는 않는다. 

 

K-Nearest Neighbor는 training sample이 많으면 많을수록 어떤 함수든 표현 가능하다. 즉 머신러닝 모델 또한 입력이 데이터, 출력이 예측값인 함수로 표현 가능하므로 어떤 문제든 처리 가능하다고 할 수 있다.

 

Curse of Dimensionality (차원의 저주)

특정한 data space를 모두 포괄하는 training set은 해당 data의 차원이 증가할때마다 지수함수적으로 증가한다

 

예를 들어, 32 X 32 크기의 binary 이미지의 경우 존재 가능한 이미지가 약 10308 존재한다. 관측가능한 우주에

존재하는 소립자의 수가 대략 1097정도라는 것을 생각하면 이 간단한 binary 이미지의 space를 모두 커버하는

데이터를 모으는 것조차 불가능하는 것을 알 수 있다.

 

데이터가 많으면 많을수록 좋은 K-Nearest Neighbor 알고리즘 특성상 raw pixel에 대한 K-Nearest Neighbor 알고리즘은 현실에서는 그다지 쓰이지 않는다 predict 시간도 오래 걸리고, predict이 적절하게 이루어지려면 데이터도 매우 많이 필요하다. 또한 위에서 볼 수 있듯이 raw pixel value에 적용한 distance metric의 결과도

semantically meaningful 하지 않다.

 

하지만 ConvNet을 이미지에 적용시켜 구한 feature vector를 가지고 K-Nearest Neighbor를 적용하면 
semantically meaningful 하며 괜찮은 결과를 얻을 수 있다고 한다.

 

요약

 

2강은 여기까지였는데, 강의 듣는 시간보다 강의 정리하고 포스팅 하는 시간이 몇 배는 되는 거 같다 ㅜㅜ

강의만 들었으면 최소 5강까지는 나갔을거 같기도 하고 좀 간략하게 핵심만 정리해야 하나...

어쨌든 1강에서 언급했던대로 과제가 벌써 나왔다.

https://web.eecs.umich.edu/~justincj/teaching/eecs498/FA2020/assignment1.html

 

Assignment 1

Website for UMich EECS course

web.eecs.umich.edu

과제는 파이토치 튜토리얼과 K-Nearest Neighbor 구현으로 이루어져 있는데, 파이토치는 튜토리얼 답게

쉽다. 파이썬 튜토리얼과 비슷했던거 같다. 근데 좀 문제가 많아서 생각보다 시간 많이 잡아 먹었다.

그리고 K-Nearest Nieghbor는 과제가 19년도 과제에서 몇 가지가 추가되었는데, 과제 설명 부분에서 이게

설명이 안 되어 있어서 은근히 시간 잡아 먹혔다.ㅜㅜ  현강이었으면 피드백 받았겠지만, 유튜브 강의다보니 아쉽지만

어쩔 수 없는 점이겠지만

728x90