Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide
Yn dit artikel sil ik jo fertelle hoe't jo in masine-learomjouwing yn 30 minuten kinne ynstelle, in neuraal netwurk meitsje foar ôfbyldingsherkenning, en dan itselde netwurk útfiere op in grafyske prosessor (GPU).

Litte wy earst definiearje wat in neural netwurk is.

Yn ús gefal, dit is in wiskundige model, likegoed as syn software of hardware belichaming, boud op it prinsipe fan organisaasje en funksjonearjen fan biologyske neuronale netwurken - netwurken fan senuwsellen fan in libbene organisme. Dit konsept ûntstie by it bestudearjen fan de prosessen dy't foarkomme yn 'e harsens en besykje dizze prosessen te modellearjen.

Neurale netwurken binne net programmearre yn 'e gewoane sin fan it wurd, se wurde oplaat. De mooglikheid om te learen is ien fan 'e wichtichste foardielen fan neurale netwurken boppe tradisjonele algoritmen. Technysk bestiet learen út it finen fan de koeffizienten fan ferbiningen tusken neuroanen. Tidens it trainingsproses is it neurale netwurk yn steat om komplekse ôfhinklikens te identifisearjen tusken ynfiergegevens en útfiergegevens, en ek generalisaasje útfiere.

Fanút it eachpunt fan masine learen is in neural netwurk in spesjaal gefal fan metoaden foar patroanherkenning, diskriminearjende analyze, klusteringmetoaden en oare metoaden.

Wetter - Agrarwetter

Litte wy earst nei de apparatuer sjen. Wy hawwe in tsjinner nedich mei it Linux-bestjoeringssysteem derop ynstalleare. De apparatuer dy't nedich is om masine-learsystemen te betsjinjen is frij krêftich en, as gefolch, djoer. Foar dyjingen dy't gjin goede masine by de hân hawwe, advisearje ik omtinken te jaan oan de oanbiedingen fan wolkproviders. Jo kinne de fereaske tsjinner fluch hiere en allinich betelje foar de tiid fan gebrûk.

Yn projekten wêr't it nedich is om neurale netwurken te meitsjen, brûk ik de servers fan ien fan 'e Russyske wolkproviders. It bedriuw biedt wolkservers te hier spesifyk foar masine-learen mei krêftige Tesla V100-grafyske processors (GPU) fan NVIDIA. Koartsein: it brûken fan in tsjinner mei in GPU kin tsientallen kearen effisjinter (snel) wêze yn ferliking mei in server fan ferlykbere kosten dy't in CPU (de bekende sintrale ferwurkingsienheid) brûkt foar berekkeningen. Dit wurdt berikt troch de funksjes fan 'e GPU-arsjitektuer, dy't rapper omgaat mei berekkeningen.

Om de hjirûnder beskreaune foarbylden út te fieren, kochten wy de folgjende server foar ferskate dagen:

  • SSD skiif 150 GB
  • RAM 32 GB
  • Tesla V100 16 Gb prosessor mei 4 kearnen

Wy ynstalleare Ubuntu 18.04 op ús masine.

It opsetten fan it miljeu

Litte wy no alles ynstallearje dat nedich is foar wurk op 'e tsjinner. Sûnt ús artikel is benammen foar begjinners, Ik sil prate oer guon punten dy't sil wêze nuttich foar harren.

In protte fan it wurk by it ynstellen fan in omjouwing wurdt dien fia de kommandorigel. De measte brûkers brûke Windows as har wurkjende OS. De standertkonsole yn dit OS lit in protte te winskjen oer. Dêrom sille wy in handich ark brûke Cmder/. Download de mini ferzje en rinne Cmder.exe. Folgjende moatte jo ferbine mei de tsjinner fia SSH:

ssh root@server-ip-or-hostname

Ynstee fan server-ip-of-hostnamme, spesifisearje it IP-adres of DNS-namme fan jo server. Fier dan it wachtwurd yn en as de ferbining suksesfol is, moatte wy in berjocht krije dat fergelykber is mei dit.

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

De haadtaal foar it ûntwikkeljen fan ML-modellen is Python. En it populêrste platfoarm foar syn gebrûk op Linux is Anaconda.

Litte wy it ynstallearje op ús server.

Wy begjinne mei it bywurkjen fan de lokale pakketbehearder:

sudo apt-get update

Ynstallearje curl (kommando-rigelprogramma):

sudo apt-get install curl

Download de lêste ferzje fan Anaconda Distribution:

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

Litte wy de ynstallaasje begjinne:

bash Anaconda3-2019.10-Linux-x86_64.sh

Tidens it ynstallaasjeproses wurde jo frege om de lisinsje-oerienkomst te befêstigjen. Nei suksesfolle ynstallaasje moatte jo dit sjen:

Thank you for installing Anaconda3!

In protte kaders binne no makke foar de ûntwikkeling fan ML-modellen dy't wy wurkje mei de populêrste: PyTorch и Tensorstream.

It brûken fan it ramt lit jo de snelheid fan ûntwikkeling ferheegje en klearmakke ark brûke foar standerttaken.

Yn dit foarbyld sille wy wurkje mei PyTorch. Litte wy it ynstallearje:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

No moatte wy Jupyter Notebook lansearje, in populêr ûntwikkelingsark foar ML-spesjalisten. It lit jo koade skriuwe en fuortendaliks de resultaten fan syn útfiering sjen. Jupyter Notebook is opnommen mei Anaconda en is al ynstalleare op ús server. Jo moatte dermei ferbine fanút ús buroblêdsysteem.

Om dit te dwaan, sille wy Jupyter earst starte op 'e server dy't poarte 8080 spesifisearret:

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

Folgjende, iepenje in oare ljepper yn ús Cmder konsole (topmenu - Nije konsole dialooch) wy sille ferbine fia poarte 8080 mei de tsjinner fia SSH:

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

As wy it earste kommando ynfiere, sille wy keppelings wurde oanbean om Jupyter yn ús browser te iepenjen:

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

Litte wy de keppeling brûke foar localhost: 8080. Kopiearje it folsleine paad en plak it yn 'e adresbalke fan jo lokale browser fan jo PC. Jupyter Notebook sil iepenje.

Litte wy in nij notebook oanmeitsje: Nij - Notebook - Python 3.

Litte wy de juste wurking fan alle komponinten kontrolearje dy't wy ynstalleare. Litte wy it foarbyld PyTorch-koade yn Jupyter ynfiere en de útfiering útfiere (knop Run):

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

It resultaat moat sa'n ding wêze:

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

As jo ​​​​in ferlykber resultaat hawwe, dan hawwe wy alles goed konfigureare en kinne wy ​​​​begjinne mei it ûntwikkeljen fan in neural netwurk!

It meitsjen fan in neural netwurk

Wy sille in neural netwurk meitsje foar ôfbyldingsherkenning. Litte wy dit as basis nimme liederskip.

Wy sille de publyklik beskikbere CIFAR10-dataset brûke om it netwurk te trenen. It hat klassen: "fleantúch", "auto", "fûgel", "kat", "hert", "hûn", "kikkert", "hynder", "skip", "truck". Ofbyldings yn CIFAR10 binne 3x32x32, dat is 3-kanaal kleurôfbyldings fan 32x32 piksels.

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide
Foar wurk sille wy it pakket brûke dat is makke troch PyTorch foar wurkjen mei ôfbyldings - torchvision.

Wy sille de folgjende stappen yn folchoarder dwaan:

  • Laden en normalisearjen fan trainings- en testgegevenssets
  • Neural Network Definition
  • Netwurktraining op trainingsgegevens
  • Netwurk testen op testgegevens
  • Litte wy training en testen werhelje mei GPU

Wy sille alle koade hjirûnder útfiere yn Jupyter Notebook.

CIFAR10 laden en normalisearje

Kopiearje en útfiere de folgjende koade yn 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')

It antwurd moat wêze:

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

Litte wy ferskate trainingsôfbyldings werjaan foar testen:


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

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

Neural Network Definition

Litte wy earst beskôgje hoe't in neuraal netwurk foar ôfbyldingsherkenning wurket. Dit is in ienfâldich punt-to-punt netwurk. It nimt ynfiergegevens, giet it troch ferskate lagen ien foar ien, en produsearret dan úteinlik útfiergegevens.

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

Litte wy in ferlykber netwurk meitsje yn ús omjouwing:


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

Wy definiearje ek in ferliesfunksje en in optimizer


import torch.optim as optim

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

Netwurktraining op trainingsgegevens

Litte wy ús neurale netwurk begjinne te trainen. Tink derom dat jo nei't jo dizze koade útfiere, wat tiid moatte wachtsje oant it wurk foltôge is. It duorre my 5 minuten. It duorret tiid om it netwurk te trenen.

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

Wy krije it folgjende resultaat:

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

Wy bewarje ús trained model:

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

Netwurk testen op testgegevens

Wy trainden it netwurk mei in set trainingsgegevens. Mar wy moatte kontrolearje oft it netwurk al wat leard hat.

Wy sille dit testen troch it klasseetiket te foarsizzen dat it neuronale netwurk útfiert en it testen om te sjen oft it wier is. As de foarsizzing goed is, foegje wy de stekproef ta oan de list mei juste foarsizzings.
Litte wy in ôfbylding sjen litte fan 'e testset:

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

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

Litte wy no it neurale netwurk freegje om ús te fertellen wat op dizze foto's is:


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

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

De resultaten lykje aardich goed: it netwurk hat trije fan de fjouwer foto's korrekt identifisearre.

Litte wy sjen hoe't it netwurk prestearret oer de heule dataset.


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

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

It liket derop dat it netwurk wat wit en wurket. As hy de klassen willekeurich bepale, soe de krektens 10% wêze.

Litte wy no sjen hokker klassen it netwurk better identifisearret:

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

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

It liket derop dat it netwurk it bêste is om auto's en skippen te identifisearjen: 71% krektens.

Sa wurket it netwurk. Litte wy no besykje har wurk oer te bringen nei de grafyske prosessor (GPU) en sjen wat der feroaret.

Training in neural netwurk op GPU

Earst sil ik koart útlizze wat CUDA is. CUDA (Compute Unified Device Architecture) is in parallel komputerplatfoarm ûntwikkele troch NVIDIA foar algemiene berekkenjen op grafyske ferwurkingsienheden (GPU's). Mei CUDA kinne ûntwikkelders komputerapplikaasjes dramatysk fersnelle troch de krêft fan GPU's te benutten. Dit platfoarm is al ynstalleare op ús server dy't wy kocht hawwe.

Litte wy earst ús GPU definiearje as it earste sichtbere cuda-apparaat.

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 )

Jo earste neuronale netwurk op in grafyske ferwurkingsienheid (GPU). Beginners Guide

It netwurk ferstjoere nei de GPU:

net.to(device)

Wy sille ek ynputs en doelen moatte stjoere by elke stap nei de GPU:

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

Litte wy it netwurk opnij traine op 'e 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')

Dizze kear duorre de netwurktraining sa'n 3 minuten. Lit ús ûnthâlde dat itselde poadium op in konvinsjonele prosessor duorre 5 minuten. It ferskil is net signifikant, dit bart om't ús netwurk net sa grut is. By it brûken fan grutte arrays foar training sil it ferskil tusken de snelheid fan 'e GPU en in tradisjonele prosessor tanimme.

Dat liket alles te wêzen. Wat wy slagge om te dwaan:

  • Wy seagen wat in GPU is en selekteare de tsjinner wêrop it ynstalleare is;
  • Wy hawwe in software-omjouwing ynsteld om in neural netwurk te meitsjen;
  • Wy makken in neural netwurk foar byld erkenning en trained it;
  • Wy werhelle de netwurktraining mei de GPU en krigen in ferheging fan snelheid.

Ik sil bliid wêze om fragen te beantwurdzjen yn 'e kommentaren.

Boarne: www.habr.com

Add a comment