import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
# 코랩에서 GPU 환경으로 변경
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(device)
loader = torch.utils.data.DataLoader(
dataset=list(zip(x_train, y_train)),
# 학습 사이즈를 64개로 설정
batch_size=64,
# 섞지 않으면 순서에 맞춰서 데이터 분할
shuffle=True,
# 데이터를 64개씩 자르는데 64개 이하일 경우, 마지막에 남는 데이터를 사용할 것인지 말 것인지.
drop_last=False
)
# 배치단위(64개)만큼 뽑아짐.
imgs, labels = next(iter(loader))
fig, axes = plt.subplots(nrows=8, ncols=8, figsize=(14, 14))
for ax, img, label in zip(axes.flatten(), imgs, labels):
ax.imshow(img.reshape(8, 8), cmap='gray')
ax.set_title(str(label))
ax.axis('off')
# 학습
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 += loss
y_prob = nn.Softmax(1)(y_pred)
y_pred_index = torch.argmax(y_prob, axis=1)
acc = (y_batch == y_pred_index).float().sum() / len(y_batch) * 100
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}%')
# 10번 테스트 데이터 확인
plt.imshow(x_test[10].reshape((8,8)), cmap='gray')
print(y_test[10])
# 테스트 데이터로 예측값 도출
y_pred = model(x_test)
# 기울기 확인
y_pred[10]
# 예측값에 대한 확률 도출
y_prob = nn.Softmax(1)(y_pred)
y_prob[10]
# 0 ~ 9까지의 확률값을 뽑아내 어떤 숫자로 예측하였는지 보기
for i in range(10):
print(f'숫자 {i}일 확률: {y_prob[0][i]:.2f}')