Ushbu maqolada men sizga 30 daqiqada mashinani o'rganish muhitini qanday sozlashni, tasvirni aniqlash uchun neyron tarmoqni yaratishni va keyin xuddi shu tarmoqni grafik protsessorda (GPU) ishga tushirishni aytib beraman.
Birinchidan, neyron tarmoq nima ekanligini aniqlaymiz.
Bizning holatda, bu matematik model, shuningdek, biologik neyron tarmoqlarni - tirik organizmning asab hujayralari tarmoqlarini tashkil etish va ishlash tamoyiliga asoslangan dasturiy ta'minot yoki apparat timsoli. Bu kontseptsiya miyada sodir bo'ladigan jarayonlarni o'rganish va bu jarayonlarni modellashtirishga harakat qilish paytida paydo bo'lgan.
Neyron tarmoqlar so'zning odatiy ma'nosida dasturlashtirilmagan, ular o'qitilgan. O'rganish qobiliyati neyron tarmoqlarning an'anaviy algoritmlarga nisbatan asosiy afzalliklaridan biridir. Texnik jihatdan o'rganish neyronlar orasidagi bog'lanish koeffitsientlarini topishdan iborat. O'quv jarayonida neyron tarmoq kirish ma'lumotlari va chiqish ma'lumotlari o'rtasidagi murakkab bog'liqlikni aniqlashga, shuningdek umumlashtirishni amalga oshirishga qodir.
Mashinani o'rganish nuqtai nazaridan neyron tarmoq naqshni aniqlash usullari, diskriminant tahlili, klasterlash usullari va boshqa usullarning alohida holatidir.
uskunalar
Birinchidan, uskunani ko'rib chiqaylik. Bizga Linux operatsion tizimi o'rnatilgan server kerak. Mashinani o'rganish tizimlarini ishlatish uchun zarur bo'lgan uskunalar juda kuchli va natijada qimmat. Qo'lida yaxshi mashinaga ega bo'lmaganlar uchun bulutli provayderlarning takliflariga e'tibor berishni maslahat beraman. Siz kerakli serverni tezda ijaraga olishingiz va faqat foydalanish vaqti uchun to'lashingiz mumkin.
Neyron tarmoqlarni yaratish zarur bo'lgan loyihalarda men rus bulut provayderlaridan birining serverlaridan foydalanaman. Kompaniya NVIDIA’dan kuchli Tesla V100 grafik protsessorlari (GPU) bilan mashinani o‘rganish uchun bulutli serverlarni ijaraga taklif qiladi. Qisqasi: GPU bilan serverdan foydalanish hisob-kitoblar uchun protsessordan (taniqli markaziy protsessor) foydalanadigan shunga o'xshash narxdagi serverga nisbatan o'nlab marta samaraliroq (tezkor) bo'lishi mumkin. Bunga hisob-kitoblarni tezroq bajaradigan GPU arxitekturasining xususiyatlari tufayli erishiladi.
Quyida tasvirlangan misollarni amalga oshirish uchun biz bir necha kun davomida quyidagi serverni sotib oldik:
- SSD disk 150 GB
- RAM 32 GB
- 100 yadroli Tesla V16 4 Gb protsessor
Biz Ubuntu 18.04 ni kompyuterimizga o'rnatdik.
Atrof muhitni sozlash
Endi serverda ishlash uchun zarur bo'lgan hamma narsani o'rnatamiz. Bizning maqolamiz birinchi navbatda yangi boshlanuvchilar uchun bo'lganligi sababli, men ular uchun foydali bo'lgan ba'zi fikrlar haqida gapiraman.
Atrof muhitni o'rnatishda ko'p ish buyruq qatori orqali amalga oshiriladi. Ko'pgina foydalanuvchilar o'zlarining operatsion tizimi sifatida Windows-dan foydalanadilar. Ushbu OSdagi standart konsol ko'p narsani orzu qiladi. Shuning uchun biz qulay vositadan foydalanamiz
ssh root@server-ip-or-hostname
Server-ip-yoki-hostname o'rniga serveringizning IP-manzilini yoki DNS nomini belgilang. Keyin parolni kiriting va agar ulanish muvaffaqiyatli bo'lsa, shunga o'xshash xabarni olishimiz kerak.
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-74-generic x86_64)
ML modellarini ishlab chiqish uchun asosiy til Python hisoblanadi. Va uni Linuxda ishlatish uchun eng mashhur platforma
Keling, uni serverimizga o'rnatamiz.
Biz mahalliy paket menejerini yangilashdan boshlaymiz:
sudo apt-get update
Curl o'rnating (buyruqlar qatori yordam dasturi):
sudo apt-get install curl
Anaconda Distribution-ning so'nggi versiyasini yuklab oling:
cd /tmp
curl –O https://repo.anaconda.com/archive/Anaconda3-2019.10-Linux-x86_64.sh
O'rnatishni boshlaylik:
bash Anaconda3-2019.10-Linux-x86_64.sh
O'rnatish jarayonida sizdan litsenziya shartnomasini tasdiqlash so'raladi. Muvaffaqiyatli o'rnatishdan keyin siz buni ko'rishingiz kerak:
Thank you for installing Anaconda3!
Endi ML modellarini ishlab chiqish uchun ko'plab ramkalar yaratilgan; biz eng mashhurlari bilan ishlaymiz:
Ramkadan foydalanish rivojlanish tezligini oshirish va standart vazifalar uchun tayyor vositalardan foydalanish imkonini beradi.
Ushbu misolda biz PyTorch bilan ishlaymiz. Keling, uni o'rnatamiz:
conda install pytorch torchvision cudatoolkit=10.1 -c pytorch
Endi biz ML mutaxassislari uchun mashhur ishlab chiqish vositasi bo'lgan Jupyter Notebook-ni ishga tushirishimiz kerak. Bu sizga kod yozish va uning bajarilishi natijalarini darhol ko'rish imkonini beradi. Jupyter Notebook Anaconda-ga kiritilgan va bizning serverimizga allaqachon o'rnatilgan. Unga ish stolimiz tizimidan ulanishingiz kerak.
Buni amalga oshirish uchun avval 8080 portini ko'rsatuvchi serverda Jupyterni ishga tushiramiz:
jupyter notebook --no-browser --port=8080 --allow-root
Keyin, Cmder konsolida boshqa yorliqni ochib (yuqori menyu - Yangi konsol dialog oynasi) biz 8080 port orqali serverga SSH orqali ulanamiz:
ssh -L 8080:localhost:8080 root@server-ip-or-hostname
Birinchi buyruqni kiritganimizda, bizga brauzerimizda Jupyterni ochish uchun havolalar taklif etiladi:
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
Keling, localhost:8080 uchun havoladan foydalanamiz. To'liq yo'ldan nusxa oling va uni shaxsiy kompyuteringizning mahalliy brauzerining manzil satriga joylashtiring. Jupyter Notebook ochiladi.
Keling, yangi daftar yaratamiz: New - Notebook - Python 3.
Keling, biz o'rnatgan barcha komponentlarning to'g'ri ishlashini tekshiramiz. Keling, misol PyTorch kodini Jupyter-ga kiritamiz va ijroni ishga tushiramiz (Run tugmasi):
from __future__ import print_function
import torch
x = torch.rand(5, 3)
print(x)
Natija shunday bo'lishi kerak:
Agar sizda shunga o'xshash natija bo'lsa, biz hamma narsani to'g'ri sozladik va biz neyron tarmoqni rivojlantirishni boshlashimiz mumkin!
Neyron tarmog'ini yaratish
Tasvirni aniqlash uchun neyron tarmoq yaratamiz. Keling, buni asos qilib olaylik
Tarmoqni o'qitish uchun biz hammaga ochiq CIFAR10 ma'lumotlar to'plamidan foydalanamiz. Uning sinflari mavjud: "samolyot", "avtomobil", "qush", "mushuk", "kiyik", "it", "qurbaqa", "ot", "kema", "yuk mashinasi". CIFAR10-dagi tasvirlar 3x32x32, ya'ni 3x32 pikselli 32 kanalli rangli tasvirlar.
Ish uchun biz PyTorch tomonidan tasvirlar bilan ishlash uchun yaratilgan paketdan foydalanamiz - torchvision.
Biz quyidagi bosqichlarni tartibda bajaramiz:
- O'quv va test ma'lumotlar to'plamlarini yuklash va normallashtirish
- Neyron tarmoq ta'rifi
- Trening ma'lumotlari bo'yicha tarmoq treningi
- Sinov ma'lumotlari bo'yicha tarmoq sinovi
- Keling, GPU yordamida trening va testlarni takrorlaymiz
Quyidagi barcha kodlarni Jupyter Notebook da bajaramiz.
CIFAR10ni yuklash va normallashtirish
Jupyter-da quyidagi kodni nusxalash va ishga tushirish:
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')
Javob quyidagicha bo'lishi kerak:
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
Sinov uchun bir nechta o'quv rasmlarini ko'rsatamiz:
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)))
Neyron tarmoq ta'rifi
Keling, avval tasvirni aniqlash uchun neyron tarmoq qanday ishlashini ko'rib chiqaylik. Bu oddiy nuqtadan nuqtaga tarmoq. U kirish ma'lumotlarini oladi, uni bir necha qatlamlardan birma-bir o'tkazadi va nihoyat chiqish ma'lumotlarini ishlab chiqaradi.
Keling, bizning muhitimizda shunga o'xshash tarmoq yarataylik:
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()
Shuningdek, biz yo'qotish funktsiyasi va optimallashtiruvchini aniqlaymiz
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
Trening ma'lumotlari bo'yicha tarmoq treningi
Neyron tarmog'imizni mashq qilishni boshlaylik. E'tibor bering, ushbu kodni ishga tushirgandan so'ng, ish tugaguncha biroz kutishingiz kerak bo'ladi. Menga 5 daqiqa vaqt ketdi. Tarmoqni o'rgatish uchun vaqt kerak bo'ladi.
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')
Biz quyidagi natijani olamiz:
Biz o'qitilgan modelimizni saqlaymiz:
PATH = './cifar_net.pth'
torch.save(net.state_dict(), PATH)
Sinov ma'lumotlari bo'yicha tarmoq sinovi
Biz tarmoqni o'quv ma'lumotlari to'plamidan foydalangan holda o'rgatganmiz. Ammo biz tarmoq umuman biror narsani o'rganganligini tekshirishimiz kerak.
Biz buni neyron tarmoq chiqaradigan sinf yorlig'ini bashorat qilish va uning to'g'ri yoki yo'qligini tekshirish orqali sinab ko'ramiz. Agar bashorat to'g'ri bo'lsa, biz namunani to'g'ri bashoratlar ro'yxatiga qo'shamiz.
Keling, test to'plamidan rasmni ko'rsatamiz:
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)))
Endi neyron tarmoqdan ushbu rasmlarda nima borligini aytib berishini so'raymiz:
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)))
Natijalar juda yaxshi ko'rinadi: tarmoq to'rtta rasmdan uchtasini to'g'ri aniqladi.
Keling, tarmoq butun ma'lumotlar to'plamida qanday ishlashini ko'rib chiqaylik.
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))
Tarmoq nimanidir biladi va ishlayotganga o'xshaydi. Agar u tasodifiy sinflarni aniqlasa, aniqlik 10% ni tashkil qiladi.
Keling, tarmoq qaysi sinflarni yaxshiroq aniqlashini ko'rib chiqaylik:
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]))
Aftidan, tarmoq avtomobillar va kemalarni aniqlashda eng yaxshisi: 71% aniqlik.
Shunday qilib, tarmoq ishlaydi. Endi uning ishini grafik protsessorga (GPU) o'tkazishga harakat qilaylik va qanday o'zgarishlarni ko'ramiz.
GPU-da neyron tarmoqni o'rgatish
Birinchidan, men CUDA nima ekanligini qisqacha tushuntiraman. CUDA (Compute Unified Device Architecture) - NVIDIA tomonidan grafik ishlov berish birliklarida (GPU) umumiy hisoblash uchun ishlab chiqilgan parallel hisoblash platformasi. CUDA yordamida ishlab chiquvchilar GPU quvvatidan foydalangan holda hisoblash ilovalarini keskin tezlashtirishi mumkin. Ushbu platforma allaqachon biz sotib olgan serverimizga o'rnatilgan.
Keling, birinchi navbatda GPU-ni birinchi ko'rinadigan cuda qurilmasi sifatida aniqlaylik.
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 )
Tarmoqni GPUga yuborish:
net.to(device)
Shuningdek, biz GPUga har bir qadamda kirish va maqsadlarni yuborishimiz kerak bo'ladi:
inputs, labels = data[0].to(device), data[1].to(device)
Keling, tarmoqni GPU-da qayta o'rgatamiz:
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 safar tarmoq treningi taxminan 3 daqiqa davom etdi. Eslatib o'tamiz, an'anaviy protsessorda xuddi shu bosqich 5 daqiqa davom etgan. Farqi muhim emas, bu bizning tarmog'imiz unchalik katta emasligi sababli sodir bo'ladi. Trening uchun katta massivlardan foydalanganda GPU tezligi va an'anaviy protsessor o'rtasidagi farq ortadi.
Hammasi shu kabi ko'rinadi. Biz nimaga erishdik:
- Biz GPU nima ekanligini ko'rib chiqdik va u o'rnatilgan serverni tanladik;
- Biz neyron tarmoqni yaratish uchun dasturiy muhitni o'rnatdik;
- Biz tasvirni aniqlash uchun neyron tarmog'ini yaratdik va uni o'rgatdi;
- Biz GPU yordamida tarmoq treningini takrorladik va tezlikni oshirdik.
Izohlarda savollarga javob berishdan xursand bo'laman.
Manba: www.habr.com