본문 바로가기

Study doc./Deep Learning

[cs231n] kNN보다 나은 선형분류(Linear Classification)

지난 포스팅에서 이미지 분류 기법 중 하나인 k-NN 에 대해 공부해보았습니다.

하지만 모든 사진의 픽셀 행렬값을 연산하는 방법은 너무 비효율적이기 때문에 실무에서는 사용하지 않는다고 했고,

오늘은 그 문제점을 극복한 선형 분류(Linear Classification) 기법을 공부해보겠습니다.

 

 

순서

  1. 선형 분류의 원리
  2. 오차 함수(Loss function)의 등장
  3. 규제 (Regularization)
  4. 최적화 (Optimization)
  5. 결론

 


 

1. 선형 분류의 원리

말 그대로 선형 분류는 이미지를 선형식으로 나타낸 후 분류하는 기법입니다. 

이전 포스팅에서 이미지는 픽셀별 숫자의 형태, 즉 행렬의 형태로 나타난다고 했었는데요,

이 행렬의 특성을 이용하여 가중치 w와 편향값 b를 추가하여 선형식으로 변환하는 것입니다.

 

선형식을 만드는 과정은 다음과 같습니다.

먼저 이미지의 행렬값을 하나의 열로 쭉 편 다음, 가중치를 곱해주고 편향값을 더해주면 됩니다.

이때 가중치 행렬의 사이즈는 (카테고리 수 * 하나의 열로 편 이미지 행의 수) 가 되어야 합니다.

 

 

이렇게 선형식을 거치면 카테고리 수만큼의 값이 나오게 되는데, 그 값들을 각 카테고리별 점수라고 생각하시면 됩니다.

이 점수를 이용하여 테스트 이미지가 어떤 카테고리에 속하는지 판단하는 것입니다.

 

 

위 사진을 보면 강아지 카테고리의 점수가 437.9로 가장 높기 때문에 해당 이미지는 강아지라고 판단하게 됩니다.

 

 

2. 오차 함수(Loss function)의 등장

선형함수의 가중치(W)와 편향값(b)는 어떻게 정할까요?

바로 오차 함수를 정의하고, 그 오차를 최소화하는 w와 b를 찾는게 기본 개념입니다.

cs231n 강의에서는 두 가지 오차함수를 설명했는데요, 그 함수들에 대해 정리해보겠습니다.

 

1) 첫 번째로 SVM 오차 함수(hinge loss) 입니다.

SVM 오차 함수의 규칙은 다음과 같습니다.

  1. 선형식을 통해 빠져나온 카테고리별 점수를 확인합니다. 정답 카테고리의 경우에는 loss = 0
  2. (현재 카테고리 점수 + 1)이 정답 카테고리 점수보다 작은 경우 loss = 0
  3. 높은 경우 loss = (현재 카테고리 점수 +1) - (정답 카테고리 점수) 으로 합니다.
  4. 나오는 loss를 모두 더하고, 최종 오차값은 그 합의 평균으로 합니다.

* 여기서 +1(stafy margin)을 하는 이유는 운 좋게(정답 카테고리 점수와 현재 카테고리 점수의 차이가 미세한 경우) 판단되는 경우를 구분하기 위해서 입니다!!

 

여기서 최종 오차값은 (2.9 + 0 + 12.9) / 3 으로 5.27 입니다.

 

 

2) 두 번째 softmax 오차 함수(cross entropy loss) 입니다.

softmax 오차 함수의 규칙은 다음과 같습니다.

softmax 오차함수의 경우에는 svm 오차함수에 비해 잘못된 예측에 대한 패널티를 많이 줍니다(-log때문에).

패널티를 많이 주는게 좋은지, 조금 주는게 좋은지는 모델의 목적에 따라 다릅니다!!

  1. 선형식을 통해 빠져나온 카테고리 점수를 e에 제곱해줍니다.
  2. 정규화를 통해 확률값으로 만들어줍니다(다 더했을때 1이 되게).
  3. -log 를 씌워줍니다(높은 확률일수록 낮은 오차를 표현하기 위해).

 

 

3. 규제 (Regularization)

오차를 어떻게 구하는지 알아봤습니다. 

그럼 이걸 바로 오차함수로 봐도 될까요?

아직 안됩니다!! 과적합(overfitting)의 경우를 생각해야 합니다.

