본문 바로가기
cs231n

[cs231n] Lecture 2

by 이재현9999 2025. 2. 17.

lecture 2

Image Classification

우리는 위의 사진을 볼 때 단번에 고양이가 보일 것이다. 하지만 컴퓨터에게 이미지는 단순히 숫자의 집합에 불과하다.

이러한 차이를 우리는 Semantic gap이라고 한다.

또한 카메라를 옆으로 조금만 옮겨도 모든 픽셀값들이 완전히 달라지지만, 이 사진이 고양이라는 것은 변함이 없을 것이다.

즉, 우리의 알고리즘은 조명, 각도, 방향, 객체의 변형, occlusion 등과 같은 조건에 robust해야할 것이다.

그렇다면 어떤 요소들이 이를 가능하게 할까?

데이터 중심 접근방법(Data-Driven Approach)

방대한 양의 데이터를 학습하자.

입력 이미지를 고양이로 인식하려면 두 개의 함수가 필요하다.

  1. Train 함수
    1. 입력 : 이미지, 레이블
    2. 출력 : 모델
  2. Predict 함수
    1. 입력 : 모델
    2. 출력 : 이미지의 예측 값

더 알아보기전에 잠시 간단한 Classifier를 알아보자.

Nearest Neighbor (NN)

NN 알고리즘은 매우 간단하다.

Train Step에서는 아무 일도 하지 않고 모든 학습 데이터를 기억한다.

Predict Step에서는 새로운 이미지가 들어오면 새로운 이미지와 기존 학습 데이터를 비교해서 가장 유사한 이미지로 레이블링을 예측한다.

간단하지만 Data-driven Approach 로써 아주 좋은 알고리즘이다.

 

Machine Learning에서 자주 쓰이는 연습용 데이터셋인 CIFAR10을 예시로 보자.

위 그림처럼 유사한 순서대로 그림이 정렬된다.

이 이미지에서 NN 알고리즘을 적용하면 트레이닝 셋에서 “가장 가까운 샘플”을 찾게 된다.

 

그렇다면 이미지 쌍이 있을 떄는 어떻게 비교할 것인가?

L1 distance ( Manhattan distance )

4x4 테스트 이미지가 있다고 생각해보자.

테스트/트레이닝 이미지릐 같은 자리의 픽셀을 서로 빼고 절댓값을 취한다.

그리고 모든 픽셀값을 더한다. 위 사진에는 456만큼 차이가 나는 것을 알 수 있다.



import numpy as np

class NearestNeighbor:
    def __init__(self):
        pass

    def train(self, X, y):
        self.Xtr = X
        self.ytr = y

    def predict(self, X):
        num_test = X.shape[0]
        Ypred = np.zeros(num_test, dtype = self.ytr.dtype)

        for i in xrange(num_test):
            distances = np.sum(np.abs(self.Xtr - X[i, :]), axis = 1)
            min_index = np.argmin(distances)
            Ypred[i] = self.ytr[min_index]

            return Ypred

복잡도는 Train O(1), Predict O(N)이다.

하지만 이는 Test Time에서 N개의 학습 데이터 전부를 테스트 이미지와 비교해야 하기 때문에 이는 매우 느린 것을 알 수 있다.

우리는 Train Time은 조금 느려도 되지만 Test Time에서는 빠르게 동작하기를 원하기 때문이다.

 

이는 NN 알고리즘은 시각화 한 것이다.

점은 학습 데이터를 나타내고, 색은 레이블, 카테고리를 나타낸다.

이 그림을 보면 NN 알고리즘에서 발생 가능한 문제점을 살펴볼 수 있다.

가운데를 보면 노란색이 초록 영역을 침범한 것을 볼 수 있다.

또한 파란 영역에 초록 영역이 침범한 것도 볼 수 있다.

 

이러한 문제를 해결하기 위해 k-NN 알고리즘이 탄생하였다.

K-Nearest Neighbors

 

단순하게 가까운 이웃을 찾는 것이 아닌, Distance metric을 이용해서 가까운 이웃을 K개 만큼 찾고, 이웃끼리 투표하는 방법이다.

가운데의 노란 영역이 없어지고, 빨강/파랑 사이의 뾰족한 경계들도 점차 부드러워지는 것을 볼 수 있다.

참고로 K=1은 사용하지 않는다.

그리고 흰색 영역은 어떻게 처리하는지에 대해서는 흰색 영억은 가장 가까운 이웃이 존재하지 않으면 흰색으로 칠했다. 라고 한다.

 

k-nn을 사용할 때 결정해야 할 한 가지 사항이 더 있다.

바로 서로 다른 점들을 어떻게 비교할 것인지이다.

 

우리는 지금까지 “픽셀 간 차이 절대값의 합”인 L1 Distance를 이용했다.

하지만 Euclidean distance를 사용하는 L2 방법도 있다. 이는 “제곱 합의 제곱근”을 거리로 사용한다.

어떤 “거리 척도(distance metric)”을 선택할지는 아주 중요한 부분인데, 왜냐하면 서로 다른 metric에서는 해당 공간의 근본적인 기하학적 구조 자체가 서로 다르기 때문이다.

왼쪽에 보이는 사각형은 사실 L1 Distance의 관점에서는 원이라고 볼 수 있다.

L1의 경우에는 좌표계가 회전하면 변하고 L2는 좌표계랑 독립적인 것을 알 수 있다.

 

k-nn에 다양한 거리 척도를 사용하면 이미지 외에도 다양한 데이터를 다룰 수 있다.

하이퍼 파라미터 (Hyper Parameter)

앞에서 배웠던 k와 distance와 같은 것들을 하이퍼 파라미터라고 할 수 있다.

하이퍼 파라미터는 우리가 직접 지정해줘야 하는 것이다.

 

그렇다면 어떠한 기준으로 하이퍼 파라미터를 설정해야할까?

 

1. 학습 데이터의 정확도와 성능을 최대화하는 방법. (Only your dataset)

 

이 방법은 가장 나쁜 방법이다. NN 분류기의 경우 k=1일 때 학습 데이터를 가장 완벽하게 분류한다.

기계학습에서는 학습 데이터를 얼마나 잘 맞추는지는 중요하지 않다. 우리가 학습시킨 분류기가 한 번도 보지 못한 데이터를 얼마나 잘 예측하는 지가 중요한 것이다.

 

2. 전체 데이터셋 중 학습 데이터를 쪼개서 일부를 테스트 데이터로 사용. (train, test)

 

학습 데이터로 다양한 하이퍼 파라미터 값들을 학습 시키고 테스트 데이터에 적용시켜본 다음, 하이퍼 파라마미터를 선택하는 방법이다.

이 역시 쓰레기다. 테스트셋으로는 한 번도 보지 못했던 데이터에서의 알고리즘의 성능을 측정할 수 있어야 한다. 이 방법을 사용한다면 우리는 그저 테스트 셋에서만 잘 동작하는 하이퍼 파라미터를 고른 것일 수 있다.

 

3. 데이터를 train, validation, test로 나누는 것.

 

train 데이터를 학습, validation으로 검증한 후 이에서 가장 좋았던 하이퍼 파라미터를 선택한 후 test set에서는 “오로지 한 번만” 수행한다.

 

4. Cross-Validation (교차 검증)

이 방법은 작은 데이터셋일 경우 많이 사용하고, 딥러닝에서는 많이 사용하지 않는다.

 

아이디어는 train을 여러개로 나눈 뒤, 번갈아가면서 validation을 지정해 학습시킨다.

knn은 너무 느리고 L1, L2 distance가 이미지간의 거리를 측정하기에 적절하지 않기 때문에 이미지 분류에 잘 쓰이지 않는다.

또한 knn이 잘 동작하려면 전체 공간을 조밀하게 덮을 만큼의 충분한 학습 데이터가 필요한데, 그 양은 차원이 증가함에 따라 기하급수적으로 증가하고, 현실적으로 이 데이터들을 전부 모으는 것은 불가능하다.

Linear Classification

NN(Neural Network)와 CNN의 기반이 되는 알고리즘이다.

Linear Classification은 “parametric model”의 가장 단순한 형태이다.

 

parametric model에는 두가지 요소가 있다.

입력 이미지를 x, 파라미터를 W라고 한다.

이 함수는 x와 W를 가지고 10개의 숫자를 출력하는데, 이 숫자는 CIFAR-10의 각 10개의 카테고리의 스코어이다.

 

예를 들어, “고양이”의 스코어가 높다는 것은 입력 x가 “고양이”일 확률이 크다는 것이다.

 

knn에서는 파라미터를 사용하지 않고 전체 트레이닝 셋을 Test time에서 비교하는 방식이었다.

parametric에서는 train 데이터의 정보를 요약해서 W에 모아준다. 따라서 Test time에 더이상 트레이닝 데이터를 직접 비교하지 않고, W만 사용할 수 있게 된 것이다.

딥러닝이 이 함수 f의 구조를 적절하게 설계하는 일이라고 할 수 있다.

 

그래서 Linear Classifier은 x와 W를 곱하는 것.

즉, f(x, W) = Wx이다.

 

먼저 입력 32x32x3을 열벡터로 만들면 3072x1이 된다. 이를 x를 W와 곱했을 때, 10개의 스코어가 나와야 하므로, W는 10x3072가 되어야한다. 따라서 이 둘을 곱하게 되면 10-classes 스코어를 의미하는 10x1 짜리 하나의 열 벡터를 얻게 된다.

Bias는 데이터와 무관하게 특정 클래스에 우선권을 부여한다.

 

예시를 보자.

먼저 2x2 이미지를 입력으로 받고 이를 4-dim 열 벡터로 쭉 편다.

여기선 3개의 클래스만 있다고 보자. 그렇다면 W는 4x3 행렬이 된다.

그리고 3-dim bias 벡터도 있다.

 

이러한 Linear Classification은 템플릿 매칭과 거의 유사하다.

가중치 행렬 W의 각 행은 각 이미지에 대한 템플릿으로 볼 수 있고 그 행 벡터와 이미지의 열벡터 간의 내적을 계산하는데, 여기서 내적이란 결국 클래스 간 템플릿의 유사도를 측정하는 것과 유사함을 알 수 있다.

 

가중치 행렬 W의 한 행을 뽑아서 이미지로 시각화 시켜 보면 Linear classifier가 이미지 데이터를 인식하기 위해서 어떤 일을 하는지 짐작할 수 있다.

Linear classifier는 클래스 당 하나의 템플릿 밖에 허용하지 않기 때문에 문제가 발생할 수 있지만, 이는 NN과 같은 복잡한 모델로 해결할 수 있다.

 

Linear classifier에서 이미지를 고차원 공간의 한 점으로 보는 관점으로도 해석할 수 있다.

 

Linear classifier는 각 클래스를 구분시켜 주는 선형 decision boundary를 그어주는 역할을 한다.

 

하지만 홀/짝수를 분류하는 것과 같은 parity problem. 또는 Multimodal problem (맨 오른쪽)은 Linear classifier로는 일반적으로 해결하기 어렵다.