Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas
Tässä artikkelissa kerron sinulle, kuinka määrität koneoppimisympäristön 30 minuutissa, luot hermoverkon kuvantunnistusta varten ja käytän sitten samaa verkkoa grafiikkaprosessorilla (GPU).

Ensin määritellään mikä hermoverkko on.

Meidän tapauksessamme tämä on matemaattinen malli sekä sen ohjelmisto- tai laitteistosuoritusmuoto, joka on rakennettu biologisten hermoverkkojen - elävän organismin hermosoluverkkojen - organisoinnin ja toiminnan periaatteelle. Tämä käsite syntyi, kun tutkittiin aivoissa tapahtuvia prosesseja ja yritettiin mallintaa näitä prosesseja.

Neuraaliverkkoja ei ohjelmoida sanan tavallisessa merkityksessä, vaan niitä koulutetaan. Oppimiskyky on yksi hermoverkkojen tärkeimmistä eduista perinteisiin algoritmeihin verrattuna. Teknisesti oppiminen koostuu neuronien välisten yhteyksien kertoimien löytämisestä. Harjoitteluprosessin aikana hermoverkko pystyy tunnistamaan monimutkaiset riippuvuudet tulo- ja lähtödatan välillä sekä suorittamaan yleistyksen.

Koneoppimisen näkökulmasta hermoverkko on muodontunnistusmenetelmien, erotteluanalyysin, klusterointimenetelmien ja muiden menetelmien erikoistapaus.

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

Ensin katsotaan varusteita. Tarvitsemme palvelimen, johon on asennettu Linux-käyttöjärjestelmä. Koneoppimisjärjestelmien käyttämiseen tarvittavat laitteet ovat varsin tehokkaita ja siksi kalliita. Niille, joilla ei ole hyvää konetta käsillä, suosittelen huomioimaan pilvipalveluntarjoajien tarjoukset. Voit vuokrata tarvitsemasi palvelimen nopeasti ja maksaa vain käyttöajasta.

Projekteissa, joissa on tarpeen luoda hermoverkkoja, käytän yhden venäläisen pilvipalveluntarjoajan palvelimia. Yritys tarjoaa vuokralle pilvipalvelimia erityisesti koneoppimiseen NVIDIA:n tehokkailla Tesla V100 -grafiikkaprosessoreilla (GPU). Lyhyesti: GPU:lla varustetun palvelimen käyttö voi olla kymmeniä kertoja tehokkaampaa (nopeampaa) verrattuna samanhintaiseen palvelimeen, joka käyttää CPU:ta (tuttua keskusyksikköä) laskelmiin. Tämä saavutetaan GPU-arkkitehtuurin ominaisuuksien ansiosta, joka selviää laskelmista nopeammin.

Alla kuvattujen esimerkkien toteuttamiseksi ostimme seuraavan palvelimen useiksi päiviksi:

  • SSD-levy 150GB
  • RAM 32GB
  • Tesla V100 16 Gb prosessori, 4 ydintä

Asensimme Ubuntu 18.04:n koneellemme.

Ympäristön järjestäminen

Asennataan nyt kaikki työhön tarvittava palvelimelle. Koska artikkelimme on tarkoitettu ensisijaisesti aloittelijoille, puhun joistakin kohdista, jotka ovat hyödyllisiä heille.

Suuri osa ympäristön määrittämisestä tehdään komentorivin kautta. Suurin osa käyttäjistä käyttää Windowsia käyttöjärjestelmänä. Tämän käyttöjärjestelmän vakiokonsoli jättää paljon toivomisen varaa. Siksi käytämme kätevää työkalua Cmder/. Lataa miniversio ja suorita Cmder.exe. Seuraavaksi sinun on muodostettava yhteys palvelimeen SSH:n kautta:

ssh root@server-ip-or-hostname

Määritä palvelimen IP-osoite tai isäntänimi sijasta palvelimesi IP-osoite tai DNS-nimi. Syötä seuraavaksi salasana ja jos yhteys onnistuu, meidän pitäisi saada vastaava viesti.

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

