[PyTorch] 파이토치로 선형회귀 구현하기,nn.Module
Import
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
torch: 텐서를 생성하는 라이브러리
torch.autograd: 자동미분 기능을 제공하는 라이브러리
torch.nn: 신경망을 생성하는 라이브러리
torch.multiprocessing: 병럴처리 기능을 제공하는 라이브러리
torch.utils: 데이터 조작 등 유틸리티 기능 제공
torch.legacy(./nn/.optim): Torch로부터 포팅해온 코드
torch.onnx: ONNX(Open Neural Network Exchange) 서로 다른 프레임워크 간의 모델을 공유할 때 사용
Train 만들기
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[2], [4], [6]])
3x1 모양의 tensor를 만들어 x,y train 생성
가중치와 편향 초기화
간단히 설명을 하자면,,
직선의 방정식 y = Wx+b 에서 w와 b를 조정하여 최적의 y값(정답)에 가깝도록 해주는 것이
머신러닝의 목적이다.
더 자세한 설명은
↓↓↓↓↓↓↓↓↓↓↓
W = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
W와 b를 0으로 설정해준다.
따라서 y = 0x + 0 이된다.
hypothesis = x_train * W + b
print(hypothesis)
W와 b를 조정하기 위해서 가설을 세워준다.
H(x) = Wx+b라고 식을 세울 수 있는데 이때 x_train데이터이다.
loss함수 선언
>>> cost = torch.mean((hypothesis - y_train) ** 2)
>>> print(cost)
tensor(18.6667, grad_fn=<MeanBackward1>)
loss함수는 MSE(평균 제곱 오차)를 사용해보자.
정답데이터에서 y_train을 빼고 제곱한 평균이다.
경사하강법(SGD)
optimizer = optim.SGD([W, b], lr=0.01)
optimizer.zero_grad()
cost.backward()
optimizer.step()
optim.SGD함수에 W,b를 넣어주고 학습률은 0.01로 설정해준다.
zero_grad()함수는 기울기를 0으로 초기화 시켜준다. 파이토치는 이전 기울기를 값에 누적시키기 때문이다.
cost.backward()함수를 호출하면 기울기 계산이 된다.
optimizer.step()함수는 W와 b에서 리턴되는 변수를 0.01(학습률)을 빼주어 업데이트가 된다.
최종 학습 코드
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[2], [4], [6]])
W = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
optimizer = optim.SGD([W, b], lr=0.01)
nb_epochs = 1999
for epoch in range(nb_epochs + 1):
hypothesis = x_train * W + b
cost = torch.mean((hypothesis - y_train) ** 2)
optimizer.zero_grad()
cost.backward()
optimizer.step()
if epoch % 100 == 0:
print('Epoch {:4d}/{} W: {:.3f}, b: {:.3f} Cost: {:.6f}'.format(
epoch, nb_epochs, W.item(), b.item(), cost.item()
))
1. x_train, y_train 지정.
2. W,b 0으로 초기화.
3. Optimizer를 SGD로 설정.
4. epochs는 원하는 학습 횟수
5. epochs의 수만큼 for문 돌리기
5-1. 가설식 H(x) 세우기
5-2. loss함수 만들기
5-3. loss함수로 H(x) 업데이트 시켜주기
5-4. 로그 출력하는 if문 써주기
nn.Module로 구현하기
모듈이 있다면 더 쉽게 구현이 가능하다.
이번에는 다중 선형 회귀 모델을 구현해보자.
import torch
import torch.nn as nn
import torch.nn.functional as F
필요한 모듈을 import시켜준다.
torch.manual_seed(1)
다음에 모델을 돌릴 때에도 같은 값이 나오게 하기 위해서 random_seed 설정을 해준다.
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]])
데이터셋을 간단하게 만들어 준 후
model = nn.Linear(3,1)
nn.Linear모델 안에 (3,1) 인자를 넣어준다.
3개의 입력 x에 대해서 1개의 출력 y를 가진다는 뜻이다.
optimizer = torch.optim.SGD(model.parameters(), lr=1e-5)
optimizer도 SGD로 설정해주면 된다.
위 모든 코드를 다 합치면 다음과 같이 된다.
nb_epochs = 2000
for epoch in range(nb_epochs+1):
prediction = model(x_train)
cost = F.mse_loss(prediction, y_train)
optimizer.zero_grad()
cost.backward()
optimizer.step()
if epoch % 100 == 0:
print('Epoch {:4d}/{} Cost: {:.6f}'.format(
epoch, nb_epochs, cost.item()
))
epochs만큼 도는 for문을 만든다.
nn.Module로 만든 model변수안에 x_train을 넣어주어 가설식을 세운다.
F.mse_loss는 파이토치에서 제공하는 MSE 함수이다.
zero_grad()로 gradient를 0 초기화 해준다.
backward()로 그라디언트 계산한다.
step()으로 미분간을 업데이트한다.
if문으로 출력 로그를 만든다.
class로 모델 구현하기
파이토치는 대부분 모델 생성을 할 때 class를 사용하고 있다고 한다.
같은 모델인데도 파이토치 코드가 괜히 어렵게 보인다고 느끼는 이유가 있었나보다.
model = nn.Linear(1,1)
input = 1, output = 1인 Linear모델을 선언했다.
이를 클래스로 구현한다면 아래와 같다.
class LinearRegressionModel(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(1, 1)
def forward(self, x):
return self.linear(x)
model = LinearRegressionModel()
LinearRegressionModel은 nn.Module을 상속받는다.
__init__()에서는 모델의 구조와 동작을 정의하는 생성자를 정의한다.
super()함수를 부르면 nn.Module 클래스의 속성들을 가지고 초기화 된다.
LinearRegressionModel()을 model변수에 넣고
model()에 넣으면 자동으로 forward 함수의 연산이 진행된다.
위 class의 형식은 파이토치 모델 사용에서 대부분 사용하고 있으므로 외우는 것이 좋겠다.,
그럼 본격적으로 학습을 시켜보자.
x_train = torch.FloatTensor([[1], [2], [3]])
y_train = torch.FloatTensor([[2], [4], [6]])
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
train데이터를 만들고 optimizer도 SGD로 설정해주었다.
nb_epochs = 2000
for epoch in range(nb_epochs+1):
prediction = model(x_train)
cost = F.mse_loss(prediction, y_train)
optimizer.zero_grad()
cost.backward()
optimizer.step()
if epoch % 100 == 0:
print('Epoch {:4d}/{} Cost: {:.6f}'.format(
epoch, nb_epochs, cost.item()
))
나머지 코드는 위의 for문과 동일하다.
prediction으로 가설식을 만들 때 model()안에 x_train을 넣으면 된다.
'Artificial Intelligence > Deep Learning' 카테고리의 다른 글
[PyTorch] PyTorch란? 파이토치의 구성요소, 파이토치로 텐서 조작하기 (2) | 2022.11.19 |
---|---|
Hands-On Machine Learning(핸즈온 머신러닝) - 10장 연습문제 (5) | 2022.07.19 |
[딥러닝] LSTM(Long Short Term Memory) (8) | 2022.02.25 |
[딥러닝] RNN (Recurrent Neural Network) - 순환신경망 구조 (12) | 2022.02.24 |
[딥러닝] Embeding Layer / 차원의 저주 (curse of dimensionality) /자연어 처리 / 단어 백터화 (13) | 2022.02.23 |
댓글