Vaše první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Vaše první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky
V tomto článku vám řeknu, jak za 30 minut nastavit prostředí pro strojové učení, vytvořit neuronovou síť pro rozpoznávání obrazu a poté stejnou síť spustit na grafickém procesoru (GPU).

Nejprve si definujme, co je neuronová síť.

V našem případě se jedná o matematický model, stejně jako jeho softwarové či hardwarové provedení, postavené na principu organizace a fungování biologických neuronových sítí – sítí nervových buněk živého organismu. Tento koncept vznikl při studiu procesů probíhajících v mozku a pokusu tyto procesy modelovat.

Neuronové sítě nejsou naprogramovány v obvyklém slova smyslu, jsou natrénované. Schopnost učit se je jednou z hlavních výhod neuronových sítí oproti tradičním algoritmům. Technicky se učení skládá z hledání koeficientů spojení mezi neurony. Během trénovacího procesu je neuronová síť schopna identifikovat složité závislosti mezi vstupními daty a výstupními daty a také provádět zobecnění.

Z hlediska strojového učení je neuronová síť speciálním případem metod rozpoznávání vzorů, diskriminační analýzy, shlukování a dalších metod.

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

Nejprve se podíváme na výbavu. Potřebujeme server s nainstalovaným operačním systémem Linux. Zařízení potřebné pro provoz systémů strojového učení je poměrně výkonné a v důsledku toho drahé. Pro ty, kteří nemají po ruce dobrý stroj, doporučuji věnovat pozornost nabídkám cloudových poskytovatelů. Požadovaný server si můžete rychle pronajmout a platit pouze za dobu používání.

V projektech, kde je potřeba vytvářet neuronové sítě, využívám servery jednoho z ruských cloudových poskytovatelů. Společnost nabízí k pronájmu cloudové servery speciálně pro strojové učení s výkonnými grafickými procesory Tesla V100 (GPU) od NVIDIA. Stručně řečeno: použití serveru s GPU může být desítkykrát efektivnější (rychlejší) ve srovnání se serverem s podobnou cenou, který pro výpočty používá CPU (známá centrální procesorová jednotka). Toho je dosaženo díky vlastnostem architektury GPU, která se rychleji vypořádá s výpočty.

Abychom mohli implementovat níže popsané příklady, zakoupili jsme na několik dní následující server:

  • SSD disk 150 GB
  • RAM 32 GB
  • Procesor Tesla V100 16 Gb se 4 jádry

Nainstalovali jsme Ubuntu 18.04 na náš počítač.

Nastavení prostředí

Nyní nainstalujeme vše potřebné pro práci na serveru. Protože je náš článek primárně pro začátečníky, budu mluvit o některých bodech, které se jim budou hodit.

Hodně práce při nastavování prostředí se provádí přes příkazový řádek. Většina uživatelů používá Windows jako svůj pracovní OS. Standardní konzole v tomto OS ponechává mnoho přání. Proto použijeme pohodlný nástroj ředitel/. Stáhněte si mini verzi a spusťte Cmder.exe. Dále se musíte připojit k serveru přes SSH:

ssh root@server-ip-or-hostname

Namísto server-ip-or-hostname zadejte IP adresu nebo DNS název vašeho serveru. Dále zadejte heslo a pokud je připojení úspěšné, měli bychom obdržet zprávu podobnou této.

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

Hlavním jazykem pro vývoj ML modelů je Python. A nejoblíbenější platforma pro jeho použití na Linuxu je Anaconda.

Pojďme si to nainstalovat na náš server.

Začneme aktualizací místního správce balíčků:

sudo apt-get update

Nainstalujte curl (utilita příkazového řádku):

sudo apt-get install curl

Stáhněte si nejnovější verzi Anaconda Distribution:

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

Začněme instalaci:

bash Anaconda3-2019.10-Linux-x86_64.sh

Během procesu instalace budete požádáni o potvrzení licenční smlouvy. Po úspěšné instalaci byste měli vidět toto:

Thank you for installing Anaconda3!

Pro vývoj ML modelů bylo nyní vytvořeno mnoho frameworků, pracujeme s těmi nejoblíbenějšími: PyTorch и tenzorový tok.

Použití frameworku umožňuje zvýšit rychlost vývoje a používat hotové nástroje pro standardní úlohy.

V tomto příkladu budeme pracovat s PyTorchem. Pojďme to nainstalovat:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Nyní musíme spustit Jupyter Notebook, oblíbený vývojový nástroj pro specialisty na ML. Umožňuje vám psát kód a okamžitě vidět výsledky jeho provádění. Jupyter Notebook je součástí Anacondy a je již nainstalován na našem serveru. Musíte se k němu připojit z našeho desktopového systému.

Za tímto účelem nejprve spustíme Jupyter na serveru specifikující port 8080:

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

Dále otevřením další záložky v naší Cmder konzoli (horní menu - Dialog Nová konzola) se připojíme přes port 8080 k serveru přes SSH:

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

Když zadáme první příkaz, budou nám nabídnuty odkazy pro otevření Jupyter v našem prohlížeč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žijme odkaz pro localhost:8080. Zkopírujte úplnou cestu a vložte ji do adresního řádku místního prohlížeče vašeho počítače. Jupyter Notebook se otevře.

