[모두의 딥러닝] 5. 경사 하강법(gradient decent)

기울기와 오차의 관계

- y = ax + b에서 기울기 a와 오차는 이차 함수 관계

- 기울기를 너무 크게 잡거나 너무 작게 잡으면 오차 커짐

- 적절한 기울기(m)를 찾았을 때 오차 최소화

오차가 가장 작을 때 : 기울기 == m

 

 

 

경사 하강법(gradient decent)

- 오차의 변화에 따라 이차 함수 그래프를 만들고 적절한 학습률을 설정해 미분 값이 0인 지점을 구하는 것

 

 

  •  계산법

1. 어느 한 점(a1)에서 미분을 구한다

2. 구한 기울기의 반대 방향(기울기가 +면 음의 방향, -면 양의 방향)으로 얼마간 이동시킨 점(a2)에서 미분을 구한다

3. 앞에서 구한 미분 값이 0이 아니면 1, 2번 반복

 

  • 학습률(learning rate)

: 매회 얼마의 강도로 업데이트 되어야 하는지 제어하는 척도

: 기울기를 바꿔 이동할 때 적절한 학습률을 찾지 못하면 a값이 한 점으로 모이지 않고 발산한다

적절한 학습률을 찾지 못하면 수렴하지 않는다

 

 

 

평균 제곱 오차, 경사 하강법 적용한 단순 선형 회귀 - 파이썬 코드로 구현

- 독립 변수 : 공부한 시간 / 종속 변수 : 성적

- 최소 제곱법으로 계산한 결과, a = 2.3, b = 79

공부한 시간 2 4 6 8
성적 81 93 91 97

 

 

1. 환경 및 데이터 준비

# 넘파이, 맷플롯립 라이브러리 불러오기
import numpy as np
import matplotlib.pyplot as plt

# 공부 시간 X와 성적 Y의 넘파이 배열을 만듦
x = np.array([2, 4, 6, 8])
y = np.array([81, 93, 91, 97])

※ 코랩 대신 주피터 노트북을 사용하는 경우, matplotlib 라이브러리 사용 전에 !pip install matplotlib 필요

 

2. 변수 설정

# 기울기 a와 절편 b의 값 초기화
a = 0
b = 0

# 학습률 설정
lr = 0.03

# 몇 번 반복될지 설정 
epochs = 1701

 

3. 경사 하강법

  • 평균 제곱 오차의 식을 각각 a와 b로 편미분

# x 값이 총 몇 개인지 셈
n=len(x)

#경사 하강법 시작
for i in range(epochs):  # epoch 수 만큼 반복
    
    y_pred = a * x + b  # 예측 값을 구하는 식 
    error = y - y_pred  # 실제 값과 비교한 오차를 error로 놓기
    
    # 오차 함수를 각각 a, b로 편미분
    a_diff = (2/n) * sum(-x * (error))
    b_diff = (2/n) * sum(-(error)) 
    
    # 학습률을 곱해 기존 값을 업데이트
    a = a - lr * a_diff 
    b = b - lr * b_diff
    
    if i % 100 == 0:  # 100번 반복될 때마다 현재의 a 값, b 값을 출력
        print("epoch=%.f, 기울기=%.04f, 절편=%.04f" % (i, a, b))

 

4. 그래프 확인

# 앞서 구한 최종 a값을 기울기, b값을 y절편에 대입하여 그래프 생성
y_pred = a * x + b      

# 그래프 출력
plt.scatter(x, y)
plt.plot(x, y_pred,'r')
plt.show()

 

5. 결론

- 반복하면서 최소 제곱법에서 구한 a = 2.3, b = 79에 수렴

- 최소 제곱법을 사용하지 않고도 평균 제곱 오차와 경사 하강법을 사용하여 원하는 결과값을 구할 수 있다

 

 

 

'모두의 딥러닝 개정 3판'의 내용과 https://github.com/taehojo/deeplearning의 코드 참고