reference: https://cs231n.github.io/linear-classify/ - 2022/11/7
이미지 분류를 위한 보다 강력한 방법인 Neural Network와 Convolution Neural Network를 알아볼 것이다.
이 두 방법들은 두 가지 중요한 요소가 있다. 데이터를 클래스 스코어로 매핑시키는 Score Function, 그리고 예측한 스코어와 실제 라벨과의 차이를 정량화해주는 Loss Function이 그 두 가지이다.
이를 최적화 문제로 바꾸어서 스코어 함수의 파라미터들에 대한 손실함수를 최소화할 것이다.
이미지의 픽셀값들을 클래스 스코어로 매핑해주는 가장 단순한 함수로 선형 매핑 함수가 있다.
K: 서로 다른 클래스의 개수
N: 학습 데이터의 수
D: 학습 데이터의 차원(곱)
x: [D * 1]
W: [K * D]
b: [K * 1]
W 안의 파라미터들은 보통 weight, 즉 가중치로 불리고, b는 bias 벡터 라고 불린다.
선형 분류기는 클래스 스코어를 이미지의 모든 픽셀 값들의 가중치 합으로 스코어를 계산한다. 여기서 가중치에 어떤 값을 주느냐에 따라 스코어 함수는 이미지의 특정 위치에서 특정 위치에서 특정 색깔을 선호하거나 선호하지 않거나 할 수 있다.
위 예시에서는 이미지가 픽셀 4개로만 이루어지며, 색 체널도 고려하지 않은 단일 채널이며, 3개의 클래스가 있다고 가정한 것이다. 현재의 파라미터는 낮은 cat 스코어를 갖도록 한다. 따라서 파라미터 값들이 매우 안 좋은 예시임을 알 수 있다.
최적의 가중치를 구하기 위해 현재의 가중치를 입력으로 받아 각 스코어를 확인하고 현재 가중치가 얼마나 나쁜지를 정량적으로 말해주는 것이 손실함수(Loss function)이다.
손실함수가 주어진 가중치가 현재 적절한지 정량화 해준다. 하지만 우리가 원하는 것은 가장 좋은 가중치가 무엇인지 찾아내는 효율적인 과정을 찾는 것이다. 이 과정이 바로 최적화 과정이다.
손실함수 를 정의하면, 를 통해 의 스코어를 계산하고 스코어를 정답 레이블 와 파라미터로 사용하여 손실 Loss를 구한다. 최종 Loss는 각 N 개의 샘플들의 대한 Loss의 평균이 된다.
두 파라미터 W, b를 하나로 표현하는 간단한 트릭이 있다. 앞으로 내용을 전개해 나갈 때 W, b 두 파라미터를 매번 동시에 고려해야 한다면 표현이 번거로워진다. 흔히 사용하는 트릭은 이 두 파라미터들을 하나의 행렬로 합치고, 를 1의 값을 갖는 한 차원을 늘리는 방식이다. 이 한 차원을 추가하는 것으로, 새 스코어 함수는 행렬곱 한 번으로 계산이 가능해진다.
가장 먼저 이미지 분류 문제에 적합한 손실함수 중 하나인 multi-class SVM loss에 대해 알아본다. SVM에서 손실을 Hinge loss라 한다.
을 구하는 방법
1. True 카테고리 를 제외한 나머지 카테고리와 True 카테고리의 스코어를 비교한다.
2. 스코어의 격차가 일정 마진(safety margin) 이상으로 True 카테고리의 점수가 더 높으면, True 카테고리의 점수가 다른 false 카테고리보다 크다는 것으로 Loss는 0이된다.
3. 그렇지 않은 경우(), 정답이 아닌 카테고리의 값을 모두 합한 값이 Loss가 된다.
4. 전체 트레이닝 데이터 셋에서 그 Loss들의 평균을 구한다.
위의 그래프 모양을 보자. x축은 로 실제 정답 클래스의 스코어이며 y축은 Loss이다. 정답 카테고리의 점수가 올라갈 수록 Loss가 선형적으로 줄고, wrong카테고리 스코어가 True 카테고리 스코어보다 마진만큼 작아질 때부터 Loss는 0이 된다. Loss가 0이라는 것은 분류가 잘 된다는 의미이다.
*예시
safety margin을 1로 설정하는 것은 큰 상관이 없다. 우리가 궁금한 것은 여러 스코어 간의 상대적인 차이이기 때문이다.
SVM의 Loss는 0 ~ 무한대의 값으로, 모든 스코어가 0에 가깝고 True 카테고리의 값과 비슷하다면 Loss는 (클래스의 수 - 1)의 값일 것이다.
위와 같이 제곱 항으로 바꾸면, 결과를 더욱 극대화시킬 수 있다. 즉, 틀린 것들은 정말로 그게 틀린 것이 되는 것이다. 둘 중 어떤 loss를 선택하느냐는 우리가 에러에 대해 얼마나 신경쓰고, 그것을 어떻게 정령화 할 것인지에 달려있다.
def L_i_vectorized(x, y, W):
scores = W.dot(x)
margins = np.maximum(0, scores - scores[y] + 1)
# True 클래스에 대해 loss를 0으로 설정해 굳이 다 돌 필요없게 만듦: vectorizsd 기법
margins[y] = 0
loss_i = np.sum(margins)
return loss_i
하지만, Loss가 0이 되도록 하는 가중치 W는 유일하지 않다.
손실 함수라는 것이 어떤 W를 찾아야하는 것인지 말해주는 것이라면, 이는 머신러닝의 핵심과 맞지 않다. 왜냐하면 이는 오직 데이터의 loss만 신경쓰며 분류기에게 트레이닝 데이터에 맞는 W를 으로 찾도록 하는 것이기 때문이다. 머신러닝의 핵심은 트레이닝 데이터를 이용하여 찾은 어떤 분류기를 테스트 데이터에 적용하는 것으로, 테스트 데이터에 적용했을 때의 성능에 관심이 있는 것이다.
위의 예시를 보면, 분류기가 모든 트레이닝 데이터를 완벽히 분류하기 위해 파란 곡선을 만들었지만, 테스트 데이터가 들어왔을 때, 파란 곡선은 완전히 틀리게 된다. 사실 우리가 의도했던 것은 초록 선이다.
이를 해결하기 위해 Regularization 항을 추가한다. 이전의 "Data Loss Term"에서는 분류기가 트레이닝 데이터에 핏하게 하고, "Regularization term"을 추가해 모델이 좀 더 단순한 W를 선택하도록 도와주는 것이다.
Regularization의 종류 중 가장 보편적인 것은 Regularization으로 Weight decay라고도 한다.
람다는 하이퍼파라미터로 R(W)의 값을 적당히 맞춰주기 위해 설정되어야 한다. 람다가 너무 커지면 너무 regulariztion 되어 loss 값은 낮추는 것이 의미가 없어지고, 너무 작으면 overfit 현상을 해결할 수 없다.
Multinomial logistic regression, 즉 softmax는 딥러닝에서 자주 쓰인다.
softmax라는 손실함수를 사용해 스코어를 가지고 클래스 별 확률 분포를 계산한다. 스코어들을 모두 지수로 취해 양수로 만들고 그 지수들의 합으로 다시 정규화 시킨다. 그래서 softmax 함수를 거치게 되면 확률 분포를 얻을 수 있고, 그것은 바로 해당 클래스일 확률이 된다.
확률이기 때문에 0에서 1 사이의 값이고 모든 확률의 합은 1이 된다. 우리가 원하는 것은 정답 클래스에 해당하는 클래스의 확률이 1에 가깝게 계산되는 것이다. 하지만 Loss는 반대로 확률이 높을 수록 작고 확률이 낮을수록 크게 나와야므로 "" 이 된다.
softmax loss를 cross entropy loss라고도 부른다. 최솟값은 0이고 최댓값은 무한대이다. 정답 클래스에 대한 Log 확률이기 때문에 이고, 이므로. 위의 고양이를 완벽히 분류했다면 Loss는 0이다. 확률이 1이 되려면 스코어가 다른 클래스의 점수보다 극단적으로 높아야한다. 대개 softmax loss가 수학적으로 nice하고 편리하다고 말한다.
지금까지 정리하면, (x, y)의 데이터셋을 갖고 있을 때, 함수 f를 통해(dot product) 각 라벨에 대한 스코어를 내고 알고리즘이 얼마나 나쁘게 동작하고 있는지 측정할 손실함수(Softmax or SVM...)를 작성한다. 모델이 복잡해 지는 것을 막고 테스트 셋이 좋은 결과를 내기 위해 Regularization term을 추가한다.
다음 question.. 어떻게 분류기를 훈련시키는가?, W값으로 loss를 구하는 것은 알겠는데, W값을 어떻게 찾으라는 것인가?