본문 바로가기
Deep Learning

[CS231n] 02. Loss Functions and Optimization

by TaekGeun 2022. 1. 26.

지난 포스팅에서 다뤘던 Linear Classifier에 대해서 다시 한번 간단하게 얘기하면서 본 포스팅을 시작하도록 하겠습니다.

 

Linear Classifier의 핵심은 어떤 복잡한 고차원의 특징 공간 내에서 서로 다른 클래스 간의 구분을 위한 선형의 결정 경계를 만들어주는 방법론이라 다루었습니다.

 

대충 수식으로 $w_{11}x_{1}+w_{12}x_{2}+w_{13}x_{3}+w_{14}x_{4}+b_{1}$ 이렇게 정의할 수 있었습니다.(특징 벡터가 4차원으로 정의되었을 때의 경우입니다.)

 

그렇다면 저 $w_{11},w_{12},w_{13},w_{14},b_{1}$ 이 녀석들은 어떻게 찾아야 할까요?

 

$w_{11},w_{12},w_{13},w_{14},b_{1}$ 여기에 아무런 값이나 들어가면 우리가 원하는 대로 구분을 잘할 수 있는 경계는 얻지 못할 것입니다. 좀 더 nice한 boundary를 찾기 위해서는 현재의 boundary가 구분을 잘하고 있는지 못하고 있는지에 대한 정도를 나타낼 수 있는 정량적인 값이 정의가 되어야 할 것 같습니다.

Loss Function

여기서 등장하는 개념이 손실 함수(Loss Function)이라고 합니다. 손실 함수는 비용 함수, 목적함수라고도 불립니다. 저 Loss Function이 의미하는 것은 현재 우리의 방법론이 예측하고 있는 값과 실제 정답 값과의 차이를 정량적으로 계산하는 함수로써 쉽게 이해하려면 오차의 정도를 나타낸다고 보면 됩니다.

 

손실 함수의 값이 크다는 것은 현재 방법론의 예측이 잘못되었다는 것을 의미하기 때문에 오차가 큰 상황이다! 이렇게 해석할 수 있으며, 값이 작다는 것은 예측을 잘하고 있다 이렇게 받아들일 수 있습니다.

 

쉽게 얘기하면 손실 함수를 작아지게 만드는 것이 우리의 목표라고 생각할 수 있습니다. 왜냐하면 오차를 줄여야 좀 더 정확해지기 때문입니다.

 

위의 formulation은 정말 일반적인 손실 함수의 형태라고 볼 수 있습니다. 

 

  • $f(x_{i},W)$ : 모델이 $W$라는 파라미터를 가지고 $x_{i}$라는 입력이 들어왔을 때 반환한 예측 값입니다.
  • $L_{i}(f(x_{i},W),y_{i})$ : 우리의 예측값인 $f(x_{i},W)$와 실제 정답 값인 $y_{i}$ 간의 차이를 나타내는 함수입니다.

Train data 전체에 대해 Loss를 계산하고 평균 처리를 통해 Loss가 구해지게 됩니다.

 

이제 분류 문제를 해결하기 위한 간단한 손실 함수 두 종류를 알아보도록 하겠습니다.

Multi-Class SVM Loss

머신러닝 분야에서 hinge loss라고도 불리는 이 multi-class svm loss는 classifier를 학습시키기 위해 사용이 됩니다. 

 

formulation은 위의 수식과 같습니다. 

 

  • $s_{y_{i}}$ : 정답 클래스에 대한 예측 score입니다.
  • $s_{j}$ : 정답 클래스가 아닌 클래스에 대한 예측 score입니다.

단순하게 생각해보겠습니다. 어떠한 분류기가 예측한 정답 클래스의 점수가 높으면 높을수록 정확한 분류기라 생각할 수 있을 것 같습니다. 

 

Loss를 만들어내는 상황은 $s_{y_{i}}$가 $s_{j}+1$ 보다 작을 때 $s_{y_{i}}-s_{j}+1$ 이라는 수치로 Loss값이 계산이 되는 상황입니다. $s_{y_{i}}$가 $s_{j}+1$ 보다 작다라는 것은 분류기가 예측하는 정답 클래스의 점수가 다른 클래스에 비해 그리 높지 않다는 상황입니다.

 

그림을 통해 한번 보도록 하겠습니다.

 

고양이 사진이 들어왔습니다. 우리가 지금 사용하는 분류기는 이전에 살펴봤던 선형 분류기라 가정하겠습니다. 선형 분류기가 사진 데이터를 받고 세 가지의 클래스에 대해 각각 score를 예측하고 있습니다. 고양이 사진이 들어왔기 때문에 

 

  • $s_{y_{i}}=3.2$
  • $s_{j}=\{ -1.7,5.1\}$

이렇게 정의할 수 있겠네요. Loss formulation에 넣어서 계산해보면

 

  • $L_{i}=\sum\nolimits_{j} max(0,s_{j}-s_{y_{i}}+1)=max(0,2.9)+max(0,-3.9)=2.9$

3.2라는 스코어는 -1.7보다 1이라는 safety margin 보다도 더 크기 때문에 Loss가 발생하지 않지만 5.1이라는 스코어와 비교했을 땐 이미 작은 상황이네요. 그래서 Loss가 2.9로 어떠한 값이 발생을 하였습니다.

 

즉, Loss를 발생시키지 않으려면 정답 클래스의 예측 score가 다른 모든 클래스의 score보다 safety margin보다 도 더 큰 값을 가질 때 Loss가 발생하지 않습니다. safety margin이 있는 이유는 단순히 정답 클래스의 score가 간신히 다른 클래스의 score를 넘기는 것보다는 어느 정도의 gap을 둘 수 있도록 설정한 margin입니다.

 

자동차 이미지가 들어왔을 때는 선형 분류기가 예측한 정답 클래스 점수(4.9)가 다른 클래스의 예측 점수를 safety margin을 넘기는 상황이 나왔기 때문에 Loss가 발생하지 않았습니다. 개구리 이미지는 선형 분류기가 예측한 정답 클래스 점수(-3.1)가 가장 낮은 스코어를 보여주기 때문에 Loss값이 크게 발생한 상황이네요.

 

Multi Class SVM Loss 입장에서는 결국 safety margin을 두고 정답 클래스 점수와 다른 클래스 점수 간의 대소 비교가 핵심 메커니즘이라 볼 수 있습니다. 간단한 손실 함수를 알아보았는데 이제는 분류 문제에서 가장 흔하게 사용되는 CrossEntropy Loss 함수에 대해서 살펴보도록 하겠습니다.

Cross-Entropy Loss

딥러닝에서 자주 사용하는 이 Cross-Entropy Loss는 그 뼈대가 정보 이론으로부터 나왔다고 합니다. 목적 자체를 다양하게 해석할 수 있겠지만 target probability distribution과 확률 분포가 비슷해지도록 만들기 위해서 사용한다고 보면 됩니다.

 

예를 들어 A B C 클래스가 있다고 가정하면 정답 확률 분포는 [1 , 0 , 0] 이렇다고 볼 수 있습니다. A 클래스일 확률이 정답 입장에서는 100%이기 때문입니다. 그리고 우리의 예측 모델이 반환한 확률 분포는 [0.4 , 0.3 , 0.3] 이렇다고 보면, 우리의 목적은 [0.4 , 0.3 , 0.3] -> [1, 0 , 0] 이렇게 될 수 있도록 최적화를 시켜주는 것입니다.

 

갑자기 확률은 왜 등장하였나? 위에서 우리가 봤던 예측 score들은 각 class에 대해서 normalize가 되어 있지 않아 불안정합니다. 이를 확률 분포로 정규화시켜주는 함수가 Softmax Function이라고 합니다.

 

  • $f(s_{k})=\frac{e^{s_{k}}}{\sum\nolimits_{j} e^{s_{j}}}$로 정의가 됩니다.

unnormalized score를 softmax 함수에 넣어주면 이는 이제 확률로써 작동을 하게 됩니다. 모든 정규화된 값들을 더 해주면 1이 되기 때문에 하나의 이산 확률분포가 된다고 보면 됩니다.

 

그래서 우리의 예측은 이제 확률 값이 가장 큰 클래스를 가지고 예측을 수행하는 것이지요.

 

고양이 사진을 넣어줬을 때 고양이일 확률이 0.13로 낮게 나왔습니다. Cross Entropy Loss에 대입하여 Loss를 계산하면 0.89라는 손실 값이 발생하였네요.

 

출처 : https://ml-cheatsheet.readthedocs.io/en/latest/loss_functions.html

Cross Entropy Loss 함수는 정답 클래스에 대해 예측 확률이 1에 가까울수록 적은 Loss를 발생시키고 0에 가까울수록 보다 큰 Loss를 발생시킵니다. 따라서 점점 정답 클래스에 대해서 예측 확률이 1에 가까워지면서 true probability distribution과 비슷해지는 구조라 보면 됩니다.

 

Cross-Entropy Loss와 Multi-Class SVM Loss를 비교해보겠습니다. Multi-Class SVM Loss 입장에서는 [10,-2,3] , [10,9,9] [10,-100,-100]에 대해서 모두 Loss가 발생하지 않습니다. 하지만 Cross Entropy Loss 입장에서는 조금 다르게 동작하죠.

 

  • [10,9,9] -> [0.5761, 0.2119, 0.2119]
  • [10,-100,-100] -> [1,0,0] 

softmax function을 취해주면 서로 다른 probability를 보여줍니다. [10,9,9]인 상황에서는 [10,-100,-100] 보다 더 큰 Loss를 가지게 되겠네요 왜냐하면 정답 클래스의 예측 확률이 [10,-100,-100] 보다 더 낮게 나왔기 때문이죠.

 

비슷한 기능을 수행할 수 있어도 손실 함수는 그 정의된 형태에 따라 다르게 최적화됩니다. 손실 함수에 대해 알아보았으니 이제는 정규화(Regularization)이란 게 뭔지 알아보도록 하겠습니다.

Regularization

머신러닝과 딥러닝 관련 공부를 해보았다면 들었을 법한 개념이 있습니다. 과적합(Overfitting)이라는 것인데요. 모델이 학습 데이터 분포에만 너무 과하게 fitting이 된 상황을 의미합니다. 데이터의 분포를 이해하는 것이 머신러닝/딥러닝 방법의 목표라 볼 수 있지만 하나 주의해야 할 것이 있습니다. General 한 data distribution을 학습해야 한다는 것입니다. 아래의 사진을 보면

 

이런 식으로 데이터의 분포를 설명하는 상황은 좋지 않습니다. 학습 데이터에 대해서는 잘 동작할지 몰라도 unseen, wild 한 데이터가 들어왔을 때 대처하기에는 유연하지 못하겠죠.

 

Overfitting이 발생하는 이유는 다양합니다. 데이터의 문제일 수 있고, 모델 architecture의 문제일 수 있고 정말 다양하지만 그중 Overfitting을 어느 정도 방지할 수 있는 Regularization에 대해서 알아보겠습니다.

 

단순히 정의하자면 Regularization은 손실 함수에 model parameter term을 추가하여 parameter가 커지는 상황에 추가적인 penalty를 부여하는 것이라 보면 됩니다.

 

Regularization을 사용하지 않고 단순히 손실 함수가 작아지는 방향으로만 parameter가 갱신되다 보면 특정 parameter 값들이 커지면서 overfitting 되는 상황이 발생합니다. 특정 parameter가 다른 parameter와 scale의 차이가 너무 크다면 새로운 데이터에 대처 하기에는 potential이 불안정합니다. 따라서 Regularization은 Cost를 줄이면서도 parameter가 커지지 않도록 최적화하겠다 이런 의미로 받아들이면 됩니다.

 

 

