상세 컨텐츠

본문 제목

[ML] 파이썬으로 경사하강법 구현하기

Programming/Machine Learning

by PrJun 2022. 1. 2. 02:46

본문

키와 발사이즈의 상관관계를 보고 텐서플로우 없이 경사하강법을 한번 구현을 해봅시다.

 

먼저 키입니다

[100, 120, 130, 140, 150, 160, 170, 180, 190]

 

그리고 이건 발사이즈.

[200, 205, 210, 220, 230, 250, 270, 280, 285]

 

100cm면 200. 120cm면  205 이런식으로 가는거죠.

극단적인 데이터라고 볼 수 있겠습니다 실제로 사용하기에는 많이 아쉬운 데이터죠.

learning_rate = 0.01 # 학습률

학습률을 설정해주었습니다

m = len(x_data) # x축 데이터 수

나중에 1/m을 곱해줘야할일도 생기니 x축에 들어갈 데이터의 수를 저장해줍니다.

w = 0 # 가중치
b = 0 # y절편

epochs = 3000 # 학습 횟수

그 다음 가중치와 y절편의 초기값은 0으로 대충 던져주고, 학습은 3000번 돌려줄겁니다.

x = np.array([100,300]) # 직선 범위

키 데이터, 즉 x축의 데이터가 100에서 시작해서 190즈음에 끝나니 100~300까지만 그래프를 그려봅시다.

 

여기서 손실함수의 식을 세워봅시다.

필기 사진은 '나동빈' 님의 -머신러닝의 기초 선형회귀 한번에 이해하기- 라는 영상의 일부를 가져온 사진입니다.

m은 x데이터의 갯수, Wxi + b는 가설식, 즉 예측 값이라고 할 수 있으며 yi는 거기서 실제의 값을 빼주어

실제 값과 예측 값의 차이가 얼마나 나는지를 알 수 있게 됩니다.

그리고 제곱을 하면 이차항이 되므로 W의 기울기를 알기위해 편미분을 해주고,

b의 기울기를 알기위해 편미분을 해줍니다.

안에 있는 2는 묶어서 앞으로 보내고, 어차피 상수니까 무시하고 지워줘도 되겠네요.

이제 이것을 코드로 옮겨봅시다. 

for i in range(epochs): # 학습 횟수만큼 반복
    tmp0 = 0
    tmp1 = 0
    for k in range(m): # 시그마 계산
        tmp0 += learning_rate * x_data[k] * (w * x_data[k] + b - y_data[k])
        tmp1 += learning_rate * (w * x_data[k] + b - y_data[k])
    b -= (2*tmp1)/m
    w -= (2*tmp0)/m
    
    if i%int(epochs/10)==0:
        y = w*x + b
        plt.plot(x,y, 'y', label = str(i))
        print("loading : %d%%"%int(i*100/epochs))
y = w*x + b # 최종 가설 식

plt.plot(x_data, y_data, 'r.')

plt.plot(x,y)
print('x: ' + str(x))
print('y: ' + str(y))
plt.show()

최종적으로 가설식을 세워주고, 그래프를 그려줍니다.

그런데? 결과가 좀 이상했습니다. 왜그런지 다른분께 자문을 구해보니..

학습률에서 문제가 있다고 했습니다.

학습률이 너무 작게되면 학습하는데에 시간이 너무 오래걸리고, 학습률이 너무 크다면 접선의 기울기가 0이 되는부분,

즉 손실의 최소지점을 지나쳐버린다는 것입니다.

그래서 저의 경우는 학습률이 너무 커서 최소지점을 지나쳐 버렸기에 저런 결과가 생겼습니다.

학습률을 0.01에서 0.00001로 바꿔주고 다시 학습을 진행해봅니다.

좋습니다! 잘나왔군요

댓글 영역