머신러닝&딥러닝/이론

[머신러닝&딥러닝] 파이토치 선형회귀-단항 선형 회귀

거북이07 2024. 1. 10. 10:10

파이토치 선형회귀

import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt

 

필요한 라이브러리, 모델들을 import 해준다.

torch.manual_seed(2024) # 처음에는 랜덤값이 뽑히지만 다시 랜덤으로 뽑을 경우 같은 값으로 뽑기 위한 작업

 

 

x_train = torch.FloatTensor([[1],[2],[3]])
y_train = torch.FloatTensor([[2],[4],[6]])
print(x_train, x_train.shape)
print(y_train, y_train.shape)

x_train과 y_train 변수를 만든 후 FloatTensor() 함수를 이용하여 실수타입의 텐서를 만들어준다.

이렇게 만들어진 텐서 변수의 shape를 찍어보면 아래와 같이 출력된다.

tensor([[1.],
        [2.],
        [3.]]) torch.Size([3, 1])
tensor([[2.],
        [4.],
        [6.]]) torch.Size([3, 1])
plt.figure(figsize=(6, 4))
plt.scatter(x_train, y_train)

plt.scatter() 함수를 이용하여 x_train, y_train 변수를 시각화해준다.

# y = ax + b -> y = Wx + b
model = nn.Linear(1, 1) # 입력값, 출력값 그 뒤에 아무런 옵션이 없다면 바이어스를 사용한다는 뜻, bias=False를 쓰면 기울기만으로 조정한다는 뜻(근데 잘 안씀)
print(model)

nn.Linear() 함수를 이용하여 선형모델을 만들어준다. 만든 모델을 출력하면 아래 처럼 나온다.

Linear(in_features=1, out_features=1, bias=True)

 

y_pred = model(x_train)
print(y_pred) # 학습을 안해서 값이 이상하게 나옴

y_pred 변수를 만들고 x_train을 넣으면 예측값이 나오는데 해당 예측값은 학습을 하지 않아 값이 다르게 나온다.

tensor([[0.7260],
        [0.7894],
        [0.8528]], grad_fn=<AddmmBackward0>)

파라미터 확인

print(list(model.parameters())) # w:0.9437, b:-0.7614
[Parameter containing:
tensor([[1.9499]], requires_grad=True), Parameter containing:
tensor([0.1138], requires_grad=True)]

model.parameters() 함수를 이용하연 기울기와 바이어스(절편)를 확인할 수 있다.

w : 1.9499

b :  0.1138 


MES() 구하기

loss = nn.MSELoss()(y_pred, y_train)
print(loss)

파이토치에서 MESLoss() 함수를 이용하여 MES를 구할 수 있다.

tensor(12.8082, grad_fn=<MseLossBackward0>)

경사하강법(Gradient Descent)

비용함수의 값을 최소로 하는 w와 b를 찾는 알고리즘을 옵티마이저(최적화) 알고리즘이라고한다. 옵티마이저 알고리즘 중에 가장 기본이되는 기술이 경사하강법이다. 옵티마이저 알고리즘을 통해 w와 b를 찾아낸 과정을 "학습"이라고 부른다.

 

 SGD(Stochastic Gradient Descent)

  •  랜덤하게 데이터를 하나씩 뽑아서 loss를 만든다.
  • 데이터를 뽑고 다시 데이터를 넣고를 반복한다.
  • 빠르게 방향을 결정한다.
optimizer = optim.SGD(model.parameters(), lr=0.01) # lr = 학습률

 

학습률(Learning rate)

- 한 번 움직이는 거리(increment step)

loss=nn.MSELoss()(y_pred, y_train)
print(loss)
tensor(12.8082, grad_fn=<MseLossBackward0>)

 

loss는 0에 가까울수록 좋다.


반복학습

반복 학습을 통해 틀린w, b를 수정하면서 오차를 계속 줄여나가는 작업을 진행해준다.

epochs = 1000 # epochs: 반복 학습 횟수(에포크)

for epoch in range(epochs + 1):
    y_pred = model(x_train)
    loss = nn.MSELoss()(y_pred, y_train)
    # gradient를 초기화
	# 초기화해주지않으면 오차값이 누적되어 저장됨 그래서 제대로된 값을 찾을 수 없음.
    optimizer.zero_grad()
    # 역전파: 비용 함수를 미분하여 gradient(기울기) 계산
    loss.backward()
    # W와 b를 업데이트
    optimizer.step()

    if epoch % 100 == 0:
        print(f'Epoch: {epoch}/{epochs} Loss: {loss:.6f}')
print(list(model.parameters())) # W: 1.9499, b:0.0342

학습 후 다시 파라미터를 출력해주면 기울기와 절편이 달라진걸 확인할 수 있다.

[Parameter containing:
tensor([[1.9499]], requires_grad=True), Parameter containing:
tensor([0.1138], requires_grad=True)]

 

위에 학습시킨 모델에 test데이터를 넣고 예측값을 확인해보면 아래와 같은 결과가 나온다.

x_test = torch.FloatTensor([[8]])
y_pred = model(x_test)
print(y_pred)
tensor([[15.7134]], grad_fn=<AddmmBackward0>)