Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide
I denne artikel vil jeg fortælle dig, hvordan du opsætter et maskinlæringsmiljø på 30 minutter, opretter et neuralt netværk til billedgenkendelse og derefter kører det samme netværk på en grafikprocessor (GPU).

Lad os først definere, hvad et neuralt netværk er.

I vores tilfælde er dette en matematisk model såvel som dens software eller hardware-udførelsesform, bygget på princippet om organisering og funktion af biologiske neurale netværk - netværk af nerveceller i en levende organisme. Dette koncept opstod, mens man studerede de processer, der forekommer i hjernen, og forsøgte at modellere disse processer.

Neurale netværk er ikke programmeret i ordets sædvanlige betydning, de er trænet. Evnen til at lære er en af ​​de vigtigste fordele ved neurale netværk i forhold til traditionelle algoritmer. Teknisk set består læring i at finde koefficienterne for forbindelser mellem neuroner. Under træningsprocessen er det neurale netværk i stand til at identificere komplekse afhængigheder mellem inputdata og outputdata, samt udføre generalisering.

Fra et maskinlæringssynspunkt er et neuralt netværk et særligt tilfælde af mønstergenkendelsesmetoder, diskriminantanalyse, klyngemetoder og andre metoder.

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

Lad os først se på udstyret. Vi har brug for en server med Linux-operativsystemet installeret på den. Det udstyr, der kræves til at betjene maskinlæringssystemer, er ret kraftfuldt og som et resultat dyrt. For dem, der ikke har en god maskine ved hånden, anbefaler jeg at være opmærksom på tilbuddene fra cloud-udbydere. Du kan leje den nødvendige server hurtigt og kun betale for brugstiden.

I projekter, hvor det er nødvendigt at skabe neurale netværk, bruger jeg serverne hos en af ​​de russiske cloud-udbydere. Virksomheden tilbyder cloud-servere til leje specifikt til maskinlæring med kraftfulde Tesla V100-grafikprocessorer (GPU) fra NVIDIA. Kort sagt: Brug af en server med en GPU kan være titusinder gange mere effektiv (hurtig) sammenlignet med en server til lignende omkostninger, der bruger en CPU (den velkendte centralenhed) til beregninger. Dette opnås på grund af funktionerne i GPU-arkitekturen, som klarer beregninger hurtigere.

For at implementere eksemplerne beskrevet nedenfor købte vi følgende server i flere dage:

  • SSD disk 150 GB
  • RAM 32 GB
  • Tesla V100 16 Gb processor med 4 kerner

Vi installerede Ubuntu 18.04 på vores maskine.

Opsætning af miljøet

Lad os nu installere alt det nødvendige for arbejde på serveren. Da vores artikel primært er for begyndere, vil jeg tale om nogle punkter, der vil være nyttige for dem.

Meget af arbejdet, når du opsætter et miljø, udføres via kommandolinjen. De fleste af brugerne bruger Windows som deres fungerende OS. Standardkonsollen i dette OS lader meget tilbage at ønske. Derfor vil vi bruge et praktisk værktøj Cmder/. Download miniversionen og kør Cmder.exe. Dernæst skal du oprette forbindelse til serveren via SSH:

ssh root@server-ip-or-hostname

I stedet for server-ip-eller-værtsnavn skal du angive IP-adressen eller DNS-navnet på din server. Indtast derefter adgangskoden, og hvis forbindelsen er vellykket, skulle vi modtage en meddelelse, der ligner denne.

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

Hovedsproget til udvikling af ML-modeller er Python. Og den mest populære platform til dens brug på Linux er Anaconda.

Lad os installere det på vores server.

Vi starter med at opdatere den lokale pakkehåndtering:

sudo apt-get update

Installer curl (kommandolinjeværktøj):

sudo apt-get install curl

Download den seneste version af Anaconda Distribution:

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

Lad os starte installationen:

bash Anaconda3-2019.10-Linux-x86_64.sh

Under installationsprocessen bliver du bedt om at bekræfte licensaftalen. Efter vellykket installation bør du se dette:

Thank you for installing Anaconda3!

Der er nu skabt mange rammer til udvikling af ML-modeller; vi arbejder med de mest populære: PyTorch и Tensorflow.

Ved at bruge rammen kan du øge udviklingshastigheden og bruge færdige værktøjer til standardopgaver.

I dette eksempel vil vi arbejde med PyTorch. Lad os installere det:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Nu skal vi lancere Jupyter Notebook, et populært udviklingsværktøj for ML-specialister. Det giver dig mulighed for at skrive kode og straks se resultaterne af dens udførelse. Jupyter Notebook er inkluderet med Anaconda og er allerede installeret på vores server. Du skal oprette forbindelse til det fra vores desktop-system.

For at gøre dette vil vi først starte Jupyter på serveren, der angiver port 8080:

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

Dernæst åbner vi en anden fane i vores Cmder-konsol (øverste menu - Ny konsoldialog), og vi forbinder via port 8080 til serveren via SSH:

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

Når vi indtaster den første kommando, vil vi blive tilbudt links til at åbne Jupyter i vores browser:

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

Lad os bruge linket til localhost:8080. Kopier den fulde sti og indsæt den i adresselinjen på din pc's lokale browser. Jupyter Notebook åbnes.

Lad os oprette en ny notesbog: Ny - Notesbog - Python 3.

Lad os kontrollere den korrekte funktion af alle de komponenter, vi installerede. Lad os indtaste PyTorch-eksemplet i Jupyter og køre udførelsen (Kør-knappen):

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

Resultatet skulle være noget som dette:

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Hvis du har et lignende resultat, så har vi konfigureret alt korrekt, og vi kan begynde at udvikle et neuralt netværk!

Oprettelse af et neuralt netværk

Vi vil skabe et neuralt netværk til billedgenkendelse. Lad os tage dette som grundlag lederskab.

Vi vil bruge det offentligt tilgængelige CIFAR10-datasæt til at træne netværket. Det har klasser: "fly", "bil", "fugl", "kat", "hjort", "hund", "frø", "hest", "skib", "lastbil". Billeder i CIFAR10 er 3x32x32, det vil sige 3-kanals farvebilleder på 32x32 pixels.

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide
Til arbejde vil vi bruge pakken oprettet af PyTorch til at arbejde med billeder - torchvision.

Vi udfører følgende trin i rækkefølge:

  • Indlæsning og normalisering af trænings- og testdatasæt
  • Definition af neuralt netværk
  • Netværkstræning om træningsdata
  • Netværkstest på testdata
  • Lad os gentage træning og test med GPU

Vi vil udføre al koden nedenfor i Jupyter Notebook.

Indlæser og normaliserer CIFAR10

Kopier og kør følgende kode i 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')

Svaret burde være:

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

Lad os vise flere træningsbilleder til test:


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

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Definition af neuralt netværk

Lad os først overveje, hvordan et neuralt netværk til billedgenkendelse fungerer. Dette er et simpelt punkt-til-punkt netværk. Den tager inputdata, sender dem gennem flere lag ét efter ét og producerer derefter outputdata.

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Lad os skabe et lignende netværk i vores miljø:


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 definerer også en tabsfunktion og en optimizer


import torch.optim as optim

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

Netværkstræning om træningsdata

Lad os begynde at træne vores neurale netværk. Bemærk venligst, at efter du har kørt denne kode, skal du vente noget tid, indtil arbejdet er afsluttet. Det tog mig 5 minutter. Det tager tid at træne netværket.

 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år følgende resultat:

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Vi gemmer vores trænede model:

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

Netværkstest på testdata

Vi trænede netværket ved hjælp af et sæt træningsdata. Men vi skal tjekke, om netværket overhovedet har lært noget.

Vi vil teste dette ved at forudsige klassemærket, som det neurale netværk udsender, og teste det for at se, om det er sandt. Hvis forudsigelsen er korrekt, tilføjer vi prøven til listen over korrekte forudsigelser.
Lad os vise et billede fra testsættet:

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

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Lad os nu bede det neurale netværk om at fortælle os, hvad der er på disse billeder:


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

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Resultaterne virker ret gode: netværket identificerede tre ud af fire billeder korrekt.

Lad os se, hvordan netværket klarer sig på tværs af hele datasættet.


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

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Det ser ud til, at netværket ved noget og fungerer. Hvis han bestemte klasserne tilfældigt, ville nøjagtigheden være 10%.

Lad os nu se, hvilke klasser netværket identificerer bedst:

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

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Det ser ud til, at netværket er bedst til at identificere biler og skibe: 71 % nøjagtighed.

Så netværket virker. Lad os nu prøve at overføre dets arbejde til grafikprocessoren (GPU) og se, hvad der ændrer sig.

Træning af et neuralt netværk på GPU

Først vil jeg kort forklare, hvad CUDA er. CUDA (Compute Unified Device Architecture) er en parallel computerplatform udviklet af NVIDIA til generel databehandling på grafikprocessorenheder (GPU'er). Med CUDA kan udviklere dramatisk accelerere computerapplikationer ved at udnytte kraften i GPU'er. Denne platform er allerede installeret på vores server, som vi har købt.

Lad os først definere vores GPU som den første synlige cuda-enhed.

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 )

Dit første neurale netværk på en grafikprocessor (GPU). Begynderguide

Sende netværket til GPU'en:

net.to(device)

Vi bliver også nødt til at sende input og mål ved hvert trin til GPU'en:

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

Lad os genoptræne netværket på GPU'en:

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

Denne gang varede netværkstræningen omkring 3 minutter. Lad os huske, at det samme trin på en konventionel processor varede 5 minutter. Forskellen er ikke væsentlig, dette sker fordi vores netværk ikke er så stort. Når du bruger store arrays til træning, vil forskellen mellem hastigheden på GPU'en og en traditionel processor stige.

Det ser ud til at være alt. Hvad vi nåede at gøre:

  • Vi kiggede på, hvad en GPU er, og valgte den server, som den er installeret på;
  • Vi har oprettet et softwaremiljø for at skabe et neuralt netværk;
  • Vi skabte et neuralt netværk til billedgenkendelse og trænede det;
  • Vi gentog netværkstræningen ved hjælp af GPU'en og fik en stigning i hastigheden.

Jeg vil med glæde besvare spørgsmål i kommentarerne.

Kilde: www.habr.com

Tilføj en kommentar