Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide
I denna artikel kommer jag att förklara hur du pÄ 30 minuter kan stÀlla in en miljö för maskininlÀrning, skapa ett neuralt nÀtverk för bildigenkÀnning och sedan köra samma nÀtverk pÄ en grafisk processor (GPU).

LÄt oss först definiera vad ett neuralt nÀtverk Àr.

I vĂ„rt fall Ă€r det en matematisk modell samt dess program- eller hĂ„rdvaruimplementation, uppbyggd enligt principerna för organisation och funktion av biologiska neurala nĂ€tverk — nĂ€tverk av nervceller i en levande organism. Detta begrepp uppstod vid studiet av processer i hjĂ€rnan och i ett försök att modellera dessa processer.

Neurala nÀtverk programmeras inte pÄ det traditionella sÀttet, de trÀnas. Möjligheten att trÀna Àr en av de största fördelarna med neurala nÀtverk jÀmfört med traditionella algoritmer. Tekniskt sett innebÀr trÀning att hitta vikterna pÄ kopplingarna mellan neuroner. Under trÀningsprocessen kan det neurala nÀtverket identifiera komplexa beroenden mellan ingÄngs- och utgÄngsdata, samt utföra generalisering.

Ur ett maskininlÀrningsperspektiv Àr ett neuralt nÀtverk ett specifikt fall av mönsterigenkÀnning, diskriminantanalyser, klusteranalysmetoder och andra metoder.

Utrustning

Först lÄt oss gÄ igenom hÄrdvaran. Vi behöver en server med ett installerat operativsystem Linux. HÄrdvaran för maskininlÀrningssystem behöver vara tillrÀckligt kraftfull och dÀrmed dyr. För dem som inte har en bra dator tillgÀnglig rekommenderar jag att titta pÄ erbjudanden frÄn molnleverantörer. Den behövda servern kan snabbt hyras och man betalar bara för den tid som anvÀnds.

I projekt dÀr det krÀvs skapande av neurala nÀtverk anvÀnder jag servrar frÄn en av de ryska molnleverantörerna. Företaget erbjuder molnservrar speciellt för maskininlÀrning med kraftfulla grafiska processorer (GPU) Tesla V100 frÄn NVIDIA. Kort sagt: anvÀndning av en server med GPU kan vara tiotals gÄnger mer effektiv (snabb) jÀmfört med en motsvarande server dÀr berÀkningar görs av en CPU (den vÀlkÀnda centrala processorn). Detta uppnÄs tack vare sÀrskild arkitektur för GPU, som snabbare hanterar berÀkningar.

För att genomföra exemplen som beskrivs nedan har vi hyrt en sÄdan server i nÄgra dagar:

  • SSD-disk 150 GB
  • RAM 32 GB
  • Processor Tesla V100 16 Gb med 4 kĂ€rnor

PĂ„ maskinen installerades Ubuntu 18.04.

Installerar miljön

Nu ska vi installera allt som behövs för att arbeta pÄ servern. Eftersom vÄr artikel framför allt Àr för nybörjare, kommer jag att prata om nÄgra punkter som kommer att vara anvÀndbara för dem.

Mycket av arbetet nÀr man konfigurerar miljön görs via kommandoraden. De flesta anvÀndare anvÀnder Windows som arbets-OS. Standardkonsolen i detta operativsystem lÀmnar mycket att önska. DÀrför kommer vi att anvÀnda ett bekvÀmt verktyg Cmder/. Ladda ner mini-versionen och starta Cmder.exe. DÀrefter mÄste vi koppla upp oss mot servern via SSH-protokollet:

ssh root@server-ip-or-hostname

I stÀllet för server-ip-or-hostname anger du IP-adressen eller DNS-namnet pÄ din server. Skriv sedan in ditt lösenord, och vid en lyckad anslutning bör vi fÄ nÄgot liknande detta meddelande.

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

Det frÀmsta sprÄket för att utveckla ML-modeller Àr Python. Den mest populÀra plattformen för dess anvÀndning pÄ Linux Àr Anaconda.

LÄt oss installera det pÄ vÄr server.

Vi börjar med att uppdatera den lokala paketchefen:

sudo apt-get update

Installerar curl (kommandoradsverktyg):

sudo apt-get install curl

Laddar ner den senaste versionen av Anaconda Distribution:

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

Startar installationen:

bash Anaconda3-2019.10-Linux-x86_64.sh

Under installationen behöver du bekrÀfta licensavtalet. Vid en lyckad installation bör du se detta:

Thank you for installing Anaconda3!

För utveckling av ML-modeller finns det nu ett antal ramverk tillgÀngliga, vi arbetar med de mest populÀra: PyTorch och Tensorflow.

AnvÀndningen av ramverket gör det möjligt att öka hastigheten pÄ utvecklingen och anvÀnda redan fÀrdiga verktyg för standarduppgifter.

I det hÀr exemplet kommer vi att arbeta med PyTorch. Vi installerar det:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Nu behöver vi starta Jupyter Notebook — ett populĂ€rt utvecklingsverktyg för ML-specialister. Det gör att du kan skriva kod och omedelbart se resultaten av dess körning. Jupyter Notebook ingĂ„r i Anaconda och Ă€r redan installerad pĂ„ vĂ„r server. Vi behöver ansluta till den frĂ„n vĂ„rt skrivbordssystem.

För att göra detta först startar vi Jupyter pÄ servern och anger port 8080:

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

DĂ€refter öppnar vi en ny flik i vĂ„r konsol Cmder (övre menyn — New console dialog) och ansluter till servern via SSH pĂ„ port 8080:

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

NÀr vi anger den första kommandot kommer vi att erbjudas lÀnkar för att öppna Jupyter i vÄr webblÀsare:

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

Vi anvÀnder lÀnken för localhost:8080. Kopiera den fullstÀndiga sökvÀgen och klistra in den i adressfÀltet i din lokala webblÀsare. Jupyter Notebook öppnas.

Vi skapar en ny notebook: New — Notebook — Python 3.

Vi kontrollerar att alla komponenter vi har installerat fungerar korrekt. Vi skriver in ett exempel pÄ PyTorch-kod i Jupyter och kör det (knapp: Run):

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

Resultatet bör se ungefÀr ut sÄ hÀr:

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

Om du fÄr ett liknande resultat har vi konfigurerat allt korrekt och kan börja utveckla ett neuralt nÀtverk!

Vi skapar ett neuralt nÀtverk

Vi kommer att skapa ett neuralt nÀtverk för bildigenkÀnning. Vi tar detta som utgÄngspunkt en guide.

För trĂ€ning av nĂ€tverket kommer vi att anvĂ€nda den offentliga datamĂ€ngden CIFAR10. Den har klasser: "flygplan", "bil", "fĂ„gel", "katt", "hjort", "hund", "groda", "hĂ€st", "skepp", "lastbil". Bilderna i CIFAR10 har storleken 3x32x32, det vill sĂ€ga 3-kanaliga fĂ€rgbilder med storleken 32×32 pixlar.

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide
För vĂ„rt arbete kommer vi att anvĂ€nda den skapade PyTorch-paketet för bildbehandling — torchvision.

Vi kommer att genomföra följande steg i ordning:

  • Nedladdning och normalisering av trĂ€ningsoch testdatamĂ€ngder
  • Definiera det neuronala nĂ€tverket
  • TrĂ€na nĂ€tverket pĂ„ trĂ€ningsdata
  • Testa nĂ€tverket med testdata
  • Vi upprepar trĂ€ningen och testningen med hjĂ€lp av GPU

All kod nedan kommer vi att köra i Jupyter Notebook.

Nedladdning och normalisering av CIFAR10

Kopiera och kör följande kod 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 ska se ut sÄ hÀr:

Nedladdning av https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz till ./data/cifar-10-python.tar.gz
Extrahering av ./data/cifar-10-python.tar.gz till ./data
Filer har redan laddats ner och verifierats

Vi kommer att visa nÄgra trÀningsbilder för verifiering:


import matplotlib.pyplot as plt
import numpy as np

# funktioner för att visa en bild

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

# hÀmta nÄgra slumpmÀssiga trÀningsbilder
dataiter = iter(trainloader)
images, labels = dataiter.next()

# visa bilder
imshow(torchvision.utils.make_grid(images))
# skriv ut etiketter
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

Definiera det neuronala nÀtverket

Vi börjar med att se hur ett neuralt nÀtverk för bildigenkÀnning fungerar. Det Àr ett enkelt feedforward-nÀtverk. Det tar indata, skickar dem genom flera lager ett efter ett och ger slutligen utdata.

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

LÄt oss skapa ett liknande nÀtverk i vÄr 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 definierar ocksÄ en förlustfunktion och en optimizer


import torch.optim as optim

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

TrÀna nÀtverket pÄ trÀningsdata

Vi börjar trÀningen av vÄrt neurala nÀtverk. Jag vill pÄpeka att efter att du kör den hÀr koden, mÄste du vÀnta en stund tills den Àr klar. Det tog mig 5 minuter. Att trÀna nÀtverket tar tid.

 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öljande resultat:

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

Sparar vÄr trÀnade modell:

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

Testa nÀtverket med testdata

Vi har trÀnat nÀtverket med hjÀlp av trÀningsdata. Men vi mÄste kontrollera om nÀtverket faktiskt har lÀrt sig nÄgot.

Vi kommer att kontrollera detta genom att förutsÀga klassens etikett som det neurala nÀtverket ger och kontrollera den mot den verkliga etiketten. Om förutsÀgelsen Àr korrekt lÀgger vi till exemplet i listan över korrekta förutsÀgelser.
LÄt oss visa en bild frÄn testdatasetet:

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

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

Nu ber vi det neurala nÀtverket att berÀtta för oss vad som finns pÄ dessa bilder:


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

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

Resultaten verkar ganska bra: nÀtverket identifierade tre bilder korrekt av fyra.

LÄt oss se hur nÀtverket presterar pÄ hela datasetet.


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

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

Det verkar som om nÀtverket vet nÄgot och fungerar. Om det hade klassificerat pÄ ett slumpmÀssigt sÀtt skulle noggrannheten vara 10%.

LÄt oss nu se vilka klasser nÀtverket identifierar bÀst:

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

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

Det verkar som att nÀtverket mest korrekt identifierar bilar och fartyg: 71% noggrannhet.

SÄ nÀtverket fungerar. Nu ska vi försöka köra det pÄ en grafisk processor (GPU) och se vad som förÀndras.

TrÀning av neuronnÀt pÄ GPU

Först ska jag kort förklara vad CUDA Ă€r. CUDA (Compute Unified Device Architecture) — en plattform för parallella berĂ€kningar, utvecklad av NVIDIA, för allmĂ€nna berĂ€kningar pĂ„ grafiska processorer (GPU). Med CUDA kan utvecklare avsevĂ€rt snabba upp berĂ€kningsapplikationer genom att utnyttja grafiska processorer. PĂ„ vĂ„r server, som vi har köpt, Ă€r denna plattform redan installerad.

LÄt oss först definiera vÄr GPU som den första synliga CUDA-enheten.

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# Anta att vi Àr pÄ en CUDA-maskin, detta bör skriva ut en CUDA-enhet:
print(device)

Din första neurala nÀtverk pÄ en grafisk processor (GPU). En nybörjarguide

Skickar nÀtverket till GPU:

net.to(device)

Vi mÄste ocksÄ skicka indata och mÄl vid varje steg till GPU:

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

LÄt oss trÀna nÀtverket igen, denna gÄng pÄ 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')

Denna gÄng var nÀtverkets trÀningade tid ungefÀr 3 minuter. Kom ihÄg att samma steg pÄ en vanlig processor tog 5 minuter. Skillnaden Àr inte betydande, och det beror pÄ att vÄrt nÀtverk inte Àr sÄ stort. NÀr vi anvÀnder större datamÀngder för trÀning kommer skillnaden i hastighet mellan GPU och traditionell processor att öka.

Det verkar som att vi har kommit till slutet. Vad vi lyckades Ästadkomma:

  • Vi gick igenom vad en GPU Ă€r och valde en server dĂ€r den Ă€r installerad;
  • Vi stĂ€llde in den programmiljö som krĂ€vs för att skapa ett neuronnĂ€t;
  • Vi skapade ett neuronnĂ€t för bildigenkĂ€nning och trĂ€nade det;
  • Vi upprepade trĂ€ningen av nĂ€tverket med hjĂ€lp av GPU och fick en hastighetsförbĂ€ttring.

Jag ser fram emot att svara pÄ frÄgor i kommentarerna.

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster