Python(Colab) 파이토치(Pytorch) + 데이터 로더

2023. 6. 20. 22:55파이썬/머신러닝 및 딥러닝

데✔️ 데이터로더

데이터 양이 많을 때, 배치 단위로 학습하는 방법을 의미한다.

 

 

데이터 로더를 적용하여 손글씨 인식하기

 

1. 데이터 셋 셋팅 및 기초 셋팅 

 

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transforms
import matplotlib.pyplot as plt

from sklearn.datasets  import load_digits
 
# GPU
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(device)

 

2. 학습데이터 뽑아오기

 

digits = load_digits()

x_data = digits.data
y_data = digits.target

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

 

3. 학습데이터 시각화해서 보기

 

fig,axes = plt.subplots(2,5, figsize=(14,8))

for i,ax in enumerate(axes.flatten()):
    ax.imshow(x_data[i].reshape(8,8),cmap='plasma') #ax는 이미지가 들어가있다.
    ax.set_title(y_data[i])
    ax.axis('off')
 

 

4. 데이터셋 텐서로 변환 

 

x_data = torch.FloatTensor(x_data)
y_data = torch.LongTensor(y_data)

print(x_data.shape)
print(y_data.shape)
 
y_one_hot = nn.functional.one_hot(y_data,num_classes=10).float()  #num_classes = 종류 개수 정하기

y_one_hot[:13]
 

 

5. 학습,검증데이터 분리하기

from sklearn.model_selection import train_test_split
 
x_train, x_test, y_train, y_test = train_test_split(x_data,y_one_hot,test_size=0.2, random_state=10)

print(x_train.shape)
print(y_train.shape)

print(x_test.shape)
print(y_test.shape)
 

 

 

🟡6. 데이터 로더 적용시키기

 

loader = torch.utils.data.DataLoader(
    dataset = list(zip(x_train,y_train)),
    batch_size=64,
    shuffle=True
) # 64개씩 쪼개고, 데이터를 섞는다.

imgs, labels= next(iter(loader))
# next와 같이사용된다. iter(데이터) : 데이터의 요소를 반복가능객체로 만들어서 1개씩 뽑는다.
# img는 문제고 label은 해당 답이라 생각하면 된다.



fig,axes = plt.subplots(8,8, figsize=(13,13))  #우리가 총 64개여서 64개를 표현하려고

for ax,img,label in zip(axes.flatten(),imgs,labels):
    ax.imshow(img.reshape(8,8),cmap='plasma') #ax는 이미지가 들어가있다.
    ax.set_title(str(torch.argmax(label)))
    ax.axis('off')

 

 

 

 

7. 학습시키기

# 학습시키기

model = nn.Sequential(
    nn.Linear(64,10)
)

optimizer = optim.Adam(model.parameters(),lr=0.01)

epochs= 50

for epoch in range(epochs+1):
    sum_losses = 0
    sum_accs = 0

    for x_batch,y_batch in loader:
        y_pred = model(x_batch)

        loss=nn.CrossEntropyLoss()(y_pred,y_batch)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        sum_losses = sum_losses + loss

        #배치 단위로 정확도 저장
        #배치 마다의 가장 높은 것들 더해서 나눈다.
        y_prob = nn.Softmax(1)(y_pred)
        y_pred_index = torch.argmax(y_prob,axis=1)
        y_batch_index = torch.argmax(y_batch,axis=1)

        acc = (y_batch_index == y_pred_index).float().sum() / len(y_batch) * 100

        sum_accs = sum_accs + acc

    avg_loss = sum_losses / len(loader)
    avg_acc = sum_accs / len(loader)

    print(f'Epoch{epoch:4d}/{epochs}  Loss: {avg_loss:.6f} Accuracy: {avg_acc:.2f}')

 

 

8. 테스트해보기

 

plt.imshow(x_test[0].reshape(8,8),cmap='gray')
 

 

y_pred = model(x_test)
y_pred[0]
 
y_prob = nn.Softmax(1)(y_pred)
y_prob[0]
 
for i in range(10):
    print(f'숫자 {i}일 확률 : {y_prob[0][i]:.2f}')

 

y_pred_index = torch.argmax(y_prob,axis=1)
y_test_index = torch.argmax(y_test,axis=1)
accuracy = (y_test_index == y_pred_index).float().sum() / len(y_test) * 100
print(f'테스트 정확도{accuracy:.2f}% 입니다.')
728x90