Vytvořme nový zápisník: Nový – Notebook – Python 3.

Pojďme zkontrolovat správnou funkci všech komponent, které jsme nainstalovali. Zadáme ukázkový kód PyTorch do Jupyter a spustíme provedení (tlačítko Spustit):

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

Výsledek by měl být něco takového:

Vaše první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Pokud máte podobný výsledek, pak jsme vše správně nakonfigurovali a můžeme začít s vývojem neuronové sítě!

Vytvoření neuronové sítě

Vytvoříme neuronovou síť pro rozpoznávání obrazu. Vezměme to jako základ průvodce.

K trénování sítě použijeme veřejně dostupný datový soubor CIFAR10. Má třídy: „letadlo“, „auto“, „pták“, „kočka“, „jelen“, „pes“, „žaba“, „kůň“, „loď“, „náklaďák“. Obrázky v CIFAR10 jsou 3x32x32, tedy 3kanálové barevné obrázky o 32x32 pixelech.

Vaše první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky
Pro práci nám poslouží balík vytvořený PyTorchem pro práci s obrázky - torchvision.

Provedeme následující kroky v pořadí:

  • Načítání a normalizace tréninkových a testovacích datových sad
  • Definice neuronové sítě
  • Síťový trénink na tréninkových datech
  • Testování sítě na testovacích datech
  • Zopakujme si školení a testování pomocí GPU

Veškerý níže uvedený kód spustíme v Jupyter Notebooku.

Načítání a normalizace CIFAR10

Zkopírujte a spusťte následující 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')

Odpověď by měla znít:

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ážeme si několik tréninkových obrázků pro testování:


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še první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Definice neuronové sítě

Nejprve se podívejme, jak funguje neuronová síť pro rozpoznávání obrazu. Jedná se o jednoduchou síť typu point-to-point. Vezme vstupní data, projde je postupně přes několik vrstev a nakonec vytvoří výstupní data.

Vaše první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Vytvořme podobnou síť v našem prostředí:


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 také ztrátovou funkci a optimalizátor


import torch.optim as optim

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

Síťový trénink na tréninkových datech

Začněme trénovat naši neuronovou síť. Vezměte prosím na vědomí, že po spuštění tohoto kódu budete muset nějakou dobu počkat, než bude práce dokončena. Trvalo mi to 5 minut. Trénink sítě 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 následující výsledek:

Vaše první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Náš natrénovaný model ukládáme:

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

Testování sítě na testovacích datech

Trénovali jsme síť pomocí sady tréninkových dat. Musíme ale zkontrolovat, zda se síť vůbec něco naučila.

Otestujeme to tak, že předpovíme označení třídy, které neuronová síť vydává, a otestujeme, zda je pravdivé. Pokud je předpověď správná, přidáme vzorek do seznamu správných předpovědí.
Ukažme si obrázek z testovací 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še první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Nyní požádejme neuronovou síť, aby nám řekla, co je na těchto obrázcích:


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še první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Výsledky vypadají docela dobře: síť správně identifikovala tři ze čtyř obrázků.

Podívejme se, jak si síť vede napříč celým datovým souborem.


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še první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Vypadá to, že síť něco ví a funguje. Pokud by třídy určil náhodně, přesnost by byla 10 %.

Nyní se podívejme, které třídy síť identifikuje lépe:

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še první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Zdá se, že síť je nejlepší v identifikaci aut a lodí: přesnost 71 %.

Takže síť funguje. Nyní zkusme přenést jeho práci na grafický procesor (GPU) a uvidíme, co se změní.

Trénink neuronové sítě na GPU

Nejprve stručně vysvětlím, co je CUDA. CUDA (Compute Unified Device Architecture) je paralelní výpočetní platforma vyvinutá společností NVIDIA pro obecné výpočty na grafických procesorových jednotkách (GPU). S CUDA mohou vývojáři výrazně urychlit výpočetní aplikace využitím výkonu GPU. Tato platforma je již nainstalována na našem serveru, který jsme zakoupili.

Pojďme nejprve definovat naše GPU jako první viditelné zařízení cuda.

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še první neuronová síť na grafickém procesoru (GPU). Průvodce pro začátečníky

Odeslání sítě do GPU:

net.to(device)

Budeme také muset posílat vstupy a cíle v každém kroku do GPU:

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

Pojďme znovu natrénovat síť 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')

Trénink sítě tentokrát trval asi 3 minuty. Připomeňme, že stejná fáze na běžném procesoru trvala 5 minut. Rozdíl není výrazný, děje se tak proto, že naše síť není tak velká. Při použití velkých polí pro trénink se rozdíl mezi rychlostí GPU a tradičního procesoru zvětší.

Zdá se, že to je vše. Co se nám podařilo:

  • Podívali jsme se, co je GPU, a vybrali jsme server, na kterém je nainstalován;
  • Nastavili jsme softwarové prostředí pro vytvoření neuronové sítě;
  • Vytvořili jsme neuronovou síť pro rozpoznávání obrazu a natrénovali jsme ji;
  • Zopakovali jsme síťový trénink pomocí GPU a došlo ke zvýšení rychlosti.

Dotazy rád zodpovím v komentářích.

Zdroj: www.habr.com

Přidat komentář