항등함수와 소프트맥스 함수
지난 글에서 신경망의 출력층에서 사용되는 활성화 함수에 대해서 정리했습니다.
이번 글에서는 손실 함수가 무엇인지 그리고 평균 제곱 오차와 교차 엔트로피 오차에 대해 글을 정리하겠습니다.
손실 함수란
손실 함수(loss function)란 쉽게 말해 신경망 학습에서 사용하는 하나의 지표라고 할 수 있습니다.
신경망에서는 이 손실 함수라는 지표를 기준으로 최적의 매개변수 값을 탐색합니다.
신경망에서 학습을 한다는 것은, 최적의 매개변수(가중치, 편향)를 탐색하면서 손실 함수의 값을 가능한 작게 하는 매개변수 값을 찾는 것을 의미합니다.
손실 함수의 변화를 보면서 학습 데이터에 대한 오차가 얼마나되는지 측정할 수 있습니다.
손실 함수로서 임의적으로 다른 함수를 사용할 수도 있지만 일반적으로 평균 제곱 오차와 교차 엔트로피 오차를 사용합니다.
평균 제곱 오차
가장 많이 쓰이는 손실 함수는 평균 제곱 오차(mean squared error, MSE)입니다.
평균 제곱 오차의 수식은 다음과 같습니다.
$$E=\dfrac{1}{2}\sum _{k}\left( y_{k}-t_{k}\right) ^{2}$$
\(y_{k}\)는 신경망의 출력, \(t_{k}\)는 정답 레이블, \(k\)는 데이터의 차원 수를 뜻합니다.
import numpy as np
y = []
t = []
def mse(y, t):
return 0.5 * np.sum((y-t)**2)
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
print(f'mse = {mse(np.array(y), np.array(t))}')
t = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
print(f'mse = {mse(np.array(y), np.array(t))}')
mse = 0.09750000000000003
mse = 0.25
위의 코드 블럭은 평균 제곱 오차를 구현한 것입니다.
10개의 클래스 분류를 예로 들어 구현한 것입니다.
y는 소프트맥스 함수의 출력이며, t는 정답 레이블입니다.
평균 제곱 오차는 앞선 수식처럼, 각 원소의 출력 값과 정답 레이블의 차를 제곱한 후, 그 총합을 계산해 구할 수 있습니다.
첫 번재의 예는 정답이 '2'이고 신경망의 출력도 '2'에서 가장 높은 경우입니다.
그러나, 두 번째 예에서는 정답은 같지만 신경망의 출력이 '7'에서 가장 높습니다.
결과를 보면 첫 번째 예의 손실 함수 출력이 더 작으며 정답 레이블과의 오차도 작은 것을 알 수 있습니다.
따라서, 평균 제곱 오차를 기준으로 첫 번째 추정 결과가 정답에 더 가까울 것으로 판단할 수 있습니다.
교차 엔트로피 오차
교차 엔트로피 오차(cross entropy error, CEE)도 많이 사용하는 손실 함수입니다.
교차 엔트로피 오차의 수식은 다음과 같습니다.
$$E=-\sum _{k}t_{k}\log y_{k}$$
위 수식에서 \(log\)는 밑이 \(e\)인 자연로그이며, \(y_{k}\)는 신경망의 출력, \(t_{k}\)는 정답 레이블을 뜻합니다.
\(t_{k}\)에서 정답에 해당하는 레이블 인덱스의 원소만 1이고 나머지는 0입니다. 따라서 정답일 때의 추정의 자연로그를 계산하는 식이 됩니다.
예를 들어, 정답인 레이블의 신경망 출력이 0.6이라 가정한다면 교차 엔트로피 오차는 \(-log0.6 = 0.51\)이 됩니다. 0.1이라면 \(-log0.1 = 2.30\)이 됩니다.
교차 엔트로피 오차는 정답일 때의 출력이 전체 값을 정하게 되는 것입니다.
마찬가지로 파이썬 코드로 구현한 것을 보며 이해보도록 합시다.
import numpy as np
y = []
t = []
def mse(y, t):
return 0.5 * np.sum((y-t)**2)
def cee(y, t):
delta = 1e-7
return -np.sum(t * np.log(y + delta))
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
print(f'cee = {cee(np.array(y), np.array(t))}')
t = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]
print(f'cee = {cee(np.array(y), np.array(t))}')
cee = 0.510825457099338
cee = 2.1927228474611695
첫 번째 예는 정답일 때의 출력이 0.6인 경우입니다. 이때의 교차 엔트로피 오차 값은 약 0.51입니다.
두 번째는 정답일 때의 출력이 0.1일 때의 경우입니다. 이때의 교차 엔트로피 오차 값은 2.3정도 입니다.
즉, 결과가 더 작은 첫 번째 추정이 정답일 가능성이 높다고 판단한 것입니다.
앞서 평균 제곱 오차의 판단과 일치함을 볼 수 있습니다.
'머신러닝 & 딥러닝 > 기초 이론' 카테고리의 다른 글
[머신러닝/딥러닝 기초] 12. 미분과 수치미분 (0) | 2022.02.17 |
---|---|
[머신러닝/딥러닝 기초] 11. 정확도 대신 손실 함수를 사용하는 이유 (0) | 2022.02.17 |
[머신러닝/딥러닝 기초] 9. 항등 함수와 소프트맥스 함수 (0) | 2022.02.15 |
[머신러닝/딥러닝 기초] 8. 신경망과 신경망의 구조 (0) | 2022.02.11 |
[머신러닝/딥러닝 기초] 7. 퍼셉트론에서 신경망으로 가는 핵심: 활성화 함수란? (0) | 2022.02.11 |
댓글