minhui study

03. 선형 회귀와 경사 하강법, 선형 회귀 뉴런 구현 본문

딥러닝,인공지능/Do it! 딥러닝입문

03. 선형 회귀와 경사 하강법, 선형 회귀 뉴런 구현

minhui 2021. 4. 4. 12:00

손실 함수와 경사 하강법의 관계

손실함수

예상한 값과 실제 타깃값의 차이를 함수로 정의한 것으로 보통 '제곱 오차'를 손실 함수로 사용한다.

제곱 오차(squared error)는 다음과 같다.

경사 하강법'어떤 손실 함수가 정의되었을 때 손실 함수의 값이 최소가 되는 지점을 찾아가는 방법'이다.

위의 식을 풀어써보면 다음과 같다.

위의 식을 보면 w^2의 계수와 b^2의 계수가 항상 양수이므로 다음과 같이 아래로 볼록한 형태의 2차 함수가 그려진다.

https://bnzn2426.tistory.com/111

경사 하강법은 위의 그래프에서 최소값인 접선의 기울기가 0이 되는 지점, 즉 미분값이 0인 점을 찾는 방법이다.
방법은 임의의 w 또는 b인 점에서 시작해 그 점에서의 접선의 기울기인 편미분 값을 빼나가는 것이다.

https://bnzn2426.tistory.com/111

w에 대해 편미분한 식은 다음과 같고 보통은 제곱 오차 공식을 2로 나눈 함수를 편미분한다. 

가중치에 대한 제곱 오차의 변화율을 구했고, 앞에서 가중치 업데이트에 변화율을 더했던 것과 비슷한 방법으로 가중치를 업데이트한다. 이때 w에서 변화율을 더하지 않고 빼는 이유는 손실 함수의 낮은 쪽으로 이동하고 싶기 때문이다.

결론적으로 앞에 오차 역전파를 알아보며 적용했던 수식 w + w_rate * err 과 제곱 오차를 미분했던 것과 같다는 것을 알 수 있다. 졀편 역시 식을 전개해 보면 b = b + (y-y_hat)으로 동일해진다. 

이런 식으로 w와 b를 업데이트 해나가면 각각의 변화율이 작아지면서 손실 함수의 최솟값에 근접하게 된다.

그리고 여기서 변화율을 경사(gradient)라 부르며 경사가 점점 완만해지며 아래로 내려가는 거에 의해 경사 하강법이라고 한다.

 


선형 회귀를 위한 뉴런 클래스

1. __init()__ 메서드

__init()__ 메서드에 필요한 변수를 선언한다.

 def __init__(self):
    self.w=1.0  # 가중치를 초기화한다.
    self.b=1.0  # 절편을 초기화한다.

 

2. 정방향 계산 만들기

→ 정방향 계산 : 뉴런으로 도식화한 상태에서 y_hat을 구하는 방향을 보고 만든 용어이다.

즉, 3개의 입력 신호(w,b,x)를 가지고 예측값을 계산하는 것  y_hat = w * x + b

  def forpass(self,x):
    y_hat=x*self.w+self.b  # 직선 방정식을 계산한다.
    return y_hat

 

3. 역방향 계산 만들기

gradient를 이용해 w와 b를 업데이트 하는 것으로 오차가 역방향으로 전파되기 때문에 역방향 계산 즉,오차 역전파라고 한다.

  def backprop(self,x,err):
    w_grad=x*err  # 가중치에 대한 그레이디언트를 계산한다.
    b_grad=1*err  # 절편에 대한 그레이디언트를 계산한다.
    return w_grad, b_grad

https://tensorflow.blog

4. Neuron 클래스

class Neuron:

  def __init__(self):
    self.w=1.0  # 가중치를 초기화한다.
    self.b=1.0  # 절편을 초기화한다.

  def forpass(self,x):
    y_hat=x*self.w+self.b  # 직선 방정식을 계산한다.
    return y_hat

  def backprop(self,x,err):
    w_grad=x*err  # 가중치에 대한 그레이디언트를 계산한다.
    b_grad=1*err  # 절편에 대한 그레이디언트를 계산한다.
    return w_grad, b_grad

이 과정을 조합하여 훈련 데이터를 통해 가중치와 절편을 업데이트할 수 있도록 fit()메서드를 구현해보자. 

바로 이 과정이 훈련이다.

 

 

5. 훈련을 위한 fit() 메서드 구현

  def fit(self,x,y,epochs=100):
    for i in range(epochs): # 에포크만큼 반복한다.
      for x_i, y_i in zip(x,y):  # 모든 샘플에 대해 반복한다.
        y_hat = self.forpass(x_i)  # 정방향 계산
        err=-(y_i - y_hat)  # 오차 계산
        w_grad, b_grad = self.backprop(x_i, err)  # 역방향 계산
        self.w -= w_grad  # 가중치 업데이트
        self.b -= b_grad  # 절편 업데이트

- forpass() 메서드를 호출하여 y_hat를 구한 다음 오차를 계산한다.

- backprop() 메서드를 호출하여 가중치와 절편에 대한 gradient를 구한다.

- 마지막으로 gradient를 가중치와 절편에서 빼면 가중치와 절편의 업데이트가 끝난다.

이 과정을 모든 훈련 샘플에 대해 수행하고(1 epoch) 적절한 가중치와 절편이 구해질 만큼(100 epoch) 반복하면 된다.

 

 

6. 모델 훈련

Neuron클래스의 객체 neuron을 생성하고 fit() 메서드에 입력 데이터(x)와 타깃 데이터(y)를 전달하면 된다.

neuron = Neuron()
neuron.fit(x,y)

 

 

7. 학습이 완료된 모델의 가중치와 절편 확인하기

< 참고 자료 >

Do it! 딥러닝 입문 - 박해선 지음

Comments