본문 바로가기
머신러닝 & 딥러닝

14. 파이토치로 구현한 선형회귀

by 곽정우 2024. 6. 13.

1. 단항 선형 회귀

  • 한 개의 입력이 들어가서 한 개의 출력이 나오는 구조
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
# 파이썬 코드를 재실행해도 같은 결과가 나올 수 있도록 랜점시드를 설정
torch.manual_seed(2024)

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

plt.figure(figsize=(6, 4))
plt.scatter(x_train, y_train)

# y = wx + b

model = nn.Linear(1, 1)
print(model)

y_pred = model(x_train)
print(y_pred)

print(list(model.parameters()))

list(model.parameters()) # 0.0634 b: 0.6625
# y = 0.0634x + 0.6625
# x=1, 0.0634 + 0.6625 = 0.7259
# x=2, (0.0634*2) + 0.6625 = 0.7893

((y_pred - y_train) ** 2).mean()

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

 

2. 경사하강법(Gradient Descent)

  • 비용함수의 값을 최소로 하는 W와 b를 찾는 알고리즘을 옵티마이저(최적화) 알고리즘이라고 함
  • 옵티마이저 알고리즘 중 가장 기본적인 기술이 경사하강법
  • 옵티마이저 알고리즘을 통해 W와 b를 찾아낸 과정을 "학습"이라고 부름
  • 학습률(Learning rate): 한 번 움직이는 거리(increment step)

# SGD(Stochastic Gradient Descent)
# 랜덤하게 데이터를 하나씩 뽑아서 loss을 만듦(랜덤이라 Stochastic)
# 데이터를 뽑고 다시 데이터를 넣고 반복
# 빠르게 방향을 결정

optimizer = optim.SGD(model.parameters(), lr=0.01)
loss = nn.MSELoss()(y_pred, y_train)
# gradient를 초기화
optimizer.zero_grad()

# 역전파: 비용 함수를 미분하여 gradient(기울기) 계산
loss.backward()

# W와 b를 업데이트
optimizer.step()

print(list(model.parameters())) # W: 0.2177 b: 0.7267

# 반복 학습을 통해 오차가 있는 W, b를 수정하면서 오차를 계속 줄여나감
# epochs : 반복 학습 횟수(에포크)

epochs = 1000

for epoch in range(epochs + 1):
    y_pred = model(x_train)
    loss = nn.MSELoss()(y_pred, y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f'Epoch {epoch}/{epoch} Loss: {loss:.6f}')
    # Loss값이 점점 작아짐 >>> 오차가 작아짐

# 학습된 모델의 파라미터

print(list(model.parameters()))

x_test = torch.FloatTensor([5])
y_pred = model(x_test)
print(y_pred)

2. 다중 선형 회귀

  • 여러 개의 입력이 들어가서 한 개의 출력이 나오는 구조
X_train = torch.FloatTensor([[73, 80, 75],
                             [93, 88, 93],
                             [89, 91, 90],
                             [96, 98, 100],
                             [73, 66, 70]])
y_train = torch.FloatTensor([[150], [190], [180], [200], [130]])

print(X_train, X_train.shape)
print('---------------------------')
print(y_train, y_train.shape)

# 가설: y = W1x1 + W2x2 + W3x3 + ... + b
model = nn.Linear(3, 1)
print(model)

optimizer = optim.SGD(model.parameters(), lr=0.00001)
epochs = 10000
for epoch in range(epochs + 1):
    y_pred = model(X_train)
    loss = nn.MSELoss()(y_pred, y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    if epoch % 100 == 0:
        print(f'Epoch {epoch}/{epoch} Loss: {loss: .6f} ')

print(list(model.parameters())) # W: [[0.3478, 0.6414, 1.0172] b: [-0.2856]

x_test = torch.FloatTensor([[93, 93, 93]])
y_pred = model(x_test)
print(y_pred)

X_train = torch.FloatTensor([[73, 80, 75],
                             [93, 88, 93],
                             [89, 91, 90],
                             [96, 98, 100],
                             [73, 66, 70]])
y_train = torch.FloatTensor([[150], [190], [180], [200], [130]])

 

3. temps.csv 데이터에서 기온에 따른 지면 온도를 예측해보기

import pandas as pd
import numpy as np
temp_df = pd.read_csv('/content/drive/MyDrive/KDT/6.머신러닝과 딥러닝/Data/temps.csv', encoding='cp949')
temp_df

df.isnull().mean()

df = df.dropna()
df.isnull().mean()

x_data = df[['기온(°C)']]
y_data = df[['지면온도(°C)']]
x_data = torch.FloatTensor(x_data.values)
y_data = torch.FloatTensor(y_data.values)

print(x_data.shape)
print(y_data.shape)

plt.figure(figsize=(12, 8))
plt.scatter(x_data, y_data)

model = nn.Linear(1, 1)
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
print(list(model.parameters())) # w: -0.5700, b: 0.2403

epochs = 10000

for epoch in range(epochs + 1):
    y_pred = model(x_data)
    loss = nn.MSELoss()(y_pred, y_data)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if epoch % 100 == 0:
        print(f'Epoch {epoch}/{epoch} Loss: {loss:.6f}')

list(model.parameters()) # w: 1.0854, b: 0.8198

y_pred = model(x_data).detach().numpy() # 저장 후 numpy 배열로 변환
y_pred

plt.figure(figsize=(8, 6))
plt.scatter(x_data, y_data)
plt.scatter(x_data, y_pred)

result = model(torch.FloatTensor([[26]]))
print(result)

'머신러닝 & 딥러닝' 카테고리의 다른 글

16. 데이터 로더  (0) 2024.06.13
15. 파이토치로 구현한 논리회귀  (0) 2024.06.13
13. 파이토치(Pytorch)  (0) 2024.06.13
12. KMeans  (0) 2024.06.13
11. 다양한 모델 적용  (0) 2024.06.13