티스토리 뷰

https://wikidocs.net/61073

 

06-08 다층 퍼셉트론으로 MNIST 분류하기

앞서 소프트맥스 회귀로 MNIST 데이터를 분류하는 실습을 해봤습니다. 소프트맥스 회귀 또한 인공 신경망이라고 볼 수 있는데, 입력층과 출력층만 존재하므로 소프트맥스 함수를 활성…

wikidocs.net

실습 코드 에러나는 부분 수정한 버전 (23.1.15 ver)

# 1. 데이터 로드하기
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_openml

mnist = fetch_openml('mnist_784', version=1, cache=True)

print(mnist.data.iloc[0])  # 코드 수정

print(mnist.data.iloc[0].min())
print(mnist.data.iloc[0].max())

print (mnist.target[0])

print (mnist.target[0])
print (type(mnist.target[0]))

X = mnist.data / 255  # 0-255값을 [0, 1]구간으로 정규화
y = mnist.target

print(X.iloc[0].min())
print(X.iloc[0].max())

print(y[0])

plt.imshow(X.iloc[0].array.reshape(28, 28), cmap='gray')  # 코드 수정
print("이 이미지 데이터의 레이블은 {:.0f}이다".format(y[0]))
# 2. 훈련 데이터와 테스트 데이터의 분리

from torch.utils.data import TensorDataset, DataLoader
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=1/7, random_state=0)

X_train = X_train.to_numpy()  # 코드 수정
X_test = X_test.to_numpy()

y_train, y_test = y_train.array, y_test.array  # 코드 수정

X_train = torch.Tensor(X_train)
X_test = torch.Tensor(X_test)
y_train = torch.LongTensor(y_train)
y_test = torch.LongTensor(y_test)

ds_train = TensorDataset(X_train, y_train)
ds_test = TensorDataset(X_test, y_test)

loader_train = DataLoader(ds_train, batch_size=64, shuffle=True)
loader_test = DataLoader(ds_test, batch_size=64, shuffle=False)
# 3. 다층 퍼셉트론
model = nn.Sequential()
model.add_module(name='fc1', module=nn.Linear(28*28*1, 100))
model.add_module(name='relu1', module=nn.ReLU())
model.add_module(name='fc2', module=nn.Linear(100, 100))
model.add_module(name='relu2', module=nn.ReLU())
model.add_module(name='fc3', module=nn.Linear(100, 10))
print (model)

from torch import optim

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

# 가중치 학습을 위한 최적화 기법
optimizer = optim.Adam(params=model.parameters(), lr=0.1)

def train(epoch):
  model.train()  # 모델을 학습모드로 전환
  # 데이터로더에서 미니배치를 하나씩 꺼내 학습 수행
  for data, targets in loader_train:
    
    optimizer.zero_grad()  # 경사를 0으로 초기화 
    loss = loss_fn(model(data), targets)  # forward(데이터를 입력하고 출력 계산), 출력과 훈련 데이터 정답 간의 loss 계산
    loss.backward()  # backward(오차를 역전파 계산)
    optimizer.step()  # update(역전파 계산한 값으로 가중치 수정)
  print("epoch{}:완료\n".format(epoch))


def test():
  model.eval()  # 신경망을 추론모드로 전환
  correct = 0

  # 데이터 로더에서 미니 배치를 하나씩 꺼내 추론을 수행
  with torch.no_grad():  # 추론과정에는 미분이 필요 없음.
    for data, targets in loader_test:

      # optimizer.zero_grad()  # 경사를 0으로 초기화하는 과정이 필요 없음. 
      output = model(data)  # 데이터를 입력하고 출력을 계산. ([64, 10]의 텐서가 나옴.)
      # loss = loss_fn(output, targets)  # 출력값과 실제 정답 사이의 차이 계산하는 과정이 필요 없음.
      # loss.backward()  # loss값을 역전파 계산하는 과정이 필요 없음.
      # optimizer.step()  # 계산한 값으로 optimizer에 있는 가중치 수정하는 과정이 필요 없음.

      # 추론 계산
      _, predicted = torch.max(output, dim=1)  # 확률이 가장 높은 레이블이 무엇인지 계산. (values, indices 반환)
      # predicted는 64 크기의 tensor. targets도 64 크기의 텐서.
      correct += predicted.eq(targets.data.view_as(predicted)).sum() # 정답과 일치한 경우 정답 카운트를 증가

    # 정확도 출력
    data_num = len(loader_test.dataset)  # 데이터 총 건수
    print('\n테스트 데이터에서 예측 정확도: {}/{} ({:.0f}%)\n'.format(correct,
                                                   data_num, 100. * correct / data_num))
for epoch in range(3):
    train(epoch)
test()
index = 2018

model.eval()  # 추론 모드로 전환.

data = X_test[index]
output = model(data)
_, predicted = torch.max(output, 0)

print ("예측결과:", predicted)

X_test_show = (X_test[index]).numpy()
plt.imshow(X_test_show.reshape(28, 28), cmap='gray')

'torch' 카테고리의 다른 글

07-04 자연어 처리를 위한 1D CNN 연습문제 풀이 (Pytorch Conv1D 예제)  (0) 2023.01.15
XOR gate  (0) 2023.01.15
댓글
Total
Today
Yesterday
공지사항
최근에 올라온 글
글 보관함