머신러닝 기초 완전정복 : MSE(Mean Squared Error)와 SGD(확률적 경사하강법) 쉽게 배우기 - 1

MSE와 SGD가 도대체 뭐야!!!! 겁먹지 마세요. 어렵지 않습니다. 생각해보니까 어려운 거 같기도

  • SGD(Stochastic Gradient Descent), 한국말로 하면 확률적 경사하강법 입니다.
    • SGD는 정답과 예측의 차이를 줄이기 위해, 데이터를 하나씩(또는 작은 묶음씩) 보면서 기울기(경사) 가 가리키는 반대 방향으로 조금씩 움직여 파라미터를 고치는 방법인데요.
    • SGD를 직접 해보기 위해서 문제를 세팅하고, Loss함수로 MSE를 사용해 직접 머신러닝까지 해볼거에요.
    • 오늘은 문제 세팅을 한 후 MSE, 그리고 기본개념에 대해서 설명해보도록 할게요.
👍
Loss 함수가 뭔지, sgd가 뭐고 MSE가 뭔지 아무것도 모르겠어도 괜찮아요. 머신러닝하러 가봅시다.
  • 문제 세팅
    • 데이터 (x,y) 쌍 m개가 다음과 같이 주어집니다.
import numpy as np 

m = 100
X = np.linspace(-5, 5, m)

A, B, C = 0.5, 1.0, 2.0
noise = np.random.randn(m)

y = A*X**2 + B*X + C + noise
del A, B, C

try:
    import matplotlib.pyplot as plt
    plt.scatter(X, y)
    plt.xlabel("x")
    plt.ylabel("y")
    plt.show()
except:
    pass
자, 위 코드가 이해되나요? 이해가 되면 밑의 설명은 넘어가도록 합시다. 혹시나 표준정규분포의 자세한 개념도 까먹었을까봐 친절하게 써뒀습니다. 내가까먹은거아님

자세한 코드 해설

표준정규분포 N(0,1)란..ㅎㅎ

  • 정규분포 : 종 모양 곡선으로, 평균값에 많은 데이터가 몰려있고, 갈수록 점점 줄어드는 모양.
    • 키, 시험점수, 오차, 자연현상 같은 것들이 대체로 이 분포를 따른다.
  • N(0,1)
    • N은, Normal distribution이라는 뜻
    • 첫번째 숫자는 평균. 즉 데이터가 모여 있는 중심이다.
    • 두번째 숫자는 분산. 퍼져있는 정도이며, 표준편차의 제곱이다.
    • 편차란, 각 데이터에서 평균을 뺀 값이다.
    • 편차들을 제곱한것들의 평균이 분산이다.
    • 따라서 분산의 제곱근은 표준편차이다
  • 즉, 평균이 0이고 흩어진 정도가 1인 정규분포.
    • 표준편차 1은, 값 대부분이 -3~3 안으로 들어옴.
  • 68–95–99.7 법칙(= 3-시그마 규칙)
    • 정규분포 N(평균,σ^2)에서
      ±1σ 구간 [평균-1σ, 평균+1\σ] 안에 데이터가 약 68.27%
      ±2σ 구간 안에 약 95.45%
      ±3σ 구간 안에 약 99.73%가 들어온다는 경험 법칙. (반올림해서 68–95–99.7)
import numpy as np 

파이썬의 대표적인 수치계산 라이브러리인 Numpy를 불러온다.


m = 100            # 데이터 점 개수
X = np.linspace(-5, 5, m)  # -5부터 5까지 균등 간격으로 m개

Numpy의 linspace 함수는, linear space의 줄임말이다.'균등하게' 나눠진 '공간' 이라는 뜻이다. 쉽죠? 3개의 주요인자를 받고 인자는 시작, 끝, 원소갯수 이다.
그리고 NumPy 배열, numpy.ndarray를 반환한다.

따라서 X ndarray의 원소 갯수를 -5에서 5까지 균등한 간격으로 100개 만든다는 뜻이다.


A, B, C = 0.5, 1.0, 2.0
noise = np.random.randn(m)  # 평균 0, 표준편차 1인 정규분포 잡음

이건, random.randn()는 난수 갯수를 뜻하는 하나의 인자(예를들어 m)를 받고, 표준정규분포 N(0,1)에서 독립(i.i.d)으로 m개의 난수를 뽑아 길이 m의 NumPy 배열(ndarray)로 반환한다.


y = A*X**2 + B*X + C + noise
del A, B, C
  • numpy 배열 간 덧셈은 원소별(element-wise) 연산을 한다. 즉, 같은 인덱스끼리 더한다. X도 100개고 noise 도 100개니까 배열 간 원소별 덧셈이 된다.
  • 파이썬에서 del 키워드는 이름(변수)을 메모리에서 삭제한다.

try:
    import matplotlib.pyplot as plt # 그래프 그리는 라이브러리 불러오기
    plt.scatter(X, y) # 밑에 자세히 설명
    plt.xlabel("x") #x축에 이름을 "x"라고 단다.
    plt.ylabel("y") #y축에 이름을 "y"라고 단다.
    plt.show() #지금까지 만든 그림을 화면에 표시. 
