22년 5월 18일 정식으로 M1 pytorch 가 공개되었다.(Nightly 버전) [Introducing accelerated pytorch training on mac]
마침 M1, Intel iMac 을 둘 다 가지고 있고 시간도 잠시 생겼으니 간단하게 테스트해보자.
설치페이지에서 Nightly - Mac - pip - python
을 선택해서 나오는 명령어로 설치할 수 있다.
(이제 공식 지원 되니까!)
설치하고 버전을 확인해보았다.
print(torch.__version__)
# 1.13.0.dev20220522
# 버그가 있어서 꼭 해당 버전 이상으로 설치하시기 바랍니다.
import torch
from torchvision import datasets, transforms
from tqdm import tqdm
# Devices
# Colab - T4
device = 'cuda'
# M1 gpu
device = 'mps'
# M1 & Intel cpu
device = 'cpu'
# hyperparameters
learning_rate = 0.001
training_epochs = 10
batch_size = 100
# MNIST dataset
mnist_train = datasets.MNIST(root='MNIST_data/',
train=True,
transform=transforms.ToTensor(),
download=True)
mnist_test = datasets.MNIST(root='MNIST_data/',
train=False,
transform=transforms.ToTensor(),
download=True)
# dataset loader
data_loader = torch.utils.data.DataLoader(dataset=mnist_train,
batch_size=batch_size,
shuffle=True,
drop_last=True)
# CNN Model (3 conv layers)
class CNN(torch.nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.layer1 = torch.nn.Sequential(
torch.nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2))
self.layer2 = torch.nn.Sequential(
torch.nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2))
self.layer3 = torch.nn.Sequential(
torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2, stride=2))
self.fc = torch.nn.Linear(3 * 3 * 128, 10, bias=True)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = self.layer3(out)
out = out.view(out.size(0), -1)
out = self.fc(out)
return out
# instantiate CNN model
model = CNN().to(device)
# define cost/loss & optimizer
criterion = torch.nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
# train my model
total_batch = len(data_loader)
print('Learning started. It takes sometime.')
for epoch in range(training_epochs):
avg_cost = 0
for X, Y in tqdm(data_loader):
X = X.to(device)
Y = Y.to(device)
optimizer.zero_grad()
hypothesis = model(X)
cost = criterion(hypothesis, Y)
cost.backward()
optimizer.step()
avg_cost += cost / total_batch
print('[Epoch: {:>4}] cost = {:>.9}'.format(epoch + 1, avg_cost))
print('Learning Finished!')
# Test model and check accuracy
with torch.no_grad():
X_test = mnist_test.test_data.view(len(mnist_test), 1, 28, 28).float().to(device)
Y_test = mnist_test.test_labels.to(device)
prediction = model(X_test)
correct_prediction = torch.argmax(prediction, 1) == Y_test
accuracy = correct_prediction.float().mean()
print('Accuracy:', accuracy.item())