Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur
Í þessari grein mun ég segja þér hvernig á að setja upp vélnámsumhverfi á 30 mínútum, búa til tauganet fyrir myndgreiningu og keyra síðan sama netið á grafískum örgjörva (GPU).

Í fyrsta lagi skulum við skilgreina hvað tauganet er.

Í okkar tilviki er þetta stærðfræðilegt líkan, sem og útfærsla hugbúnaðar eða vélbúnaðar, byggt á meginreglunni um skipulag og virkni líffræðilegra tauganeta - net taugafrumna lifandi lífveru. Þetta hugtak kom upp þegar rannsakað var ferlana sem eiga sér stað í heilanum og reynt að móta þessa ferla.

Taugakerfi eru ekki forrituð í venjulegum skilningi þess orðs, þau eru þjálfuð. Hæfni til að læra er einn helsti kostur tauganeta umfram hefðbundin reiknirit. Tæknilega séð felst nám í því að finna tengingarstuðla milli taugafrumna. Meðan á þjálfunarferlinu stendur getur tauganetið greint flóknar ósjálfstæði milli inntaksgagna og úttaksgagna, auk þess að framkvæma alhæfingu.

Frá sjónarhóli vélanáms er tauganet sérstakt tilfelli af mynsturgreiningaraðferðum, aðgreiningargreiningu, klasaaðferðum og öðrum aðferðum.

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

Fyrst skulum við skoða búnaðinn. Okkur vantar netþjón með Linux stýrikerfinu uppsett á honum. Búnaðurinn sem þarf til að reka vélanámskerfi er nokkuð öflugur og þar af leiðandi dýr. Fyrir þá sem eru ekki með góða vél við höndina mæli ég með að fylgjast með tilboðum skýjaveitna. Þú getur leigt nauðsynlegan netþjón fljótt og borgað aðeins fyrir notkunartímann.

Í verkefnum þar sem nauðsynlegt er að búa til taugakerfi nota ég netþjóna eins af rússnesku skýjaveitunum. Fyrirtækið býður skýjaþjóna til leigu sérstaklega fyrir vélanám með öflugum Tesla V100 grafíkörgjum (GPU) frá NVIDIA. Í stuttu máli: að nota netþjón með GPU getur verið tugfalt skilvirkari (hraðvirkari) samanborið við miðlara með svipaðan kostnað sem notar CPU (vel þekkta miðvinnslueininguna) til útreikninga. Þetta er náð vegna eiginleika GPU arkitektúrsins, sem tekst á við útreikninga hraðar.

Til að útfæra dæmin sem lýst er hér að neðan keyptum við eftirfarandi netþjón í nokkra daga:

  • SSD diskur 150 GB
  • Vinnsluminni 32 GB
  • Tesla V100 16 Gb örgjörvi með 4 kjarna

Við settum upp Ubuntu 18.04 á vélinni okkar.

Að setja upp umhverfið

Nú skulum við setja upp allt sem þarf til að vinna á þjóninum. Þar sem greinin okkar er fyrst og fremst fyrir byrjendur mun ég tala um nokkur atriði sem munu nýtast þeim.

Mikið af vinnunni við að setja upp umhverfi fer fram í gegnum skipanalínuna. Flestir notendur nota Windows sem vinnustýrikerfi. Staðlaða stjórnborðið í þessu stýrikerfi skilur eftir sig miklu. Þess vegna munum við nota þægilegt tól Cmdder/. Sæktu smáútgáfuna og keyrðu Cmder.exe. Næst þarftu að tengjast þjóninum í gegnum SSH:

ssh root@server-ip-or-hostname

Í stað netþjóns-ip-eða-hýsingarheiti skaltu tilgreina IP-tölu eða DNS-nafn netþjónsins þíns. Næst skaltu slá inn lykilorðið og ef tengingin gengur vel ættum við að fá skilaboð sem líkjast þessu.

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

Aðaltungumálið til að þróa ML módel er Python. Og vinsælasti vettvangurinn til notkunar á Linux er Anaconda.

