PyTorch, отсутствующее руководство по загрузке набора данных MNIST

PyTorch — это фреймворк машинного обучения (ML), основанный на Torch. Torch — это тензорная библиотека, как и Numpy, но, в отличие от Numpy, Torch имеет мощную поддержку графического процессора.

Вы можете использовать Torch либо с помощью языка программирования Lua, либо, если вы предпочитаете Python, как я, вы можете использовать PyTorch.

Нет необходимости упоминать, что вы можете использовать PyTorch вместе со всеми основными пакетами Python, такими как scipy, Numpy, matplotlib и Cython, и получать преимущества от системы автоградации PyTorch.


Здесь я предполагаю, что вы хотите заняться машинным обучением или уже пробовали PyTorch.

Хотя PyTorch сделал много отличных вещей, я обнаружил, что Веб-сайт PyTorch отсутствуют некоторые примеры, особенно как загружать наборы данных.

Вот почему я привожу здесь пример загрузки Набор данных MNIST.

В этом примере мы используем класс PyTorch. DataLoader из torch.utils.data. Это загрузит ресурс с веб-сайта Яна Лекуна.

Янн Лекун — главный специалист по искусственному интеллекту в Facebook, если он все еще там, когда вы читаете это.

Набор данных MNIST содержит в общей сложности 70 000 изображений, где 60 000 изображений представляют собой набор поездов, а 10 000 изображений — набор для проверки (тестирования).

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader, Dataset, TensorDataset
from torch.optim import *
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import os
import numpy as np
import random


dev = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
bs=512

t = transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize(mean=(0), std=(1))]
                       )

dl_train = DataLoader( torchvision.datasets.MNIST('/data/mnist', download=True, train=True, transform=t), 
                batch_size=bs, drop_last=True, shuffle=True)
dl_valid = DataLoader( torchvision.datasets.MNIST('/data/mnist', download=True, train=False, transform=t), 
                batch_size=bs, drop_last=True, shuffle=True)

Когда у вас есть загрузчики данных, вам нужна модель. Здесь мы будем использовать модель с ResBlock внутри.

class ResBlock(nn.Module):
  def __init__(self, nf):
    super().__init__()
    
    self.conv1 = nn.Conv2d(nf, nf, kernel_size=3, stride=1, padding=1, bias=False) 
    self.bn1 = nn.BatchNorm2d(nf)    
    self.relu = nn.ReLU(inplace=True)
    self.conv2 = nn.Conv2d(nf, nf, kernel_size=3, stride=1, padding=1, bias=False)
    self.bn2 = nn.BatchNorm2d(nf)    

  def forward(self, x):
    o = self.conv1(x)
    o = self.bn1(o)
    o = self.relu(o)
    o = self.conv2(o)
    o = self.bn2(o)
    o = o + x
    o = self.relu(o)
    return o 
   

# kernel of 3x3, stride of 2 and padding 1
def convk3s2p1(ni, nf):
    return nn.Sequential(
        nn.Conv2d(ni, nf, 3,2,1, bias=False),
        nn.BatchNorm2d(nf),
        nn.ReLU()
    )
        
model=nn.Sequential(
    convk3s2p1(1,8),
    ResBlock(8),
    convk3s2p1(8,16),
    ResBlock(16),
    convk3s2p1(16,32),
    ResBlock(32),
    convk3s2p1(32,16),
    convk3s2p1(16,10),
    nn.Flatten()
).to('cuda')

# read 85 as BS
input=(torch.randn(85, 1, 24,24))
output=model(input.to('cuda'))
print(output.shape)
model

Когда у вас есть модель, вам нужен оптимизатор и функция потерь.

optimizer = torch.optim.SGD(model.parameters(), lr=0.5, momentum=0.9)
loss_fn = nn.CrossEntropyLoss()

Как только у вас есть все, что вам нужно, петля поезда.

epochs=10
losses=[]

total_steps=len(dl_train)*epochs
scheduler = torch.optim.lr_scheduler.OneCycleLR(optimizer, 
                                                max_lr=0.5, 
                                                steps_per_epoch=len(dl_train),
                                                epochs=epochs)

from sklearn.metrics import accuracy_score, f1_score

for epoch in range(1,epochs+1):
    print(f"Epoch {epoch}")

    # TRAINING PHASE
    model.train()

   
    ect=0 # epoch correct test
    ecv=0 # epoch correct validation
    ett=0 # len of epoch train examples
    etv=0 # len of epoch validation examples   

    for i, (input,target) in enumerate(dl_train):
                
        if(i%10==0): print(i, end=" ")
        optimizer.zero_grad()
        
        input = input.to(dev)
        target = target.to(dev)
        
        output = model(input)
        ect+= accuracy_score(output.argmax(dim=-1).cpu(), target.cpu(), normalize=False)
                

        loss = loss_fn(output, target) # one batch loss        
        losses.append(loss.item())
        loss.backward()
        optimizer.step()
        scheduler.step() 
        ett+=len(target)    
        

    # VALIDATION PHASE
    model.eval() 
    with torch.no_grad(): #gradients should not eval        
        for j, (input,target) in enumerate(dl_valid):

            input = input.to(dev)
            target = target.to(dev)
            output = model(input)
            ecv+= accuracy_score(output.argmax(dim=-1).cpu(), target.cpu(), normalize=False)
            etv+=len(target)            

    print("")
    print("Epoch training accuracy" , ect/ ett)
    # experiment.log_metric("Epoch training accuracy", ect/ ett)
    print("Epoch valid accuracy" , ecv/ etv)
    # experiment.log_metric("Epoch valid accuracy", ecv/ etv)

Результаты, достижения:

Epoch 1
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9074519230769231
Epoch valid accuracy 0.968030427631579
Epoch 2
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9788828792735043
Epoch valid accuracy 0.9822162828947368
Epoch 3
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9845753205128205
Epoch valid accuracy 0.9815995065789473
Epoch 4
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9887319711538461
Epoch valid accuracy 0.987047697368421
Epoch 5
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9914863782051282
Epoch valid accuracy 0.9903371710526315
Epoch 6
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9930889423076923
Epoch valid accuracy 0.9899259868421053
Epoch 7
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9957098023504274
Epoch valid accuracy 0.9922902960526315
Epoch 8
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9979801014957265
Epoch valid accuracy 0.9924958881578947
Epoch 9
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9990985576923077
Epoch valid accuracy 0.9923930921052632
Epoch 10
0 10 20 30 40 50 60 70 80 90 100 110 
Epoch training accuracy 0.9995826655982906
Epoch valid accuracy 0.9923930921052632

Чтобы воспроизвести точно такие же результаты, я использовал эту функцию и семя 12.

def set_seed(seed):
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False
    np.random.seed(seed)
    random.seed(seed)
    os.environ['PYTHONHASHSEED'] = str(seed)

set_seed(12)

Узнайте больше о том, что я пишу в обзор программирования или в моем вести блог

Я благодарен pixabay images за основное изображение статьи.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *