CS231n 2017 Lecture 3 : Loss Functions and Optimization
Lecture 2에서 배운 내용의 review로 시작하는 Justin. Linear classifier는 W를 가지고 있었고, 각 W 값은 해당 픽셀이 얼마나 score에 영향을 끼칠지 결정한다.
이번 시간에 배울 loss function과 optimization. 우리의 예측의 질을 측정하는 척도가 되는 loss function을 정의하고(질이 좋으면 loss가 낮고 질이 나쁘면 loss가 높게), 그 loss 값을 낮추는 방향으로 W를 optimization 시키자는 아이디어이다.
전반적인 loss function이 돌아가는 모양을 알려준다. 우선 xi와 W가 곱해져서 score를 뱉는다. 이것이 우리의 classifier의 예측이다. 그 score를 yi와 함께 loss function에 넣고 loss를 계산한다. 이것은 i번째 데이터의 loss인 loss_i이므로, N개의 데이터에 대해 loss_1부터 loss_N을 구하고 평균을 낸 것이 우리의 최종 loss이다.
먼저 배울 loss는 multiclass SVM loss이다. 좋은 classifier라면 가령 cat을 넣었을 때 score_cat이 score_car나 score_frog보다 높아야 한다. 얼마만큼 더 높아야 하는지는 safety margin이라고 하고, 여기서는 1로 한다. 각 class의 score에 대해 Sj-Syi+1 연산을 해서 sum하는데, Syi가 높아질수록 loss가 내려가며, 0보다 작은 값이 나오면 0을 뱉는다.
그래프는 이렇다. 모양 때문에 hinge loss라고도 부른다고 한다.
car-cat+1을 하면 2.9가 나온다. frog-cat+1을 하면 -3.9가 나오는데, 0 이하이므로 0이 된다. 2.9+0 = 2.9가 우리의 loss가 된다. 상당히 간단하다.
첫번째 question이다. 이번 강의에서는 몇 번의 문제를 던지고 생각할 거리를 준다. car의 score를 보면 4.9로 이미 1.3이나 2.0에 비해 압도적이다. 하지만 우리의 hinge loss는 보다시피 다른 score보다 1 이상 높은것에 대해 가산점을 주지 않고 다 똑같이 loss 0을 뱉는다. car를 3.0까지 깎아도 loss는 변하지 않을 것이다.
Q2는 SVM loss의 최대 최소값이 각각 얼마냐는 질문이다. 최소값은 당연히 0이고, 최대값은 무한대이다.
Q3. 모든 score가 0일 경우 Sj - Syi + 1 = 0 - 0 + 1이 된다. 이 연산을 하나의 Syi가 다른 모든 class의 score에 대해 수행하고 sum하기 때문에, 답은 class_num - 1이다. 이걸 이용해서 코딩할때 디버깅을 하면 좋다고 한다.
Q4. Syj가 자기 자신을 뺀 다른 class의 score와 연산한다고 했는데, 여기에 자기 자신과의 연산 Syj-Syj+1 = 1 이 추가된 것 뿐이므로 loss는 1 더해진다. 이렇게 하지 않는 이유는 이 경우 loss의 최소값이 1이 되는데, 문제가 없을 때 loss가 0인 것이 더 직관적이기 때문이라고 한다.
Q5. sum 말고 mean을 쓰면 어떻냐는 것인데, 단순히 loss가 class_num으로 나누어진 것일 뿐이다. 그런데 우리가 신경쓰는것은 loss가 줄어드는 경향성이지 그 값 자체에는 관심이 없다.
Q6. 제곱을 하면 어떨까? classifier가 심하게 잘못된 예측을 하면 그것에 대해 더 심하게 벌주게 될 것이다. Loss function을 정의하는 것은 알고리즘에게 내가 어떤 부분을 신경 쓰는지 전달하는 것이다. 그런 관점에서 볼때 이런 squared hinge loss를 사용한다는 것은 classifier의 큰 잘못에 대해 더 신경을 쓰겠다는 표현인 것이다.
상당히 간단한 코드로 SVM Loss를 나타낼 수 있다.
SVM Loss가 0인 W를 찾았다면, 그 W가 유일한가? 그렇지 않다. 우선 hinge loss는 safety margin 이상으로 차이나는 것을 신경쓰지 않기 때문에, Syi를 무한히 키워도 loss는 계속 0일 것이다. 다른 관점에서, loss가 0인 W를 찾았다면 2W의 loss 역시 0이다. Syi가 다른 score와 차이가 1 이상이라면, 2배로 scale하면 차이가 2 이상이 될 것이고 loss는 역시 0일 것이다.
Overfitting을 다루는 슬라이드가 나왔다. 그래프 상의 원이 training data고 네모가 test data이다. Training data에 overfit 된 W는 필요 이상으로 복잡하고 구불구불해지는 바람에 일반화 능력이 떨어져서 unseen data는 잘 맞추지 못한다. Overfitting과 regularization에 대한 설명은 익숙해지도록 들었지만 이 부분에서 오컴의 면도날을 언급한 건 신선한 충격이었다. 똑똑한 사람들은 발상부터가 다르다는걸 느꼈다. 오컴의 면도날이란건 어떤 현상을 설명할 때 불필요한 가정을 잘라내라는 말이다. 여기서는 어떤 training data를 예측하는 함수를 만들때 필요 이상으로 복잡하게 만들지 말라는 얘기로 적용되었다. 굳이 직선 하나로 설명이 되는데 구불구불하게 만들면 test dataset에서 힘을 못쓴다.
그래서 나온게 regularization이다.
그 종류도 다양한데, 결국은 어떤 방식으로든 W를 통제하는 알고리즘이다. L2의 경우 제곱이 붙었기 때문에 W의 원소들이 평탄한 값이 되기를 원하고, L1의 경우는 sparsity를 선호한다고 한다.
가령 L2의 경우는 (0.9,0,0,0)보다 (0.25,0.25,0.25,0.25)를 선호할 것이다. 한 값이 클 경우에 제곱을 거쳐서 나온 값이 엄청 커지기 때문이다. L1은 (0.25,0.25,0.25,0.25)보다는 (0.9,0,0,0)을 선호할 것이다. Regularization 방법마다 complexity를 줄인다는 목적 자체는 같아도, complexity를 정의하는 방식은 다름을 알 수 있다. 어떤 방법을 선택할 것인지는 problem dependent하기 때문에 상황에 맞게 사용하는 것이 중요하다.
SVM을 알아보았지만 여러 SVM 종류 중 하나에 불과하다고 한다. 하지만 그 방식들도 다 비슷하기 때문에 따로 다루지는 않겠다고 한다.
Softmax는 우리가 다루던 score에 확률 값이라는 의미를 더해준다. 지금까지는 score 값 자체는 의미가 없었고 score 끼리의 차이가 몇인가가 중요했다. Softmax를 거치면서 score들이 모두 합치면 1이 되는 확률 값으로 바뀌고 의미가 생긴다. 정답 label에 대한 추정 확률을 P라고 하고, loss는 -log P가 된다.
우리는 P가 1일때 loss를 0으로 만들고 싶기 때문에 -log를 사용할 것이다.
위에서 설명한 softmax를 실제로 적용시키면서 loss를 구하는 과정이다. Loss의 min/max를 묻는 문제가 나왔는데, 위의 그래프를 보면 알 수 있듯이 min=0이고 max는 무한대이다. 하지만 그 값을 보기 위해서는 score가 상당히 극단적으로 나와야 하므로 실제로 min/max를 볼 일은 없을 것이다.
Q2는 score가 0에 가까울 때의 loss를 묻고 있다. Score가 0이면 e^score = 1이므로 각 class의 확률 값은 1/class_num일 것이다. 이것에 -log를 취하면 loss는 log(class_num)이 된다. SVM에서와 마찬가지로 디버깅할때 유용하게 사용할 수 있다.
SVM과의 비교.
정답 score가 10일때, score들을 조작한 후 softmax와 SVM에서 loss가 어떻게 변할 지를 묻고 있다. SVM은 safe margin=1 이상의 차이에 대해 신경을 쓰지 않으므로 저기서의 loss 변화는 없을것이다. 하지만 softmax의 cross-entropy loss는 연속적으로 변화할 것이다. P가 1이 될 때까지 학습을 멈추지 않을 것이다.
지금까지 배운 것들의 정리이다. 데이터를 넣고, score를 계산하고, score를 바탕으로 loss_i를 계산한다. Loss_i를 구하는 방식은 softmax와 SVM이 각각 다르다. 그 후에 Loss_i를 sum하고 regularization을 더해준다.
Loss function의 최소값을 찾는 문제는 산을 걷고 있는 남자와 비슷하다. 최저 지점을 어떻게 찾을 것인가? Loss의 도함수를 구해서 최소값을 찾으면 되지 않나 싶지만, deep learning에서 loss가 충분히 복잡해지면 불가능하다. Iterative method를 사용할 수 밖에 없다.
떠올릴 수 있는 가장 단순한 방법 random search. 시도조차 해보고 싶지 않은 방법이다. Assignment에 있을 것 같은 불길한 예감이 든다. 10개의 class에 대해 15%의 정확도가 나왔다고 한다.
산을 내려가려면 현재의 정보를 바탕으로 경사면을 따라 내려가는 수 밖에 없다. 현재 W에서의 gradient를 구한 후 negative를 취하면 The direction of steepest descent를 찾을 수 있다.
Numerical gradient를 구하는 과정을 보여준다. W를 아주 작은 값 h만큼 변화시켜서 Loss에 미치는 영향을 h로 나눈다. 좋은 생각 같아 보이지만 수 많은 W의 모든 원소에 대해 이렇게 할 수는 없다.
다행히도 뉴턴과 라이프니츠 덕에 analytic gradient를 구할 수 있다.
Numerical gradient는 작성하기 쉬운 대신 느리고, 정밀하지 않다.
Analytic gradient는 정확하고 빠르지만, 오류가 나기 쉽다. 미분 과정에서 실수를 할 수도 있고 코드 자체도 조금 더 복잡해질 것이기 때문이다.
Numerical gradient는 디버깅 용으로는 좋다. Numerical과 비교해서 analytic gradient를 잘 구했는지 확인하는 과정을 gradient check라고 한다.
Gradient를 구해서 W에서 빼주는 간결한 코드이다. Step_size는 흔히 learning rate라고 한다. Learning rate는 Justin이 가장 먼저 체크하는 hyperparameter이다.
큰 dataset을 한 번에 계산하는 것은 비효율적이므로 minibatch로 나누어 사용한다. 소수의 데이터만 보고 gradient를 계산해서 update 하기 때문에 stochastic하다고 말한다. 여기서는 언급하지 않았지만 minibatch를 사용하는 또 다른 중요한 원인은 메모리 용량이다.
Lecture 2에서도 다뤘듯이 image의 raw pixels를 바로 linear classifier에 넣는 것은 좋은 생각은 아니었다. 그래서 deep learning이 지배적이기 전에는 feature extraction 방식이 많이 쓰였다.
Raw pixels가 선형으로 분리할 수 없다 해도, feature를 추출하면 선형 분리가 가능하게 할 수 있다.
Fei-Fei 교수가 대학원생일때 하던 연구도 이쪽이라고 한다. 이미지를 잘게 쪼개서 군집화하여 가방에 넣고(Bag of Words) 그것을 feature로 사용한다.
CNN도 크게 다르지 않다. 다른 점은 feature extraction 부분까지도 학습을 시킨다는 것이다. 저번에도 그렇고 justin이 하고 싶은 말은 deep learning이라는게 하루 아침에 생긴게 아니라는 말인 것 같다.
Lecture 4에서는 neural network와 backpropagation을 배울 것이다.