인공지능,딥러닝,머신러닝 기초

[Do it!딥러닝 입문] 경사 하강법( Gradient descent )

풍요 평화 만땅 연구원 2022. 7. 14. 15:03

참고 :

https://www.youtube.com/watch?v=7RQhfuN5qw4&list=PLJN246lAkhQgbBx2Kag0wIZedn-P9KcH9&index=6&ab_channel=%EB%B0%95%ED%95%B4%EC%84%A0 

 

- 경사하강법으로 산점도 잘 표현한 직선 구하기

2번째 직선이 산점도를 잘 나타냄

 

- 타깃(원래 알고있는 값) 나타낼수있는 a,b 규칙을 찾아서 방정식 만듦 -> 만든 방정식으로 예측값 찾을 수 있음


훈련 데이터에 잘 맞는 w와 b를 찾는 방법

1. 무작위로 w와 b를 정합니다(무작위로 모델 만들기)

2. x에서 샘플 하나를 선택하여 ŷ 을 계산합니다(무작위로 모델 예측)

3. ŷ 과 선택한 샘플의 진짜 y를 비교함(예측한 값과 진짜 정답 비교하기, 틀릴 확률 99%)

4. ŷ이 y와 더 가까워지도록 w,b를 조정함(모델 조정하기)

5. 모든 샘플을 처리할 때까지  다시 2~4항목을 반복

 

 

 

- 변화율 더하면 예측값 증가

 

->>  절편(b)변화율은 항상 "1"

 


1. 오차 역전파로 업데이트

 

- 그러나 오차가 넘 클때? -> 오차 역전파로 가중치와 절편을 업데이트 함


2. 두번째 샘플을 사용하여 w와 b 계산

 

3. 전체 샘플을 사용하여 w와 b 계산

4. 더 정확하게 하기위해 반복

5. 모델로 예측하기


<전체 코드>


##선형회귀
#############################################
from sklearn.datasets import load_diabetes
diabetes = load_diabetes()
#data[0:3] -> 슬라이싱
#print(diabetes.data[0:3])
#target 뽑기
#print(diabetes.target[:3])

import matplotlib.pyplot as plt
#[:,2] -> 모든행, 세번째 특성
plt.scatter(diabetes.data[:,2], diabetes.target)
plt.xlabel('x')
plt.ylabel('y')
#print(plt.show())

#x,y 설정(이후 코드를 간단하게 쓰기 위해)
x = diabetes.data[:,2]
y = diabetes.target


##경사하강법
#############################################
w=1.0
b=1.0
#y_hat : 예측값
y_hat = x[0]*w + b
print(y_hat) #-> 1.0616962065186832
#y : 실제값
print(y[0]) #-> 151.0

#w값을 조절해 예측값을 바꾸어 봄
#w>0.1만큼 증가시키면 y_hat이 조금 증가 : 올바른 결정~
w_inc = w+0.1
y_hat_inc = x[0]*w_inc + b
print(y_hat_inc) #-> 1.0678658271705517

#그럼 얼마만큼 증가했나?
w_rate = (y_hat_inc - y_hat) / (w_inc - w)
print(w_rate)

### 절편 변화율
b_inc = b+0.1
y_hat_inc = x[0]*w + b_inc
b_rate = (y_hat_inc - y_hat) / (b_inc)
print(b_rate)

#오차역전파로 가중치와 절편을 업데이트
err = y[0] - y_hat
w_new = w + w_rate*err
b_new = b+1*err
print(w_new, b_new)

##두번째 샘플을 사용하여 w와b를 계산
y_hat = x[1]*w_new + b_new
err = y[1] - y_hat
#update
w_rate = x[2]
w_new = w_new + w_rate*err
b_new = b_new + 1*err
print(w_new, b_new)

#전체 샘플을 반복하여 가중치와 절편을 조정하기
for x_i,y_i in zip(x, y):
    y_hat = x_i*w +b
    err = y_i - y_hat
    w_rate = x_i
    w = w + w_rate*err
    b = b+1*err
print(w,b)

# 더 정확하게하려면 여러번 수행
for i in range(1,100):
    for x_i,y_i in zip(x, y):
        y_hat = x_i*w +b
        err = y_i - y_hat
        w_rate = x_i
        w = w + w_rate*err
        b = b+1*err
print(w,b)

plt.scatter(x,y)
pt1 = (-0.1,-0.1*w+b)
pt2 = (0.15, 0.15*w+b)
plt.plot([pt1[0],pt2[0],pt1[1],pt2[1]])
plt.xlabel('x')
plt.ylabel('y')
plt.show()