데이터분석, 머신러닝
Do it 시리즈 딥러닝 공부-1
kanb
2022. 12. 19. 19:13
#딥러닝 doit
#회귀 문제를 푸는 알고리즘은 아주 많습니다. 딥러닝은 훨씬 많은 양의 데이터를 다룹니다.
#경사하강법은 이렇게 많은 양의 데이터에 사용하기 좋은 알고리즘입니다.
#회귀문제를 푸는 알고리즘은 정규방정식, 결정트리, 서포트벡터머신 등 아주 많습니다.
import matplotlib.pyplot as plt
from sklearn.datasets import load_diabetes
diabetes=load_diabetes()
x=diabetes.data[:,2]
y=diabetes.target
w=1
b=1
y_hat=x[0]*w+b
print(y_hat)
print(y[0])
w_inc=w+0.1
y_hat_inc=x[0]*w_inc+b
print(y_hat_inc)
w_rate=(y_hat_inc-y_hat)/(w_inc-w)#x[0]에 대한 w의 변화율, 신기하게도 w_rate를 수식으로 적어 정리하면 변화율=x[0]임을 알 수 있습니다.
print(w_rate)#변화율이 양수이므로 w값을 증가시키면 y_hat 의 값을 증가시킬 수 있다. 만약 변화율이 음수일때 y_hat 의 값을 증가시켜야 한다면 감소시키면 된다.
#가중치와 절편을 더욱 적절하게 업데이트하는 방법
#오차와 변화율을 곱하여 가중치 업데이트하기
for x_i, y_i in zip(x,y): #zip()함수는 여러개의 배열에서 동시에 요소를 하나씩 꺼내줍니다.
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)
#오차와 변화율을 곱하는이유: 변화율이 +면 증가하고,-이면 감소하는 방향으로 맞출 수가 있다. 그 폭의 척도를 오차만큼으로 결정한 것이다.
print('-'*50)
#여러에포크를 반복하기
#보통 경사하강법에서는 주어진 훈련데이터로 학습을 여러번 반족합니다. 이렇게 전체 훈련 데이터를 모두 이용하여 한 단위의 작업을 진행하는 것을 특별히 에포크라고 부릅니다.
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)
#Q. 아까 위에서는 똑같은 코드로 계산할 때의 결과가 (587.8654539985616 99.4093556453094)이 나옴을 알 수 있다.
#그러나 왜 100번 에포크를 반복할 때 나오는 결과값은 (913.5973364346786 123.39414383177173)이 나올까?
#위에서 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()
#3-3 손실함수(=비용함수=목적함수)와 경사하강법의 관계를 알아봅니다.
#경사하강법을 좀 더 기술적으로 표현하면 '어떤 손실 함수'가 정의되었을 때 손실 함수의 값이 최소가 되는 지점을 찾아가는 방법'입니다.
#앞에서 '오차를 변화율에 곱하여 가중치와 절편 업데이트하기'는 '제곱 오차'라는 손실 함수를 미분한 것과 같습니다.
#제곱오차SE=(y-y_hat)^2 , 제곱 오차가 최소가 되면 산점도 그래프를 가장 잘 표현한 직선이 그려진다.
#책갈피#
#3-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_gad=1*err #절편에 대한 그레이디언트를 계산합니다.
return w_grad,b_grad
#훈련을 위한 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 #절편 업데이트