RL Researcher

평균제곱오차(Mean Square Error) 본문

Machine-Learning/Algorithm

평균제곱오차(Mean Square Error)

Lass_os 2020. 12. 23. 00:28

1. 손실함수(Loss Function)


손실함수(Loss function)는 정답에 대한 오류를 나타내는 값입니다. 손실함수(Loss function)은 정답에 가까울수록 작은 값이 나오고, 정답과 멀어질수록 큰 값이 나오게 됩니다.

손실함수를 사용하는 이유??

  • 궁극적인 목표는 높은 'Accuracy'를 끌어내는 매개변수 값을 찾는 것입니다.

그렇다면 'Accuracy'라는 지표를 나두고 'Loss function'을 택하는 이유??

  • 신경망 학습에서는 최적의 매개변수(가중치(weight): w, 편향(bias) : b)를 탐색할 때 손실 함수의 값을 가능한 작게 만들 수 있는 매개변수 값을 찾습니다.

손실함수에서 미분?

  • 가중치의 매개변수 값을 변화시켰을 때 손실 함수가 어떻게 변하게 되는가라는 의미입니다.

'Accuracy'를 지표로 삼으면 안되는 이유는 미분값이 대부분의 장소에서 0이 되어 매개변수를 갱신할 수 없기 때문입니다.

2. 평균제곱오차(Mean Square Error)


오차(잔차)의 제곱에 대해 평균을 취한것을 말합니다.

$$MSE = \frac{1}{N}\sum (y_{i}-t_{i})^{2}$$

MSE(Mean Square Error)의 식은 다음과 같습니다.

$y_{i}$ : 신경망의 출력(신경망이 추정한 값)
$t_{i}$ : 정답 레이블
$i$ : 데이터의 차원수

※ 결과 : 컴퓨터(Machine)가 추정한 값과 실제 정답값의 차이를 구하여 그 값을 제곱하고(제곱하게 되면 양의 값이 나옵니다.), 그 값들을 전부 더한 후, 더한 값들을 전체의 개수로 나누어 평균값을 도출하는 것

위의 수식을 파이썬으로 실습해보겠습니다.

import numpy as np
def MSE(y,t):
    return(np.sum((y - t) ** 2) / len(y))

# label은 2
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]

# 7일 확률이 가장 높다고 추정함(0.6)
y = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0]

mse_value1 = MSE(np.array(y),np.array(t))
print('{:.4f}'.format(mse_value1))

# 2일 확률이 가장 높다고 추정함(0.6)
y = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]

mse_value2 = MSE(np.array(y),np.array(t))
print('{:.4f}'.format(mse_value2))

========================================================================

<output>
0.1195    # mse_value1의 결과 값
0.0195    # mse_value2의 결과 값

t : 정답 값

첫번째 y : 0일 확률이 0.1, 1일 확률이 0.05, 2일 확률이 0.1로 정답값에서 현저히 멀어졌습니다.

두번째 y : 0일 확률이 0.1, 1일 확률이 0.05, 2일 확률이 0.6입니다.

※ 만약에 두번째 y가 학습시킨 모델이라고 했을 때 에러 값을 현저히 줄였기 때문이 이런식으로 가중치(weight : w), 편향(bias : b)을 줄여간다면 조금더 성공적인 모델을 만들 수 있을 것입니다.

mse_value1 : 정답이 2이고, 신경망의 출력도 2에서 가장 높은 경우입니다.
mse_value2 : 정답이 2이고, 신경망의 출력은 7에서 가장 높은 경우입니다.

MSE(Mean Square Error)값이 mse_value1의 손실함수 출력이 작고, 정답 레이블과의 오차도 작은 것을 알 수 있습니다.

평균제곱오차(Mean Square Error)를 기준으로 첫번째 추청 결과가 정답에 더 가까울 것으로 판단이 됩니다.


조금더 순차적으로 코드를 진행해보도록하겠습니다.

print(t) # 실제 정답 값
print(y) # 컴퓨터(Machine)가 예측한 정답 값

========================================================================

<output>
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0]
# 실제 정답 값(t) - 컴퓨터(Machine)이 예측한 정답 값
print(np.array(t) - np.array(y))

========================================================================

<output>
[-0.1  -0.05  0.4   0.   -0.05 -0.1   0.   -0.1   0.    0.  ]

실제 정답 값과 예측 정답 값을 빼줍니다.

# np.squre(실제 정답값(t) - 컴퓨터(Machine)가 예측한 정답 값(y)) 
print((np.array(t) - np.array(y)) ** 2)

========================================================================

<output>
[0.01   0.0025 0.16   0.     0.0025 0.01   0.     0.01   0.     0.    ]

실제 정답 값과 예측한 정답 값을 뺀 것을 제곱해줍니다.

print(sum((np.array(t) - np.array(y)) ** 2))

========================================================================

<output>
0.19500000000000006

실제 정답 값과 예측한 정답 값을 뺀 것을 제곱한 후, 그것들을 Add해줍니다.

print(sum((np.array(t) - np.array(y)) ** 2)/ len(y))

========================================================================

<output>
0.019500000000000007

최종으로 Add한 것을 컴퓨터(Machine)이 예측한 값으로 나누어 줍니다.

※ 처음의 코드는 소수점 4자리까지 자른것이기 때문에 값은 동일합니다.

Comments