Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend
Selles artiklis rÀÀgin, kuidas 30 minutiga seadistada keskkond masinÔppe jaoks, luua pildituvastamiseks nÀrvivÔrk ja seejÀrel kÀivitada sama vÔrk graafikaprotsessoril (GPU).

Alustame sellega, mis on nÀrvivÔrk.

Meie puhul on see matemaatiline mudel, samuti selle programmiline vĂ”i riistvaraline kehastus, mis on ĂŒles ehitatud bioloogiliste nĂ€rvivĂ”rkude — elusorganismide nĂ€rvirakkude — organisatsiooni ja toimimise printsiipide jĂ€rgi. See mĂ”isted tekkisid aju toimimise uurimise kĂ€igus ja selle protsesside modelleerimise katses.

NĂ€rvivĂ”rke ei programmeerita tavas mĂ”ttes, vaid need Ă”pitakse. Õppimise vĂ”imalus on nĂ€rvivĂ”rkude ĂŒks peamisi eeliseid traditsiooniliste algoritmide ees. Tehniliselt seisneb Ă”ppimine neuronite vaheliste ĂŒhenduste koefitsientide leidmises. Õppeprotsessi kĂ€igus suudab nĂ€rvivĂ”rk tuvastada keerulisi seoseid sissesiandmete ja vĂ€ljundite vahel ning teostada ĂŒldistamist.

MasinĂ”ppe vaatenurgast on nĂ€rvivĂ”rk erijuht tunnustamistuvastuse, diskrimineerimisanalĂŒĂŒsi, klasterdamismeetodite ja muude meetodite osas.

Varustus

Esmalt vaatame varustust. Me vajame serverit, millel on paigaldatud Linuxi operatsioonisĂŒsteem. MasinĂ”ppe sĂŒsteemide tööks vajalik riistvara peab olema piisavalt vĂ”imas ja seega ka kallis. Neile, kes ei saa head masinat kĂ€eulatuses, soovitan pöörata tĂ€helepanu pilveteenuse pakkujate pakkumistele. Vajalikku serverit saab kiiresti rentida ja maksta ainult kasutamise aja eest.

Projektides, kus on vajalik nĂ€rvivĂ”rkude loomine, kasutan ĂŒhe vene pilveteenuse pakkuja servereid. EttevĂ”te pakub masinĂ”ppe jaoks spetsiaalselt tugevaid Tesla V100 graafikaprotsessoreid (GPU) rentimiseks. Ütlen lĂŒhidalt: GPU kasutamine vĂ”ib olla kĂŒmneid kordi tĂ”husam (kiirem) vĂ”rreldes samas hinnaklassis CPU-d (keskprotsessor, millest kĂ”ik on hĂ€sti teadlikud) kasutava serveriga. See saavutatakse GPU arhitektuuri eripĂ€rade tĂ”ttu, mis suudab arvutusi kiiremini teostada.

KÀesolevas nÀites, mis on edaspidi kirjeldatud, ostsime mÔneks pÀevaks jÀrgmise serveri:

  • SSD ketas 150 GB
  • RAM 32 GB
  • Protsessor Tesla V100 16 Gb 4 tuumaga

Meie masinale on installitud Ubuntu 18.04.

Installime keskkonna

NĂŒĂŒd installime serverile kĂ”ik vajalikud tööriistad. Kuna meie artikkel on peamiselt suunatud algajatele, rÀÀgin selles mĂ”ningatest punktidest, mis neile kasulikud on.

Palju tööd keskkonna seadistamisel tehakse kĂ€surea kaudu. Enamik kasutajatest kasutab tööoperatsioonisĂŒsteemina Windowsi. Selle opsĂŒsteemi standardne konsool jĂ€tab soovida. SeetĂ”ttu kasutame mugavat tööriista Cmder/. Laadige alla mini versioon ja kĂ€ivitage Cmder.exe. Edasi tuleb serveriga ĂŒhendada SSH protokolli kaudu:

ssh root@server-ip-or-hostname

Serveri IP-koodi vĂ”i DNS-nime sisestamiseks asendage server-ip-or-hostname. Edasi sisestage parool ja edukal ĂŒhendamisel peaksime saama umbes sellise sĂ”numi.

Tere tulemast Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-74-generic x86_64)

