[CS231n] Lecture 3 : Loss Functions and Optimization

정재윤·2021년 9월 29일
0

Introduction

지난 2강에서는 Linear Classifier가 어떤 방식으로 작동하고 score를 뽑는지에 대해서 배웠습니다. 이 때 W, 가중치가 사용된다는 점도 확인했습니다. 그러나 중요한 점은 이 가중치가 이미지 분류를 제대로 해낼 수 있는지를 평가해야한다는 점입니다.

지난 강의 마지막 예시를 보면 자동차에 대해서는 제대로 분류했지만, 고양이나 개구리는 분류하지 못했다는 것을 알 수 있습니다. 이는 W의 성능이 좋지 못하다는 것을 의미하죠 그렇다면 우리는 이것을 어떻게 정량적으로 평가할 수 있을까요?

W의 성능이 괜찮은지 정량적으로 파악할 수 있는 방법이 바로 Loss Function입니다. Loss function을 통해 우리가 구한 W가 좋지 않다고 판단되면 좋은 W로 학습시켜야 할 것입니다. 이 과정을 Optimization이라고 합니다. 이번 3강에서는 이 2가지를 중점으로 강의가 진행됩니다.

Loss function

앞서 이야기 했듯이 Loss function이란 Classifier가 이미지를 잘 분류하는지에 대해서 정량적으로 평가하는 함수입니다. 우선 이미지 데이터인 x와 라벨 데이터인 y가 한 쌍인 데이터셋을 준비합니다. Classifier의 예측값과 라벨 데이터 y를 비교하여 모두 더한 뒤, 데이터의 개수로 나눈 값이 loss가 됩니다.

Multiclass SVM loss

강의에서는 우선 Multiclass SVM loss에 대해서 설명합니다.

Multiclass SVM loss을 그래프로 그리면 위의 파란 그래프와 같은 형태를 지닙니다. 이 그래프가 문의 힌지와 비슷하고 해서 흔히 hinge loss라고도 불립니다. 구체적인 loss를 구하는 방법은 식과 같습니다. 여기서 sjs_j는 정답이 아닌 클래스의 score를 의미하고, syis_{y_i}는 정답인 클래스의 score를 의미합니다. 그리고 상수는 safety margin으로 강의에서는 1로 설정했습니다. 여기서 safety margin을 더해서 분류의 최소값을 올리므로서 분류 성능을 끌어올리고 것입니다.

만약 정답인 클래스의 score가 정답이 아닌 클래스의 score + safety margin보다 크다면 loss는 0 값을 가집니다. 아니라면 sjsyi+1s_j - s_{y_i} + 1의 loss값을 가지게 됩니다. 그리고 이 값들을 모두 합한 값이 최종 loss가 됩니다.

위의 방식으로 각 class별 loss를 구하면 2.9, 0, 12.9라는 값을 가지게 됩니다. 마지막으로 모든 class별 loss의 평균을 구해주므로서 최종 loss인 LL을 구할 수 있게 됩니다. 위의 예시에서는 5.27이라는 값을 가지게 되는 것이죠.

Q1. 만약 자동차의 스코어를 약간 바꾼다면 loss에서는 무슨 일이 벌어질까?
A1. score를 약간 바꿔도 loss는 0으로 변하는 건 없습니다. 자동차의 score를 1.9보다 큰 값으로 빼지 않는이상 변하는 것은 없습니다. 이는 SVM의 특징으로 safety margin의 영향으로 볼 수 있을 것 같습니다.

Q2. loss가 가질 수 있는 최소값과 최대값은 무엇일까요?
A2. 그래프를 보면 알 수 있듯이 최소값은 0, 최대값은 무한대가 될 것입니다.