Við skulum setja það upp á netþjóninum okkar.

Við byrjum á því að uppfæra staðbundna pakkastjórann:

sudo apt-get update

Settu upp krulla (skipanalínuforrit):

sudo apt-get install curl

Sæktu nýjustu útgáfuna af Anaconda Distribution:

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

Við skulum hefja uppsetninguna:

bash Anaconda3-2019.10-Linux-x86_64.sh

Meðan á uppsetningarferlinu stendur verður þú beðinn um að staðfesta leyfissamninginn. Eftir vel heppnaða uppsetningu ættirðu að sjá þetta:

Thank you for installing Anaconda3!

Margir rammar hafa nú verið búnir til fyrir þróun ML líkana; við vinnum með vinsælustu: PyTorch и Tensorflæði.

Notkun ramma gerir þér kleift að auka hraða þróunar og nota tilbúin verkfæri fyrir staðlað verkefni.

Í þessu dæmi munum við vinna með PyTorch. Við skulum setja það upp:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Nú þurfum við að setja Jupyter Notebook á markað, vinsælt þróunartæki fyrir ML sérfræðinga. Það gerir þér kleift að skrifa kóða og sjá strax niðurstöður framkvæmdar hans. Jupyter Notebook fylgir Anaconda og er þegar uppsett á netþjóninum okkar. Þú þarft að tengjast því frá skjáborðskerfinu okkar.

Til að gera þetta munum við fyrst ræsa Jupyter á þjóninum sem tilgreinir höfn 8080:

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

Næst, opnaðu annan flipa í Cmder stjórnborðinu okkar (efri valmynd - Ný stjórnborðsgluggi) við munum tengjast í gegnum port 8080 við netþjóninn í gegnum SSH:

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

Þegar við slærð inn fyrstu skipunina mun okkur bjóðast tenglar til að opna Jupyter í vafranum okkar:

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

Notum hlekkinn fyrir localhost:8080. Afritaðu alla leiðina og límdu hana inn í veffangastikuna í staðbundnum vafra tölvunnar þinnar. Jupyter Notebook opnast.

Búum til nýja fartölvu: Nýtt - Minnisbók - Python 3.

Við skulum athuga rétta virkni allra íhluta sem við settum upp. Við skulum slá inn dæmi PyTorch kóðann í Jupyter og keyra framkvæmdina (Run hnappur):

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

Útkoman ætti að vera eitthvað á þessa leið:

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Ef þú hefur svipaða niðurstöðu, þá höfum við stillt allt rétt og við getum byrjað að þróa taugakerfi!

Að búa til taugakerfi

Við munum búa til tauganet fyrir myndgreiningu. Við skulum leggja þetta til grundvallar forystu.

Við munum nota opinberlega aðgengilega CIFAR10 gagnasafnið til að þjálfa netið. Það hefur flokka: "flugvél", "bíll", "fugl", "köttur", "dádýr", "hundur", "froskur", "hestur", "skip", "vörubíll". Myndir í CIFAR10 eru 3x32x32, það er 3-rása litmyndir með 32x32 pixlum.

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur
Fyrir vinnu munum við nota pakkann sem PyTorch bjó til til að vinna með myndir - torchvision.

Við munum gera eftirfarandi skref í röð:

  • Hleðsla og staðlað þjálfunar- og prófunargagnasett
  • Skilgreining á tauganeti
  • Netþjálfun á þjálfunargögnum
  • Netprófun á prófunargögnum
  • Við skulum endurtaka þjálfun og prófanir með því að nota GPU

Við munum keyra allan kóðann hér að neðan í Jupyter Notebook.

Hleður og staðlar CIFAR10

Afritaðu og keyrðu eftirfarandi kóða í 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')

Svarið ætti að vera:

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

Sýnum nokkrar þjálfunarmyndir til að prófa:


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

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Skilgreining á tauganeti

Við skulum fyrst íhuga hvernig taugakerfi fyrir myndgreiningu virkar. Þetta er einfalt punkt-til-punkt net. Það tekur inntaksgögn, fer í gegnum nokkur lög eitt af öðru og framleiðir síðan að lokum úttaksgögn.

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Búum til svipað net í umhverfi okkar:


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

Við skilgreinum einnig tapaðgerð og fínstillingu


import torch.optim as optim

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

Netþjálfun á þjálfunargögnum

Byrjum að þjálfa tauganetið okkar. Vinsamlegast athugaðu að eftir að þú keyrir þennan kóða þarftu að bíða í nokkurn tíma þar til verkinu er lokið. Það tók mig 5 mínútur. Það tekur tíma að þjálfa netið.

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

Við fáum eftirfarandi niðurstöðu:

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Við vistum þjálfað líkan okkar:

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

Netprófun á prófunargögnum

Við þjálfuðum netið með því að nota safn af þjálfunargögnum. En við þurfum að athuga hvort netið hafi lært eitthvað.

Við munum prófa þetta með því að spá fyrir um flokkamerkið sem tauganetið gefur frá sér og prófa það til að sjá hvort það sé satt. Ef spáin er rétt bætum við sýnishorninu á listann yfir réttar spár.
Sýnum mynd úr prófunarsettinu:

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

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Nú skulum við biðja taugakerfið að segja okkur hvað er á þessum myndum:


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

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Niðurstöðurnar virðast nokkuð góðar: netið benti rétt á þrjár af fjórum myndum.

Við skulum sjá hvernig netið virkar í öllu gagnasafninu.


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

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Það lítur út fyrir að netið viti eitthvað og sé að virka. Ef hann ákvarði flokkana af handahófi væri nákvæmnin 10%.

Nú skulum við sjá hvaða flokka netið auðkennir betur:

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

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Svo virðist sem netið sé best við að bera kennsl á bíla og skip: 71% nákvæmni.

Þannig að netið virkar. Nú skulum við reyna að flytja verk þess yfir á grafískan örgjörva (GPU) og sjá hvað breytist.

Þjálfa taugakerfi á GPU

Fyrst mun ég útskýra stuttlega hvað CUDA er. CUDA (Compute Unified Device Architecture) er samhliða tölvuvettvangur þróaður af NVIDIA fyrir almenna tölvuvinnslu á grafískum vinnslueiningum (GPU). Með CUDA geta verktaki hraðað verulega tölvuforritum með því að nýta kraftinn í GPU. Þessi vettvangur er þegar uppsettur á netþjóninum okkar sem við keyptum.

Við skulum fyrst skilgreina GPU okkar sem fyrsta sýnilega cuda tækið.

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 )

Fyrsta tauganetið þitt á grafískri vinnslueiningu (GPU). Leiðbeiningar fyrir byrjendur

Að senda netið í GPU:

net.to(device)

Við verðum líka að senda inntak og markmið í hverju skrefi til GPU:

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

Við skulum endurþjálfa netið á 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')

Að þessu sinni tók netþjálfunin um 3 mínútur. Við skulum muna að sama stig á hefðbundnum örgjörva stóð í 5 mínútur. Munurinn er ekki marktækur, þetta gerist vegna þess að netið okkar er ekki svo stórt. Þegar stór fylki eru notuð til þjálfunar mun munurinn á hraða GPU og hefðbundins örgjörva aukast.

Það virðist vera allt. Það sem okkur tókst að gera:

  • Við skoðuðum hvað GPU er og völdum netþjóninn sem hann er settur upp á;
  • Við höfum sett upp hugbúnaðarumhverfi til að búa til taugakerfi;
  • Við bjuggum til tauganet fyrir myndgreiningu og þjálfuðum það;
  • Við endurtókum netþjálfunina með því að nota GPU og fengum aukinn hraða.

Ég mun gjarnan svara spurningum í athugasemdunum.

Heimild: www.habr.com

Bæta við athugasemd