Soft skills/Lecture
[딥러닝 강의] [1] 데이터 기반 이미지 분류 (Data-driven Image Classification)
2020. 1. 23. 21:32그림. 사람과 컴퓨터의 이미지 인식 차이
그림. Rule-based approach vs. Data-driven approach
데이터 기반 방법은 수많은 이미지와 레이블 (ex. 개, 고양이 등) 이 있는 데이터셋을 통해 모델을 학습 (training) 한다. 이 때, 모델을 학습하는 것을 머신 러닝 (Machine Learning) 이라고 말한다. 이렇게 학습된 머신러닝 모델은 새로운 이미지를 인풋으로 받아 그 이미지의 레이블을 예측 (prediction or test) 한다. 즉, 이미지를 분류하는 모델을 만드는 방법 중 데이터 기반 방법을 머신러닝이라고 하며, 머신러닝 모델은 데이터셋을 통해 이미지를 학습하는 과정과 새로운 이미지를 예측하는 과정이 있다. 머신러닝 모델의 학습을 위한 데이터셋은 직접 웹 등으로부터 수집할 수 있다. 또한 ImageNet, CIFAR 등 공개된 질 좋은 데이터셋도 있기 때문에 누구나 직접 머신러닝 모델을 구축해볼 수 있다. 예를 들어, CIFAR-10 데이터셋은 10개의 클래스, 50000개의 트레이닝셋, 10000개의 테스트셋으로 구성된다.
그림. CIFAR-10 데이터셋
이미지 분류를 위한 첫 번째 알고리즘 : Nearest neighbor
데이터 기반 모델의 첫 번째 간단한 예시로 nearest neighbor (NN) 방법을 살펴보자. KNN 방법은 먼저 학습 데이터셋을 저장한 후에, 예측 단계에서는 투입된 이미지와 가장 가까운 데이터의 레이블을 통해 예측 하는 방법이다. 그러면 이미지와 이미지의 가까운 정도 (distance) 는 어떻게 구할 수 있을까? 다양한 지표 (metric) 이 있지만 그 중 한 가지인 L1 distance 는 다음과 같다.
$$ d_1 (I_1, I_2) = \sum_{p} | I_1^p - I_2^p | $$
L1 distance 를 distance metric 으로 사용하는 nearest neighbor 을 파이썬 코드로 아래처럼 구현할 수 있다.
import numpy as np class NearestNeighbor(object): def __init__(self): pass def train(self, X, y): """ X is N x D where each row is an example. Y is 1-dimension of size N """ # the nearest neighbor classifier simply remembers all the training data self.Xtr = X self.ytr = y def predict(self, X): """ X is N x D where each row is an example we wish to predict label for """ num_test = X.shape[0] # lets make sure that the output type matches the input type Ypred = np.zeros(num_test, dtype = self.ytr.dtype) # loop over all test rows for i in xrange(num_test): # find the nearest training image to the i'th test image # using the L1 distance (sum of absolute value differences) distances = np.sum(np.abs(self.Xtr - X[i,:]), axis = 1) min_index = np.argmin(distances) # get the index with smallest distance Ypred[i] = self.ytr[min_index] # predict the label of the nearest example return Ypred
위 코드를 사용해서 테스트셋에 대한 성능을 평가한 결과 38.6 % 정도의 성능을 보인다. 우선, 임의로 찍은 수치 (10 %) 보다 성능이 좋기 때문에 모델을 만드는데 큰 노력을 들이지 않았다는 점을 감안해 괜찮은 수치이다. 하지만 state-of-the-art 인 Convolutional Neural Network 기반 모델의 성능 (95 %) 과 비교하면 매우 낮다.
L1 외에도 다양한 metric 을 쓸 수 있다. 예를 들어, L2 distance 는 다음과 같다.
$$ d_2 (I_1, I_2) = \sqrt{\sum_{p} ( I_1^p - I_2^p )^2} $$
L1 L2 distance 의 차이
L1 과 L2 는 p-norm 계열의 distance measure 이다. 그러면 L1 과 L2 의 차이는 L2 distance 는 L1 distance 를 사용하는 것보다 차이가 큰 것에 더 관대하지 않다는 것이다. 즉, L1 이 아닌 L2 distance 를 쓴다는 것은 여러개의 dimension 에서 적당한 차이를 보이는 것보다 하나의 dimension 에서 큰 차이를 보이는것에 더 페널티를 많이준다는 의미다.
K-nearest neighbor
nearest neighbor (NN) 은 단점이 많은 알고리즘이다. 먼저, NN 은 단 하나의 label 만 prediction 에서 고려하기 때문에 안정성이 떨어지는 결과를 보여준다. 한 마디로 성능이 떨어진다. 이를 보완하기 위해 k-nearest neighbor (KNN) 를 활용할 수 있다. 이 방법은 테스트 (또는 예측) 단계에서 인풋과 가까운 순으로 총 k 개의 데이터의 레이블을 구한 후, 가장 빈번하게 나오는 레이블로 예측하는 방법이다. 이렇게 여러개로부터 가장 빈번하게 나오는 것을 예측 결과로 하는 것을 머신러닝에서는 voting 이라고 부른다.
그림. k-nearest neighbor
위 그림을 보면 NN 대신에 K-nearest neighbor 을 사용하면 어떤 장점이 있는지 확인할 수 있다. NN 에는 이상치 (outlier) 를 중심으로 섬과 같은 지역 (decision boundary) 가 생긴다는 것을 볼 수 있다. 하지만 KNN 의 경우, 이상치에 더 둔감하다. NN 의 경우 이상치에 민감하기 때문에 트레이닝 데이터에 국한된 규칙을 배울 가능성이 높다. KNN 을 사용하면 처음 보는 데이터 (unseen data) 대한 성능 (generalization)이 높을 것임을 짐작할 수 있다. 그리고 처음 보는 데이터를 올바르게 예측하는 것이 머신러닝 방법을 사용한 예측 모델링의 주요 목적이다. K-nearest neighbor 를 실제로 사용할 때 한가지 고려 사항은 k 를 어떻게 정하냐는 것이다. k 가 높으면 물론 좋겠지만 그만큼 테스트 단계에서의 계산량이 매우 많아진다는 단점이 있다.
Validation set 을 통한 Hyperparameter tuning
K-nearest neighbor 에서 우리가 정해야할 것은 k 와 distance function 이다. 이를 알고리즘 자체의 파라미터, hyperparameter 라고 한다. 그리고 이를 조정하는 방법을 hyperparameter tuning 이라고 한다. 머신러닝에서 hyperparameter tuning 을 하는 주 방법은 여러번 해봐서 가장 좋은것을 찾는 것이다. 이것은 별다른 아이디가 없을 때 좋은 방법이다. 하지만 hyperparameter 를 찾는데 테스트셋을 사용할 수는 없다. 머신러닝에서 테스트셋은 성능을 평가하는 것 이외에 다른 목적으로 쓰일 수 없다. 만약 테스트셋으로 hyperparameter tuning을 하면 모델이 테스트셋에 과적합 (overfitting) 되며, 다른 처음보는 데이터에 적용했을 때 상당히 성능이 떨어지는 문제를 겪게 된다. 테스트셋은 반드시 모델 구축이 끝난 후, 단 한 번 평가 되어야 한다. 따라서 방법은 트레이닝 셋의 일부를 hyperparameter tuning 을 위하여 분할하여 사용하는 것이다. 이를 validation set 이라고 부른다. validation set 을 통한 hyperparameter tuning 은 머신러닝에서 중요한 개념 중 하나이다. Validation set 을 통한 Hyperparameter tuning 을 아래와 같은 파이썬 코드로 구현해볼 수 있다.
# assume we have Xtr_rows, Ytr, Xte_rows, Yte as before # recall Xtr_rows is 50,000 x 3072 matrix Xval_rows = Xtr_rows[:1000, :] # take first 1000 for validation Yval = Ytr[:1000] Xtr_rows = Xtr_rows[1000:, :] # keep last 49,000 for train Ytr = Ytr[1000:] # find hyperparameters that work best on the validation set validation_accuracies = [] for k in [1, 3, 5, 10, 20, 50, 100]: # use a particular value of k and evaluation on validation data nn = NearestNeighbor() nn.train(Xtr_rows, Ytr) # here we assume a modified NearestNeighbor class that can take a k as input Yval_predict = nn.predict(Xval_rows, k = k) acc = np.mean(Yval_predict == Yval) print 'accuracy: %f' % (acc,) # keep track of what works on the validation set validation_accuracies.append((k, acc))
Nearest neighbor 은 잘 작동할까?
nearest neighbor 은 매우 이해하기 쉬운 알고리즘인 반면 여러 단점이 존재한다.
1) 현실적인 단점은 NN은 테스트 단계에서 시간이 오래걸린다는 것이다. 모든 n 개의 트레이닝 데이터에 대해서 distance 를 구해야하기 때문에 O(n) 의 복잡성을 갖는다. 따라서 현실의 어플리케이션에 적용하기는 매우 어렵다. (NN 의 테스트 단계에서의 계산 복잡성을 줄이기 위해 Approximate Nearest Neighbor (ANN) 도 연구가 활발히 이루어지고 있는 분야이다. ANN 을 구현한 FLANN 라는 것도 있다. 기본 아이디어는 kdtree 나 k-means 알고리즘 등을 통해 데이터 인덱싱을 먼저 수행하여 테스트 단계에서 조회할 데이터를 줄이는 것이다.)
2) NN 우리의 물체의 유사성에 대한 인식 (perceptual similarity) 과 부합하지 않는 결과를 내놓을 수 있다. 아래 그림은 모두 original 데이터와 L2 distance 를 기준으로 같은 유사성을 보이도록 이미지를 변환한 것이다 예를 들어 우리가 original 과 shifted 이미지를 인식할 때, 피사체의 위치에 차이만 있을 뿐 물체에는 아무런 차이가 없다. 하지만 단지 물체가 옆으로 이동한 것만으로도 상당한 distance 가 생기게 된다는 것이다.
그림. 원본 이미지와 같은 L2 distance 를 갖는 이미지 모음
Raw-pixel 을 이용한 모델은 왜 실패하는가?
왜 이런 문제가 생길까? 문제는 물체의 특성이 아닌 각 픽셀을 기준으로 차이를 비교한다는 것이다. 물론 픽셀이 이미지의 특성을 반영하지만, 픽셀 값의 많은 부분이 물체 인식과 크게 관련이 없다. 아래 그림은 CIFAR-10 데이터셋에 t-SNE 를 적용해 이미지를 2차원으로 표현한 것이다. 이렇게 고차원을 저차원으로 바꾸는 것을 dimension reduction 또는 embedding 이라고도 부른다. 고차원 데이터를 공간상에 표현하는 것이 힘들기 때문에 이와 같이 저차원으로 바꾸어 표현하고자 한 것이다. 이상적으로는 CIFAR의 10개의 클래스에 맞게 군집화 되어야한다. 하지만 그림을 자세히 살펴보면 물체에 인식과 관련있는 특성 뿐 아니라 배경, 또는 색깔 등에 큰 영향을 받는다는 것을 알 수 있다. 즉, 픽셀은 물체에 대한 인식 뿐 아니라 불필요한 것까지 표현한다. 따라서 raw-pixel 을 기준으로 nearest neighbor 을 적용 하는 것은 적절하지 않은 방법이다. 단지, nearest neighbor 뿐 아니라 raw-pixel 을 output 으로 direct mapping 하는 대부분의 머신러닝 알고리즘은 같은 이유로 이미지 데이터에 효과적으로 적용되기 어렵다. 어떻게 이미지를 '우리의 인식과 관련 있는 특성' 으로 요약할 수 있을지에 관한 것이 representation learning 이며, 이것은 딥러닝 (deep learning) 의 핵심 아이디어이다.
그림. CIFAR-10 의 tSNE를 통한 2차원 임베딩
Summary
- 데이터 기반 이미지 분류의 기본 개념 1) 이미지-레이블 데이터셋을 통해 모델 학습 2) 새로운 데이터에 대해 예측
- Nearest Neighbor 을 통해 이미지 분류 하는법 + Validation set 을 통해 hyperparameter tuning 하는 방법
- training, validation, test set 의 개념. test set 은 모든 프로세스에서 반드시 한 번만 사용되어야 한다.
- Raw-pixel 에 을 output 으로 direct mapping 해서 모델을 만드는 것이 실패하는 이유 (인식과 표현의 차이)
참고
'Soft skills > Lecture' 카테고리의 다른 글
[딥러닝강의] [2] GPU 와 딥러닝 소프트웨어 (2) | 2020.02.07 |
---|