ML mudelite arendamiseks on peamine keel Python. Ja kÔige populaarsem platvorm selle kasutamiseks Linuxi all on Anaconda.

Installime selle meie serverile.

Alustame kohaliku pakihalduri vÀrskendamisega:

sudo apt-get update

Installime curl (kÀsklusprogramm):

sudo apt-get install curl

Laadime alla Anaconda Distributsiooni viimase versiooni:

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

KĂ€ivitame installatsiooni:

bash Anaconda3-2019.10-Linux-x86_64.sh

Installimise kÀigus tuleb nÔustuda litsentsilepinguga. Eduka installimise korral peaksite nÀgema seda:

AitÀh, et installisite Anaconda3!

ML mudelite arendamiseks on loodud palju raamistikku, me töötame kÔige populaarsematega: PyTorch ja Tensorflow.

Raamistiku kasutamine vĂ”imaldab arenduse kiirus kasvada ja kasutada juba olemasolevaid tööriistu standardsete ĂŒlesannete tĂ€itmiseks.

Selles nÀites töötame PyTorchiga. Installime selle:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

NĂŒĂŒd peame kĂ€ivitama Jupyter Notebooki — ML spetsialistide seas populaarse arendustööriista. See vĂ”imaldab kirjutada koodi ja kohe nĂ€ha selle tĂ€itmise tulemusi. Jupyter Notebook on Anaconda osaks ja juba installitud meie serverisse. Peame sellele oma töölauasĂŒsteemist ĂŒhenduma.

Selleks kÀivitame kÔigepealt Jupyter serveris, mÀÀrates pordi 8080:

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

SeejĂ€rel avame meie konsoolis Cmder veel ĂŒhe vahekaart (ĂŒlemine menĂŒĂŒ — New console dialog) ja ĂŒhendame SSH kaudu serveriga pordil 8080:

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

Esimese kÀsu sisestamisel pakutakse meile linke Jupyter'i avamiseks meie brauseris:

Notebooksse pÀÀsemiseks avage see fail brauseris:
        file:///root/.local/share/jupyter/runtime/nbserver-18788-open.html
    VÔi kopeerige ja kleepige mÔni neist URL-idest:
        http://localhost:8080/?token=cca0bd0b30857821194b9018a5394a4ed2322236f116d311
     vÔi http://127.0.0.1:8080/?token=cca0bd0b30857821194b9018a5394a4ed2322236f116d311

Kasutame linki localhost:8080. Kopeerige tÀielik tee ja kleepige see teie PC kohalikku brauseri aadressiribale. Jupyter Notebook avaneb.

Loome uue notepad'i: New — Notebook — Python 3.

Kontrollime, et kÔik installitud komponendid töötavad Ôigesti. Sisestame Jupyterisse PyTorch'i koodi nÀite ja kÀivitame selle (nupp Run):

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

Tulemus peaks olema umbes selline:

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

Kui teil on sarnane tulemus — siis on meil kĂ”ik Ă”igesti seadistatud ja saame alustada nĂ€rvivĂ”rgu arendamist!

Loome nÀrvivÔrgu

Loome nÀrvivÔrgu piltide Àra tundmiseks. Meie aluseks on jÀrgmine juhend.

VĂ”rgu treenimiseks kasutame avalikku CIFAR10 andmekogumit. Sellel on klassid: „lennuk“, „auto“, „lind“, „kass“, „hirv“, „koer“, „konn“, „hobune“, „laev“, „veok“. CIFAR10 pildid on mÔÔtmetega 3x32x32, st kolmekanalilised vĂ€rvilised pildid, mille suurus on 32×32 pikslit.

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend
Töötamiseks kasutame loodud PyTorch'i paketti piltide töötlemiseks — torchvision.

Teeme jÀrgmised sammud jÀrjekorras:

  • Treening- ja testandmete komplektide laadimine ja normaliseerimine
  • NĂ€rvivĂ”rgu mÀÀratlemine
  • VĂ”rgu treenimine koolitusandmetel
  • VĂ”rgu testimine testandmetel
  • Kordame treenimist ja testimist GPU kasutamisega

Kogu allpool toodud koodi tÀidame Jupyter Notebooks.

CIFAR10 laadimine ja normaliseerimine

Kopeerige ja kÀivitage Jupyter'is jÀrgmine kood:


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 = ('lennuk', 'auto', 'lind', ' kass',
           'hirv', 'koer', 'konn', 'hobune', 'laev', 'veok')

Vastus peaks olema jÀrgmine:

Laadimine https:\/\/www.cs.toronto.edu\/~kriz\/cifar-10-python.tar.gz .\/data\/cifar-10-python.tar.gz
Pakkimine .\/data\/cifar-10-python.tar.gz .\/data
Failid on juba alla laaditud ja kontrollitud

Kuvame mÔned treeningpildid kontrollimiseks:


import matplotlib.pyplot as plt
import numpy as np

# funktsioon pildi kuvamiseks

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

# vÔtame mÔned juhuslikud treeningpildid
dataiter = iter(trainloader)
images, labels = dataiter.next()

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

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

NÀrvivÔrgu mÀÀratlemine

Vaadakem kĂ”igepealt, kuidas töötab piltide tuvastamise nĂ€rvivĂ”rk. See on lihtne otseĂŒhenduste vĂ”rk. See vĂ”tab sisendi, edastab selle lĂ€bi mitme kihi jĂ€rjestikku ja seejĂ€rel annab lĂ”puks vĂ€ljundi.

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

Loome meie keskkonnas sarnase vÔrgu:


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()

MÀÀrame ka kaotuse funktsiooni ja optimeerija


import torch.optim as optim

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

VÔrgu treenimine koolitusandmetel

Alustame meie nÀrvivÔrgu treeningut. TÔin vÀlja, et pÀrast koodi kÀivitamist peate ootama mÔnda aega, kuni see lÔpule jÔuab. Minu jaoks vÔttis see 5 minutit. VÔrgu treenimiseks on vajalik aeg.

 kuni aeg, kui vahemik on 2: # kordame andmeid mitu korda

 jooksva_kadu = 0.0
 kÔigi, andmete_hulgad in enumerate(trainloader, 0):
 # saame sisendid; andmed on loend [sisendid, sildid]
 sisendid, sildid = andmed

 # nullime parameetrite gradandid
 optimizer.zero_grad()

 # edasi + tagasi + optimeeri
 vÀljundid = net(sisendid)
 kadumine = criterion(vÀljundid, sildid)
 kadumine.backward()
 optimizer.step()

 # trĂŒki statistika
 jooksva_kadu += kadumine.item()
 kui i % 2000 == 1999: # prindi vÀlja iga 2000 mini-batch'ide kohta
 print('[%d, ] kadumine: %.3f' %
 (aeg + 1, i + 1, jooksva_kadu / 2000))
 jooksva_kadu = 0.0

print('Koolitus lÔpetatud')

Saame sellise tulemuse:

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

Salvestame meie koolitatud mudeli:

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

VÔrgu testimine testandmetel

Olemegi koolitanud vĂ”rku, kasutades koolitusandmete kogumit. Kuid peame kontrollima, kas vĂ”rku on ĂŒldse midagi Ă”petatud.

Kontrollime seda, ennustades klassi sildi, mis vÀljundit annab nÀrvivÔrk, ja kontrollides seda tÔe suhtes. Kui ennustus on Ôige, lisame nÀite Ôigete ennustuste loendisse.
Kujutame ette pilti testimiskogust:

dataiter = iter(testloader)
pildid, sildid = dataiter.next()

# trĂŒki pildid
imshow(torchvision.utils.make_grid(pildid))
print('TÔeline tÔde: ', ' '.join('%5s' % klassid[sildid[j]] for j in range(4)))

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

NĂŒĂŒd palume nĂ€rvivĂ”rgul öelda meile, mis nende piltide peal on:


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

vÀljundid = net(pildid)

_, ennustatud = torch.max(vÀljundid, 1)

print('Ennustatud: ', ' '.join('%5s' % klassid[ennustatud[j]]
                              for j in range(4)))

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

Tulemused nĂ€ivad ĂŒsna head: vĂ”rk tuvastas Ă”igesti kolm pilti neljast.

Vaatame, kuidas vÔrku töötab kogu andmekogumiga.


Ôige = 0
total = 0
with torch.no_grad():
    for andmed in testloader:
        pildid, sildid = andmed
        vÀljundid = net(pildid)
        _, ennustatud = torch.max(vÀljundid.data, 1)
        total += sildid.size(0)
        Ôige += (ennustatud == sildid).sum().item()

