Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov
V tomto článku vám ukážem, ako nastaviť prostredie pre strojové učenie za 30 minút, vytvoriť neurónovú sieť na rozpoznávanie obrázkov a potom spustiť tú istú sieť na grafickom procesore (GPU).

Na začiatok určme, čo je to neurónová sieť.

V našom prípade ide o matematický model, ako aj o jeho programové alebo hardvérové zobrazenie, postavené na princípe organizácie a fungovania biologických neurónových sietí - sieť nervových buniek živého organizmu. Tento pojem vznikol pri štúdiu procesov prebiehajúcich v mozgu a pri pokuse modelovať tieto procesy.

Neurónové siete sa neprogramujú v bežnom zmysle tohto slova, učia sa. Možnosť učenia je jednou z hlavných výhod neurónových sietí oproti tradičným algoritmom. Technicky učenie spočíva v hľadaní koeficientov spojení medzi neurónmi. Počas učenia je neurónová sieť schopná odhaľovať zložité závislosti medzi vstupnými a výstupnými dátami, ako aj vykonávať generalizáciu.

Z hľadiska strojového učenia je neurónová sieť osobitným prípadom metód rozpoznávania vzorov, diskriminačnej analýzy, metód klasifikácie a iných metód.

Zariadenie

Najprv sa pozrime na hardvér. Potrebujeme server s nainštalovaným operačným systémom Linux. Hardvér na prácu systémov strojového učenia je potrebný dosť výkonný a v dôsledku toho aj drahý. Tým, ktorí nemajú poruke dobrý stroj, odporúčam venovať pozornosť ponuke cloudových poskytovateľov. Potrebný server si môžete rýchlo prenajať a platiť len za čas používania.

V projektoch, kde je potrebné vytvoriť neurónové siete, používam servery jedného z ruských cloudových poskytovateľov. Spoločnosť ponúka na prenájom cloudové servery špeciálne pre strojové učenie s výkonnými grafickými procesormi (GPU) Tesla V100 od spoločnosti NVIDIA. V skratke: použitie servera s GPU môže byť niekoľkokrát efektívnejšie (rýchlejšie) v porovnaní s rovnakým cenovým serverom, kde sa na výpočty používa CPU (všetkým dobre známy centrálna procesor). To sa dosahuje vďaka špecifikám architektúry GPU, ktorá rýchlejšie zvláda výpočty.

Na vykonanie príkladov popísaných nižšie sme si na niekoľko dní zakúpili taký server:

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

Na stroj nám nainštalovali Ubuntu 18.04.

Nastavujeme prostredie

Teraz nainštalujeme na server všetko potrebné na prácu. Keďže náš článok je predovšetkým pre začiatočníkov, budem v ňom hovoriť o niektorých aspektoch, ktoré sa im hodia.

Veľa práce pri nastavovaní prostredia sa vykonáva cez príkazový riadok. Väčšina používateľov používa ako pracovný operačný systém Windows. Štandardná konzola v tomto operačnom systéme zanecháva veľa prianí. Preto budeme používať pohodlný nástroj Cmder/. Stiahneme mini verziu a spustíme Cmder.exe. Potom je potrebné sa pripojiť k serveru prostredníctvom protokolu SSH:

ssh root@server-ip-or-hostname

Namiesto server-ip-or-hostname zadajte IP adresu alebo DNS meno vášho servera. Potom zadáme heslo a pri úspešnom pripojení by sme mali dostať približne takúto správu.

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

Hlavným jazykom pre vývoj ML modelov je Python. A najpopulárnejšou platformou pre jeho použitie v Linuxe je Anaconda.

Nainštalujeme ju na náš server.

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

sudo apt-get update

Inštalujeme curl (pomocný program príkazového riadku):

sudo apt-get install curl

Stiahneme najnovšiu verziu Anaconda Distribution:

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

Spúšťame inštaláciu:

bash Anaconda3-2019.10-Linux-x86_64.sh

Počas inštalácie bude potrebné potvrdiť licenčnú dohodu. Pri úspešnej inštalácii by ste mali vidieť toto:

Thank you for installing Anaconda3!

Na vývoj ML modelov existuje množstvo rámcov, my pracujeme s najpopulárnejšími: PyTorch a Tensorflow.

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

V tomto príklade budeme pracovať s PyTorch. Nainštalujeme ho:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Teraz musíme spustiť Jupyter Notebook — populárny nástroj vývoja u odborníkov na ML. Umožňuje písať kód a okamžite vidieť výsledky jeho vykonania. Jupyter Notebook je súčasťou Anacondy a už je nainštalovaný na našom serveri. Musíme sa k nemu pripojiť z našej pracovnej stanice.

Na to najprv spustíme Jupyter na serveri a uvedieme port 8080:

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

Ďalej otvoríme v našej konzole Cmder ďalší panel (horné menu — New console dialog) a pripojíme sa cez port 8080 k serveru cez SSH:

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

Pri zadaní prvej príkazu sa nám ponúknu 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

Využijeme odkaz pre localhost:8080. Skopírujte celú cestu a vložte ju do adresného riadku miestneho prehliadača vášho PC. Otvorí sa Jupyter Notebook.

Vytvoríme nový notebook: Nový — Notebook — Python 3.

Skontrolujeme korektnú funkciu všetkých komponentov, ktoré sme nainštalovali. Zadajte do Jupyteru príklad kódu PyTorch a spustite vykonanie (tlačidlo Run):

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

Výsledok by mal byť približne takýto:

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov

Ak máte rovnaký výsledok — znamená to, že sme všetko nastavili správne a môžeme začať s vývojom neurónovej siete!

Vytvárame neurónovú sieť

Budeme vytvárať neurónovú sieť na rozpoznávanie obrázkov. Ako základ vezmeme toto príručka.

Na trénovanie siete budeme používať verejne dostupný údajový súbor CIFAR10. Ten obsahuje triedy: „lietadlo“, „automobil“, „vták“, „mačka“, „jelen“, „pes“, „žaba“, „kôň“, „loď“, „nákladné auto“. Obrázky v CIFAR10 majú rozmer 3x32x32, teda 3-kanálové farebné obrázky s veľkosťou 32×32 pixlov.

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov
Na prácu budeme používať vytvorený PyTorch balík pre prácu s obrázkami — torchvision.

Zrealizujeme nasledujúce kroky postupne:

  • Načítanie a normalizácia súborov tréningových a testovacích dát
  • Definovanie neurónovej siete
  • Trénovanie siete na tréningových dátach
  • Testovanie siete na testovacích dátach
  • Opakujeme tréning a testovanie s využitím GPU

Celý nasledujúci kód budeme vykonávať v Jupyter Notebook.

Načítanie a normalizácia CIFAR10

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


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ť takáto:

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

Vyhodíme niekoľko tréningových obrázkov na kontrolu:


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 grafickom procesore (GPU). Príručka pre začiatočníkov

Definovanie neurónovej siete

Najprv si priblížime, ako funguje neurónová sieť na rozpoznávanie obrázkov. Je to jednoduchá sieť s priamym prepojením. Prijíma vstupné dáta, prechádza nimi cez niekoľko vrstiev po sebe a nakoniec produkuje výstup.

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov

Vytvoríme 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ž funkciu straty a optimalizátor


import torch.optim as optim

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

Trénovanie siete na tréningových dátach

Začíname s tréningom našej neurónovej siete. Upozorňujem, že po spustení tohto kódu bude potrebné некоторое время počkať, kým sa vykonanie dokončí. Mne to trvalo 5 minút. Na tréning siete je potrebný čas.

 pre epoch in range(2): # cyklus nad datasetom viackrát

 bežiaca_strata = 0.0
 pre i, data in enumerate(trainloader, 0):
 # získať vstupy; data je zoznam [vstupy, štítky]
 vstupy, štítky = data

 # nulovať gradienty parametrov
 optimizer.zero_grad()

 # dopredu + dozadu + optimalizácia
 výstupy = net(vstupy)
 strata = criterion(výstupy, štítky)
 strata.backward()
 optimizer.step()

 # vytlačiť štatistiky
 bežiaca_strata += strata.item()
 ak i % 2000 == 1999: # vytlačiť každých 2000 mini-batchov
 print('[%d, ] strata: %.3f' %
 (epoch + 1, i + 1, bežiaca_strata / 2000))
 bežiaca_strata = 0.0

print('Tréning dokončený')

Dostaneme takýto výsledok:

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov

Ukladáme náš naučený model:

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

Testovanie siete na testovacích dátach

