Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi
Bu yazıda sizə 30 dəqiqə ərzində maşın öyrənmə mühitinin necə qurulacağını, təsvirin tanınması üçün neyron şəbəkəsinin yaradılmasını və sonra eyni şəbəkəni qrafik prosessorda (GPU) necə işlətəcəyini söyləyəcəyəm.

Əvvəlcə neyron şəbəkənin nə olduğunu müəyyən edək.

Bizim vəziyyətimizdə bu, bioloji neyron şəbəkələrinin - canlı orqanizmin sinir hüceyrələrinin şəbəkələrinin təşkili və işləməsi prinsipi əsasında qurulmuş riyazi model, eləcə də onun proqram və ya aparat təcəssümüdür. Bu konsepsiya beyində baş verən prosesləri öyrənərkən və bu prosesləri modelləşdirməyə çalışarkən yaranıb.

Neyron şəbəkələri sözün adi mənasında proqramlaşdırılmır, öyrədilir. Öyrənmək bacarığı neyron şəbəkələrin ənənəvi alqoritmlərə nisbətən əsas üstünlüklərindən biridir. Texniki cəhətdən öyrənmə neyronlar arasındakı əlaqə əmsallarını tapmaqdan ibarətdir. Təlim prosesi zamanı neyroşəbəkə daxilolma məlumatları ilə çıxış məlumatları arasında mürəkkəb asılılıqları müəyyən edə, həmçinin ümumiləşdirmə apara bilir.

Maşın öyrənməsi nöqteyi-nəzərindən neyron şəbəkə nümunənin tanınması üsulları, diskriminant analizi, klasterləşdirmə metodları və digər üsulların xüsusi halıdır.

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

Əvvəlcə avadanlıqlara baxaq. Bizə Linux əməliyyat sistemi quraşdırılmış server lazımdır. Maşın öyrənmə sistemlərini idarə etmək üçün tələb olunan avadanlıq kifayət qədər güclüdür və nəticədə bahalıdır. Əlində yaxşı bir maşını olmayanlar üçün bulud provayderlərinin təkliflərinə diqqət yetirməyi məsləhət görürəm. Siz tələb olunan serveri tez bir zamanda icarəyə götürə və yalnız istifadə müddətinə görə ödəyə bilərsiniz.

Neyron şəbəkələri yaratmaq lazım olan layihələrdə mən Rusiyanın bulud provayderlərindən birinin serverlərindən istifadə edirəm. Şirkət NVIDIA-dan güclü Tesla V100 qrafik prosessorları (GPU) ilə maşın öyrənməsi üçün xüsusi olaraq bulud serverlərini icarəyə təklif edir. Qısacası: GPU ilə serverdən istifadə, hesablamalar üçün CPU (tanınmış mərkəzi prosessor) istifadə edən oxşar dəyəri olan serverlə müqayisədə onlarla dəfə daha səmərəli (sürətli) ola bilər. Bu, hesablamalarla daha sürətli məşğul olan GPU arxitekturasının xüsusiyyətləri sayəsində əldə edilir.

Aşağıda təsvir edilən nümunələri həyata keçirmək üçün bir neçə gün ərzində aşağıdakı serveri satın aldıq:

  • SSD disk 150 GB
  • RAM 32 GB
  • Tesla V100 16 nüvəli 4 Gb prosessor

Maşınımıza Ubuntu 18.04 quraşdırdıq.

Ətraf mühitin qurulması

İndi serverdə işləmək üçün lazım olan hər şeyi quraşdıraq. Məqaləmiz ilk növbədə yeni başlayanlar üçün olduğundan, onlara faydalı olacaq bəzi məqamlardan danışacağam.

Bir mühit qurarkən bir çox iş komanda xətti vasitəsilə həyata keçirilir. İstifadəçilərin əksəriyyəti Windows əməliyyat sistemi kimi istifadə edirlər. Bu OS-dəki standart konsol arzuolunan çox şey buraxır. Buna görə də rahat bir vasitədən istifadə edəcəyik Cmder/. Mini versiyanı yükləyin və Cmder.exe proqramını işə salın. Sonra SSH vasitəsilə serverə qoşulmalısınız:

ssh root@server-ip-or-hostname

Server-ip-və ya-hostname əvəzinə serverinizin IP ünvanını və ya DNS adını göstərin. Sonra, parolu daxil edin və əlaqə uğurlu olarsa, buna bənzər bir mesaj almalıyıq.

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

ML modellərinin inkişafı üçün əsas dil Python-dur. Linux-da istifadəsi üçün ən populyar platformadır Anakonda.