Pääkieli ML-mallien kehittämisessä on Python. Ja suosituin alusta sen käyttöön Linuxissa on Anaconda.

Asennataan se palvelimellemme.

Aloitamme päivittämällä paikallisen paketinhallinnan:

sudo apt-get update

Asenna curl (komentorivi-apuohjelma):

sudo apt-get install curl

Lataa uusin versio Anaconda Distributionista:

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

Aloitetaan asennus:

bash Anaconda3-2019.10-Linux-x86_64.sh

Asennuksen aikana sinua pyydetään vahvistamaan lisenssisopimus. Onnistuneen asennuksen jälkeen sinun pitäisi nähdä tämä:

Thank you for installing Anaconda3!

ML-mallien kehittämiseen on nyt luotu monia viitteitä; työskentelemme suosituimpien kanssa: PyTorch и Tensorflow.

Kehyksen avulla voit nopeuttaa kehitystä ja käyttää valmiita työkaluja vakiotehtäviin.

Tässä esimerkissä työskentelemme PyTorchin kanssa. Asennataan se:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Nyt meidän on julkaistava Jupyter Notebook, suosittu kehitystyökalu ML-asiantuntijoille. Sen avulla voit kirjoittaa koodia ja nähdä välittömästi sen suorituksen tulokset. Jupyter Notebook sisältyy Anacondaan ja on jo asennettu palvelimellemme. Sinun on muodostettava siihen yhteys työpöytäjärjestelmästämme.

Tätä varten käynnistämme ensin Jupyterin palvelimella määrittämällä portin 8080:

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

Seuraavaksi avaamalla toisen välilehden Cmder-konsolissa (ylävalikko - Uusi konsoli -valintaikkuna), muodostamme yhteyden portin 8080 kautta palvelimeen SSH:n kautta:

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

Kun annamme ensimmäisen komennon, meille tarjotaan linkkejä Jupyterin avaamiseen selaimessamme:

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

Käytetään linkkiä localhostille:8080. Kopioi koko polku ja liitä se tietokoneesi paikallisen selaimen osoitepalkkiin. Jupyter-muistikirja avautuu.

Luodaan uusi muistikirja: Uusi - Muistikirja - Python 3.

Tarkastetaan kaikkien asentamiemme komponenttien oikea toiminta. Syötetään esimerkki PyTorch-koodi Jupyteriin ja suoritetaan suoritus (Suorita-painike):

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

Tuloksen pitäisi olla jotain tämän kaltaista:

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Jos sinulla on samanlainen tulos, olemme konfiguroineet kaikki oikein ja voimme aloittaa hermoverkon kehittämisen!

Neuroverkon luominen

Luomme hermoverkon kuvantunnistusta varten. Otetaan tämä pohjaksi руководство.

Käytämme julkisesti saatavilla olevaa CIFAR10-tietoaineistoa verkon kouluttamiseen. Siinä on luokat: "lentokone", "auto", "lintu", "kissa", "peura", "koira", "sammakko", "hevonen", "laiva", "kuorma-auto". CIFAR10:n kuvat ovat 3x32x32 eli 3x32 pikselin 32-kanavaisia ​​värikuvia.

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas
Työssä käytämme PyTorchin luomaa pakettia kuvien kanssa työskentelemiseen - torchvision.

Teemme seuraavat vaiheet järjestyksessä:

  • Harjoitus- ja testitietosarjojen lataus ja normalisointi
  • Neuraaliverkon määritelmä
  • Verkkokoulutus koulutustiedoista
  • Verkkotestaus testitiedoilla
  • Toistetaan koulutus ja testaus GPU:lla

Suoritamme kaiken alla olevan koodin Jupyter Notebookissa.

Ladataan ja normalisoidaan CIFAR10

Kopioi ja suorita seuraava koodi Jupyterissa:


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

Vastauksen pitäisi olla:

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

Näytämme useita harjoituskuvia testausta varten:


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

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Neuraaliverkon määritelmä