Naučili sme sieť na súbore trénovacích dát. Ale musíme skontrolovať, či sa sieť naozaj niečo naučila.

Skontrolujeme to tým, že predpovieme triedu, ktorú neurónová sieť vypustila, a overíme jej pravdivosť. Ak je predpoveď správna, pridáme vzor do zoznamu správnych predpovedí.
Poďme si ukázať obrázok z testovacieho súboru:

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

# tlačiť obrázky
imshow(torchvision.utils.make_grid(images))
print('Skutočná pravda: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka 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('Predikované: ', ' '.join('%5s' % classes[predicted[j]]
                              for j in range(4)))

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov

Výsledky vyzerajú celkom dobre: sieť správne identifikovala tri obrázky z štyroch.

Pozrime sa, ako sieť funguje na celom datasete.


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('Presnosť siete na 10000 testovacích obrázkoch: %d %%' % (
    100 * correct / total))

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov

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

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

class_correct = list(0. pre i in range(10))
class_total = list(0. pre i in range(10))
with torch.no_grad():
 pre data in testloader:
 obrázky, štítky = data
 výstupy = net(obrázky)
 _, predikované = torch.max(výstupy, 1)
 c = (predikované == štítky).squeeze()
 pre i in range(4):
 štítok = štítky[i]
 class_correct[štítok] += c[i].item()
 class_total[štítok] += 1


pre i in range(10):
 print('Úspešnosť %5s : %%' % (
 classes[i], 100 * class_correct[i] / class_total[i]))

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov

Zdá sa, že sieť najlepšie rozpoznáva automobily a lode: 71% presnosť.

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

Tréning neurónovej siete na GPU

Najskôr stručne vysvetlím, čo je CUDA. CUDA (Compute Unified Device Architecture) je platforma paralelných výpočtov vyvinutá spoločnosťou NVIDIA pre všeobecné výpočty na grafických procesoroch (GPU). S pomocou CUDA môžu vývojári výrazne zrýchliť výpočtové aplikácie, využívajúc možnosti grafických procesorov. Na našom serveri, ktorý sme zakúpili, je táto platforma už nainštalovaná.

Najprv si určíme naše GPU ako prvé viditeľné zariadenie CUDA.

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# Predpokladajme, že sme na zariadení CUDA, toto by malo vytlačiť zariadenie CUDA:
print(device)

Vaša prvá neurónová sieť na grafickom procesore (GPU). Príručka pre začiatočníkov

Posielame sieť na GPU:

net.to(device)

Takisto budeme musieť posielať vstupy a ciele na každom kroku na GPU:

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

Spustíme opakovaný tréning siete už na GPU:

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
pre epoch in range(2): # cyklus nad datasetom viackrát

 bežiaca_strata = 0.0
 pre i, data in enumerate(trainloader, 0):
 # získať vstupy; data je zoznam [vstupy, štítky]
 vstupy, štítky = data[0].to(device), data[1].to(device)

 # nulovať gradienty parametrov
 optimizer.zero_grad()

 # dopredu + dozadu + optimalizácia
 výstupy = net(vstupy)
 strata = criterion(výstupy, štítky)
 strata.backward()
 optimizer.step()

 # vytlačiť štatistiky
 bežiaca_strata += strata.item()
 ak i % 2000 == 1999: # vytlačiť každých 2000 mini-batchov
 print('[%d, ] strata: %.3f' %
 (epoch + 1, i + 1, bežiaca_strata / 2000))
 bežiaca_strata = 0.0

print('Tréning dokončený')

Tentokrát tréning siete trval približne 3 minúty. Pripomeňme, že tá istá fáza na bežnom procesore trvala 5 minút. Rozdiel nie je významný, to preto, že naša sieť nie je taká veľká. Pri použití väčších súborov na tréning sa rozdiel v rýchlosti medzi GPU a tradičným procesorom zvýši.

Na tomto sa zdá, že všetko. Čo sa nám podarilo:

  • Preskúmali sme, čo je GPU a vybrali sme server, na ktorom je nainštalovaný;
  • Nastavili sme programové prostredie pre vytvorenie neurónovej siete;
  • Vytvorili sme neurónovú sieť na rozpoznávanie obrázkov a trénovali sme ju;
  • Opakovali sme tréning siete s použitím GPU a dosiahli sme nárast v rýchlosti.

Rád odpoviem na otázky v komentároch.

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster