728x90
반응형
SMALL
📄사용할 예제 - sklearn의 손글시 데이터셋
[데이터셋 정보] https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_digits.html
1. 손글씨 인식 모델 만들기
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.datasets as datasets
import torchvision.transforms as transfoms
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits # 손글씨 데이터
✅ GPU 환경으로 변경
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(device)
# device.to(): 연산할 matrix를 gpu로 보내야 사용할 수 있음!!
📍 코랩에서 런타임 ➡️ 런타임 유형 변경 ➡️ GPU 로 변경 ➡️ 런타임 재실행!!
digits = load_digits()
x_data = digits['data']
y_data = digits['target']
print(x_data.shape) # (1797, 64): 1797글씨를 8x8 바이트(64) 픽셀로 되어있음
print(y_data.shape)
>>>
(1797, 64)
(1797,)
✅ x_data 시각화해서 보기
fig, axes = plt.subplots(nrows=2, ncols=5, figsize=(14, 8))
for i, ax in enumerate(axes.flatten()): #flatten():배열을 한줄로 만듦
ax.imshow(x_data[i].reshape((8,8)), cmap='gray')
ax.set_title(y_data[i])
ax.grid('off')
✅ 데이터를 텐서형으로 변경
# tensor로 변경
x_data = torch.FloatTensor(x_data)
y_data = torch.LongTensor(y_data)
print(x_data.shape)
print(y_data.shape)
>>>
torch.Size([1797, 64])
torch.Size([1797])
✅ 데이터 원 핫 인코딩
# one-hot-encoding
y_one_hot = nn.functional.one_hot(y_data, num_classes=10).float() # 0~ 9
y_one_hot[:10]
✅ 학습데이터와 테스트데이터 분리
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(x_test.shape)
print(y_train.shape)
print(y_test.shape)
>>> torch.Size([1437, 64])
torch.Size([360, 64])
torch.Size([1437, 10])
torch.Size([360, 10])
2. 데이터 로더(DataLoader)
- 데이터의 양이 많을 때 배치 단위로 학습하는 방법
✅ 데이터 로더 생성 - 배치사이즈가 64
loader = torch.utils.data.DataLoader(
dataset = list(zip(x_train, y_train)),
batch_size=64,
shuffle=True
)
# next(): iterator 값을 하나씩 꺼냄(더이상 없을 때 까지 )
# iter(): next()로 꺼낸 데이터를 iterable한 객체로 만듦
imgs, labels = next(iter(loader))
fig, axes = plt.subplots(nrows=8, ncols=8, figsize=(16,16))
for ax, img, label in zip(axes.flatten(), imgs, labels): #flatten():배열을 한줄로 만듦
ax.imshow(img.reshape((8,8)), cmap='gray')
ax.set_title(str(torch.argmax(label))) # 텐서값중 확률이 가장 큰 값의 label
ax.grid('off')
✅ 배치단위로 학습시키기
# 모델 정의
model = nn.Sequential(
nn.Linear(64, 10) # batch size: 64(input), 계산이 2개이상 들어가는 모델-> 딥러닝 모델
)
optimizer = optim.Adam(model.parameters(), lr=0.01)
epochs = 50
for epoch in range(epochs + 1):
sum_losses = 0
sum_accs = 0
# 배치 사이즈:64
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 # 일치하는 bool값을 float형으로 바꾸고 더한 뒤 전체 데이터 수로 나눔 (백분율)
sum_accs = sum_accs + acc
avg_loss = sum_losses / len(loader) # 배치단위(64개)를 50번 반복하기 때문에 평균으로 찍어줌
avg_acc = sum_accs / len(loader)
print(f'Epoch {epoch:4d} / {epochs} Loss: {avg_loss:.6f} Accuracy: {avg_acc:.2f}%')
📍배치단위로 학습했기 때문에 평균 loss와 평균 정확도를 계산함!
✅ 0번 테스트 데이터 확인
plt.imshow(x_test[0].reshape((8,8)), cmap='gray')
✅테스트 데이터로 예측값 도출
y_pred = model(x_test)
y_pred[0]
>>> tensor([ 2.1293, -4.6106, -6.3739, 0.0610, -2.6799, 16.4323, -4.4906, -2.6905,
-1.4101, -3.9731], grad_fn=<SelectBackward0>)
✅ 예측값에 대한 확률 도출
y_prob = nn.Softmax(1)(y_pred)
y_prob[0]
>>> tensor([6.1420e-07, 7.2645e-10, 1.2457e-10, 7.7629e-08, 5.0084e-09, 1.0000e+00,
8.1908e-10, 4.9553e-09, 1.7830e-08, 1.3742e-09],
grad_fn=<SelectBackward0>)
✅ 0 ~ 9까지의 확률값을 뽑아내 어떤 숫자로 예측하였는지 보기
for i in range(10):
print(f'숫자 {i}일 확률: {y_prob[0][i]:.2f}')
>>>
숫자 0일 확률: 0.00
숫자 1일 확률: 0.00
숫자 2일 확률: 0.00
숫자 3일 확률: 0.00
숫자 4일 확률: 0.00
숫자 5일 확률: 1.00
숫자 6일 확률: 0.00
숫자 7일 확률: 0.00
숫자 8일 확률: 0.00
숫자 9일 확률: 0.00
✅ 테스트 정확도
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}% 입니다!')
>>> 테스트 정확도는 95.83% 입니다!
728x90
반응형
LIST
'Python > ML&DL' 카테고리의 다른 글
[파이썬, Python] 활성화 함수(Activation Function) 종류에 대해 알아보자! (0) | 2023.06.29 |
---|---|
[파이썬, Python] 딥러닝(DeepLearning) - 퍼셉트론과 역전파 (0) | 2023.06.29 |
[파이썬, Python] 파이토치(Pytorch)로 논리 회귀(Logistic Regression)구현하기! (0) | 2023.06.26 |
[파이썬, Python] 파이토치(Pytorch)로 선형회귀(Linear Regression) 구현하기! (0) | 2023.06.23 |
[파이썬, Python] 파이토치(Pytorch)란❓ & 파이토치의 특징 알아보기!🧐 (0) | 2023.06.23 |