Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan
Sa artikulong ito, sasabihin ko sa iyo kung paano mag-set up ng machine learning environment sa loob ng 30 minuto, gumawa ng neural network para sa pagkilala ng imahe, at pagkatapos ay patakbuhin ang parehong network sa isang graphics processor (GPU).

Una, tukuyin natin kung ano ang isang neural network.

Sa aming kaso, ito ay isang modelo ng matematika, pati na rin ang software o hardware na sagisag nito, na binuo sa prinsipyo ng organisasyon at paggana ng mga biological neural network - mga network ng mga nerve cell ng isang buhay na organismo. Ang konseptong ito ay lumitaw habang pinag-aaralan ang mga prosesong nagaganap sa utak at sinusubukang i-modelo ang mga prosesong ito.

Ang mga neural network ay hindi naka-program sa karaniwang kahulugan ng salita, sila ay sinanay. Ang kakayahang matuto ay isa sa mga pangunahing bentahe ng mga neural network sa mga tradisyonal na algorithm. Sa teknikal, ang pag-aaral ay binubuo ng paghahanap ng mga coefficient ng mga koneksyon sa pagitan ng mga neuron. Sa panahon ng proseso ng pagsasanay, natutukoy ng neural network ang mga kumplikadong dependency sa pagitan ng data ng input at data ng output, pati na rin magsagawa ng generalization.

Mula sa punto ng view ng machine learning, ang neural network ay isang espesyal na kaso ng mga pamamaraan ng pagkilala ng pattern, discriminant analysis, clustering method at iba pang pamamaraan.

ΠžΠ±ΠΎΡ€ΡƒΠ΄ΠΎΠ²Π°Π½ΠΈΠ΅

Una, tingnan natin ang kagamitan. Kailangan namin ng server na may naka-install na Linux operating system dito. Ang mga kagamitan na kinakailangan upang patakbuhin ang mga sistema ng pag-aaral ng makina ay napakalakas at, bilang resulta, mahal. Para sa mga walang magandang makina sa kamay, inirerekumenda kong bigyang pansin ang mga alok ng mga tagapagbigay ng ulap. Maaari kang magrenta ng kinakailangang server nang mabilis at magbayad lamang para sa oras ng paggamit.

Sa mga proyekto kung saan kinakailangan upang lumikha ng mga neural network, ginagamit ko ang mga server ng isa sa mga tagapagbigay ng ulap ng Russia. Nag-aalok ang kumpanya ng mga cloud server para sa upa partikular para sa machine learning na may malalakas na Tesla V100 graphics processors (GPU) mula sa NVIDIA. Sa madaling salita: ang paggamit ng server na may GPU ay maaaring sampu-sampung beses na mas mahusay (mabilis) kumpara sa isang server na may katulad na halaga na gumagamit ng CPU (ang kilalang central processing unit) para sa mga kalkulasyon. Nakamit ito dahil sa mga tampok ng arkitektura ng GPU, na mas mabilis na nakayanan ang mga kalkulasyon.

Upang ipatupad ang mga halimbawang inilarawan sa ibaba, binili namin ang sumusunod na server sa loob ng ilang araw:

  • SSD disk 150 GB
  • RAM 32 GB
  • Tesla V100 16 Gb processor na may 4 na core

Nag-install kami ng Ubuntu 18.04 sa aming makina.

Pag-set up ng kapaligiran

Ngayon, i-install natin ang lahat ng kailangan para sa trabaho sa server. Dahil ang aming artikulo ay pangunahin para sa mga nagsisimula, magsasalita ako tungkol sa ilang mga punto na magiging kapaki-pakinabang sa kanila.

Ang maraming gawain kapag nagse-set up ng isang kapaligiran ay ginagawa sa pamamagitan ng command line. Karamihan sa mga gumagamit ay gumagamit ng Windows bilang kanilang gumaganang OS. Ang karaniwang console sa OS na ito ay nag-iiwan ng maraming nais. Samakatuwid, gagamit kami ng isang maginhawang tool Cmder/. I-download ang mini na bersyon at patakbuhin ang Cmder.exe. Susunod na kailangan mong kumonekta sa server sa pamamagitan ng SSH:

ssh root@server-ip-or-hostname

Sa halip na server-ip-or-hostname, tukuyin ang IP address o DNS name ng iyong server. Susunod, ipasok ang password at kung matagumpay ang koneksyon, dapat tayong makatanggap ng mensaheng katulad nito.

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

Ang pangunahing wika para sa pagbuo ng mga modelo ng ML ay Python. At ang pinakasikat na platform para sa paggamit nito sa Linux ay Anaconda.

I-install natin ito sa aming server.

Magsisimula kami sa pamamagitan ng pag-update ng lokal na manager ng package:

sudo apt-get update

I-install ang curl (utility ng command line):

sudo apt-get install curl

I-download ang pinakabagong bersyon ng Anaconda Distribution:

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

Simulan natin ang pag-install:

bash Anaconda3-2019.10-Linux-x86_64.sh

Sa panahon ng proseso ng pag-install, hihilingin sa iyo na kumpirmahin ang kasunduan sa lisensya. Sa matagumpay na pag-install dapat mong makita ito:

Thank you for installing Anaconda3!

Maraming mga balangkas ang nagawa na ngayon para sa pagbuo ng mga modelo ng ML na nagtatrabaho kami sa pinakasikat: PyTorch ΠΈ daloy ng tensor.

Ang paggamit ng balangkas ay nagbibigay-daan sa iyo upang mapataas ang bilis ng pag-unlad at gumamit ng mga handa na tool para sa mga karaniwang gawain.

Sa halimbawang ito, gagana kami sa PyTorch. I-install natin ito:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Ngayon ay kailangan nating ilunsad ang Jupyter Notebook, isang sikat na tool sa pag-develop para sa mga espesyalista sa ML. Pinapayagan ka nitong magsulat ng code at agad na makita ang mga resulta ng pagpapatupad nito. Ang Jupyter Notebook ay kasama sa Anaconda at naka-install na sa aming server. Kailangan mong kumonekta dito mula sa aming desktop system.

Upang gawin ito, ilulunsad muna namin ang Jupyter sa server na tumutukoy sa port 8080:

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

Susunod, pagbubukas ng isa pang tab sa aming Cmder console (top menu - Bagong console dialog) kami ay kumonekta sa pamamagitan ng port 8080 sa server sa pamamagitan ng SSH:

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

Kapag ipinasok namin ang unang command, bibigyan kami ng mga link upang buksan ang Jupyter sa aming 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

Gamitin natin ang link para sa localhost:8080. Kopyahin ang buong path at i-paste ito sa address bar ng lokal na browser ng iyong PC. Magbubukas ang Jupyter Notebook.

Gumawa tayo ng bagong notebook: Bago - Notebook - Python 3.

Suriin natin ang tamang operasyon ng lahat ng mga sangkap na na-install namin. Ipasok natin ang halimbawang PyTorch code sa Jupyter at patakbuhin ang pagpapatupad (Run button):

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

Ang resulta ay dapat na ganito:

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

Kung mayroon kang isang katulad na resulta, pagkatapos ay na-configure namin ang lahat ng tama at maaari naming simulan ang pagbuo ng isang neural network!

Paglikha ng isang neural network

Gagawa kami ng neural network para sa pagkilala ng imahe. Gawin natin ito bilang batayan pamumuno.

Gagamitin namin ang pampublikong magagamit na dataset ng CIFAR10 para sanayin ang network. Mayroon itong mga klase: "eroplano", "kotse", "ibon", "pusa", "usa", "aso", "palaka", "kabayo", "barko", "trak". Ang mga larawan sa CIFAR10 ay 3x32x32, iyon ay, 3-channel na mga larawang may kulay na 32x32 pixels.

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan
Para sa trabaho, gagamitin namin ang package na nilikha ng PyTorch para sa pagtatrabaho sa mga imahe - torchvision.

Gagawin namin ang mga sumusunod na hakbang sa pagkakasunud-sunod:

  • Naglo-load at nag-normalize ng mga set ng data ng pagsasanay at pagsubok
  • Kahulugan ng Neural Network
  • Pagsasanay sa network sa data ng pagsasanay
  • Pagsubok sa network sa data ng pagsubok
  • Ulitin natin ang pagsasanay at pagsubok gamit ang GPU

Ipapatupad namin ang lahat ng code sa ibaba sa Jupyter Notebook.

Naglo-load at nag-normalize ng CIFAR10

Kopyahin at patakbuhin ang sumusunod na code sa 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')

Ang sagot ay dapat na:

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

Ipakita natin ang ilang larawan ng pagsasanay para sa pagsubok:


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

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

Kahulugan ng Neural Network

Isaalang-alang muna natin kung paano gumagana ang isang neural network para sa pagkilala ng imahe. Ito ay isang simpleng point-to-point network. Ito ay tumatagal ng data ng input, ipinapasa ito sa ilang mga layer nang paisa-isa, at pagkatapos ay sa wakas ay gumagawa ng data ng output.

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

Gumawa tayo ng katulad na network sa ating kapaligiran:


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

Tinutukoy din namin ang isang function ng pagkawala at isang optimizer


import torch.optim as optim

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

Pagsasanay sa network sa data ng pagsasanay

Simulan natin ang pagsasanay sa ating neural network. Pakitandaan na pagkatapos mong patakbuhin ang code na ito, kakailanganin mong maghintay ng ilang oras hanggang sa makumpleto ang gawain. Inabot ako ng 5 minutes. Kailangan ng oras upang sanayin ang network.

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

Nakukuha namin ang sumusunod na resulta:

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

I-save namin ang aming sinanay na modelo:

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

Pagsubok sa network sa data ng pagsubok

Sinanay namin ang network gamit ang isang set ng data ng pagsasanay. Ngunit kailangan nating suriin kung may natutunan ang network.

Susubukan namin ito sa pamamagitan ng paghula sa label ng klase na ilalabas ng neural network at pagsubok ito upang makita kung ito ay totoo. Kung tama ang hula, idinaragdag namin ang sample sa listahan ng mga tamang hula.
Magpakita tayo ng larawan mula sa test set:

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

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

Ngayon, hilingin natin sa neural network na sabihin sa amin kung ano ang nasa mga larawang ito:


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

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

Mukhang maganda ang mga resulta: tama ang pagkakakilala ng network ng tatlo sa apat na larawan.

Tingnan natin kung paano gumaganap ang network sa buong 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))

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

Mukhang may alam ang network at gumagana. Kung tinutukoy niya ang mga klase nang random, ang katumpakan ay magiging 10%.

Ngayon tingnan natin kung aling mga klase ang mas nakikilala ng network:

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

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

Mukhang ang network ay pinakamahusay sa pagtukoy ng mga kotse at barko: 71% katumpakan.

Kaya gumagana ang network. Ngayon subukan nating ilipat ang gawain nito sa graphics processor (GPU) at tingnan kung ano ang mga pagbabago.

Pagsasanay ng neural network sa GPU

Una, ipapaliwanag ko nang maikli kung ano ang CUDA. Ang CUDA (Compute Unified Device Architecture) ay isang parallel computing platform na binuo ng NVIDIA para sa pangkalahatang computing sa mga graphics processing unit (GPU). Sa CUDA, mapapabilis ng mga developer ang mga application sa pag-compute sa pamamagitan ng paggamit ng kapangyarihan ng mga GPU. Naka-install na ang platform na ito sa aming server na binili namin.

Tukuyin muna natin ang ating GPU bilang ang unang nakikitang cuda device.

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 )

Ang iyong unang neural network sa isang graphics processing unit (GPU). Gabay sa Baguhan

Pagpapadala ng network sa GPU:

net.to(device)

Kakailanganin din naming magpadala ng mga input at target sa bawat hakbang sa GPU:

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

Muli nating sanayin ang network sa 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')

Sa pagkakataong ito, ang pagsasanay sa network ay tumagal ng halos 3 minuto. Alalahanin natin na ang parehong yugto sa isang maginoo na processor ay tumagal ng 5 minuto. Ang pagkakaiba ay hindi makabuluhan, ito ay nangyayari dahil ang aming network ay hindi masyadong malaki. Kapag gumagamit ng malalaking array para sa pagsasanay, tataas ang pagkakaiba sa pagitan ng bilis ng GPU at ng tradisyonal na processor.

Iyon lang daw. Ang nagawa namin:

  • Tiningnan namin kung ano ang GPU at pinili ang server kung saan ito naka-install;
  • Nag-set up kami ng software environment para lumikha ng neural network;
  • Gumawa kami ng neural network para sa pagkilala ng imahe at sinanay ito;
  • Inulit namin ang pagsasanay sa network gamit ang GPU at nakatanggap kami ng pagtaas ng bilis.

Ikalulugod kong sagutin ang mga tanong sa mga komento.

Pinagmulan: www.habr.com

Magdagdag ng komento