Lecture 3. Loss Functions and Optimization

Eunjin Kim·2022년 5월 21일
0

cs231n

목록 보기
3/6
post-thumbnail
post-custom-banner

지난시간에 실제로 가장 좋은 행렬 WW를 구하기 위해 어떻게 트레이닝 데이터를 활용해서 행렬 W를 만들어야 하는지는 다루지 않았다.

Linear Classifier에서 어떤 WW가 가장 좋은지를 결정하기 위해서는 지금의 WW가 좋은지 나쁜지를 정량화할 방법이 필요하다. WW를 입력으로 받아서 각 결과값(스코어)를 확인하고 이 WW가 얼마나 구린지 정량적으로 말해주는 것이 Loss Function(손실함수)이다. 이 손실 함수가 해야하는 일은 임의의 값 WW가 얼마나 좋은지 나쁜지를 정량화하는 것이다. 우리는 “가장 덜 구린” WW가 무엇인지 찾고싶은 것이다. 이 과정이 Opitmization(최적화) 과정이다.

Loss Function

위같은 이미지 분류 문제라면

  • xx는 이미지
  • yy는 예측하고 싶은 것으로 label(or target)
  • 함수 ffxxWW를 입력으로 받아서 yy를 예측
  • 손실함수 LiL_i는 예측함수 ff와 정답값 yy를 입력으로 받아 얼마나 구리게 예측하는지를 정량화
  • 최종 Loss는 데이터셋에서 NN개의 샘플들의 Loss 평균

1. Multiclass SVM loss

  • SS: 분류기 출력으로 나온 예측된 스코어 (1이 고양이고 2가 강이지면 s1s_1은 고양이스코어 s2s_2는 강아지 스코어)
  • yiy_i: 이미지의 실제 정답 카테고리 (정수값)
  • syis_{y_i}: 트레이닝 셋의 i번째 이미지의 정답 클래스의 스코어

이렇게 0과 Max(0,value)Max(0, value)와 같은 식의 손실함수는 아래와 같은 그래프 모양이고 ‘Hinge Loss’라고 부르기도 한다.

최종 Loss LL를 구해보면 아래와 같다.

Q1. What happens to loss if car scores change a bit?

  • Car 스코어를 조금 바꾼다 해도 다른 정답이 아닌 스코어와 차이가 많이 나기 때문에 Loss 값에는 차이가 없을 것이다.

Q2. What is the min/max possible loss?

  • Min: 0 Max:

Q3. At initialization W is small so all s≈0. What is loss?

  • #of classes - 1 Why? Loss 를 계산할 때 정답이 아닌 클래스를 순회한다. 그러면 c-1 클래스를 순회한다. 비교하는 두 스코어가 거의 비슷하니 margin 때문에 1 스코어를 얻게 될 것이다. 그리고 전에 loss는 c-1을 얻게 되는 것이다.

Q4. What if the sum was over all classes?(including j = y_i)

  • Loss 가 1이 더 증가할 것이다.

Q5. What if we used mean instead of sum?

  • loss가 더 작아지지만 이는 의미상으로 크게 다르지는 않다.

Q6. What if we used square?

  • Loss 값이 달라지며 안좋은 것은 더 안좋아지게 된다.

SVM Loss의 예시 코드를 봐보면 위와 같다.

여기서 margins[y] = 0 은 max로 나온 결과에서 정답 클래스만 0으로 만들어줘서 굳이 전체를 순회할 필요가 없이(vectorized 기법) 전체 합을 구할 때 제외하고 싶은 부분만 0으로 함으로써 간결하게 코드를 작성할 수 있다.

또한 L = 0인 W를 찾았다고 해서 그것이 유일한 W값을 아니다. (2W도 L=0을 만들 수 있음)

여기서 주의할 점은 다양한 W중 loss가 0인 것을 선택하는 것은 옳지 않다.

왜냐하면 지금은 오직 데이터의 loss에만 신경쓰고 있고 분류기에게 트레이닝 데이터에 맞는 W를 찾으라고 말하는 것과 같기 때문이다. 하지만 우리는 분류기가 트레이닝 데이터에 얼마나 맞는지는 신경 쓰지 않는다.

기계학습의 핵심은 트레이닝 데이터를 이용해 어떤 분류기를 찾는 것인데 그 분류기는 테스트 데이터에 적용할 것이기 때문이다. 우리는 테스트 데이터에서의 성능에 관심이 있다.

그래서 분류기에게 트레이닝 데이터의 Loss만 신경쓰라고 한다면 not good,,,

예를 들어 아래 그래프를 봐보자.

트레이닝 데이터에만 맞춰서 분류기를 생성하면 파란색 그래프와 같이 나온다. 하지만 우리가 원하는 그래프는 새로운 데이터 초록색 점들이 들어왔을 때 그려지는 초록색 그래프이다. 이는 기계학습에서 가장 중요한 문제이고 이런 overfitting 문제를 해결하기 위한 방법이 Regularization이다.

손실함수에 항을 추가해 ‘Data loss term’ 에서는 분류기가 트레이닝 데이터에 핏하게 하고 ‘regularization term’에서는 모델이 좀 더 단순한 W를 선택하도록 도와준다.

일반적인 loss fucntion의 형태는 Data loss와 Regularizaion Loss를 갖게 되고 여기서 hyperparameter 람다 (λ)는 두 항간의 trade-off이다.

Regularization에는 위와 같은 것들이 있고, dropout, bath normalization 등은 앞으로 더 살펴볼 것이다.

정리하자면 Regularization은 모델이 트레이닝 데이터셋에 완벽히 핏하지 못하도록 모델의 복잡도에 패널티를 부여하는 방법이다.

L1, L2 regularizaiton을 더 살펴보자.

위에서 L2 regularization는 w2w_2의 norm이 더 작기 때문에 w2w_2를 더 선호한다. 즉 L2 regularization은 가중치들의 coarse(값이 매끄러움)함을 측정해 분류기의 ‘complexity’ 기준을 잡는다. 따라서 coarse한 값들을 통해 x의 모든 요소에 영향을 고루 줄 수 있는 것을 원한다.

L1 regularization은 반대 경우이다.  L1 regularization을 쓰게 되면 w2보다는 w1을 더 선호하게 된다. L1 regularization은 다른 종류의 ‘complexity’를 정의하기 때문이다. L1 regularization은 가중치 W에 0의 갯수에 따라 모델의 복잡도를 다룬다. L1에 대한 일반적인 직관은 “일반적으로 L1은 sparse한 solution을 선호한다”는 것이다. 이것은 W의 요소 중 대부분이 0이 되게 할것이다.

그렇기 때문에 L1이 “복잡하다”고 느끼고 측정하는 것은 0이 아닌 요소들의 갯수가 될수 있다. 반면 L2의 경우 W의 요소가 전체적으로 퍼져있을 때 “덜 복잡하다”라고 생각하게 된다.

그래서 어떤 문제가 있고 어떤 모델과 데이터가 있을 때 우리는 이 문제에서 ‘complexity’를 어떻게 측정할 것인지 고민해야한다.

2. Softmax classifier (Multinomial Logistic Regression)

Multi-class SVM loss에서 우리는 ‘스코어' 자체에 대한 해석을 고려하지 않았다. 그러나 softmax classifier에서는 스코어 자체에 추가적인 의미를 부여해 아래 수식을 이용해 스코어를 가지고 클래스 별 확률 분포를 계산할 것이다.

log를 최대화 시키는 것이 그냥 확률값을 최대화 시키는 것보다 쉽기 때문에 log를 사용한다. (log는 단조증가함수라서 정답클래스인 logPlogP 를 최대화 시키는 것은 log P가 높았으면 좋겠다는 것. 그런데 손실함수는 ‘얼마나 나구린지’를 측정하는 것이기 때문에 (-)를 붙여준다. )

구체적인 예시를 들어서 살펴보자.

Softmax(다항 로지스틱 회귀)

1) 파란박스의 스코어 자체를 Loss로 쓰지 않고 스코어를 지수화 시킨다. (모두 양수)

2) 합이 1이 되도록 정규화를(normalize) 시켜준다.

3) 정답 스코어에만 -log를 적용한다.

Q1. What is the min/max possible loss LiL_i?

  • Min : 0. Max:

Q2. Usually at initialization W is small so all s≈0. What is loss?

  • logClogC

SVM Loss는 정답 스코어와 정답이 아닌 스코어 간의 margins을 신경쓰고, Softmax는 확률을 구한 후에 log(정답클래스)-log(정답클래스)의 값에 신경을 쓰는 것이다.

Q: Suppose I take a datapoint and I jiggle a bit (changing its scores slightly). What happens to the loss in both cases?

정답 스코어가 충분히 높고, 다른 클래스 스코어가 충분히 낮은 상태에서도 Softmax는 최대한 정답 클래스에 확률을 근사하려고 할 것이고, 정답 클래스는 무한대로 그 외의 클래스는 음의 무한대로 보내려 할 것이다. 반면에 SVM은 일정한 margin을 넘기게 되면 더 이상 성능 개선에 신경쓰지 않는다.

이제 어떻게 실제 Loss를 줄이는 W를 찾을 수 있을까? “최적화”❗️

Optimization

최적화는골짜기에 위에 있는 우리가 산 아래로 가는 길을 찾고 있다고 말할 수 있다.

임의로 샘플링한 w들을 많이 모아놓고 Loss를 계산해서 어떤 w가 좋은지 살펴보는 것으로 매우 좋지 않은 방법이다.

방법 2: Follow the slope

더 나은 방법으로 지역적인 기하학적 특성을 이용하는 것이다.(local geometry) 위에서 본 골짜기 상황에서 계곡의 밑바닥을 눈으로 볼 수은 없지만 서있는 곳의 지형은 두발로 느낄 수 있다. 그래서 두 발로 땅의 경사를 느끼고, 어느 방향으로 내려갈 수 있을지를 예측할 수 있을 것이다. 이제 그 방향으로 조금씩 내려가면서 다시 방향을 찾는 것을 반복하다보면 결국 골짜기를 다 내려갈 수 있을 것이다.

slope(경사)은 1차원에서 어떤 함수에 대한 미분값이다.

이제 실제로는 x가 스칼라 값이 아닌 벡터이기 때문에 위의 개념을 multi-variable로 확장시켜야 한다. 다차원에서 미분을 일반화시키면 gradient로 벡터 x의 각 요소들의 편도함수들의 집합이다. (gradient의 모양은 입력 x와 같다.)  gradient 의 각 요소가 알려주는 것은 ‘what is the slope of the function ff if we move in to that coordinate direction?’이다.

만약 특정방향에서 얼마나 가파른지 알고싶다면 이는 그 방향의 unit 벡터와 gradient 벡터를 내적하면 알 수 있다.

gradient는 함수의 어떤 점에서 선형 근사 함수를 알려주기 때문에 매우 중요하다. 그래서 실제로 많은 딥러닝 알고리즘들이 gradient를 계산하고 모델의 파라미터 벡터를 반복적으로 업데이트할 때 그 gradient를 사용한다.

이 gradient를 사용할 수 있는 가장 단순한 방법 중 하나는 finite difference methods(유한 차분법)를 이용하는 것이다.

위를 보면 파라미터 벡터 W를 사용하면 1.25정도의 Loss를 가진다. 우리가 원하는 것은 W와 모양이 같은 gradient dW를 구하는 것이다. 여기서 gradient의 각 요소가 말해주는 것은 우리가 그 방향으로 아주 조금 이동했을 때 Loss가 어떻게 변하는지이다.

이것을 finite difference methods로 계산해보자. W의 첫번째 요소 0.34에 아주 작은 h값을 더해본다. 그리고 다시 loss를 계산해보면 첫번째 요소를 조금 움직이면 Loss값이 아주 조금 감소한다는 것을 알수 있다.

이제 극한식을 사용해서 finite difference methods로 근사시킨 gradient를 구한다. 그런 다음에 다시 첫번째 요소를 원래대로 놓고 두번째 요소를 조금 증가시킨 후 위의 계산을 반복하면 두번째 요소 gradient의 근사치를 계산할 수 있다. 이걸 계속 반복하는 것이다.

하지만 이 방법은 시간이 너~무 오래걸린다.🤯 만약 함수 f가 CNN같이 엄청 큰 함수였다면 super super 느렸을 것이다. 따라서 실제로는 절대 이런식으로 gradient를 계산하지 않는다.

다행히 우리는 뉴턴과 라이프니츠 덕분에 “미분”을 사용해 더 정확하고 빠르게 gradient를 계산할 수 있다.

다시 방금 예제를 살펴보면 이제 W의 모든 원소를 순회하는 것이 아니라 gradient를 나타내는 식이 무엇인지 먼저 찾아내서 그걸 수식으로 나타내면 한번에 gradient dW를 계산할 수 있게 된다!

요약해보면 먼저 본 numerical gradient는 간단하고 괜찮아 보이지만 실제로는 사용하지 않고, 실제 gradient 계산을 구현할 때는 analytic gradient를 이용한다.

이제 gradient를 계산하는 방법을 알고 난 후에는 이 간단한 코드인 Gradient Descent 알고리즘이 엄청 복잡하고 싶은 신경망 알고리즘의 학습 방법에 대한 핵심을 담고 있다.

Gradient Descent


1. 우선 W를 임의의 값으로 초기화
2. Loss와 gradient를 계산한 뒤에 가중치를 gradient의 반대방향(-gradient)으로 업데이트
3. 위를 반복하다 보면 결국 수렴

위에서 step size는 learning rate로 -gradient 방향으로 얼마나 나아가야하는지를 알려주는 중요한 hyperparameter이다.

빨간 동그라미 부분이 Low Loss로 우리가 원하는 것이라고 할 수 있다.

Adam, momentum등의 optimizer 들의 핵심은 gradient descent라는 기본적인 알고리즘을 사용하고 있고, 다음 스텝을 결정하기 위해 이전 모든 스텝의 gradient 정보를 이용한다는 것이다. 이제 gradient 정보를 정확히 어떻게 이용할 것인지에 따라 여러 update rule이 존재하는 것이다.

Stochasic Gradient Descent(SGD)

여기서 또 고려해 볼 것은 실제 우리의 데이터 N의 크기는 매우 크다는 것이다.(ImageNet의 경우 130만개) 따라서 Loss를 계산하는건 수백만번의 계산이 필요하고 정말 오래 걸리게 된다. 그래서 실제로는 Stochasic Gradient Descent(SGD)를 사용한다. 전체 데이터 셋의 gradient와 loss를 계산하기 보다는 ‘minibatch’라는 작은 트레이닝 샘플 집합으로 나눠서 학습하는 것이다. 보통 32/64/128을 사용하고 이 minibatch를 이용해 Loss의 전체 합의 “추정치”과 실제 gradient의 “추정치”를 계산한다.

  1. 임의의 minibatch 생성
  2. minibatch에서 Loss와 Gradient를 계산
  3. 가중치를 gradient의 반대방향(-gradient)으로 업데이트
  4. 위를 반복하다 보면 결국 수렴

Image Feature

지금까지는 실제 raw 이미지 픽셀을 입력으로 받는 방식으로 linear classifier를 살펴봤다. 실제로 영상 자체를 입력으로 사용하는 것은 성능이 좋지 않다. Deep neural network가 활발히 사용되기 전에는 주로 두가지 stage를 거치는 방법을 사용했다.

이미지의 여러 특징 표현을 계산하고 연결(concat)시켜 하나의 특징 벡터로 만든 후

이 특징벡터가 Linear classifier의 입력으로 들어가는 것이다.

위 그림을 보면 복잡한 데이터들을 feature transform(특징변환)을 통해서 선형 분류기로 나눌 수 있게 만들어 준다. 아래서 이제 feature transform의 예시를 봐보자.

Ex1) Color Histogram

이미제에서 hue값을 뽑아 bucket에 넣어 각 bucket에 들어있는 픽셀의 갯수를 세는 것이다. 그래서 이미지가 전체적으로 어떤 색으로 구성되어 있는지 알려준다.

Ex2) HoG(Histogram of Oriented Gradients)

이미지 내에 전반적으로 어떤 종류의 edge 정보가 있는지를 나타낸다.

이미지를 88 로 픽셀을 나누고 이 지역 내에서 가장 지배적인 edge의 방향을 계산하고 양자화해서 bucket에 넣는다. 이제 전체 특징 벡터는 각각의 모든 88 지역들이 가진 “edge orientation에 대한 히스토그램”이 되는 것이다.

이미지 내에 전반적으로 어떤 종류의 edge 정보가 있는지를 알려주고 지역화된 여러 부분에 어떤 edge가 존재하는 지도 알 수 있다.

Ex3) Bag of Words

Step1 - 엄청 많은 이미지를 임의대로 조각낸 후 그 조각들을 k-means와 같은 알고리즘으로 군집화를 한다. 그러면 우리의 visual words는 다양한 색과 oriented edges등을 포착할 수 있다.

Step 2 - visual words의 집합인 codebook을 만들면 어떤 이미지에서 시각 단어들의 발생빈도를 통해 이미지를 인코딩 할 수 있다.

5-10년 전까지만해도 이미지를 입력받으면 BOW나 HOG와 같은 다양한 특징표현을 계산해 그 특징들을 Linear classifier의 입력으로 사용했다. 특징이 한번 추출되면 featue extractor는 classifer를 트레이닝하는 동안 변하지 않고 Linear classifier만 훈련이 되어 update된다.

CNN DNN은 크게 다르지 않지만 유일하게 다른점은 이미 만들어 놓은 특징들을 쓰지 않고 데이터로부터 특징들을 직접 학습한다는 것이다. 그래서 raw 픽셀이 그대로 input으로 들어가고 여러 layer를 거쳐 데이터를 통한 특징 표현을 직접 만들어 낸다. 그래서 Linear classifier뿐만 아니라 가중치 전체를 학습한다.

profile
ALL IS WELL🌻
post-custom-banner

0개의 댓글