Gəlin onu serverimizə quraşdıraq.

Yerli paket menecerini yeniləməyə başlayırıq:

sudo apt-get update

Curl quraşdırın (komanda xətti yardım proqramı):

sudo apt-get install curl

Anaconda Distribution-ın son versiyasını yükləyin:

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

Quraşdırmaya başlayaq:

bash Anaconda3-2019.10-Linux-x86_64.sh

Quraşdırma prosesi zamanı sizdən lisenziya müqaviləsini təsdiqləməyiniz xahiş olunacaq. Uğurlu quraşdırmadan sonra bunu görməlisiniz:

Thank you for installing Anaconda3!

İndi ML modellərinin inkişafı üçün bir çox çərçivə yaradılmışdır, biz ən populyarları ilə işləyirik: PyTorch и Tensor axını.

Çərçivədən istifadə inkişaf sürətini artırmağa və standart tapşırıqlar üçün hazır alətlərdən istifadə etməyə imkan verir.

Bu nümunədə biz PyTorch ilə işləyəcəyik. Onu quraşdıraq:

conda install pytorch torchvision cudatoolkit=10.1 -c pytorch

İndi biz ML mütəxəssisləri üçün məşhur inkişaf aləti olan Jupyter Notebook-u işə salmalıyıq. O, kod yazmağa və onun icrasının nəticələrini dərhal görməyə imkan verir. Jupyter Notebook Anaconda ilə birlikdədir və artıq serverimizdə quraşdırılıb. Siz ona masaüstü sistemimizdən qoşulmalısınız.

Bunu etmək üçün əvvəlcə 8080 portunu təyin edən serverdə Jupyter-i işə salacağıq:

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

Sonra, Cmder konsolumuzda başqa bir nişanı açaraq (yuxarı menyu - Yeni konsol dialoqu) SSH vasitəsilə serverə 8080 portu vasitəsilə qoşulacağıq:

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

İlk əmri daxil etdikdə bizə brauzerimizdə Jupyter-i açmaq üçün linklər təklif olunacaq:

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 üçün keçiddən istifadə edək. Tam yolu kopyalayın və kompüterinizin yerli brauzerinin ünvan çubuğuna yapışdırın. Jupyter Notebook açılacaq.

Gəlin yeni notebook yaradaq: New - Notebook - Python 3.

Quraşdırdığımız bütün komponentlərin düzgün işləməsini yoxlayaq. Gəlin nümunə PyTorch kodunu Jupyter-ə daxil edək və icranı icra edək (Run düyməsi):

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

Nəticə belə bir şey olmalıdır:

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

Bənzər bir nəticəniz varsa, onda biz hər şeyi düzgün şəkildə konfiqurasiya etdik və neyron şəbəkəsini inkişaf etdirməyə başlaya bilərik!

Neyron şəbəkəsinin yaradılması

Təsvirin tanınması üçün neyroşəbəkə yaradacağıq. Bunu əsas götürək bələdçi.

Şəbəkəni öyrətmək üçün ictimaiyyətə açıq olan CIFAR10 məlumat dəstindən istifadə edəcəyik. Onun sinifləri var: "təyyarə", "avtomobil", "quş", "pişik", "maral", "it", "qurbağa", "at", "gəmi", "yük maşını". CIFAR10-da təsvirlər 3x32x32, yəni 3x32 piksellik 32 kanallı rəngli şəkillərdir.

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi
İş üçün PyTorch tərəfindən şəkillərlə işləmək üçün yaradılmış paketdən istifadə edəcəyik - torchvision.

Aşağıdakı addımları ardıcıllıqla edəcəyik:

  • Təlim və test məlumat dəstlərinin yüklənməsi və normallaşdırılması
  • Neyron Şəbəkə Tərifi
  • Təlim məlumatları üzrə şəbəkə təlimi
  • Test məlumatlarında şəbəkə testi
  • GPU istifadə edərək məşq və testləri təkrarlayaq

Aşağıdakı bütün kodları Jupyter Notebook-da icra edəcəyik.

CIFAR10 yüklənir və normallaşdırılır

Jupyter-də aşağıdakı kodu kopyalayın və işə salın:


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

Cavab belə olmalıdır:

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

Test üçün bir neçə təlim şəklini göstərək:


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

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

Neyron Şəbəkə Tərifi

Əvvəlcə təsvirin tanınması üçün neyron şəbəkəsinin necə işlədiyini nəzərdən keçirək. Bu sadə bir nöqtədən nöqtəyə şəbəkəsidir. Giriş məlumatlarını götürür, onları bir-bir bir neçə təbəqədən keçir və nəhayət, çıxış məlumatlarını istehsal edir.

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