print('VÔrgu tÀpsus 10000 testpildil: %d %%' % (
    100 * Ôige / total))

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

Tundub, et vÔrk teab midagi ja töötab. Kui ta mÀÀraks klassid juhuslikult, oleks tÀpsus 10%.

NĂŒĂŒd vaatame, milliseid klasse vĂ”rk paremini mÀÀrab:

klass_oige = list(0. for i in range(10))
klass_kokku = list(0. for i in range(10))
with torch.no_grad():
 for andmed in testloader:
 pildid, sildid = andmed
 vÀljundid = net(pildid)
 _, ennustanud = torch.max(vÀljundid, 1)
 c = (ennustanud == sildid).squeeze()
 for i in range(4):
 silt = sildid[i]
 klass_oige[silt] += c[i].item()
 klass_kokku[silt] += 1


for i in range(10):
 print('TĂ€psus %5s : %%' % (
 klassid[i], 100 * klass_oige[i] / klass_kokku[i]))

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

Tundub, et vÔrk mÀÀrab kÔige paremini autosid ja laevu: 71% tÀpsus.

Nii et vĂ”rk töötab. NĂŒĂŒd proovime viia selle töö graafikakaardile (GPU) ja vaatame, mis muutub.

NÀrvivÔrgu treenimine GPU-l

Esialgu selgitan lĂŒhidalt, mis on CUDA. CUDA (Compute Unified Device Architecture) on NVIDIA loodud paralleelsete arvutuste platvorm ĂŒldiseks arvutamiseks graafikaprotsessoritel (GPU-del). CUDA abil saavad arendajad mĂ€rkimisvÀÀrselt kiirendada arvutusrakendusi, kasutades grafikaeidmise protsessorite vĂ”imet. Meie ostetud serveris on see platvorm juba paigaldatud.

Alustame meie GPU mÀÀratlemisega kui esimesest nÀhtavast cuda seadmetest.

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# Eeldades, et oleme CUDA masinas, peaks see printima CUDA seadme:
print(device)

Teie esimene nÀrvivÔrk graafikaprotsessoril (GPU). Algajatele mÔeldud juhend

Saadetame vÔrgustiku GPU-le:

net.to(device)

Peame samuti saadetama sisendid ja sihid igal sammul GPU-le:

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

KÀivitame vÔrgu uuestiÔppimise juba GPU-l:

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
for aeg in range(2): # kordame andmeid mitu korda

 jooksva_kadu = 0.0
 for i, andmed in enumerate(trainloader, 0):
 # saame sisendid; andmed on loend [sisendid, sildid]
 sisendid, sildid = andmed[0].to(device), andmed[1].to(device)

 # nullime parameetrite gradandid
 optimizer.zero_grad()

 # edasi + tagasi + optimeeri
 vÀljundid = net(sisendid)
 kadumine = criterion(vÀljundid, sildid)
 kadumine.backward()
 optimizer.step()

 # trĂŒki statistika
 jooksva_kadu += kadumine.item()
 kui i % 2000 == 1999: # prindi vÀlja iga 2000 mini-batch'ide kohta
 print('[%d, ] kadumine: %.3f' %
 (aeg + 1, i + 1, jooksva_kadu / 2000))
 jooksva_kadu = 0.0

print('Koolitus lÔpetatud')

Seekord kestis vÔrgu Ôpetamine umbes 3 minutit. Kinnitatakse, et sama etapp tavalisel protsessoril kestis 5 minutit. Erinevus pole oluline, see toimub seetÔttu, et meie vÔrk ei ole nii suur. Suurte andmekogumite kasutamisel suureneb erinevus GPU ja traditsioonilise protsessori töökiirusel.

Tundub, et see on kÔik. Mida me saavutasime:

  • Me uurisime, mis on GPU ja valisime serveri, millel see on paigaldatud;
  • Me seadsime ĂŒles programmikeskkonna nĂ€rvivĂ”rgu loomiseks;
  • Me tegime nĂ€rvivĂ”rgu piltide tuvastamiseks ja koolitasime seda;
  • Me kordasime vĂ”rgu Ă”petamist GPU abil ja saime kiirusetĂ”usu.

Olen valmis vastama kĂŒsimustele kommentaarides.

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster