Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov
V tomto článku vám poviem, ako za 30 minút nastaviť prostredie strojového učenia, vytvoriť neurónovú sieť na rozpoznávanie obrázkov a potom spustiť rovnakú sieť na grafickom procesore (GPU).

Najprv si definujme, čo je neurónová sieť.

V našom prípade ide o matematický model, ako aj jeho softvérové ​​či hardvérové ​​stelesnenie, postavené na princípe organizácie a fungovania biologických neurónových sietí – sietí nervových buniek živého organizmu. Tento koncept vznikol pri štúdiu procesov prebiehajúcich v mozgu a pri pokuse o modelovanie týchto procesov.

Neurónové siete nie sú naprogramované v bežnom zmysle slova, sú natrénované. Schopnosť učiť sa je jednou z hlavných výhod neurónových sietí oproti tradičným algoritmom. Technicky učenie pozostáva z hľadania koeficientov spojení medzi neurónmi. Počas tréningového procesu je neurónová sieť schopná identifikovať zložité závislosti medzi vstupnými dátami a výstupnými dátami, ako aj vykonávať zovšeobecňovanie.

Z hľadiska strojového učenia je neurónová sieť špeciálnym prípadom metód rozpoznávania vzorov, diskriminačnej analýzy, metód zhlukovania a ďalších metód.

Оборудование

Najprv sa pozrime na výbavu. Potrebujeme server s nainštalovaným operačným systémom Linux. Zariadenia potrebné na prevádzku systémov strojového učenia sú pomerne výkonné a v dôsledku toho drahé. Pre tých, ktorí nemajú po ruke dobrý stroj, odporúčam venovať pozornosť ponukám cloudových poskytovateľov. Požadovaný server si môžete rýchlo prenajať a platiť len za čas používania.

V projektoch, kde je potrebné vytvárať neurónové siete, využívam servery jedného z ruských cloudových poskytovateľov. Spoločnosť ponúka cloudové servery na prenájom špeciálne pre strojové učenie s výkonnými grafickými procesormi Tesla V100 (GPU) od NVIDIA. Stručne povedané: používanie servera s GPU môže byť desaťkrát efektívnejšie (rýchlejšie) v porovnaní so serverom s podobnou cenou, ktorý na výpočty používa CPU (známu centrálnu procesorovú jednotku). To je dosiahnuté vďaka vlastnostiam architektúry GPU, ktorá sa rýchlejšie vyrovná s výpočtami.

Na implementáciu príkladov popísaných nižšie sme na niekoľko dní zakúpili nasledujúci server:

  • SSD disk 150 GB
  • RAM 32 GB
  • Procesor Tesla V100 16 Gb so 4 jadrami

Na náš počítač sme nainštalovali Ubuntu 18.04.

Nastavenie prostredia

Teraz nainštalujte všetko potrebné pre prácu na serveri. Keďže náš článok je primárne pre začiatočníkov, poviem vám niekoľko bodov, ktoré budú pre nich užitočné.

Veľa práce pri nastavovaní prostredia sa vykonáva cez príkazový riadok. Väčšina používateľov používa Windows ako svoj pracovný OS. Štandardná konzola v tomto OS ponecháva veľa požiadaviek. Preto použijeme pohodlný nástroj Cmder/. Stiahnite si mini verziu a spustite Cmder.exe. Ďalej sa musíte pripojiť k serveru cez SSH:

ssh root@server-ip-or-hostname

Namiesto adresy IP servera alebo názvu hostiteľa zadajte adresu IP alebo názov DNS vášho servera. Ďalej zadajte heslo a ak je pripojenie úspešné, mali by sme dostať správu podobnú tejto.

Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-74-generic x86_64)

Hlavným jazykom pre vývoj modelov ML je Python. A najobľúbenejšia platforma pre jeho použitie na Linuxe je anakonda.

Poďme si ho nainštalovať na náš server.

Začneme aktualizáciou lokálneho správcu balíkov:

sudo apt-get update

Nainštalujte curl (utilita príkazového riadka):

sudo apt-get install curl

Stiahnite si najnovšiu verziu distribúcie Anaconda:

cd /tmp
curl –O https://repo.anaconda.com/archive/Anaconda3-2019.10-Linux-x86_64.sh

Začnime s inštaláciou:

bash Anaconda3-2019.10-Linux-x86_64.sh

Počas procesu inštalácie budete vyzvaní na potvrdenie licenčnej zmluvy. Po úspešnej inštalácii by ste mali vidieť toto:

Thank you for installing Anaconda3!

V súčasnosti bolo vytvorených mnoho rámcov na vývoj modelov ML; pracujeme s najpopulárnejšími: PyTorch и tenzorový tok.

Používanie frameworku umožňuje zvýšiť rýchlosť vývoja a využívať hotové nástroje pre štandardné úlohy.

V tomto príklade budeme pracovať s PyTorch. Poďme si to nainštalovať:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Teraz musíme spustiť Jupyter Notebook, populárny vývojový nástroj pre špecialistov na ML. Umožňuje vám písať kód a okamžite vidieť výsledky jeho vykonania. Jupyter Notebook je súčasťou Anaconda a je už nainštalovaný na našom serveri. Musíte sa k nemu pripojiť z nášho desktopového systému.

Aby sme to urobili, najprv spustíme Jupyter na serveri špecifikujúcom port 8080:

jupyter notebook --no-browser --port=8080 --allow-root

Potom otvorením ďalšej karty v našej konzole Cmder (horné menu - dialógové okno Nová konzola) sa pripojíme cez port 8080 k serveru cez SSH:

ssh -L 8080:localhost:8080 root@server-ip-or-hostname

Keď zadáme prvý príkaz, ponúknu sa nám odkazy na otvorenie Jupyter v našom prehliadači:

To access the notebook, open this file in a browser:
        file:///root/.local/share/jupyter/runtime/nbserver-18788-open.html
    Or copy and paste one of these URLs:
        http://localhost:8080/?token=cca0bd0b30857821194b9018a5394a4ed2322236f116d311
     or http://127.0.0.1:8080/?token=cca0bd0b30857821194b9018a5394a4ed2322236f116d311

Použime odkaz pre localhost:8080. Skopírujte celú cestu a vložte ju do panela s adresou v lokálnom prehliadači vášho počítača. Otvorí sa Zápisník Jupyter.

Vytvorme nový poznámkový blok: Nový - Zápisník - Python 3.

Skontrolujeme správnu činnosť všetkých komponentov, ktoré sme nainštalovali. Zadáme príklad kódu PyTorch do Jupyter a spustíme spustenie (tlačidlo Spustiť):

from __future__ import print_function
import torch
x = torch.rand(5, 3)
print(x)

Výsledkom by malo byť niečo takéto:

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Ak máte podobný výsledok, tak sme všetko správne nakonfigurovali a môžeme začať s vývojom neurónovej siete!

Vytvorenie neurónovej siete

Vytvoríme neurónovú sieť na rozpoznávanie obrazu. Zoberme si to ako základ sprievodca.

Na trénovanie siete použijeme verejne dostupný dataset CIFAR10. Má triedy: „lietadlo“, „auto“, „vták“, „mačka“, „jeleň“, „pes“, „žaba“, „kôň“, „loď“, „nákladné auto“. Obrázky v CIFAR10 sú 3x32x32, to znamená 3-kanálové farebné obrázky s rozmermi 32x32 pixelov.

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov
Na prácu nám poslúži balík vytvorený PyTorchom na prácu s obrázkami – torchvision.

Urobíme nasledujúce kroky v poradí:

  • Načítanie a normalizácia tréningových a testovacích dátových súborov
  • Definícia neurónovej siete
  • Sieťový tréning na tréningových údajoch
  • Testovanie siete na testovacích údajoch
  • Zopakujme si tréning a testovanie pomocou GPU

Všetky nižšie uvedené kódy spustíme v Jupyter Notebooku.

Načítavanie a normalizácia CIFAR10

Skopírujte a spustite nasledujúci kód v Jupyter:


import torch
import torchvision
import torchvision.transforms as transforms

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                         shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

Odpoveď by mala byť:

Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ./data/cifar-10-python.tar.gz
Extracting ./data/cifar-10-python.tar.gz to ./data
Files already downloaded and verified

Ukážme si niekoľko tréningových obrázkov na testovanie:


import matplotlib.pyplot as plt
import numpy as np

# functions to show an image

def imshow(img):
    img = img / 2 + 0.5     # unnormalize
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg, (1, 2, 0)))
    plt.show()

# get some random training images
dataiter = iter(trainloader)
images, labels = dataiter.next()

# show images
imshow(torchvision.utils.make_grid(images))
# print labels
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Definícia neurónovej siete

Najprv sa zamyslime nad tým, ako funguje neurónová sieť na rozpoznávanie obrázkov. Ide o jednoduchú sieť typu point-to-point. Zoberie vstupné dáta, prejde ich cez niekoľko vrstiev jednu po druhej a nakoniec vytvorí výstupné dáta.

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Vytvorme podobnú sieť v našom prostredí:


import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()

Definujeme tiež stratovú funkciu a optimalizátor


import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

Sieťový tréning na tréningových údajoch

Začnime trénovať našu neurónovú sieť. Upozorňujeme, že po spustení tohto kódu budete musieť nejaký čas počkať, kým sa práca nedokončí. Trvalo mi to 5 minút. Natrénovanie siete si vyžaduje čas.

 for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

Dostaneme nasledujúci výsledok:

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Ukladáme náš vyškolený model:

PATH = './cifar_net.pth'
torch.save(net.state_dict(), PATH)

Testovanie siete na testovacích údajoch

Trénovali sme sieť pomocou súboru tréningových dát. Musíme však skontrolovať, či sa sieť vôbec niečo naučila.

Otestujeme to predpovedaním označenia triedy, ktoré neurónová sieť vydáva, a testovaním, či je pravdivý. Ak je predpoveď správna, vzorku pridáme do zoznamu správnych predpovedí.
Ukážme obrázok z testovacej sady:

dataiter = iter(testloader)
images, labels = dataiter.next()

# print images
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Teraz požiadajme neurónovú sieť, aby nám povedala, čo je na týchto obrázkoch:


net = Net()
net.load_state_dict(torch.load(PATH))

outputs = net(images)

_, predicted = torch.max(outputs, 1)

print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]
                              for j in range(4)))

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Výsledky sa zdajú celkom dobré: sieť správne identifikovala tri zo štyroch obrázkov.

Pozrime sa, ako funguje sieť v rámci celého súboru údajov.


correct = 0
total = 0
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('Accuracy of the network on the 10000 test images: %d %%' % (
    100 * correct / total))

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Zdá sa, že sieť niečo vie a funguje. Ak by triedy určil náhodne, presnosť by bola 10 %.

Teraz sa pozrime, ktoré triedy sieť identifikuje lepšie:

class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():
    for data in testloader:
        images, labels = data
        outputs = net(images)
        _, predicted = torch.max(outputs, 1)
        c = (predicted == labels).squeeze()
        for i in range(4):
            label = labels[i]
            class_correct[label] += c[i].item()
            class_total[label] += 1


for i in range(10):
    print('Accuracy of %5s : %2d %%' % (
        classes[i], 100 * class_correct[i] / class_total[i]))

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Zdá sa, že sieť je najlepšia na identifikáciu áut a lodí: presnosť 71 %.

Takže sieť funguje. Teraz skúsme preniesť jeho prácu na grafický procesor (GPU) a uvidíme, čo sa zmení.

Trénovanie neurónovej siete na GPU

Najprv stručne vysvetlím, čo je CUDA. CUDA (Compute Unified Device Architecture) je paralelná výpočtová platforma vyvinutá spoločnosťou NVIDIA pre všeobecné výpočty na grafických procesoroch (GPU). S CUDA môžu vývojári výrazne urýchliť výpočtové aplikácie využitím výkonu GPU. Táto platforma je už nainštalovaná na našom serveri, ktorý sme zakúpili.

Najprv definujme náš GPU ako prvé viditeľné cuda zariadenie.

device = torch . device ( "cuda:0" if torch . cuda . is_available () else "cpu" )
# Assuming that we are on a CUDA machine, this should print a CUDA device:
print ( device )

Vaša prvá neurónová sieť na grafickej procesorovej jednotke (GPU). Sprievodca pre začiatočníkov

Odoslanie siete do GPU:

net.to(device)

Budeme tiež musieť odoslať vstupy a ciele v každom kroku do GPU:

inputs, labels = data[0].to(device), data[1].to(device)

Poďme znova natrénovať sieť na GPU:

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
for epoch in range(2):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        # get the inputs; data is a list of [inputs, labels]
    inputs, labels = data[0].to(device), data[1].to(device)

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 2000 == 1999:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 2000))
            running_loss = 0.0

print('Finished Training')

Tentoraz tréning siete trval približne 3 minúty. Pripomeňme, že rovnaká fáza na bežnom procesore trvala 5 minút. Rozdiel nie je výrazný, stáva sa to preto, lebo naša sieť nie je taká veľká. Pri použití veľkých polí na tréning sa rozdiel medzi rýchlosťou GPU a tradičného procesora zväčší.

Zdá sa, že to je všetko. Čo sa nám podarilo:

  • Pozreli sme sa na to, čo je GPU, a vybrali sme server, na ktorom je nainštalovaný;
  • Nastavili sme softvérové ​​prostredie na vytvorenie neurónovej siete;
  • Vytvorili sme neurónovú sieť na rozpoznávanie obrazu a natrénovali sme ju;
  • Zopakovali sme sieťový tréning pomocou GPU a dosiahli sme zvýšenie rýchlosti.

Na otázky rád odpoviem v komentároch.

Zdroj: hab.com

Pridať komentár