Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон
Дар ин мақола, ман ба шумо мегӯям, ки чӣ гуна муҳити омӯзиши мошинро дар 30 дақиқа таъсис диҳед, шабакаи нейронро барои шинохти тасвир эҷод кунед ва сипас ҳамон шабакаро дар протсессори графикӣ (GPU) иҷро кунед.

Аввалан, биёед муайян кунем, ки шабакаи нейрон чист.

Дар ҳолати мо, ин модели математикӣ, инчунин таҷассуми нармафзор ё сахтафзори он мебошад, ки дар асоси принсипи ташкил ва фаъолияти шабакаҳои нейронии биологӣ - шабакаҳои ҳуҷайраҳои асаби организми зинда сохта шудааст. Ин консепсия ҳангоми омӯзиши равандҳои дар майна ба амаломада ва кӯшиши моделсозии ин равандҳо ба вуҷуд омадааст.

Шабакаҳои нейрон ба маънои маъмулии калима барномарезӣ нашудаанд, онҳо таълим дода мешаванд. Қобилияти омӯхтан яке аз бартариҳои асосии шабакаҳои нейронӣ нисбат ба алгоритмҳои анъанавӣ мебошад. Аз ҷиҳати техникӣ, омӯзиш аз дарёфти коэффисиентҳои алоқаи байни нейронҳо иборат аст. Дар ҷараёни таълим, шабакаи нейронӣ қодир аст вобастагии мураккаби байни маълумоти воридотӣ ва баромадро муайян кунад ва инчунин умумисозиро анҷом диҳад.

Аз нуқтаи назари омӯзиши мошин, шабакаи нейрон як ҳолати махсуси усулҳои шинохти намуна, таҳлили дискриминантҳо, усулҳои кластерсозӣ ва усулҳои дигар мебошад.

Таҷҳизот

Аввалан, биёед ба таҷҳизот назар кунем. Ба мо сервере лозим аст, ки дар он системаи амалиётии Linux насб шудааст. Таҷҳизоте, ки барои идора кардани системаҳои омӯзиши мошинҳо зарур аст, хеле пурқувват аст ва дар натиҷа гарон аст. Барои онҳое, ки дар даст мошини хуб надоранд, ман тавсия медиҳам, ки ба пешниҳодҳои провайдерҳои абр диққат диҳем. Шумо метавонед сервери лозимиро зуд ба иҷора гиред ва танҳо барои вақти истифода пардохт кунед.

Дар лоиҳаҳое, ки барои сохтани шабакаҳои нейрон зарур аст, ман серверҳои яке аз провайдерҳои абрии Русияро истифода мебарам. Ширкат серверҳои абриро барои иҷора махсусан барои омӯзиши мошинсозӣ бо протсессори пурқудрати графикии Tesla V100 (GPU) аз NVIDIA пешниҳод мекунад. Хулоса: истифодаи сервер бо GPU метавонад дар муқоиса бо сервери арзиши шабеҳ, ки CPU (воҳиди коркарди маъруфи марказӣ) барои ҳисобҳо истифода мебарад, даҳҳо маротиба самараноктар (тезтар) бошад. Ин ба туфайли хусусиятҳои меъмории GPU, ки ҳисобҳоро тезтар иҷро мекунад, ба даст оварда мешавад.

Барои татбиқи мисолҳои дар зер тавсифшуда, мо сервери зеринро барои чанд рӯз харидем:

  • Диски SSD 150 ГБ
  • RAM 32 ГБ
  • Tesla V100 протсессори 16 Гб бо 4 ядро

Мо дар мошини худ Ubuntu 18.04 насб кардем.

Муқаррар кардани муҳити зист

Акнун биёед ҳама чизро барои кор дар сервер насб кунем. Азбаски мақолаи мо пеш аз ҳама барои шурӯъкунандагон аст, ман дар бораи баъзе нуктаҳое, ки ба онҳо муфид хоҳанд буд, сӯҳбат мекунам.

Бисёр корҳо ҳангоми танзими муҳити зист тавассути сатри фармон анҷом дода мешаванд. Аксарияти корбарон Windows-ро ҳамчун ОС кории худ истифода мебаранд. Консолҳои стандартӣ дар ин ОС чизи дилхоҳро тарк мекунанд. Аз ин рӯ, мо асбоби қулайро истифода мебарем Cmder/. Версияи хурдро зеркашӣ кунед ва Cmder.exe-ро иҷро кунед. Баъд шумо бояд ба сервер тавассути SSH пайваст шавед:

ssh root@server-ip-or-hostname

Ба ҷои сервер-ip-ё-хост номи, суроғаи IP ё номи DNS-и сервери худро муайян кунед. Баъдан, паролро ворид кунед ва агар пайвастшавӣ бомуваффақият бошад, мо бояд паёми шабеҳи инро гирем.

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

Забони асосӣ барои таҳияи моделҳои ML Python мебошад. Ва платформаи маъмултарин барои истифодаи он дар Linux мебошад Анаконда.