파란색으로 fitting 하는 것보다는 초록색 라인으로 fitting 시키는 것이 완벽하지는 않지만 일반적인 경향성을 파악하여 새로운 데이터인 초록색 데이터가 들어와도 대응을 할 수 있을 것 같네요.

Regularization은 Loss함수에 parameter에 대한 term을 추가하여 적용해줄 수 있습니다. parameter term을 어떻게 정의하는지에 따라 정규화 기법이 조금씩 달라지는 데 이번에는 L2 정규화에 대해서 알아보도록 하겠습니다.

L2 Regularization은 parameter의 L2 norm을 손실 함수에 넣어서 적용하는 방식입니다. $w_{1}$과 $w_{2}$를 비교하면서 L2 Regularization을 알아보도록 하겠습니다. $w_{1}$과 $w_{2}$은 모두 $x=[1,1,1,1]$에 대하여 같은 결과를 반환합니다. 하지만 Regularization term은 서로 다른 값을 가지게 되는데요

 

  • $w_{1}=[1,0,0,0],R(W)=(1^{2}+0^{2}+0^{2}+0^{2})=1$
  • $w_{2}=[0.25,0.25,0.25,0.25],R(W)=(0.25^{2}+0.25^{2}+0.25^{2}+0.25^{2})=0.25$

$w_{2}$가 $w_{1}$에 비해 L2 norm을 더 작은 값으로 가지기 때문에 L2 Regularization를 적용하는 입장에서는 $w_{2}$가 더 좋은 상황입니다. L2 Regularization는 결국 parameter들의 scale이 서로 비슷비슷 해지게 만드는 게 목적이라 볼 수 있겠네요. parameter 값들을 감소시키다 보니 L2 Regularization을 Weight decay라고도 부릅니다.

 

L1 Regularization 입장에서는 어떻게 될까요? $w_{1}$과 $w_{2}$ 모두 상관이 없습니다. 왜냐하면 둘 다 L1 norm이 같게 계산이 되기 때문입니다. 따라서 L1 Regularization은 $w_{1}=[1,0,0,0]$ 처럼 특정 parameter를 0에 가깝게 만들 수 있기 때문에 특정 특징 변수를 지워버릴 수 있다는 특징이 있습니다.

 

L1 Regularization을 사용할지 L2를 쓸지는 문제마다 다르고 결국 왕도가 없습니다. Problem dependent 하기 때문에 각 task에 잘 들어먹는 걸 사용하면 될 것 같습니다.

 

Overfitting을 방지하는 방법은 여러 가지가 있겠지만 여기서는 그중 Regularization에 대해서 그 방향성을 살펴보았습니다. 자 이제 손실 함수와 정규화에 대해서는 알아보았으니, 손실 함수를 바탕으로 model parameter의 update는 어떻게 하는지 알아보도록 하겠습니다.

Optimization

자 우리가 위에서 살펴본 것은 손실 함수라는 것으로 오차의 정도를 측정하기 위한 하나의 도구를 살펴보았습니다. 자 그럼 오차의 정도를 측정하였다면 그 정보를 바탕으로 우리 모델의 파라미터를 업데이트를 해야 할 것 같습니다. 업데이트의 방향은 어떻게 돼야 할까요?

 

당연히 손실 함수가 줄어드는 방향으로 파라미터가 업데이트가 돼야 할 것 같습니다. 그래야 모델이 학습 데이터를 통해 점점 더 정확해지겠네요.

 

그렇다면 손실 함수가 줄어드는 방향은 어떻게 찾을까요? 여기서는 경사 하강법(Gradient Descent)이라는 방법이 등장하게 됩니다. 결국 손실 함수는 무엇에 대한 함수일까요? 모델의 파라미터에 대한 함수라고 위에서 얘기를 하였습니다. 모델의 파라미터는 적게는 몇천 개 많게는 몇억 개로 상당힌 많이 이루어져 있습니다. 즉 손실 함수는 모델 파라미터에 대한 다변수 함수(MultiVariable Function)이라 볼 수 있습니다.

 

 

