Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids
In hierdie artikel sal ek jou vertel hoe om 'n masjienleer-omgewing binne 30 minute op te stel, 'n neurale netwerk vir beeldherkenning te skep en dan dieselfde netwerk op 'n grafiese verwerker (GPU) te laat loop.

Kom ons definieer eers wat 'n neurale netwerk is.

In ons geval is dit 'n wiskundige model, sowel as sy sagteware of hardeware beliggaming, gebou op die beginsel van organisasie en funksionering van biologiese neurale netwerke - netwerke van senuweeselle van 'n lewende organisme. Hierdie konsep het ontstaan ​​tydens die bestudering van die prosesse wat in die brein plaasvind en probeer om hierdie prosesse te modelleer.

Neurale netwerke word nie in die gewone sin van die woord geprogrammeer nie, hulle is opgelei. Die vermoë om te leer is een van die belangrikste voordele van neurale netwerke bo tradisionele algoritmes. Tegnies bestaan ​​leer uit die vind van die koëffisiënte van verbindings tussen neurone. Tydens die opleidingsproses is die neurale netwerk in staat om komplekse afhanklikhede tussen insetdata en uitsetdata te identifiseer, asook veralgemening uit te voer.

Uit die oogpunt van masjienleer is 'n neurale netwerk 'n spesiale geval van patroonherkenningsmetodes, diskriminantanalise, groeperingsmetodes en ander metodes.

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

Kom ons kyk eers na die toerusting. Ons benodig 'n bediener met die Linux-bedryfstelsel daarop geïnstalleer. Die toerusting wat nodig is om masjienleerstelsels te bedryf, is redelik kragtig en gevolglik duur. Vir diegene wat nie 'n goeie masjien byderhand het nie, beveel ek aan om aandag te skenk aan die aanbiedinge van wolkverskaffers. U kan die vereiste bediener vinnig huur en slegs betaal vir die tyd van gebruik.

In projekte waar dit nodig is om neurale netwerke te skep, gebruik ek die bedieners van een van die Russiese wolkverskaffers. Die maatskappy bied wolkbedieners te huur spesifiek vir masjienleer met kragtige Tesla V100 grafiese verwerkers (GPU) van NVIDIA. Kortom: die gebruik van 'n bediener met 'n GPU kan tientalle keer meer doeltreffend (vinnig) wees in vergelyking met 'n bediener van soortgelyke koste wat 'n SVE (die bekende sentrale verwerkingseenheid) vir berekeninge gebruik. Dit word bereik as gevolg van die kenmerke van die GPU-argitektuur, wat berekeninge vinniger hanteer.

Om die voorbeelde wat hieronder beskryf word te implementeer, het ons die volgende bediener vir 'n paar dae gekoop:

  • SSD-skyf 150 GB
  • RAM 32 GB
  • Tesla V100 16 Gb verwerker met 4 kerne

Ons het Ubuntu 18.04 op ons masjien geïnstalleer.

Die opstel van die omgewing

Kom ons installeer nou alles wat nodig is vir werk op die bediener. Aangesien ons artikel hoofsaaklik vir beginners is, sal ek praat oor 'n paar punte wat vir hulle nuttig sal wees.

Baie van die werk by die opstel van 'n omgewing word deur die opdragreël gedoen. Die meeste van die gebruikers gebruik Windows as hul werkende bedryfstelsel. Die standaardkonsole in hierdie bedryfstelsel laat veel te wense oor. Daarom sal ons 'n gerieflike hulpmiddel gebruik Cmdder/. Laai die mini-weergawe af en hardloop Cmder.exe. Vervolgens moet u via SSH aan die bediener koppel:

ssh root@server-ip-or-hostname

In plaas van bediener-ip-of-gasheernaam, spesifiseer die IP-adres of DNS-naam van jou bediener. Voer dan die wagwoord in en as die verbinding suksesvol is, behoort ons 'n soortgelyke boodskap te ontvang.

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

Die hooftaal vir die ontwikkeling van ML-modelle is Python. En die gewildste platform vir die gebruik daarvan op Linux is Anaconda.

Kom ons installeer dit op ons bediener.

Ons begin deur die plaaslike pakketbestuurder op te dateer:

sudo apt-get update

Installeer krul (opdraglynnutsding):

sudo apt-get install curl

Laai die nuutste weergawe van Anaconda Distribution af:

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

Kom ons begin die installasie:

bash Anaconda3-2019.10-Linux-x86_64.sh

Tydens die installasieproses sal u gevra word om die lisensie-ooreenkoms te bevestig. Na suksesvolle installasie behoort jy dit te sien:

Thank you for installing Anaconda3!

Baie raamwerke is nou geskep vir die ontwikkeling van ML-modelle; ons werk met die gewildste: PyTorch и Tensorstroom.

Deur die raamwerk te gebruik, kan u die spoed van ontwikkeling verhoog en gereedgemaakte gereedskap vir standaardtake gebruik.

In hierdie voorbeeld sal ons met PyTorch werk. Kom ons installeer dit:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Nou moet ons Jupyter Notebook bekendstel, 'n gewilde ontwikkelingshulpmiddel vir ML-spesialiste. Dit laat jou toe om kode te skryf en dadelik die resultate van die uitvoering daarvan te sien. Jupyter Notebook is by Anaconda ingesluit en is reeds op ons bediener geïnstalleer. U moet vanaf ons rekenaarstelsel daaraan koppel.

Om dit te doen, sal ons eers Jupyter op die bediener begin wat poort 8080 spesifiseer:

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

Open dan 'n ander oortjie in ons Cmder-konsole (bo-kieslys - Nuwe konsoledialoog), ons sal via poort 8080 aan die bediener koppel via SSH:

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

Wanneer ons die eerste opdrag invoer, sal ons skakels aangebied word om Jupyter in ons blaaier oop te maak:

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

Kom ons gebruik die skakel vir localhost:8080. Kopieer die volledige pad en plak dit in die adresbalk van jou rekenaar se plaaslike blaaier. Jupyter Notebook sal oopmaak.

Kom ons skep 'n nuwe notaboek: Nuut - Notaboek - Python 3.

Kom ons kyk na die korrekte werking van al die komponente wat ons geïnstalleer het. Kom ons voer die voorbeeld PyTorch-kode in Jupyter in en voer die uitvoering uit (Run-knoppie):

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

Die resultaat moet iets soos volg wees:

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

As jy 'n soortgelyke resultaat het, dan het ons alles korrek gekonfigureer en ons kan begin om 'n neurale netwerk te ontwikkel!

Die skep van 'n neurale netwerk

Ons sal 'n neurale netwerk vir beeldherkenning skep. Kom ons neem dit as 'n basis leierskap.

Ons sal die publiek beskikbare CIFAR10-datastel gebruik om die netwerk op te lei. Dit het klasse: "vliegtuig", "motor", "voël", "kat", "hert", "hond", "padda", "perd", "skip", "vragmotor". Beelde in CIFAR10 is 3x32x32, dit wil sê 3-kanaal kleurbeelde van 32x32 piksels.

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids
Vir werk sal ons die pakket wat deur PyTorch geskep is, gebruik om met beelde te werk - torchvision.

Ons sal die volgende stappe in volgorde doen:

  • Laai en normalisering van opleiding- en toetsdatastelle
  • Neurale Netwerk Definisie
  • Netwerkopleiding oor opleidingsdata
  • Netwerktoetsing op toetsdata
  • Kom ons herhaal opleiding en toetsing met GPU

Ons sal al die kode hieronder in Jupyter Notebook uitvoer.

Laai en normaliseer CIFAR10

Kopieer en voer die volgende kode in Jupyter uit:


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

Die antwoord moet wees:

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

Kom ons vertoon verskeie opleidingsbeelde vir toetsing:


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

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

Neurale Netwerk Definisie

Kom ons kyk eers na hoe 'n neurale netwerk vir beeldherkenning werk. Dit is 'n eenvoudige punt-tot-punt netwerk. Dit neem insetdata, gee dit een vir een deur verskeie lae, en produseer dan uiteindelik uitsetdata.

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

Kom ons skep 'n soortgelyke netwerk in ons omgewing:


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

Ons definieer ook 'n verliesfunksie en 'n optimaliseerder


import torch.optim as optim

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

Netwerkopleiding oor opleidingsdata

Kom ons begin ons neurale netwerk oplei. Neem asseblief kennis dat nadat jy hierdie kode uitgevoer het, jy 'n rukkie sal moet wag totdat die werk voltooi is. Dit het my 5 minute geneem. Dit neem tyd om die netwerk op te lei.

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

Ons kry die volgende resultaat:

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

Ons stoor ons opgeleide model:

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

Netwerktoetsing op toetsdata

Ons het die netwerk opgelei deur 'n stel opleidingsdata te gebruik. Maar ons moet kyk of die netwerk enigsins iets geleer het.

Ons sal dit toets deur die klasetiket te voorspel wat die neurale netwerk uitset en dit te toets om te sien of dit waar is. As die voorspelling korrek is, voeg ons die steekproef by die lys van korrekte voorspellings.
Kom ons wys 'n prent uit die toetsstel:

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

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

Kom ons vra nou die neurale netwerk om ons te vertel wat in hierdie prente 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)))

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

Die resultate lyk redelik goed: die netwerk het drie uit vier foto's korrek geïdentifiseer.

Kom ons kyk hoe die netwerk oor die hele datastel presteer.


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

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

Dit lyk of die netwerk iets weet en werk. As hy die klasse lukraak bepaal het, sou die akkuraatheid 10% wees.

Kom ons kyk nou watter klasse die netwerk beter identifiseer:

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

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

Dit blyk dat die netwerk die beste is om motors en skepe te identifiseer: 71% akkuraatheid.

Die netwerk werk dus. Kom ons probeer nou om sy werk na die grafiese verwerker (GPU) oor te dra en kyk wat verander.

Opleiding van 'n neurale netwerk op GPU

Eerstens sal ek kortliks verduidelik wat CUDA is. CUDA (Compute Unified Device Architecture) is 'n parallelle rekenaarplatform wat deur NVIDIA ontwikkel is vir algemene rekenaars op grafiese verwerkingseenhede (GPU's). Met CUDA kan ontwikkelaars rekenaartoepassings dramaties versnel deur die krag van GPU's te benut. Hierdie platform is reeds geïnstalleer op ons bediener wat ons gekoop het.

Kom ons definieer eers ons GPU as die eerste sigbare cuda-toestel.

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 )

Jou eerste neurale netwerk op 'n grafiese verwerkingseenheid (GPU). Beginnersgids

Stuur die netwerk na die GPU:

net.to(device)

Ons sal ook insette en teikens by elke stap na die GPU moet stuur:

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

Kom ons herlei die netwerk op die 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')

Hierdie keer het die netwerkopleiding sowat 3 minute geduur. Laat ons onthou dat dieselfde stadium op 'n konvensionele verwerker 5 minute geduur het. Die verskil is nie beduidend nie, dit gebeur omdat ons netwerk nie so groot is nie. Wanneer groot skikkings vir opleiding gebruik word, sal die verskil tussen die spoed van die GPU en 'n tradisionele verwerker toeneem.

Dit blyk al te wees. Wat ons reggekry het om te doen:

  • Ons het gekyk na wat 'n GPU is en die bediener gekies waarop dit geïnstalleer is;
  • Ons het 'n sagteware-omgewing opgestel om 'n neurale netwerk te skep;
  • Ons het 'n neurale netwerk vir beeldherkenning geskep en dit opgelei;
  • Ons het die netwerkopleiding met die GPU herhaal en 'n toename in spoed ontvang.

Ek sal graag vrae in die kommentaar beantwoord.

Bron: will.com

Voeg 'n opmerking