except:
    pass
  • try: ... except: ...
    • try안의 코드를 시도한다. 실행 중 오류가 나면 except: 로 떨어지고, 거기에 pass 키워드가 있으니 그냥 넘어간다.
    • 그래프가 안보이더라도 에러없이 진행하기 위한 코드
  • plt.scatter(X, y) 는 무슨 뜻인가 :
    • plt.scatter(X, y)는 같은 길이의 두 배열 X와 y를 받아서 각 인덱스 i에 대해 하나의 좌표쌍 (X[i], y[i]) 를 만들어 점 하나를 찍는다.
    • 즉, 데이터가 m개라면 점도 m개가 그려진다. 그렇게 산점도(scatter plot, 점들이 흩어진 그림)를 그린다.

이때 x를 입력으로 받아 예측값 \(\ f(x; \theta) = \hat{y} \approx y \) 를 출력하는 모델을 만들고 학습해봅시다.

여기서 모델은 \(\theta\) 를 파라미터로 가지는 다음과 같은 이차함수입니다.

\(\ f(x;\theta) = ax^2 + bx + c \)

\(\theta = \begin{pmatrix} a \\ b \\ c \end{pmatrix}\)

이 모델의 파라미터 theta를 데이터에 맞추어 잘 조절하면 예측값 \(\hat{y}\) 과 ground-truth y의 차이를 줄일 수 있을 것입니다.

Loss 함수는 mean squared error를 사용합니다. y(i)를 #B개 모아 텐서로 만든 것을 y라고 하고, 이에 대응하는 예측값을 y-hat이라고 합니다.

$$ MSE(\hat{y}, y) = \frac{\sum_{i=1}^B \left( \hat{y}^{(i)} - y^{(i)} \right)^2}{B} $$

  • Mean Squared Error (MSE) : Loss 함수의 한 종류로, 뜯어서 해석하면 "평균 제곱 오차" 라는 뜻. 그러니까 오차, 즉 (예측값-실제값) 제곱의 평균이라는 뜻
    • 예측값과 실제값을 받아서, 차를 제곱하고 그걸다 더하고 배치안의 데이터수로 나눠서 평균을 구해주는게 MSE입니다. 그게 저 공식의 내용이에요.
    • MSE는 예측값과 실제값 간 차의 제곱을 사용하기 때문에 오차가 - 든 +든 양수로 만들어주고, 오차가 커질수록 더 오차를 극대화할 수 있습니다.

이 말들이 다 이해가 가면 넘어가고, 안넘어가면 펼쳐봅시다.

공식에 대한 자세한 해설

  • \(\ \theta\) (theta,세타) : 수학, 통계, 머신러닝에서 전통적으로 알 수 없는 값(unknown parameter)을 표기하는데 사용하는 기호

  • 일단, 예측값 \(\ f(x; \theta) = \hat{y} \approx y \)를 출력하는 모델을 만들고 학습하자는데, 이게 무슨말일까?
    • \(\ f(x; \theta) \) 는, 여러분이 아는 x를 입력값으로 가지는 함수가 맞다. 저렇게 생긴건 단지, 입력값 외에 함수의 출력함수의 형태를 결정하는 \(\theta\) 라는 매개변수. 파라미터가 존재한다. 를 나타내는 것이고 ',' 말고 ';'로 구분해준 이유는, 여러분이 세타가 다른 입력값이구나 하고 헷갈릴까봐 좀 구별되라고 그렇게 적는거다.

  • 그리고, \(\theta = \begin{pmatrix} a \\ b \\ c \end{pmatrix}\) 는 단지 \(\ \theta\) 에 a,b,c가 포함된다. 라는 뜻이다.

  • \( \hat{y} \) : 이건 y-hat 이라고 읽는다. 추정치, 예측치 라는 뜻이다. y가 모자를 쓰고있는 것 같죠 딱봐도?

  • Ground-truth란 : 실제 정답 데이터 라는 의미
  • Loss 함수란 : 모델이 얼마나 틀렸는지 수치로 계산하는 함수

  • \(y^{(i)}\)를 #B개 모아 : 이게 무슨뜻일까?
    • 위 첨자 (i)는 데이터의 i번째 샘플을 뜻한다.
    • 학습은 보통 한 번에 데이터 하나만 쓰지 않고, Batch(배치)라는 묶음을 쓰는데, 그걸 몇갠진 모르겠지만, B개. 이렇게 표현한 것입니다.

  • 텐서가 무엇일까?
    • 스칼라 : 그냥 숫자 하나 (예: 5)
    • 벡터 : 숫자들을 한 줄로 모은 것 (예: [3, 5, 2])
    • 행렬 : 벡터를 여러 줄 모은 것
    • 텐서 : 행렬을 더 모아 3차원 이상으로 확장한 것 (숫자의 “상자”)

다음 시간에는 MSE의 gradient 공식, SGD를 구현하는 수도코드를 살펴보고, 나아가 구현까지 해보도록 하겠습니다. 뿅!