Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek
Ebben a cikkben elmondom, hogyan állíthat be gépi tanulási környezetet 30 perc alatt, hozzon létre egy neurális hálózatot a képfelismeréshez, majd futtassa ugyanazt a hálózatot grafikus processzoron (GPU).

Először is határozzuk meg, mi az a neurális hálózat.

Esetünkben ez egy matematikai modell, valamint annak szoftveres vagy hardveres kiviteli alakja, amely a biológiai neurális hálózatok - egy élő szervezet idegsejt-hálózatai - szerveződésének és működésének elvén épül fel. Ez a koncepció az agyban lezajló folyamatok tanulmányozása és modellezése során merült fel.

A neurális hálózatokat nem a szó szokásos értelmében programozzák, hanem betanítják. A tanulás képessége a neurális hálózatok egyik fő előnye a hagyományos algoritmusokkal szemben. Technikailag a tanulás abból áll, hogy megtaláljuk a neuronok közötti kapcsolatok együtthatóit. A betanítási folyamat során a neurális hálózat képes a bemeneti adatok és a kimeneti adatok közötti komplex függőségek azonosítására, valamint általánosításra.

A gépi tanulás szempontjából a neurális hálózat a mintafelismerő módszerek, a diszkriminanciaanalízis, a klaszterezési módszerek és egyéb módszerek speciális esete.

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

Először is nézzük a felszerelést. Szükségünk van egy szerverre, amelyen Linux operációs rendszer van telepítve. A gépi tanulási rendszerek működtetéséhez szükséges berendezések meglehetősen nagy teljesítményűek, és ennek következtében drágák. Akinek nincs kéznél jó gépe, annak javaslom, hogy figyeljen a felhőszolgáltatók ajánlataira. Gyorsan bérelheti a szükséges szervert, és csak a használat idejéért fizet.

Azokban a projektekben, ahol neurális hálózatok létrehozására van szükség, az egyik orosz felhőszolgáltató szervereit használom. A cég kifejezetten gépi tanuláshoz kínál felhőszervereket bérelhető nagy teljesítményű Tesla V100 grafikus processzorokkal (GPU) az NVIDIA-tól. Röviden: egy GPU-s szerver használata több tízszer hatékonyabb (gyorsabb) lehet egy hasonló költségű szerverhez képest, amely CPU-t (a jól ismert központi feldolgozó egységet) használ a számításokhoz. Ez a GPU architektúra jellemzőinek köszönhető, amely gyorsabban birkózik meg a számításokkal.

Az alább leírt példák megvalósításához néhány napra megvásároltuk a következő szervert:

  • SSD lemez 150 GB
  • RAM 32 GB
  • Tesla V100 16 Gb processzor 4 maggal

Az Ubuntu 18.04-et telepítettük a gépünkre.

A környezet kialakítása

Most telepítsünk mindent, ami a munkához szükséges a szerveren. Mivel cikkünk elsősorban kezdőknek szól, beszélek néhány pontról, amelyek hasznosak lesznek számukra.

A környezet beállítása során a munka nagy része a parancssoron keresztül történik. A legtöbb felhasználó a Windowst használja működő operációs rendszerként. A szabványos konzol ebben az operációs rendszerben sok kívánnivalót hagy maga után. Ezért egy kényelmes eszközt fogunk használni Cmder/. Töltse le a mini verziót, és futtassa a Cmder.exe-t. Ezután SSH-n keresztül csatlakoznia kell a szerverhez:

ssh root@server-ip-or-hostname

A szerver-ip-vagy-állomásnév helyett adja meg a kiszolgáló IP-címét vagy DNS-nevét. Ezután adja meg a jelszót, és ha a kapcsolat sikeres, egy ehhez hasonló üzenetet kell kapnunk.

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

Az ML modellek fejlesztésének fő nyelve a Python. A Linuxon való használatának legnépszerűbb platformja pedig az Anakonda.

Telepítsük a szerverünkre.

Kezdjük a helyi csomagkezelő frissítésével:

sudo apt-get update

A curl telepítése (parancssori segédprogram):

sudo apt-get install curl

Töltse le az Anaconda Distribution legújabb verzióját:

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

Kezdjük a telepítést:

bash Anaconda3-2019.10-Linux-x86_64.sh

A telepítési folyamat során meg kell erősítenie a licencszerződést. Sikeres telepítés esetén ezt kell látnia:

Thank you for installing Anaconda3!

Az ML modellek fejlesztéséhez mára számos keretrendszer készült, a legnépszerűbbekkel dolgozunk: PyTorch и tenzor áramlás.

A keretrendszer használata lehetővé teszi a fejlesztés sebességének növelését és a kész eszközök használatát a szabványos feladatokhoz.

Ebben a példában a PyTorch-al fogunk dolgozni. Telepítsük:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Most el kell indítanunk a Jupyter Notebookot, az ML-specialisták népszerű fejlesztőeszközét. Lehetővé teszi, hogy kódot írjon, és azonnal látja a végrehajtás eredményét. A Jupyter Notebook az Anaconda része, és már telepítve van a szerverünkön. Csatlakoznia kell hozzá az asztali rendszerünkből.

Ehhez először elindítjuk a Jupytert a szerveren, megadva a 8080-as portot:

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

Ezután a Cmder konzolunkban megnyitva egy másik lapot (felső menü - Új konzol párbeszédpanel) a 8080-as porton keresztül csatlakozunk a szerverhez SSH-n keresztül:

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

Amikor beírjuk az első parancsot, a rendszer felajánlja a hivatkozásokat a Jupyter megnyitásához a böngészőnkben:

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

Használjuk a localhost:8080 hivatkozást. Másolja ki a teljes elérési utat, és illessze be a számítógép helyi böngészőjének címsorába. Megnyílik a Jupyter Notebook.

Hozzon létre egy új jegyzetfüzetet: Új - Jegyzetfüzet - Python 3.

Ellenőrizzük az általunk telepített összes összetevő helyes működését. Írjuk be a példa PyTorch kódot a Jupyterbe, és futtassuk a végrehajtást (Futtatás gomb):

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

Az eredmény valami ilyesmi legyen:

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

Ha hasonló eredményt kap, akkor mindent jól konfiguráltunk, és elkezdhetjük a neurális hálózat fejlesztését!

Neurális hálózat létrehozása

Létrehozunk egy neurális hálózatot a képfelismeréshez. Vegyük ezt alapul vezetés.

A hálózat betanításához a nyilvánosan elérhető CIFAR10 adatkészletet fogjuk használni. Osztályai vannak: „repülőgép”, „autó”, „madár”, „macska”, „szarvas”, „kutya”, „béka”, „ló”, „hajó”, „teherautó”. A CIFAR10 képei 3x32x32, azaz 3 csatornás, 32x32 pixeles színes képek.

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek
A munkához a PyTorch által készített csomagot fogjuk használni a képekkel való munkához - torchvision.

Sorrendben a következő lépéseket hajtjuk végre:

  • Oktatási és tesztadatkészletek betöltése és normalizálása
  • Neurális hálózat definíciója
  • Hálózati képzés a képzési adatokról
  • Hálózati tesztelés tesztadatokon
  • Ismételjük meg a képzést és a tesztelést GPU-val

Az alábbi kódokat a Jupyter Notebookban hajtjuk végre.

CIFAR10 betöltése és normalizálása

Másolja ki és futtassa a következő kódot a Jupyterben:


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

A válasz a következő legyen:

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

Mutassunk meg néhány edzésképet tesztelésre:


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

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

Neurális hálózat definíciója

Először nézzük meg, hogyan működik a képfelismerő neurális hálózat. Ez egy egyszerű pont-pont hálózat. Bemeneti adatokat vesz fel, egyenként több rétegen halad át, majd végül kimeneti adatokat állít elő.

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

Hozzunk létre egy hasonló hálózatot a környezetünkben:


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

Definiálunk egy veszteségfüggvényt és egy optimalizálót is


import torch.optim as optim

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

Hálózati képzés a képzési adatokról

Kezdjük el tanítani a neurális hálózatunkat. Kérjük, vegye figyelembe, hogy a kód futtatása után várnia kell egy ideig, amíg a munka befejeződik. 5 percig tartott. A hálózat betanítása időbe telik.

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

A következő eredményt kapjuk:

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

Megmentjük betanított modellünket:

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

Hálózati tesztelés tesztadatokon

A hálózatot betanítottuk egy képzési adatkészlet felhasználásával. De ellenőriznünk kell, hogy a hálózat tanult-e egyáltalán valamit.

Ezt úgy fogjuk tesztelni, hogy megjósoljuk a neurális hálózat által kiadott osztálycímkét, és teszteljük, hogy igaz-e. Ha az előrejelzés helyes, a mintát hozzáadjuk a helyes előrejelzések listájához.
Mutassunk egy képet a tesztkészletből:

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

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

Most pedig kérjük meg a neurális hálózatot, hogy mondja el, mi van ezeken a képeken:


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

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

Az eredmények elég jónak tűnnek: a hálózat négy képből hármat helyesen azonosított.

Nézzük meg, hogyan teljesít a hálózat a teljes adatkészletben.


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

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

Úgy tűnik, hogy a hálózat tud valamit, és működik. Ha véletlenszerűen határozná meg az osztályokat, a pontosság 10% lenne.

Most nézzük meg, hogy a hálózat mely osztályokat azonosítja jobban:

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

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

Úgy tűnik, hogy a hálózat a legjobb az autók és hajók azonosításában: 71%-os pontossággal.

Tehát a hálózat működik. Most próbáljuk meg átvinni a munkáját a grafikus processzorra (GPU), és nézzük meg, mi változik.

Neurális hálózat betanítása GPU-n

Először röviden elmagyarázom, mi az a CUDA. A CUDA (Compute Unified Device Architecture) egy párhuzamos számítási platform, amelyet az NVIDIA fejlesztett ki grafikus feldolgozóegységeken (GPU-k) végzett általános számítástechnikai célokra. A CUDA segítségével a fejlesztők drámai módon felgyorsíthatják a számítástechnikai alkalmazásokat a GPU-k teljesítményének kihasználásával. Ez a platform már telepítve van a megvásárolt szerverünkön.

Először is határozzuk meg a GPU-nkat, mint az első látható cuda-eszközt.

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 )

Az első neurális hálózat egy grafikus feldolgozó egységen (GPU). Útmutató kezdőknek

A hálózat elküldése a GPU-nak:

net.to(device)

Ezenkívül minden lépésnél bemeneteket és célokat kell küldenünk a GPU-nak:

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

Tanítsuk újra a hálózatot a GPU-n:

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

Ezúttal a hálózati tréning körülbelül 3 percig tartott. Emlékezzünk vissza, hogy ugyanaz a szakasz egy hagyományos processzoron 5 percig tartott. A különbség nem szignifikáns, ez azért történik, mert a hálózatunk nem olyan nagy. Ha nagy tömböket használ a képzéshez, a GPU és a hagyományos processzor sebessége közötti különbség megnő.

Úgy tűnik, ez minden. Amit sikerült:

  • Megnéztük, mi az a GPU, és kiválasztottuk a szervert, amelyre telepítve van;
  • Szoftverkörnyezetet hoztunk létre egy neurális hálózat létrehozásához;
  • Létrehoztunk egy neurális hálózatot a képfelismeréshez és betanítottuk azt;
  • Megismételtük a hálózati betanítást a GPU segítségével, és sebességnövekedést kaptunk.

Kérdésekre szívesen válaszolok a megjegyzésekben.

Forrás: will.com

Hozzászólás