지도학습(Supervised Learning) 시 예측한 값(pred)과 실제 값(label)의 차이를 비 교하기 위한 함수
즉, 함수 중에 알고리즘이 얼마나 잘못 예측하는 정도
목적 함수(Objective Function), 비용 함수(Cost Function), 에너지 함수(Energy Function) 등 다양하게 불림
손실이 커질 수록 모델 학습이 잘 안되고 있다고 해석이 가능하며,
반대로 손실이 작아질 수록 모델 학습이 잘 되고 있다고 해석 가능
신경망 학습에는 최적의 매개변수(가중치와 편향)값을 탐색할 때, 손실 함수의 값을 가능한 작게 하는 매개변수 값을 찾는다.
이 때, 매개변수의 미분을 계산하고, 그 미분 값을 단서로 매개변수의 값을 서서리 갱신하는 과정을 반복한다.
한 가중치 매개변수의 손실 함수의 미분 = 가중치 매개변수의 값을 아주 조금 변화시켰을 때, 손실 함수가 어떻게 변하는가??
- : 신경망의 출력(각 뉴런의 output)
- : 정답 레이블
- : 데이터 차원의 수
관측값에서 평균을 뺀 값을 제곱하고, 그것을 모두 더한 후 전체 개수로 나눠서 수하는 분산과 유사한 개념
오차제곱합(SSE) 대신 평균제곱오차(MSE)를 사용하는 이유
평균제곱오차(MSE)는 언제 사용하는가?
구현
import numpy as np
def MSE(real, pred):
return (1/len(real)) * np.sum((real - pred)**2)
def SSE(real, pred):
return 0.5 * np.sum((real - pred)**2)
--------------------------------------
Data가 100개일 때, SSE의 결과: 0.14375
Data가 1000개일 때, SSE의 결과: 12.51875
--------------------------------------
Data가 100개일 때, MSE의 결과: 0.00288
Data가 1000개일 때, MSE의 결과: 0.0025
--------------------------------------
평균제곱오차(MSE)는 분산과 비슷하며, 마찬가지로 편차 제곱 합을 하였기 때문에 실제 편차라고 보기 힘들어, 분산과 표준편차 처럼 제곱근(Root)를 씌운 것이 평균제곱근오차(RMSE)
분산대신 표준편차를 사용하는 것과 비슷하게 평균제곱오차(MSE)는 실제 편차를 반영한다고 볼 수 없다.
평균제곱오차(MSE)의 "큰 오류를 작은 오류에 비해 확대 시킨다"는 것을 제곱근(Root)해줌으로 써 보정이 들어갔다.
즉, 평균제곱근오차(RMSE)는 제곱근(Root)을 사용함으로서 왜곡을 줄여주기 때문에 오차를 보다 실제 편차와 유사하게 볼 수 있다.
구현
class RMSELoss(torch.nn.Module):
def __init__(self):
super(RMSELoss,self).__init__()
def forward(self,x,y):
eps = 1e-6 # 역전파에서 NaN이 발생하는 것을 방지하기 위해 앱실론 추가
criterion = nn.MSELoss()
loss = torch.sqrt(criterion(x, y) + eps)
return loss
def RMSE(real, pred):
return np.sqrt((1/len(real)) * np.sum((real - pred)**2))
: 범주의 개수
: 사건의 확률 질량 함수
- 예시1) 가방안에 빨간공 20개 / 파란공 80개 들어있는 경우
- 예시2) 가방안에 빨간공 1개 / 파란공 99개 들어있는 경우
- 즉, Entropy는 예측하기 쉬운 일보다는 예측하기 어려운 일에서 값이 더 높다
인공지능 모델을 잘 학습한다는 것은 정답의 분포를 모델이 잘 따라하도록 하는 것
즉, 정답 분포와 모델이 예측한 값의 분포가 비슷해지도록 만다는 것
KL-Divergence는 정단 분포와 모델의 예측값의 분포가 얼마나 비슷한지를 측정할 때 사용 되는 지표
수식을 다르게 정리하면
로 위에서 설명한 (Entropy + Cross-Entropy)의 값으로 나뉜다.
P가 정답 분포이고, 분류 문제의 경우 정답은 하나의 1의 값을 가지고 나머지는 0
의 값을 가지는 One-Hot 형태이다
따라서 이값을 Entropy 수식에 넣으면 0이 된다.
즉, 분류 문제에서 KL-Divergence는 가 된다.
그로인해 Cross-Entropy의 값을 최적화 하는 것이 모델이 정ㄷ바 분포를 잘 따라가도록 하는 셈이 된다.
개,고양이,사자에 대한 다중 분류 문제
Cross-Entropy의 값은 의 값이 된다.
즉, 정답 레이블에서 정답에 해당하는 위치의 확률의 로그 값이 출력된다.
- 예측값이 단일 항목으로 이루어져있다면 (ex, [0.5])
- 단순 이진 분류이므로, Binary Cross Entropy 를 사용
- 예측값이 다중 항목으로 이루어져있으며, 각 항목의 확률 합이 1이상일 경우 (ex, [0.7, 0.6, 0.4])
- 멀티 이진 분류이므로, Binary Cross Entropy 를 사용
- 예측값이 다중 항목으로 이루어져있으며, 각 항목의 확률 합이 1 이라면 (ex, [0.5, 0.2, 0.3])
- 다중 분류이므로, Cross Entropy 를 사용
def CEE(predict, label):
delta = 1e-7
return -np.sum(label * np.log(predict + delta))
도출 과정
나누고자 하는 분류의 개수에 따라 사용하는 손실함수가 변경됨
범주가 2개인 데이터는 Sigmoid(0 ~ 1) 또는 tanh(-1 ~ 1) 활성화 함수를 사용해 값을 반환
로그 손실(Log Loss) 또는 로지스틱 손실(Logistic Loss)라 불리며, 즈로 로지스특 회귀의 손실함수로 사용된다.
구현
def BCEE(predict, label):
delta = 1e-7
pred_diff = 1 - predict
label_diff = 1 - label
result = -(np.sum(label*np.log(predict+delta)+label_diff*np.log(pred_diff+delta)))/len(label)
return result
torch.nn.BCEWithLogitsLoss(weight=None, size_average=None, reduce=None, reduction='mean', pos_weight=None)
Class가 3개 이상인 데이터를 대상으로 사용하는 손실함수
주로 Softmax 활성화 함수가 사용
실제 라벨은 One-Hot Vector로 구성
출력된 Vector는 각 Class에 속할 확률로 나오며, 총합은 1
Cross-Entropy Error를 N개의 데이터셋에 대해 1개의 스칼라를 추출하는 방법
구현
def CCEE(predict, label):
delta = 1e-7
log_pred = np.log(predict + delta)
return -(np.sum(np.sum(label * log_pred, axis = 1)))/label.shape[0]
분류 문제에서 사용
가중치(Weight)는 Class 불균형 문제를 개선하기 위해 수동으로 가중치별 학습 비중의 스케일을 조정하기 위해 사용
log 함수와 음(-)의 부호를 사용해 Softmax 출력값이 낮은 값은 값이 크도록 만들 수 있고, Softmax 출력값이 높은 값은 의 값이 0에 가깝도록 만든다.
다시말하면, 정답 클래스의 Softmax 출력이 높다면 출력이 정확한 것이므로 의 값이 매우 작아지게 되고, 반대의 경우에는 큰 값을 가지게 된다.
빨간색 = Hard Case 문제
초록색 = Easy Case 문제
(그래프에는 α=1,γ=1적용)
Hard 케이스보다 Easy 케이스의 경우 weight가 더 많이 떨어짐을 통해
수많은 Easy Negative 케이스에 의한 Loss가 누적되는 문제를 개선