Gəlin öz mühitimizdə oxşar şəbəkə yaradaq:


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

Biz həmçinin itki funksiyasını və optimallaşdırıcını müəyyən edirik


import torch.optim as optim

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

Təlim məlumatları üzrə şəbəkə təlimi

Neyron şəbəkəmizi məşq etməyə başlayaq. Nəzərə alın ki, bu kodu işə saldıqdan sonra iş tamamlanana qədər bir müddət gözləməli olacaqsınız. Mənə 5 dəqiqə çəkdi. Şəbəkəni öyrətmək üçün vaxt lazımdır.

 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şağıdakı nəticəni alırıq:

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

Təlim edilmiş modelimizi saxlayırıq:

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

Test məlumatlarında şəbəkə testi

Bir sıra təlim məlumatlarından istifadə edərək şəbəkəni öyrətdik. Ancaq şəbəkənin ümumiyyətlə bir şey öyrənib-öyrənmədiyini yoxlamaq lazımdır.

Biz bunu neyron şəbəkənin çıxardığı sinif etiketini proqnozlaşdırmaqla və bunun doğru olub olmadığını yoxlamaqla sınaqdan keçirəcəyik. Proqnoz düzgündürsə, nümunəni düzgün proqnozlar siyahısına əlavə edirik.
Test dəstindən bir şəkil göstərək:

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

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

İndi neyron şəbəkədən bu şəkillərdə nə olduğunu bizə bildirməsini xahiş edək:


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

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

Nəticələr olduqca yaxşı görünür: şəbəkə dörd şəkildən üçünü düzgün müəyyənləşdirdi.

Şəbəkənin bütün verilənlər bazasında necə fəaliyyət göstərdiyini görək.


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

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

Görünür, şəbəkə nəyisə bilir və işləyir. O, sinifləri təsadüfi olaraq təyin etsəydi, dəqiqlik 10% olardı.

İndi şəbəkənin hansı sinifləri daha yaxşı müəyyən etdiyinə baxaq:

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

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

Görünür, şəbəkə avtomobilləri və gəmiləri müəyyən etməkdə ən yaxşısıdır: 71% dəqiqlik.

Beləliklə, şəbəkə işləyir. İndi onun işini qrafik prosessoruna (GPU) köçürməyə çalışaq və nə dəyişdiyini görək.

GPU-da neyron şəbəkəsinin öyrədilməsi

Əvvəlcə CUDA-nın nə olduğunu qısaca izah edəcəyəm. CUDA (Compute Unified Device Architecture) qrafik emal vahidlərində (GPU) ümumi hesablamalar üçün NVIDIA tərəfindən hazırlanmış paralel hesablama platformasıdır. CUDA ilə tərtibatçılar GPU-ların gücündən istifadə etməklə hesablama proqramlarını kəskin surətdə sürətləndirə bilərlər. Bu platforma artıq satın aldığımız serverimizdə quraşdırılıb.

Əvvəlcə GPU-muzu ilk görünən cuda cihazı olaraq təyin edək.

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 )

Qrafik emal bölməsində (GPU) ilk neyron şəbəkəniz. Başlayanlar üçün Bələdçi

Şəbəkənin GPU-ya göndərilməsi:

net.to(device)

GPU-ya hər addımda giriş və hədəfləri də göndərməli olacağıq:

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

Şəbəkəni GPU-da yenidən məşq edək:

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

Bu dəfə şəbəkə təlimi 3 dəqiqəyə yaxın davam edib. Yada salaq ki, adi prosessorda eyni mərhələ 5 dəqiqə davam edirdi. Fərq əhəmiyyətli deyil, bu bizim şəbəkəmiz o qədər də böyük olmadığı üçün baş verir. Təlim üçün böyük massivlərdən istifadə edərkən, GPU ilə ənənəvi prosessorun sürəti arasındakı fərq artacaq.

Deyəsən hamısı budur. Nəyi bacardıq:

  • GPU-nun nə olduğuna baxdıq və onun quraşdırıldığı serveri seçdik;
  • Biz neyroşəbəkə yaratmaq üçün proqram mühiti qurmuşuq;
  • Biz təsvirin tanınması üçün neyron şəbəkə yaratdıq və onu öyrətdik;
  • GPU-dan istifadə edərək şəbəkə təlimini təkrarladıq və sürətdə artım əldə etdik.

Şərhlərdə suallara cavab verməkdən məmnun olaram.

Mənbə: www.habr.com

Добавить комментарий