참고자료: https://wikidocs.net/book/2788
파이토치에서 이미 구현되어 제공되고 있는 함수들을 불러오는 것으로 더 쉽게 선형 회귀 모델을 구현해보자!
👉🏻파이토치에서는 다음 함수들이 구현되어져 있다.
- nn.Linear(): 선형 회귀 모델
- nn.functional.mse_loss(): 평균 제곱오차
1. 단순 선형 회귀 구현하기
파이토치 함수를 이용해 \(y = 2x\), 즉 w=2, b=0임을 제대로 찾아내보자!
import torch
import torch.nn as nn
import torch.nn.functional as F
torch.manual_seed(1)
# 데이터
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[2], [4], [6]])
👉🏻필요한 도구를 import하고 데이터를 선언한다.
# 모델을 선언 및 초기화. 단순 선형 회귀이므로 input_dim=1, output_dim=1.
model = nn.Linear(1,1)
👉🏻선형 회귀 모델을 구현한다.
👉🏻nn.Linear(): 입력의 차원, 출력의 차원을 인수로 받는다. 위의 식은 하나의 입력 x에 대해서 하나의 출력 y를 가지므로 모두 1을 인수로 사용했다.
print(list(model.parameters()))
#[Parameter containing:
#tensor([[0.5153]], requires_grad=True), Parameter containing:
#tensor([-0.4414], requires_grad=True)]
👉🏻model.parameters(): model에 저장되어 있는 가중치 W와 편향 b를 불러온다. 첫 번째 값이 W이고, 두 번째 값이 b이다. 두 값 모두 학습의 대상이므로 requires_grad = True이다.
# optimizer 설정. 경사 하강법 SGD를 사용하고 learning rate를 의미하는 lr은 0.01
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
👉🏻model.parameters를 사용해 W와 b를 전달해 optimizer를 정의한다. 학습률은 0.01로 정한다.
# 전체 훈련 데이터에 대해 경사 하강법을 2,000회 반복
nb_epochs = 2000
for epoch in range(nb_epochs+1):
# H(x) 계산
prediction = model(x_train)
# cost 계산
cost = F.mse_loss(prediction, y_train) # <== 파이토치에서 제공하는 평균 제곱 오차 함수
# cost로 H(x) 개선하는 부분
# gradient를 0으로 초기화
optimizer.zero_grad()
# 비용 함수를 미분하여 gradient 계산
cost.backward() # backward 연산
# W와 b를 업데이트
optimizer.step()
if epoch % 100 == 0:
# 100번마다 로그 출력
print('Epoch {:4d}/{} Cost: {:.6f}'.format(
epoch, nb_epochs, cost.item()
))
#Epoch 0/2000 Cost: 13.103540
#... 중략 ...
#Epoch 2000/2000 Cost: 0.000000
👉🏻경사 하강법을 2000번 실행하며 cost가 13에서 0으로 작아졌다.
# 임의의 입력 4를 선언
new_var = torch.FloatTensor([[4.0]])
# 입력한 값 4에 대해서 예측값 y를 리턴받아서 pred_y에 저장
pred_y = model(new_var) # forward 연산
# y = 2x 이므로 입력이 4라면 y가 8에 가까운 값이 나와야 제대로 학습이 된 것
print("훈련 후 입력이 4일 때의 예측값 :", pred_y)
#훈련 후 입력이 4일 때의 예측값 : tensor([[7.9989]], grad_fn=<AddmmBackward>)
👉🏻확인을 위해 x에 임의의 값 4를 넣어 y를 예측해보았다. 8에 가까운 7.9989가 나왔기 때문에 W와 b의 값이 어느정도 최적화가 된 것으로 볼 수 있다.
print(list(model.parameters()))
#[Parameter containing:
#tensor([[1.9994]], requires_grad=True), Parameter containing:
#tensor([0.0014], requires_grad=True)]
👉🏻W의 값이 2에 가깝고 b가 0에 가까운 것을 확인할 수 있다.
2. 다중 선형 회귀 구현하기
이제 nn.Linear()와 nn.functional.mse_loss()로 다중 선형 회귀를 구현해보자!
가설 수식은 \(H(x)=w_{1}x_{1}+w_{2}x_{2}+w_{3}x_{3}+b\)과 같다.
import torch
import torch.nn as nn
import torch.nn.functional as F
torch.manual_seed(1)
# 데이터
x_train = torch.FloatTensor([[73, 80, 75],
[93, 88, 93],
[89, 91, 90],
[96, 98, 100],
[73, 66, 70]])
y_train = torch.FloatTensor([[152], [185], [180], [196], [142]])
👉🏻필요한 도구를 import하고 데이터를 선언한다.
# 모델을 선언 및 초기화. 다중 선형 회귀이므로 input_dim=3, output_dim=1.
model = nn.Linear(3,1)
👉🏻선형 회귀 모델을 구현한다. 3개의 입력 x에 대해 하나의 출력 y를 가지므로, 입력 차원은 3, 출력 차원은 1로 인수를 사용한다.
print(list(model.parameters()))
#[Parameter containing:
#tensor([[ 0.2975, -0.2548, -0.1119]], requires_grad=True), Parameter containing:
#tensor([0.2710], requires_grad=True)]
👉🏻3개의 w와 b를 확인할 수 있다. 두 값 모두 현재 랜덤 초기화가 되어져 있고, 학습의 대상이므로 requires_grad=True가 되어져 있다.
optimizer = torch.optim.SGD(model.parameters(), lr=1e-5)
nb_epochs = 2000
for epoch in range(nb_epochs+1):
# H(x) 계산
prediction = model(x_train)
# model(x_train)은 model.forward(x_train)와 동일함.
# cost 계산
cost = F.mse_loss(prediction, y_train) # <== 파이토치에서 제공하는 평균 제곱 오차 함수
# cost로 H(x) 개선하는 부분
# gradient를 0으로 초기화
optimizer.zero_grad()
# 비용 함수를 미분하여 gradient 계산
cost.backward()
# W와 b를 업데이트
optimizer.step()
if epoch % 100 == 0:
# 100번마다 로그 출력
print('Epoch {:4d}/{} Cost: {:.6f}'.format(
epoch, nb_epochs, cost.item()
))
👉🏻옵티마이저를 정의하고 경사 하강법을 2000번 반복한다.
# 임의의 입력 [73, 80, 75]를 선언
new_var = torch.FloatTensor([[73, 80, 75]])
# 입력한 값 [73, 80, 75]에 대해서 예측값 y를 리턴받아서 pred_y에 저장
pred_y = model(new_var)
print("훈련 후 입력이 73, 80, 75일 때의 예측값 :", pred_y)
#훈련 후 입력이 73, 80, 75일 때의 예측값 : tensor([[151.2305]], grad_fn=<AddmmBackward>)
👉🏻y값이 152였는데 예측값이 151로 근사하게 나왔다.
print(list(model.parameters()))
#[Parameter containing:
#tensor([[0.9778, 0.4539, 0.5768]], requires_grad=True), Parameter containing:
#tensor([0.2802], requires_grad=True)]
👉🏻3개의 w와 b의 값도 최적화된 것을 볼 수 있다.
'그 땐 AI했지 > 그 땐 DeepLearning했지' 카테고리의 다른 글
[TAVE/PyTorch] ch03 선형 회귀 | 07 커스텀 데이터셋 (0) | 2022.04.28 |
---|---|
[TAVE/PyTorch] ch03 선형 회귀 | 06 미니 배치와 데이터 로드 (0) | 2022.04.28 |
[TAVE/Study] ch03 선형 회귀 | 03 다중 선형 회귀 (0) | 2022.04.07 |
[TAVE/study] ch03 선형 회귀 | 02 자동 미분 (0) | 2022.04.07 |
[TAVE/study] ch03 선형 회귀 | 01 선형 회귀 (0) | 2022.04.07 |