Pytorch

[파이토치] iris 데이터를 위한 신경망 만들어보기

왕초보코딩러 2024. 12. 24. 17:27
728x90

iris 데이터 로드

sklearn의 데이터셋을 사용합니다.

# 피처 4개
from sklearn.datasets import load_iris

load_iris()

 

 

'data'와 'target'을 사용

X = load_iris().data
y = load_iris().target

 


학습과 검증을 위해 train, test 데이터셋으로 분리

sklearn의 train_test_split()을 이용합니다.

from sklearn.model_selection import train_test_split

train_X, test_X = train_test_split(X, test_size=0.2, random_state=123)
train_y, test_y = train_test_split(y, test_size=0.2, random_state=123)

 

잘 나눠졌는 지 확인

len(train_X), len(test_X), len(train_y), len(test_y)

 

타입 확인

type(train_y)

train_test_split()은 넘파이를 반환합니다

 

넘파이 텐서로 바꾸기

torch.tensor() / torch.from_numpy()를 사용합니다.

torch_train_X = torch.tensor(train_X)
torch_train_y = torch.tensor(train_y)
torch_test_X = torch.tensor(test_X)
torch_test_y = torch.tensor(test_y)

 


numpy to tensor

1. torch.tensor()

2. torch.from_numpy()

 

+ tensor to numpy

.numpy()


PyTorch에서는 기본적으로 torch.tensor()를 사용하면 생성된 텐서의 데이터 타입이 torch.float64가 된다.

반면, PyTorch 모델의 파라미터는 torch.float32로 초기화된다.

-> 이로 인해 입력 데이터와 모델 파라미터 간에 데이터 타입이 맞지 않아 오류가 발생할 수 있습니다.

데이터 타입 변환

type()을 사용합니다

train_X = torch_train_X.type(torch.float32)
train_y = torch_train_y.type(torch.long)
test_X = torch_test_X.type(torch.float32)
test_y = torch_test_y.type(torch.long)

 


모델 만들기

import torch
import torch.nn as nn

 

분류 모델을 만들 때 클래스(카테고리)의 수 확인

train_y.unique()

 

모델의 마지막 아웃풋 크기는 3이 되겠군요

iris 데이터는 컬럼이 4개이기 때문에

저는 4 -> 128 -> 64 -> 3 이 되는 인공신경망을 만들겠습니다.

 

nn.Module을 사용하여 클래스를 만들겠습니다.

class Net(nn.Module):
  def __init__(self):
    super(Net, self).__init__()
    self.fc1 = nn.Linear(4, 128)
    self.fc2 = nn.Linear(128, 64)
    self.fc3 = nn.Linear(64, 3)
    self.afunc = nn.ReLU()

  def forward(self, x):
    x = self.fc1(x)
    x = self.afunc(x)
    x = self.fc2(x)
    x = self.afunc(x)
    x = self.fc3(x)
    return x

 

모델 정의

model = Net()
model

 

모델이 잘 작동하는 지 확인

(배치 사이즈, 인풋 크기) 를 모델에 넣을 때

(배치 사이즈, 아웃풋 크기) 로 나오면 됩니다.

# (4개의 컬럼을 가진 10개의 데이터)
data = torch.rand(10, 4)
model(data).shape

 


모델 학습

import torch.optim as optim

 

최적화 함수, 학습률, 손실 함수, 에폭 정의

# 최적화함수, 학습률
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 손실함수
criterion = nn.CrossEntropyLoss()

# 에폭
epochs = 100

 

모델 학습

# 시각화를 위한 loss값 저장 리스트
loss_list = []

for epoch in range(epochs):
  # 학습할 때마다 기울기 초기화
  optimizer.zero_grad()

  # 순전파
  y_pred = model(train_X)

  # 손실함수 계산
  loss = criterion(y_pred, train_y)

  # loss 표시
  print(f'epoch: {epoch+1} loss: {loss}')
  loss_list.append(loss.item())

  # 역전파
  loss.backward()

  # 파라미터 업데이트
  optimizer.step()

 

loss 시각화

import matplotlib.pyplot as plt

plt.plot(range(epochs), loss_list)
plt.show()

 


모델 검증

# 모델을 평가 모드로 전환
model.eval()

correct = 0 # 맞은 개수
total = len(test_y) # 전체 test 개수

with torch.no_grad(): # 역전파 방지 기울기 계산 비활성화
  y_pred = model(test_X) # 테스트 데이터로 예측
  result = y_pred.max(dim=1)[1] # 3가지 카테고리 중 값이 가장 큰 인덱스

  correct = sum(result == test_y).item() # 단일 텐서에서 값만 뽑기 (여러 값이 들어있는 텐서는 tolist()나 numpy()로 바꿔야 됨)

accuracy = correct / total * 100
print(f'accuracy: {accuracy}')

 


y_pred.max(dim=1)[1]에 대해서 자세히 설명해보겠습니다.

y_pred = model(test_X) # (30, 3) 텐서 반환

 

우리는 3가지 카테고리 중 가장 높은 값 하나를 반환해야 합니다.

-> max()를 사용하여 확인

 

dim = 0은 각 열에서 max를 찾고

dim = 1은 각 행에서 max를 찾습니다

 

y_pred.max(dim=1)을 하면 최대값들과 그 최대값이 있는 인덱스를 반환합니다.

 

우리는 인덱스가 필요하기 때문에 [1]을 가져옵니다.

 


모델 저장하기

-> 가중치만 저장하기

torch.save(model.state_dict(), 'pth 파일 이름을 포함한 경로')

 

 


가중치만 저장한 모델 불러오기

모델 구조 정의

# 모델 구조 정의
class Net(nn.Module):
  def __init__(self):
    super(Net, self).__init__()
    self.fc1 = nn.Linear(4, 128)
    self.fc2 = nn.Linear(128, 64)
    self.fc3 = nn.Linear(64, 3)
    self.afunc = nn.ReLU()

  def forward(self, x):
    x = self.fc1(x)
    x = self.afunc(x)
    x = self.fc2(x)
    x = self.afunc(x)
    x = self.fc3(x)
    return x

load_model = Net()

 

모델 가져오기

# 모델 불러오기
load_model.load_state_dict(torch.load('iris.pth'))

'Pytorch' 카테고리의 다른 글

[파이토치] 모델 학습하기  (0) 2024.12.23
[파이토치] 모델 만들기  (1) 2024.12.15
[파이토치] 기본2  (0) 2024.08.01
[Pytorch] 모델 저장하기, 불러오기  (0) 2024.07.23
[Pytorch] 텐서(Tensor) 자료형  (0) 2024.07.16