데이터 로드
TensorDataset과 DataLoader
- 입력 데이터를 쉽게 처리하고, 배치단위로 잘라서 학습할 수 있게 도와주는 모듈
- Dataset: 학습 시 사용하는 feature와 target의 pair 로 이루어짐
- 보통 Dataset 클래스를 상속받아 커스텀 인스턴스를 생성하는 형태로 많이 사용
- DataLoader: 학습 시 각 인스턴스에 쉽게 접근할 수 있도록 순회 가능한 객체를 생성
파이토치에서는 데이터를 x, y 로 분리한 후 Dataset class 로 관리함
- train dataset, validation dataset, test dataset
- train dataloader, validation dataloader, test dataloader
- suffling, batch size, number of processes 등을 정의할 수 있음
import 부분
from torch.utils.data import TensorDataset, DataLoader
sklean의 train_test_split 등을 이용해 데이터를 분할한 후 다음과같이 데이터를 tensor 로 변환
# X,y로 분할한 데이터를 tensor로 변환
X_train = torch.tensor(X_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.int64)
y_test = torch.tensor(y_test, dtype=torch.int64)
tensor를 TensorDataset으로 생성 - X와 y가 짝으로 이루어짐
train_dataset = TensorDataset(X_train, y_train)
test_dataset = TensorDataset(X_test, y_test)
DataLoader 형태로 생성
train_dataloader = DataLoader(train_dataset, batch_size=10, shuffle=True)
test_dataloader = DataLoader(test_dataset, batch_size=10, shuffle=True)
Device 설정
- 일반적으로 학습은 GPU 를 사용하는것이 좋음
- GPU를 사용하도록 명시해야하며, 사용불가할 시 cpu로 사용하도록 해야함
# 가능한 한 cuda(gpu) 불가능하면 cpu 를 사용하도록 함
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# 모델을 gpu 로 이동(불가했다면 cpu)
model = NeuralNetwork().to(device)
신경망 생성
- torch.nn 패키지를 사용해야함.
- torch.nn 패키지는 신경망 생성 및 학습 시 설정해야하는 다양한 기능을 제공함.
import 하는 방법
import torch.nn as nn
- 신경망을 nn.Module 을 상속받아 정의해야함.
class NeuralNet(nn.Module):
def __init__(self):
super(NeuralNet, self).__init__()
self.input_layer = nn.Linear(6, 32)
self.hidden_layer = nn.Linear(32, 32)
self.output_layer = nn.Linear(32,5)
self.relu = nn.ReLU()
def forward(self, x):
out = self.relu(self.input_layer(x))
out = self.relu(self.hidden_layer(out))
out = serf.output_layer(out)
return out
위 예제 코드는 6 짜리 인풋을 받아 5짜리 아웃풋을 내는 신경망의 예제이다.
Model complie
- 학습 시 필요한 정보들(loss function, optimizer) 을 선언
- 일반적으로 loss와 optiomizer는 아래와 같이 변수로 선언하고, 변수를 train/test 시 참고할 수 있도록 매개변수로 지정해줌.
learning_rate = 0.01
loss = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr= learning_rate)
Train
- 신경망의 학습과정을 별도의 함수로 구성하는 것이 일반적
- feed forward -> loss -> errorbackpropagation -> (log) > 반복
def train_loop(train_loader, model, loss_fn, optimizer):
for batch, (X,y) in enumerate(train_loader):
X, y = X.to(device), y.to(device)
pred = model(X)
loss = loss_fn(pred, y)
# 기울기 초기화 (0으로 만들어두고 그다음 더하는 방식으로 계산)
optimizer.zero_grad()
# 기울기 계산
loss.backward()
# 매개변수 업데이트
optiizer.step()
학습과정은 데이터로더의 배치로 데이터를 로드해서 device (gpu 일수도 cpu일수도)로 옮기고 모델의 예측을 pred 로 해서
pred, y 간의 loss를 구해 기울기를 계산하여 역전파한다.
Test
- 학습 과정은 비슷한데 error back propagate 하는 부분만 없다고 보면된다.
def test_loop(test_loader, model, loss_fn, optimizer):
size = len(test_loader.dataset)
num_batches = len(test_loader)
test_loss, correct = 0, 0
# 이걸해주면서기울기 계산을 안하게됨
with torch.no_grad():
for batch, (X,y) in enumerate(test_loader):
X, y = X.to(device), y.to(device)
pred = model(X)
test_loss += loss_fn(pred, y).item()
correct += (pred.argmax(1) == y).type(torch.float).sum().item()
test_loss /= numbatches
correct /= size
print(f"Test Error\n Accuracy: {(100*correct):>0.1f}% Avg loss: {test_loss:8f}\n")
pred.argmax(1):
pred는 모델의 예측 결과입니다. 일반적으로 분류 모델의 경우, pred는 각 클래스에 대한 확률값 또는 로짓(logit) 값을 포함하는 텐서입니다.
argmax(1)은 각 샘플에 대해 가장 높은 값을 가지는 클래스 인덱스를 반환합니다. 여기서 1은 차원을 나타내며, 각 샘플에 대해 클래스 차원에서 최대값의 인덱스를 찾는 것을 의미합니다.
예를 들어, pred가 [0.1, 0.3, 0.6]이라는 확률을 출력한다면 argmax(1)은 2를 반환합니다. (가장 큰 값인 0.6의 인덱스)
(pred.argmax(1) == y):
y는 실제 레이블입니다.
pred.argmax(1) == y는 예측한 클래스 인덱스가 실제 레이블과 같은지를 비교하여 불리언 값(True 또는 False)을 반환합니다.
예를 들어, 예측이 [2, 0, 1]이고 실제 레이블이 [2, 1, 1]이라면, 결과는 [True, False, True]가 됩니다.
.type(torch.float):
type(torch.float)은 불리언 값을 부동 소수점 값으로 변환합니다. True는 1.0으로, False는 0.0으로 변환됩니다.
위의 예제에서는 [True, False, True]가 [1.0, 0.0, 1.0]으로 변환됩니다.
.sum().item():
.sum()은 텐서의 모든 요소를 더합니다. 즉, 맞은 예측의 총 개수를 계산합니다.
.item()은 파이썬 숫자로 변환합니다.
예를 들어, [1.0, 0.0, 1.0]의 합은 2.0이며, .item()을 호출하면 2.0이 됩니다.
Iteration
- 신경망 학습은 여러 epoch 를 반복해서 수앻하면서 최적의 파라미터를 찾음
- 지정한 epochs 수만큼 학습과 평가를 반복하면서 모델 성능을 체크함.
epochs = 10
for i in range(epochs):
print(f"Epoch {i+1} \n")
train_loop(train_dataloader, model, loss, optimizer)
test_loop(test_dataloader, model, loss, optimizer)
print("학습 종료")
이렇게 파이토치를 이용해서 데이터로드부터 학습까지의 간단한 구조를 살펴보았습니다.
다음 포스팅에서는 간단한 신경망으로 학습을 진행해보겠습니다.
'코딩 - > 인공지능' 카테고리의 다른 글
RNN의 모델구조만 보고 RNN을 직접 만들어보자. (0) | 2024.08.21 |
---|---|
Seaborn 사용법 Seaborn 그래프 종류별로 알아보기 파이썬 데이터 시각화 (1) | 2024.08.04 |
인공지능 용어 및 요약정리 (0) | 2021.12.13 |