
1. Fashion-MNIST

- 10가지 분류의 옷 및 액세서리(신발, 구두 등)를 이미지 데이터
- 28 X 28 픽셀 크기의 흑백 이미지
1) Fashion-MNIST 데이터로부터 DataLoader 작성
# 라이브러리 불러오기 import torch from torch import nn, optim from torch.utils.data import (Dataset, DataLoader, TensorDataset) import tqdm from torchvision.datasets import FashionMNIST from torchvision import transforms |
# 구글 드라이브와 구글 코랩을 연동 from google.colab import drive drive.mount('/content/gdrive') |
# 훈련용 데이터 가져오기 fashion_mnist_train = FashionMNIST("/content/gdrive/My Drive/FashionMNIST", train=True, download=True, transform=transforms.ToTensor()) |
# 검증용 데이터 가져오기 fashion_mnist_test = FashionMNIST("/content/gdrive/My Drive/FashionMNIST", train=False, download=True, transform=transforms.ToTensor()) |
# 배치 크기가 128인 DataLoader를 각각 작성 batch_size = 128 train_loader = DataLoader(fashion_mnist_train, batch_size=batch_size, shuffle=True) test_loader = DataLoader(fashion_mnist_train, batch_size=batch_size, shuffle=False) |
2. CNN 구축과 학습
1) 2층 합성곱과 2층 MLP를 연결한 CNN 작성
# (N, C, H, W)형식의 텐서를(N, C*H*W)로 늘리는 계층 class FlattenLayer(nn.Module): def forward(self, x): sizes = x.size() return x.view(sizes[0], -1) |
# 5x5의 커널을 사용해서 처음에 32개, 다음에 64개의 채널 작성 conv_net = nn.Sequential( nn.Conv2d(1, 32, 5), nn.MaxPool2d(2), nn.ReLU(), nn.BatchNorm2d(32), nn.Dropout2d(0.25), nn.Conv2d(32, 64, 5), nn.MaxPool2d(2), nn.ReLU(), nn.BatchNorm2d(64), nn.Dropout2d(0.25), FlattenLayer() ) |
# 합성곱에 의해 최종적으로 이미지 크기가 어떤지를 더미 데이터를 넣어서 확인한다. test_input = torch.ones(1, 1, 28, 28) conv_output_size = conv_net(test_input).size()[-1] |
# 2층 MLP mlp = nn.Sequential( nn.Linear(conv_output_size, 200), nn.ReLU(), nn.BatchNorm1d(200), nn.Dropout(0.25), nn.Linear(200, 10) ) |
# 최종 CNN net = nn.Sequential( conv_net, mlp ) |
2) 평가와 훈련용 헬퍼 함수 작성
# 평가용 헬퍼 함수 def eval_net(net, data_loader, device="cpu"): # Dropout 및 BatchNorm을 무효화 net.eval() ys = [] ypreds = [] for x, y in data_loader: # to 메서드로 계산을 실행할 디바이스로 전송 x = x.to(device) y = y.to(device) # 확률이 가장 큰 분류를 예측 # 여기선 forward(추론) 계산이 전부이므로 자동 미분에 필요한 처리는 off로 설정해서 불필요한 계산을 제한다 with torch.no_grad() : _, y_pred = net(x).max(1) ys.append(y) ypreds.append(y_pred)
# 미니 배치 단위의 예측 결과 등을 하나로 묶는다. ys = torch.cat(ys) ypreds = torch.cat(ypreds) # 예측 정확도 계산 acc = (ys == ypreds).float().sum() / len(ys) return acc.item() |
# 훈련용 헬퍼 함수 def train_net(net, train_loader, test_loader, optimizer_cls=optim.Adam, loss_fn=nn.CrossEntropyLoss(), n_iter=10, device="cpu"): train_losses = [] train_acc = [] val_acc = [] optimizer = optimizer_cls(net.parameters()) for epoch in range(n_iter): running_loss = 0.0 # 신경망을 훈련 모드로 설정 net.train() n = 0 n_acc = 0 # 시간이 많이 걸리므로 tqdm을 사용해서 진행바를 표시 for i, (xx, yy) in tqdm.tqdm(enumerate(train_loader), total = len(train_loader)): xx = xx.to(device) yy = yy.to(device) h = net(xx) loss = loss_fn(h, yy) optimizer.zero_grad() loss.backward() optimizer.step() running_loss += loss.item() n += len(xx) _, y_pred = h.max(1) n_acc += (yy == y_pred).float().sum().item() train_losses.append(running_loss / i) # 훈련 데이터의 예측 정확도 train_acc.append(n_acc / n)
# 검증 데이터의 예측 정확도 val_acc.append(eval_net(net, test_loader, device)) # epoch의 결과 표시 print(epoch, train_losses[-1], train_acc[-1], val_acc[-1], flush=True) |
3) 모든 파라미터를 GPU로 전송해서 훈련 실행
# 신경망의 모든 파라미터를 GPU로 전송 net.to("cuda:0") |
![]() |
# 훈련 실행 train_net(net, train_loader, test_loader, n_iter=20, device="cuda:0") |
![]() ![]() |
'인공지능 > 파이토치' 카테고리의 다른 글
파이토치 - 전이 학습 (0) | 2020.07.22 |
---|---|
파이토치 - 신경망의 모듈화 (0) | 2020.07.20 |
파이토치 - Dropout과 Batch Normalization (0) | 2020.07.20 |
파이토치 - Dataset과 DataLoader (0) | 2020.07.20 |
파이토치 - MLP 구축과 학습 (0) | 2020.07.20 |