Mietitään ensin, kuinka kuvantunnistuksen hermoverkko toimii. Tämä on yksinkertainen point-to-point-verkko. Se ottaa syöttödataa, kulkee sen useiden kerrosten läpi yksitellen ja tuottaa lopuksi lähtötiedot.

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Luodaan samanlainen verkosto ympäristöömme:


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äärittelemme myös häviöfunktion ja optimoijan


import torch.optim as optim

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

Verkkokoulutus koulutustiedoista

Aloitetaan neuroverkkomme kouluttaminen. Huomaa, että tämän koodin suorittamisen jälkeen sinun on odotettava jonkin aikaa, ennen kuin työ on valmis. Minulla kesti 5 minuuttia. Verkoston kouluttaminen vie aikaa.

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

Saamme seuraavan tuloksen:

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Tallennamme koulutetun mallimme:

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

Verkkotestaus testitiedoilla

Koulutimme verkkoa harjoitustietojoukon avulla. Mutta meidän on tarkistettava, onko verkko oppinut mitään.

Testaamme tätä ennustamalla hermoverkon tulostaman luokkatunnisteen ja testaamalla, onko se totta. Jos ennuste on oikea, lisäämme otoksen oikeiden ennusteiden luetteloon.
Näytetään kuva testisarjasta:

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

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Pyydetään nyt hermoverkkoa kertomaan, mitä näissä kuvissa on:


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

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Tulokset näyttävät melko hyviltä: verkko tunnisti oikein kolme neljästä kuvasta.

Katsotaan kuinka verkko toimii koko tietojoukossa.


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

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Näyttää siltä, ​​​​että verkko tietää jotain ja toimii. Jos hän määrittäisi luokat satunnaisesti, tarkkuus olisi 10%.

Katsotaan nyt, mitkä luokat verkko tunnistaa paremmin:

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

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Vaikuttaa siltä, ​​että verkosto tunnistaa parhaiten autot ja laivat: 71 %:n tarkkuus.

Verkko siis toimii. Yritetään nyt siirtää sen työ grafiikkasuorittimeen (GPU) ja katsotaan, mikä muuttuu.

Neuroverkon koulutus GPU:lla

Ensin selitän lyhyesti, mitä CUDA on. CUDA (Compute Unified Device Architecture) on NVIDIA:n kehittämä rinnakkaislaskenta-alusta yleiseen laskentaan grafiikkasuoritusyksiköissä (GPU). CUDA:n avulla kehittäjät voivat nopeuttaa laskentasovelluksia dramaattisesti hyödyntämällä grafiikkasuorittimien tehoa. Tämä alusta on jo asennettu palvelimellemme, jonka ostimme.

Määrittelemme ensin GPU:mme ensimmäiseksi näkyväksi Cuda-laitteeksi.

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 )

Ensimmäinen neuroverkkosi grafiikkasuoritusyksikössä (GPU). Aloittelijan opas

Verkon lähettäminen GPU:lle:

net.to(device)

Meidän on myös lähetettävä syötteitä ja tavoitteita jokaisessa vaiheessa GPU:lle:

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

Koulutetaan verkko uudelleen GPU:lla:

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

Tällä kertaa verkkoharjoittelu kesti noin 3 minuuttia. Muistakaamme, että sama vaihe tavallisella prosessorilla kesti 5 minuuttia. Ero ei ole merkittävä, tämä johtuu siitä, että verkostomme ei ole niin laaja. Käytettäessä suuria ryhmiä koulutukseen, GPU:n ja perinteisen prosessorin nopeuden ero kasvaa.

Siinä näyttää olevan kaikki. Mitä onnistuimme tekemään:

  • Tarkastelimme mitä GPU on ja valitsimme palvelimen, jolle se on asennettu;
  • Olemme luoneet ohjelmistoympäristön hermoverkon luomiseksi;
  • Loimme hermoverkon kuvantunnistusta varten ja koulutimme sitä;
  • Toistimme verkkokoulutuksen GPU:lla ja saimme lisäyksen nopeudessa.

Vastaan ​​mielelläni kysymyksiin kommenteissa.

Lähde: will.com

Lisää kommentti