Биёед онро дар сервери худ насб кунем.

Мо аз навсозии мудири бастаи маҳаллӣ оғоз мекунем:

sudo apt-get update

Curl насб кунед (утилитаи сатри фармон):

sudo apt-get install curl

Версияи охирини Anaconda Distribution-ро зеркашӣ кунед:

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

Биёед насбро оғоз кунем:

bash Anaconda3-2019.10-Linux-x86_64.sh

Ҳангоми насбкунӣ аз шумо хоҳиш карда мешавад, ки шартномаи литсензиониро тасдиқ кунед. Пас аз насби бомуваффақият шумо бояд инро бинед:

Thank you for installing Anaconda3!

Ҳоло чаҳорчӯбаҳои зиёде барои таҳияи моделҳои ML сохта шудаанд; мо бо маъмултарин кор мекунем: PyTorch и Танзими ҷараён.

Истифодаи чаҳорчӯба ба шумо имкон медиҳад, ки суръати рушдро афзоиш диҳед ва асбобҳои тайёрро барои вазифаҳои стандартӣ истифода баред.

Дар ин мисол мо бо PyTorch кор хоҳем кард. Биёед онро насб кунем:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

Ҳоло ба мо лозим аст, ки Jupyter Notebook, як воситаи маъмули таҳияи мутахассисони ML -ро оғоз кунем. Он ба шумо имкон медиҳад, ки код нависед ва фавран натиҷаҳои иҷрои онро бубинед. Notebook Jupyter ба Anaconda дохил карда шудааст ва аллакай дар сервери мо насб шудааст. Шумо бояд ба он аз системаи мизи кории мо пайваст шавед.

Барои ин, мо аввал Jupyter-ро дар сервер бо порти 8080 оғоз мекунем:

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

Баъдан, боз як ҷадвали дигарро дар консолии Cmder мо (менюи боло - Муколамаи консоли нав) мо тавассути порти 8080 ба сервер тавассути SSH пайваст мекунем:

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

Вақте ки мо фармони аввалро ворид мекунем, ба мо истинодҳо барои кушодани Jupyter дар браузери мо пешниҳод карда мешаванд:

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

Биёед истинодро барои localhost:8080 истифода барем. Роҳи пурраро нусхабардорӣ кунед ва онро ба сатри суроғаҳои браузери маҳаллии компютери худ часбонед. Notebook Jupyter кушода мешавад.

Биёед як дафтари нав созем: New - Notebook - Python 3.

Биёед кори дурусти ҳамаи ҷузъҳои насбшударо тафтиш кунем. Биёед рамзи намунаи PyTorch-ро ба Jupyter ворид кунем ва иҷроро иҷро кунем (Тугмаи Иҷро):

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

Натиҷа бояд чунин бошад:

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Агар шумо натиҷаи шабеҳ дошта бошед, пас мо ҳама чизро дуруст танзим кардем ва мо метавонем ба таҳияи шабакаи нейронӣ шурӯъ кунем!

Эҷоди шабакаи нейронӣ

Мо шабакаи нейронро барои шинохти тасвир эҷод мекунем. Биёед инро хамчун асос гирем роҳнамо.

Мо барои омӯзиши шабака маҷмӯаи маълумоти дастраси CIFAR10-ро истифода хоҳем бурд. Он дорои синфҳои: «ҳавопаймо», «мошин», «парранда», «гурба», «оду», «саг», «қурбоққа», «асп», «киштӣ», «мошини боркаш». Тасвирҳо дар CIFAR10 3x32x32, яъне тасвирҳои рангаи 3-канали 32x32 пиксел мебошанд.

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон
Барои кор, мо бастаеро, ки аз ҷониби PyTorch барои кор бо тасвирҳо сохта шудааст, истифода мебарем - torchvision.

Мо қадамҳои зеринро бо тартиби иҷро хоҳем кард:

  • Бор кардан ва ба эътидол овардани маҷмӯи маълумотҳои омӯзишӣ ва санҷишӣ
  • Таърифи шабакаи нейронӣ
  • Омӯзиши шабакавӣ оид ба маълумотҳои омӯзишӣ
  • Санҷиши шабакавӣ оид ба маълумоти санҷишӣ
  • Биёед омӯзиш ва санҷишро бо истифода аз GPU такрор кунем

Мо ҳамаи кодҳои дар поён овардашударо дар Jupyter Notebook иҷро хоҳем кард.

Боркунӣ ва ба эътидол овардани CIFAR10

Рамзи зеринро дар 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')

Ҷавоб бояд чунин бошад:

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

Биёед якчанд тасвирҳои омӯзиширо барои санҷиш нишон диҳем:


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

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Таърифи шабакаи нейронӣ

Биёед аввал дида бароем, ки шабакаи нейрон барои шинохти тасвир чӣ гуна кор мекунад. Ин як шабакаи оддӣ аз нуқта ба нуқта аст. Он маълумоти воридшударо мегирад, онро аз якчанд қабатҳо як ба як мегузаронад ва дар ниҳоят маълумоти баромадро истеҳсол мекунад.

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Биёед як шабакаи шабеҳро дар муҳити худ созем:


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

Мо инчунин функсияи талафот ва оптимизаторро муайян мекунем


import torch.optim as optim

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

Омӯзиши шабакавӣ оид ба маълумотҳои омӯзишӣ

Биёед ба омӯзиши шабакаи нейронии худ шурӯъ кунем. Лутфан қайд кунед, ки пас аз иҷро кардани ин код, шумо бояд то анҷоми кор каме интизор шавед. Ба ман 5 дақиқа вақт лозим шуд. Барои омӯзиши шабака вақт лозим аст.

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

Мо натиҷаи зеринро ба даст меорем:

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Мо модели омӯзонидаамонро захира мекунем:

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

Санҷиши шабакавӣ оид ба маълумоти санҷишӣ

Мо шабакаро бо истифода аз маҷмӯи маълумотҳои омӯзишӣ таълим додем. Аммо мо бояд тафтиш кунем, ки шабака умуман чизеро омӯхтааст ё не.

Мо инро тавассути пешгӯии тамғаи синф, ки шабакаи нейронӣ мебарорад ва санҷида меозмем, то бубинем, ки оё он дуруст аст. Агар пешгӯӣ дуруст бошад, мо намунаро ба рӯйхати пешгӯиҳои дуруст илова мекунем.
Биёед тасвиреро аз маҷмӯи санҷиш нишон диҳем:

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

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Акнун биёед аз шабакаи нейрон бипурсем, ки дар ин тасвирҳо чӣ мавҷуд аст:


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

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Натиҷаҳо хеле хуб ба назар мерасанд: шабака аз чор расм сетоашро дуруст муайян кард.

Биёед бубинем, ки шабака дар тамоми маҷмӯи додаҳо чӣ гуна кор мекунад.


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

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Чунин ба назар мерасад, ки шабака чизеро медонад ва кор мекунад. Агар ӯ синфҳоро ба таври тасодуфӣ муайян мекард, дақиқӣ 10% хоҳад буд.

Акнун биёед бубинем, ки кадом синфҳоро шабака беҳтар муайян мекунад:

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

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Чунин ба назар мерасад, ки шабака дар муайян кардани мошинҳо ва киштиҳо беҳтарин аст: 71% дақиқ.

Ҳамин тавр, шабака кор мекунад. Акнун биёед кӯшиш кунем, ки кори онро ба протсессори графикӣ (GPU) интиқол диҳем ва бубинем, ки чӣ тағир меёбад.

Омӯзиши шабакаи нейрон дар GPU

Аввалан, ман мухтасар шарҳ медиҳам, ки CUDA чист. CUDA (Architecture Unified Device Device Architecture) як платформаи ҳисоббарории мувозӣ мебошад, ки аз ҷониби NVIDIA барои ҳисоббарории умумӣ дар воҳидҳои коркарди графикӣ (GPU) таҳия шудааст. Бо CUDA, таҳиягарон метавонанд тавассути истифодаи қувваи GPU-ҳо барномаҳои компютериро ба таври назаррас суръат бахшанд. Ин платформа аллакай дар сервери мо, ки мо харидем, насб карда шудааст.

Биёед аввал GPU-и худро ҳамчун аввалин дастгоҳи намоёни cuda муайян кунем.

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 )

Аввалин шабакаи нейронии шумо дар воҳиди коркарди графикӣ (GPU). Дастур барои шурӯъкунандагон

Ирсоли шабака ба GPU:

net.to(device)

Мо инчунин бояд дар ҳар як қадам ба GPU воридот ва ҳадафҳо фиристем:

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

Биёед шабакаро дар 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')

Ин дафъа омӯзиши шабакавӣ тақрибан 3 дақиқа давом кард. Ёдовар мешавем, ки ҳамон марҳила дар протсессори муқаррарӣ 5 дақиқа давом мекард. Фарқият назаррас нест, ин аз он сабаб рӯй медиҳад, ки шабакаи мо он қадар калон нест. Ҳангоми истифодаи массивҳои калон барои омӯзиш, фарқият байни суръати GPU ва протсессори анъанавӣ зиёд мешавад.

Чунин ба назар мерасад, ки ҳамааш ҳамин аст. Он чизе ки мо тавонистем:

  • Мо ба он назар кардем, ки GPU чист ва сервереро, ки дар он насб шудааст, интихоб кардем;
  • Мо барои эҷоди шабакаи нейрон муҳити нармафзорро таъсис додем;
  • Мо шабакаи нейронро барои шинохти тасвир эҷод кардем ва онро омӯзонидем;
  • Мо омӯзиши шабакаро бо истифода аз GPU такрор кардем ва суръатро афзоиш додем.

Ман хурсандам, ки ба саволҳо дар шарҳҳо ҷавоб диҳам.

Манбаъ: will.com

Илова Эзоҳ