다변수 함수 입장에서는 어느 한 Point에서의 미분은 여러 개의 방향으로 정의가 됩니다. 즉 무한개의 방향벡터가 정의되는 데 우리는 그중에서 손실 함수가 줄어드는 방향을 찾고 싶습니다. 기왕이면 가장 빠르게 줄어드는 방향이 좋겠죠? 

 

그래서 그래디언트(Gradient)라는 것이 등장합니다. 그래디언트는 스칼라장의 최대 증가 방향을 나타내는 벡터로 가장 가파르게 증가하는 방향이라 이해하면 됩니다.

 

가장 가파르게 증가하는 방향의 반대 방향은 어떻게 해석할 수 있을까요? 가장 가파르게 감소하는 방향이겠죠? 즉 가장 빠르게 줄어드는 방향으로 우리의 최적화 방향이라 볼 수 있습니다.

 

  • Gradient : $\nabla L(w_{1},w_{2},\ldots ,w_{n})=\left( \frac{\partial L}{\partial w_{1}} ,\frac{\partial L}{\partial w_{2}} ,\ldots ,\frac{\partial L}{\partial w_{n}} \right) $

Gradient는 각 함수의 성분을 구성하는 독립변수에 대해(손실 함수 입장에서는 모델의 파라미터) 그 각각의 방향의 편미분으로 구성된 벡터로 정의가 됩니다.

 

  • $\overrightarrow{w} =\overrightarrow{w} -\eta \times \nabla L(\overrightarrow{w} )$

즉 우리의 parameter인 $\overrightarrow{w}$를 gradient의 반대 방향으로 어떠한 step size 만큼 업데이트해주는 방식이 Gradient Descent 기반의 최적화 방식입니다. 결국 어떠한 최소 지점을 찾고 싶은데 우선 가장 가파르게 감소하는 방향으로만 step을 밟아나가다 보면 어떠한 지점에 수렴할 수 있지 않을까?라는 게 경사 하강법(Gradient Descent)의 아이디어입니다.

 

하지만 Vanilla Gradient Descent는 나름대로의 한계점에 가지고 있습니다. 근처에 있는 minima에는 무조건 수렴하지만 그 point가 local minima라면 빠져나올 방법이 없다는 것입니다. 결국 업데이트 방식이 전적으로 Gradient에만 의존하다 보니 Gradient가 0으로 나오는 안장점(Saddle point)이나 극소점(Local minima)에 빠지면 update가 되지 않아 버리는 한계가 존재합니다. 

 

이러한 한계를 보완하기 위해서 Momentum이나 Adaptive Learning rate를 기반으로 한 많은 Gradient Descent의 후속 방법론들도 연구가 되어있습니다.

ML vs DL

마지막으로 전통적인 통계기반 Machine Learning 방식과 신경망  Deep Learning 방식의 간단한 차이만 살펴보고 이번 포스팅을 마무리하도록 하겠습니다.

 

머신러닝 기반의 방식들은 결국 어떠한 데이터의 특징을 잘 기술하는 방법과 이를 효과적으로 분류하는 알고리즘이 중요했습니다. 머신러닝 알고리즘에 대해서 얘기할 것은 아니고 특징(Feature)에 대해서 얘기를 해보도록 하겠습니다.  

위의 사진처럼 어떤 데이터의 특징이 직교 좌표계(cartesian coordinate)에서 정의가 되었다고 가정해보겠습니다. 왼쪽의 그림을 보면 저 데이터를 분류하기 위해서는 뭔가 비선형적인 결정 경계가 필요해 보입니다.

 

하지만 이러한 데이터의 특징을 다른 방식으로 기술해서 이번에는 극 좌표계(poloar coordinate)에서 정의했다고 가정해보겠습니다. 선 하나 딱 그으면 데이터가 잘 분류가 될 수 있을 것 같네요.

 

이처럼 데이터의 특징을 어떻게 정의하는지에 따라 성능에 유의미한 차이를 가져다주게 되는데요, 쉽게 생각하면 데이터를 표현하는 데 있어 더욱 풍부하고 효과적인 특징을 추출하는 Fancy 한 방법론이 필요하다는 이야기입니다.

딥러닝이 본격적으로 주목을 받기 이전에는 Handcrafted 기반의 특징을 추출하는 것이 대부분이었습니다. Handcrafted 기반의 특징이란 저희가 흔히 생각하는 알고리즘이랑 비슷하다고 보면 됩니다. 고정적인 특징 추출방식으로 학습이 되지 않는다는 것이 포인트입니다. 

 

위의 예시로 가져온 Bag of Words라는 방법론은 SIFT라는 지역 서술자를 이용하여 학습 데이터 전체에 대한 서술자를 모아 군집화(Clustering)이라는 방법론을 사용하여 코드북(Code book)이라는 일종의 데이터 전체를 설명할 수 있는 백과사전 같은 것을 만들어 놓습니다.

 

그리고 나선 평가 데이터가 들어왔을 때 codebook을 참조하여 이 이미지의 지역 서술자들이 어떠한 codeword들을 포함하고 있는지에 대한 정보를 활용하여 이미지 전체를 기술할 수 있는 전역 서술자를 생성하여 이를 가지고 분류를 진행합니다.

 

위에서 간단하게 정리한 일련의 과정들은 모두 사람이 직접 고안한 방법입니다. 

하지만 우리가 딥러닝이라 부르는 신경망 기반의 방식들은 이러한 특징들을 추출하는 과정을 학습에 포함을 시켜버립니다. 신경망이 학습이 되면서 특징을 추출하는 과정도 점점 더 좋아지는 구조라 생각하면 됩니다. 또한 특징 추출의 과정에도 이전처럼 알고리즘을 직접 고안해야 하는 것이 아니라 적당히 구조만 잘 잡아주면 알아서 학습을 통해 표현력이 풍부한 특징을 만들어준다는 점도 딥러닝의 장점이라 볼 수 있죠.

 

정리해보면 전통적인 통계기반의 머신러닝 방식들은 데이터의 특징을 추출하는 방식은 고정되어있고 학습이 일어나는 곳은 결국 분류하는 부분에서만 발생합니다. 하지만 신경망 기반의 딥러닝이라 불리는 방법은 특징을 추출하는 부분과 분류하는 부분 모두 학습이 되는 구조다 이렇게 간단하게 차이점을 정리할 수 있을 것 같습니다.

Conclusion

이번 포스팅에서는 손실 함수에 대한 정의와 분류 문제에 사용할 수 있는 두 가지 함수인 MultiClass SVM Loss와 CrossEntropy Loss에 대해서 알아보았고 정규화(Regularization)에 대해서 왜 하는지 어떻게 하는지 살펴보았습니다.

 

손실 함수를 어떻게 정의하냐에 따라 모델의 최적화 방향이 정해지기 때문에 task에 적절한 손실 함수를 고안하는 연구도 활발하게 진행되고 있다고 합니다.

 

다음으로는 손실 함수를 줄일 수 있는 방향에 대한 힌트를 제공하는 Gradient 기반의 최적화 방식을 간단하게 알아보았습니다. 더욱 깊은 이해를 원하신다면 Overview of Gradient Descent 논문을 읽어보는 것을 추천합니다.

 

마지막으로는 전통적인 통계기반의 머신러닝과 신경망 기반의 딥러닝의 차이점을 데이터 특징에 대해 비교해보면서 알아보았습니다. 다음 포스팅은 Gradient 기반의 최적화를 위해선 Gradient를 구해야겠죠? 복잡한 신경망 속에서 각 parameter에 대한 편미분 계수를 어떻게 구할 수 있는지 알아보도록 하겠습니다.

'Deep Learning' 카테고리의 다른 글

[CS231n] 03. Backpropagation and Neural Networks  (0) 2022.03.06
[CS231n] 01. Image Classification Pipeline  (0) 2022.01.25