Q3. 처음 W가 너무 작아서 score가 0에 가까우면 loss는 어떻게 될까요?
A3. 모든 score가 0이라고 가정하고 고양이를 한번 계산을 해보겠습니다. max(0,00+1)+max(0,00+1)=2max(0, 0-0+1)+max(0, 0-0+1) = 2가 되고 최종 loss는 6/3=26/3 = 2가 될 것입니다. 좀 더 보편적으로 적용해보면 class - 1의 값이 됩니다. 이는 처음 훈련을 시작할 때, 확인해볼 수 있는데 이 값이 예상과 다르게 나온다면 무엇인가 잘못됨을 파악할 수 있습니다.

Q4. 만약 모든 클래스의 loss를 구해 다 더하면 어떻게 될까요?
A4. 각각의 loss는 1씩 증가할 것이고, 최종 loss 역시 1 증가할 것입니다. 사실 질문과 같은 방식으로 학습을 진행해도 크게 상관은 없습니다. 하지만 모든 값을 다 맞췄을 때를 가정하면 최종적으로 loss는 항상 1이 남게되는 현상이 발생한다는 것을 유의해야합니다.

Q5. 단순 합 대신에 평균을 이용하면 어떨까요?
A5. 단순히 scale의 차이만 발생할 뿐, 훈련과정에서는 큰 차이가 발생하지는 않습니다. 중요한 것은 훈련을 통해 loss의 값을 줄여하는 것이지 scale를 줄이는 건 아니니까요.

Q6. LiL_i를 제곱했을 때 어떤 일이 발생할까요?
A6. 만약 위와 같은 방식으로 LiL_i를 구하면 전혀 다른 결과를 낼 것입니다. 일단 새로운 식은 선형성이 깨져있다는 점이 중요합니다. 이 같은 loss를 우리는 squared hinge loss라고 합니다. 이 loss는 제곱으로 계산되기 때문에 굉장히 큰 값이 나올 수 있으며, 이는 곧 잘못 분류할 경우, penalty를 크게 준다는 것을 의미합니다. 약간의 오류에도 큰 패널티를 부여하는 것이죠.

그렇다면 loss를 0으로 만드는 weight를 찾았다고 가정해봅시다. 과연 이 weight는 하나만 있는 것일까요? 간단하게 생각하면 weight에 상수배를 해도 loss는 변함이 없다는 것이죠.

우리가 계속해서 확인했던 예제에서 자동차의 loss를 확인해봅시다. 단순히 weight를 2배 해준 것이므로 자동차 이미지를 넣었을 때 산출되는 결과의 score를 모두 2배로 올린 뒤, 계산을 해보면 여전히 결과는 0으로 동일합니다. 즉, loss를 0으로 만드는 최적의 weight는 여러 개 존재할 수 있다는 점이죠.

이런 현상은 왜 일어나는 것일까요? 우리가 설정한 loss는 data loss로 training data와 모델의 예측값만을 가지고 loss를 구하기 때문입니다. 위의 그림을 보면 알 수 있듯이, 우리가 설정한 data loss가 0이라면 모델은 파란색 데이터를 모두 맞출 것입니다. 하지만 우리가 weight를 찾는 목적은 훈련 데이터를 완벽하게 맞추기 위한 것이 아닌, 새로운 데이터가 들어왔을 때 이를 정확하게 맞추기 위함입니다. 위의 모델에 새로운 초록색 데이터를 넣으면 하나도 못 맞추거나 맞춰도 정확도가 낮을 것입니다. 즉, overfitting이 발생하는 것이죠.

이러한 문제를 막기 위해서, overfitting된 모델이 아닌 초록색 선의 모델을 찾기 위해서 우리는 regularization을 loss function에 추가해주는 것입니다. 즉, loss function에 패널티를 부여해서 최종 loss가 너무 낮아지는 것을 방지하기 위함이죠. 이 과정을 통해 우리는 이전보다는 모델에 일반성을 부여할 수 있게 됩니다.

Regularization

위의 사진에서보면 알 수 있듯이 Regularization의 방법에는 여러 종류가 있습니다. 이번에는 대표적인 L1 regularization과 L2 regularization에 대해서 알아보도록 하겠습니다.

예를 들어 L1 regularization의 loss function은 L=1Ni=1NLi(f(xi,W),yi)L = \frac{1}{N}\sum^{N}_{i=1}{L_i(f(x_i,W),y_i)} +λnΣW+ \frac{\lambda}{n}\Sigma|W|라고 가정해봅시다. 이 후 편미분을 하고 가중치를 업데이트 하게 되면 WW -> W=Wηλnsgn(W)ηLWW' = W - \frac{\eta\lambda}{n}sgn(W) - \eta\frac{\partial L}{\partial W}이 됩니다. 결국 전체 weight는 가감방식으로 줄어들게 됩니다.

반면 L2 regularization의 loss function을 L=1Ni=1NLi(f(xi,W),yi)L = \frac{1}{N}\sum^{N}_{i=1}{L_i(f(x_i,W),y_i)} +λnΣW2+ \frac{\lambda}{n}\Sigma W^2 으로 가정해봅시다. 이 후 weight의 업데이트를 위해 편미분을 하고 연산을 진행하면 WW -> W=WηλnWηLWW' = W - \frac{\eta\lambda}{n}W - \eta\frac{\partial L}{\partial W} =(12ηλn)wηLW= (1-\frac{2\eta \lambda}{n})w - \eta\frac{\partial L}{\partial W}가 되면서 L1과 마찬가지로 줄어들기는 하나 L1과는 다르게 곱해지는 식으로 값이 변하게 됩니다.

즉, L1 regularization을 사용하게 되면 상수의 값들을 빼주기에 비중이 작은 가중치들은 0이 되어 필요한 변수들만 남게 되는 반면, L2 regularization은 상수를 곱해주면서 값을 줄여나가기 때문에 가중치의 값이 작아질지언정 모두 남게 되는 것이죠.

Softmax Classifier

이미지의 다중 분류문제에 있어서 Hinge loss보다 더 자주 쓰이는 loss는 Softmax Classifier에 사용되는 Cross Entropy Loss입니다.

고양이 사진을 예시로 들 때, softmax의 함수는 eskΣjesj\frac{e^{s_k}}{\Sigma_j{e^{s_j}}}가 됩니다. 이 때 softmax 함수에는 자연 상수 ee를 취하게 되는데요. 그 이유는 미분했을 때 계산이 용이하다는 장점과 score간의 차이를 더 극명하게 나타내기 위함입니다.

우리는 이 방식으로 확률값을 구할 수 있게되고, 정답 클래스에 log-log를 위하면서 최종 loss값을 구할 수 있게됩니다. 이 때 로그를 취하는 이유는 곱셈에 대한 계산이 용이하기 때문입니다.


https://kkukowiki.kr/w/%EB%A1%9C%EA%B7%B8%ED%95%A8%EC%88%98

그리고 음수를 취해주는 이유는 그림을 보면 알 수 있습니다. 기존의 로그함수에 음수를 취해주므로서 확률에 로그 함수를 취한 값을 양수로 만들 수 있을 뿐만 아니라 완벽히 맞췄을 경우, 0의 loss를 갖을 수 있게 됩니다.

구체적인 예시로 이를 구해보면 최종적으로 loss는 0.89라는 값을 가지게 됩니다.

Q1. LiL_i의 최대값과 최소값은 무엇일까요?
A1. 위의 로그 그래프를 보면 알 수 있듯이 최소값은 0, 최대값은 무한대가 될 것입니다.

Q2. 초기 가중치가 너무 작아 score가 0에 가까울 때 loss는 어떻게 나올까요?
A2. 간단하게 위의 식에 넣어서 계산을 해보면 됩니다. class가 cat, car, frog로 3개일 때, 모든 class의 score가 0이라고 가정합시다. 이 때 확률값을 구하면 모두 13\frac{1}{3}이 되면서 Li=log(13)L_i = -log(\frac{1}{3})이 나오게 될 것입니다. 일반화 시키면 1class의수\frac{1}{class의 수}log-log를 취한 값이 되겠죠.

그렇다면 score의 값을 약간 바꿨을 때, softmax와 SVM의 loss는 어떻게 변할까요? 앞서 설명했듯이 SVM은 변화하는 값이 충분히 크지 않는다면 기존의 loss와 차이가 없을 것입니다. 반면 softmax는 각 class의 비율이 달라지는 것이기 때문에 약간의 변화에도 굉장히 크게 변할 것입니다. 강의에서는 SVM은 둔감하고, softmax는 민감하다고 표현합니다.


최종적으로 우리는 이미지, 라벨 형식의 데이터셋을 구한 뒤, score function을 설정합니다. 이 후, loss function을 설정하여 우리가 찾은 W가 정량적으로 좋은지 나쁜지를 판단하는 것입니다. loss function의 경우, 어떤 모델, 어떤 작업을 하느냐에 따라 다 다르지만 최종적으로 사용하는 Full loss에서는 Regularization 역시 고려해주어야 합니다. 그렇다면 우리는 어떻게 좋은 weight를 구할 수 있을까요?

Optimization

최적의 weight를 찾는 방법이 바로 Optimization입니다.

흔히 Optimization은 두 눈을 가리고 산을 내려가는 것과 같다고 비유하곤 합니다. loss function의 최저점을 찾아 내려가는 것이라는 의미이죠. 이 때 몇 가지 optimization의 방법이 있습니다.

그 예시로 든 방법이 Random search입니다. 즉, 가중치를 무작위로 지정해서 결과값을 산출하는 것입니다. 물론 운이 정말 좋다면 최적의 파라미터를 찾을 수도 있지만 거의 불가능하고 절대 좋은 방법이 아닙니다. 절대 사용해서는 안되는 방법입니다.

이 방법으로 정확도를 산출해보면 15.5%를 얻을 수 있습니다. 당시 SOTA인 95%에 비하면 의미없는 성능인 것이죠.

따라서 우리는 경사를 따라 내려가는 경사하강법을 사용합니다.

이 경사하강법을 사용할 때 필요한 것이 바로 미분 공식입니다. 특히 이미지의 경우, 다차원 데이터이기 때문에 편미분을 사용하게 됩니다. 이렇게 구한 벡터를 우리는 gradient 벡터라고 하며 이는 경사가 가장 가파른 방향을 가르킬 것입니다. 따라서 우리는 이 방향의 반대 방향을 따라 내려가야 하는 것이죠.


그렇다면 위의 수식을 사용하여 한 번 직접 해보겠습니다. 우선 현재의 가중치의 loss는 그림과 같습니다. 이 때 첫 번째 값에 0.0001만큼 더한 뒤, loss를 구하면 1.25322가 나오게 되죠. 이 때 gradient벡터의 첫 번째 값을 구하면 -2.5라는 값을 얻을 수 있습니다. 이 과정을 모든 차원에서 진행하면 되죠.


하지만 이 방식은 너무 오래 걸리고 효율적이지 못합니다. 결국 우리가 원하는 것은 loss function을 W로 미분한 값이기 때문이죠.

그래서 우리는 Chain rule이라는 미분공식을 사용하여 이 값을 한 번에 구할 것입니다. (추후 강의에서 진행 예정)

요약하자면 하나하나 계산하는 방식은 대략적이고 느리지만 계산이 쉽고, 미분 공식을 활용하는 Analytic gradient는 정확하고 빠르지만 에러가 발생할 수 있다는 단점이 있죠. 그래서 우리는 항상 Analytic gradient를 사용하되 numerical gradient로 그 값을 확인하는 것입니다.

Gradient Descent

경사하강법은 위와 같이 구하면 됩니다. loss function, 전체 data, 현재 weights로 weights의 gradient를 구해줍니다. weight_gradient는 미분을 통해 구할 수 있습니다. 그리고 step size와 weight_gradient를 곱한 뒤, 현재의 weight에서 빼주시면 됩니다.


https://daebaq27.tistory.com/35

이 때 빼주는 이유는 위에서 언급했듯이 우리가 구한 gradient vector는 경사가 제일 가파른 곳(가장 심하게 변하는 곳)으로 방향을 가지기 때문입니다. 위의 그림을 보시면 좀 더 직관적인 이해가 가능합니다. 즉, 우리는 이와는 반대의 방향으로 가야 최적의 weight를 찾을 수 있기 때문에 빼주셔야 합니다.

하지만 Gradient Descent는 단점이 있는데요. 한 step을 나가기 위해서 모든 데이터를 다 훑어보고 계산하기 때문에 시간이 오래걸리고 컴퓨터의 용량이 커야한다는 점입니다.

Stochastic Gradient Descent(SGD)


이를 개선하기 위해서 나온 방식이 바로 Stochastic Gradient Descent입니다. 즉, 한 번 step을 나갈 때 전체 데이터를 보는 것이 아니라 일부의 데이터만을 가지고 step을 나가는 것입니다. 확실히 Gradient Descent보다는 훨씬 연산속도도 빠르고 컴퓨터의 용량도 덜 사용합니다. 하지만 전체 데이터를 사용하는 것이 아니기에 최적값을 찾아가는데 약간 헤메는 모습을 보여줍니다.


https://seamless.tistory.com/38

위의 사진을 보면 두 방법이 확연하게 다르다는 점을 확인할 수 있습니다.

ETC

지난 시간 배운 선형분류기를 통해 이미지를 인식시킬 때는 그냥 이미지 자체를 input으로 집어 넣었습니다. 하지만 이는 그렇게 좋은 방법이 아니었습니다. 그래서 CNN이 나오기 전 사람들은 다양한 방법을 찾았습니다. 그 중 하나가 바로 위의 사진과 같은 방법입니다.

두 단계를 거쳐서 결과를 도출하는 방식인데요. 우선 이미지의 여러 특성을 뽑아내는 과정을 거친 뒤, 이를 하나의 벡터로 연결시켜줍니다. 그리고 이 벡터가 Linear Classifier의 input으로 넣는 것입니다.

그 첫 번째 예가 color histogram입니다. 이미지에서 색상 값을 뽑아 어떤 색이 가장 많이 나오는지 그 빈도를 측정하는 것입니다.

두 번째 방법이 HoG(Histogram of Oriented Gradients)입니다. 첫 번째가 이미지의 색상 값을 feature로 뽑았다면 이 방법은 이미지의 방향값, 테두리를 feature로 뽑은 뒤, 이를 히스토그램으로 표현하는 것입니다. 그래서 이미지를 8x8로 자르고 해당 부분에 어떤 테두리의 방향이 많은지를 히스토그램으로 나타낸 뒤 이를 추출하는 것입니다.

마지막으로 bad of words 방법입니다. 이 방법은 자연어처리에서 많이 사용되는 방법입니다. 우선 기존의 이미지들을 random하게 잘라냅니다. 그리고 이 부분들을 클러스터링을 하는 것입니다. 그러면 알고리즘을 통해 색깔, 방향 등의 특징들을 기반으로 클러스터가 형성될 것입니다. 즉, codebook을 만드는 것입니다. 그리고 분류하고 싶은 이미지를 넣으면 이 이미지를 잘라서 학습된 클러스터와 비교하여 어떤 특징을 가지고 있는지를 비교하는 것입니다.

몇 년전만 해도 이렇게 feature를 추출한 뒤 이미지를 인식하는 방법을 취했다면, 이제는 CNN이 발달하면서 특징을 뽑아주는 것이 아닌 모델이 알아서 이미지의 특징을 뽑을 수 있도록 발달했습니다.

0개의 댓글