따라서 loss를 구한 후 복잡도를 제어하는 함수를 더해주는데요, 이를 규제(Regularization) 이라고 합니다.

 

식은 λ * R(W) 로 나타납니다.

R(W) 를 규제식이라 하고, 람다(λ)는 이 규제의 정도를 조절하는 역할입니다.

람다가 높을수록 규제를 많이 하고, 오차함수의 그래프가 평평(초록색 선)해지겠죠.

 

 

4. 최적화(Optimization)

자!! 이제 loss에 regularization을 더해서 오차함수를 정의했습니다.

이 오차함수는 왜 정의한거죠?

바로 최적의 가중치(w)와 편향값(b)를 구하기 위해서 였습니다.

 

잠깐!! 오차함수랑 최적화랑 어떤 관련이 있을까요?

gradient를 이용해서 오차함수를 최소화하는 w와 b 값을 찾는 과정이 최적화입니다.

 

따라서 우리는 최적의 w를 찾기 위해 loss를 비교하는 과정을 거쳐야 합니다.

아래의 그림과 같이 기존 w 원소들을 순서대로 하나씩 변화시킬때의 loss값을 비교하며 새로운 w를 정의합니다.

이런 방법을 numerical gradient 라고 합니다.

 

numerical gradient

 

numerical gradient 는 정확하지만, 그만큼 시간이 오래걸리는 단점이 있습니다.

이를 해결하기 위해 뉴턴과 라이프니츠의 미분식을 사용하게 됩니다.

이렇게 미분식을 활용하여 w를 찾는 방법을 analytic gradient 라고 합니다.

참고로 dw로 나온 행렬이 바로 w가 되는 것이 아닌, 사용자가 정의한 step size와 dw를 곱해서 기존의 w에 뺀 행렬이 새로운 w가 되는 것입니다(빼는 이유는 loss가 0에 가까울수록 좋기 때문입니다.). 

 

# Gradient Descent code
while:
    weights_grad = evaluate_gradient(loss_fun, data, weights)
    weights = weights - (step_size * weights_grad)

 

analytic gradient

하지만 여기서도 문제가 있는데요, 시간을 훨씬 단축시킨 만큼 에러의 확률도 높아지게 되었습니다.

그래서 보통 analytic gradient 를 사용하고, 디버깅을 할때 numerical gradient를 사용한다고 합니다.

 

시간이 많이 걸리는 곳이 새로운 w를 계산하는 곳에만 있는 것이 아닙니다.

w를 비교하기 위해서는 빠르게 loss값을 구해야 하는데, 데이터의 갯수가 엄청나게 많다면 한 번의 loss 값을 구하는데에도 시간이 많이 소요되게 됩니다.

 

이를 해결하기 위해 나온 개념이 'Stochastic Gradient Descent (SGD)' 입니다. 

이는 train set에서 랜덤으로 몇가지만 가져와서 계산하며 w와 b값을 조절하는 것입니다.

이 때 2의 승수(ex. 256, 512) 단위를 사용하는데, 예를 들어 처음 256개를 가지고 w를 조절했다면, 그 다음 다른 256개를 가져와서 또 조절하고 하는 방법입니다.

# Gradient Descent code
while:
    data_batch = sample_training_data(data, 256)
    weights_grad = evaluate_gradient(loss_fun, data_batch, weights)
    weights = weights - (step_size * weights_grad)

 

 

5. 결론

지금까지 선형 분류의 방법에 대해서 정리해봤습니다.

정리해보자면 컴퓨터는 이미지를 숫자로 인식하기 때문에 행렬식으로 나타낼 수 있고, 

이 행렬식에 가중치(w)를 곱하고 편향값(b)을 더해서 나온 점수를 통해 이미지를 분류할 수 있었습니다.

이때 가장 잘 분류하는 가중치와 편향값을 구하기 위해 오차함수를 정의하고, 경사 하강법 등의 기법을 통해 최적의 두 값을 구할 수 있었습니다.

 

 


 

 

기본적으로 영어강의이기 때문에 이해하지 못하는 부분도 많고, 아직 부족한 부분도 많기 때문에 틀린 부분이 있을 수 있습니다. 

혹시 포스팅에서 잘못된 부분이 있다면 언제든 피드백 해주세요!! 

 

그리고 공부한 내용을 정리하면서 이 분의 포스팅에서 많은 도움을 받았음을 밝힙니다!!