본문 바로가기

About/Pytorch

[Pytorch] Linear Regression - 파이토치를 이용한 선형회귀분석

선형 회귀 분석이란?

통계학에서, 선형 회귀(線型回歸, 영어: linear regression)는 종속 변수 y와 한 개 이상의 독립 변수 (또는 설명 변수) X와의 선형 상관 관계를 모델링하는 회귀분석 기법이다. 한 개의 설명 변수에 기반한 경우에는 단순 선형 회귀, 둘 이상의 설명 변수에 기반한 경우에는 다중 선형 회귀라고 한다 - 위키백과

 

선형 회귀 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 독립변수 1개와 종속변수 1개를 가진 선형 회귀의 예 통계학에서, 선형 회귀(線型回歸, 영어: linear regression)는 종속 변수 y와 한 개 이상의 독립 변수 (또는 설명

ko.wikipedia.org

간단하게 말해서 주어진 X(데이터)을 가장 잘 표현할 수 있는 하나의 직선을 찾는 것이다.

  • x변수가 1개(ex. y = ax+b) 인 경우 단순 선형 회귀 분석
  • x변수가 여러개 (ex. y= ax1+bx2+c) 인 경우 다중 선형 회귀 분석이라 한다.

선형 회귀 분석 그래프 예시

이를  Pytorch로 구현하여 보겠다.

 

Pytorch Linear Regression

Data Definition - 데이터 정의

이해를 돕기위해 일한시간에 비례한 월급이라는 예시로 설명하겠다.

징어나라에서 일한시간에 대한 월급의 표는 다음과 같다.

일한시간 월급
1 1500원
2 2500원
3 3500원
4 4500원
5 5500원

일한시간을 X 월급을 Y라고 생각하자. 

 

이를 Torch에서 정의하면 다음과 같다.

우선 torch를 import 하자

import torch

그 후 x, y 데이터를 정의한다.

x_list = torch.FloatTensor([1, 2, 3, 4, 5])
y_list = torch.FloatTensor([1500, 2500, 3500,4500, 5500])

 

Hypothesis - 가설 함수 정의

입력 데이터 : 1개, 출력 데이터 : 1개 이므로 우리가 찾는 식의 형태는 다음과 같다.

y = Wx + b

 

위의 식에서 W 및 b 값을 찾는 것이 목표이다.

x, y 데이터는 정해졌으니 W(Weight) 및 b(Bias) 값을 정의하자.

처음에는 값을 0으로 초기화 한다.

 

W = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)

torch의 zeros 함수를 이용하여 W,b 값을 0으로 초기화 하였다.

  • zeros()의 첫번째 인자는 데이터의 차원(여기서는 1차원)이다.
  • requires_grad = True 는 학습할 데이터라는 것을 명시하는 것이다.(True로 설정하지않으면 학습이 되질 않는다.)

Compute loss - loss(cost) 함수 정의

이 실습에서는 Mean Squared Error (MSE)를 loss함수로 설정하겠다.

Mean Squared Error

MSE를 torch에서 정의하면 다음과 같다.

# H(x) = W * x + b
hx = x_list * W + b
cost = torch.mean((hx - y_list) ** 2)

Optimizer 정의

이 실습에서는 경사하강법을 사용하여 학습하겠다.

torch에서는 torch.optim 라이브러리를 사용한다.

optimizer = torch.optim.SGD([W,b], lr=0.015) #optimizer를 SGD로 정의, learning rate = 0.015

Optimizer를 SGD로 정의하고, 학습률을 0.015로 정의한다.

SGD는 Stochastic Gradient Descent의 줄임말로 확률적 경사 하강법이라는 말이다.

lr = 0.015로 학습률을 0.015로 정의한다.

 

그 후 학습시 다음의 코드로 학습하게된다.

optimizer.zero_grad() #gradient 초기화
cost.backward() #gradient 계산
optimizer.step() #step()으로 개선

optimzer의 zero_grad() 함수로 gradient를 모두 초기화하고,

cost.backward()로 gradient를 계산한다.

그 후 optimizer.step()을 이용하여 학습시킨다.

전체 코드

위의 내용을 조합하여 전체 코드를 작성하면 다음과 같다.

import torch
import matplotlib.pyplot as plt

#데이터 정의
x_list = torch.FloatTensor([1, 2, 3, 4, 5]) 
y_list = torch.FloatTensor([1500, 2500, 3500,45000000, 5500])

#W, b값 초기화
W = torch.zeros(1, requires_grad=True);
b = torch.zeros(1, requires_grad=True)

#optimizer 정의
optimizer = torch.optim.SGD([W,b], lr=0.015)

record_cost = [] #cost값 저장을 위한 list

#반복횟수
np_epoch = 1000
for epoch in range(1,np_epoch+1):
    # H(x) = W * x + b
    h = x_list * W + b

	#cost 계산 후 출력 및 list 추가
    cost = torch.mean((h - y_list) ** 2) 
    record_cost.append(cost.item())
    print("Epoch : {:4d}, y = {:.4f}x+{:.4f} Cost {:.6f}".format(epoch, W.item(),b.item(), cost.item()))
	
    #학습
    optimizer.zero_grad()
    cost.backward()
    optimizer.step()

#cost 그래프 출력
plt.plot(record_cost, 'b')
plt.show()


 위의 코드에서 cost값을 epoch마다 list에 저장한 후 matplotlib를 이용하여 그래프를 출력하였다.

 

실행 결과

epoch에 따른 실행 결과는 다음과 같다.

  • epoch = 10

 

  • epoch = 100

  • epoch = 1000

위의 데이터에서 W,b의 정답 값은  W = 1000, b = 500이다.

Epoch = 1000으로 설정했을 때 W = 1000.3571, b = 498.7106으로 학습되었다. 정답과 거의 일치한 것을 확인할 수 있다.

데이터 표본을 더 늘리고, Epoch을 더 크게 설정한다면 정답에 더 가까운 W,b값을 찾을 수 있을 것이다

 

Epoch에 따라 변화하는 Y = Wx+b의 그래프를 시각화하면 다음과 같다.

Epoch을 증가시킬 수록 Cost값이 줄어들며 적절한 W, b값을 찾아가는 것을 확인할 수 있다.

 

 


Pytorch를 이용하여 선형회귀분석을 실습해보았다.