1. 단항 선형 회귀 실습
- 한개의 입력이 들어가서 한 개의 출력이 나오는 구조
# 필요모듈 임포트
import torch
import torch.nn as nn # 뉴럴 네트워크
import torch.optim as optim
import matplotlib.pyplot as plt
# 토치에 상수를 저장할 수 있는데, 랜덤값의 고정을 시키기 위해 2024라는 seed를 설정함.
torch.manual_seed(2024)
# 결과값 => <torch._C.Generator at 0x7c27cae915b0>
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)
# 결과값 =>
# 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)
# 직선의 방정식
# y = ax + b -> y = Wx + b
model = nn.Linear(1, 1)
# 앞 1은 입력값, 뒤 1은 출력값을 지정함.
# 만약(1, 1, bias=False)으로 설정하면 b는 사용하지 않는다고 선언.
print(model)
# 결과값 => Linear(in_features=1, out_features=1, bias=True)
y_pred = model(x_train)
print(y_pred)
# 이렇게 이상한 값이 나오는 이유 : 학습을 안해서 값이 들쑥 날쑥 한값이 랜덤으로 나온다.
# tensor([[0.7260],
# [0.7894],
# [0.8528]], grad_fn=<AddmmBackward0>)
print(list(model.parameters())) # W: 0.0634, b : 0.6625
# y = 0.0634x + 0.6625
0.0634 + 0.6625
# 결과값 =>
# [Parameter containing:
# tensor([[0.0634]], requires_grad=True), Parameter containing:
# tensor([0.6625], requires_grad=True)]
# 0.7259
# MSE
((y_pred - y_train) ** 2).mean()
# 결과값 => tensor(12.8082, grad_fn=<MeanBackward0>)
# -------------------------------------
loss = nn.MSELoss()(y_pred, y_train)
loss
# 결과값 => tensor(12.8082, grad_fn=<MseLossBackward0>)
# -------------------------------------
# 데이터 : 1, 2, 3
# W : 0.0634, b : 0.6625
# y = Wx + b
print(0.0634 * 1 + 0.6625)
print(0.0634 * 2 + 0.6625)
print(0.0634 * 3 + 0.6625)
# 결과값 =>
# 0.7259
# 0.7893
# 0.8527
2. 경사 하강법(Gradient Descent)
- 비용함수의 값을 최소로 하는 W와 b를 찾는 알고리즘 옵티마이저(최적화) 알고리즘이라고 함
- 옵티마이저 알고리즘 중 가장 기본적인 기술이 경사하강법임
- 옵티마이저 알고리즘을 통해 W와 b를 찾아내는 과정, "학습"이라고 부름.
# SGD : (Stochastic Gradient Desdoent)
# 랜덤하게 데이터를 하나씩 뽑아서 loss으로 만듦(랜덤이라 stachastic
# 데이터를 뽑고 다시 데이터를 넣고, 반복
# 빠르게 방향을 결정
# 학습률(Learning rate)
# 한번 움직이는 거리(increment step)
optimizer = optim.SGD(model.parameters(), lr=0.01)
loss = nn.MSELoss()(y_pred, y_train)
# gradient를 초기화
# 오차값이 최하가 되는 기울기를 찾을때 값이 누적이 되는것을 방지하기 위해 초기화를 하는 코드를 작성함.
optimizer.zero_grad()
# loss.backward = 역전파 : 비용 함수를 미분하여 gradient(기울기) 계산.
loss.backward()
# W와 b를 업데이트
optimizer.step()
# 기존 => W : 0.0634, b : 0.6625
print(list(model.parameters())) # W: 0.2177, b : 0.7267
# 결과값 =>
# [Parameter containing:
# tensor([[0.2177]], requires_grad=True), Parameter containing:
# tensor([0.7267], requires_grad=True)]
# 반복 학습을 통해 틀린 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}/{epochs} Loss: {loss:.6f}')
# 결과값 =>
# Epoch : 0/1000 Loss: 10.171454
# Epoch : 100/1000 Loss: 0.142044
# Epoch : 200/1000 Loss: 0.087774
# Epoch : 300/1000 Loss: 0.054239
# Epoch : 400/1000 Loss: 0.033517
# Epoch : 500/1000 Loss: 0.020711
# Epoch : 600/1000 Loss: 0.012798
# Epoch : 700/1000 Loss: 0.007909
# Epoch : 800/1000 Loss: 0.004887
# Epoch : 900/1000 Loss: 0.003020
# Epoch : 1000/1000 Loss: 0.001866
print(list(model.parameters())) # W : 1.9499, b : 0.1138
# 결과값 =>
# [Parameter containing:
# tensor([[1.9499]], requires_grad=True), Parameter containing:
# tensor([0.1138], requires_grad=True)]
# -------------------------------------
x_test = torch.FloatTensor([[8]])
y_pred = model(x_test)
print(y_pred)
# 결과값 => tensor([[15.7134]], grad_fn=<AddmmBackward0>)
3. 다중 선형 회귀
- 여러 개의 입력이 들어가서 한 개의 출력이 나오는 구조
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(y_train, y_train.shape)
# 결과값 =>
# tensor([[ 73., 80., 75.],
# [ 93., 88., 93.],
# [ 89., 91., 90.],
# [ 96., 98., 100.],
# [ 73., 66., 70.]]) torch.Size([5, 3])
# tensor([[150.],
# [190.],
# [180.],
# [200.],
# [130.]]) torch.Size([5, 1])
# y = a1x + a2x + a3x + b
model = nn.Linear(3, 1)
print(model)
# 결과값 => Linear(in_features=3, out_features=1, bias=True)
# ----------------------------------
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}/{epochs} Loss: {loss:.6f}')
print(list(model.parameters())) # W : -0.1461, 0.4496, 1.6962, b : -0.4009
# 결과값 =>
# [Parameter containing:
# tensor([[0.3478, 0.6414, 1.0172]], requires_grad=True), Parameter containing:
# tensor([-0.2856], requires_grad=True)]
# ------------------------
x_test = torch.FloatTensor([[92, 90, 89]])
y_pred = model(x_test)
print(y_pred)
# 결과값 => tensor([[179.9619]], grad_fn=<AddmmBackward0>)
'Study > 머신러닝과 딥러닝' 카테고리의 다른 글
[머신러닝과 딥러닝] 15. 파이토치로 구현한 논리회귀_1 (0) | 2024.01.10 |
---|---|
[머신러닝과 딥러닝] 14. 파이토치로 구현한 선형회귀_2(지면온도 예측) (0) | 2024.01.09 |
[머신러닝과 딥러닝] 13. 파이토치(Pytorch) (1) | 2024.01.09 |
[머신러닝과 딥러닝] 12.KMeans (1) | 2024.01.08 |
[머신러닝과 딥러닝] 11. 다양한 모델 적용 (0) | 2024.01.08 |