Yn dit artikel sil ik jo fertelle hoe't jo in masine-learomjouwing yn 30 minuten kinne ynstelle, in neuraal netwurk meitsje foar ôfbyldingsherkenning, en dan itselde netwurk útfiere op in grafyske prosessor (GPU).
Litte wy earst definiearje wat in neural netwurk is.
Yn ús gefal, dit is in wiskundige model, likegoed as syn software of hardware belichaming, boud op it prinsipe fan organisaasje en funksjonearjen fan biologyske neuronale netwurken - netwurken fan senuwsellen fan in libbene organisme. Dit konsept ûntstie by it bestudearjen fan de prosessen dy't foarkomme yn 'e harsens en besykje dizze prosessen te modellearjen.
Neurale netwurken binne net programmearre yn 'e gewoane sin fan it wurd, se wurde oplaat. De mooglikheid om te learen is ien fan 'e wichtichste foardielen fan neurale netwurken boppe tradisjonele algoritmen. Technysk bestiet learen út it finen fan de koeffizienten fan ferbiningen tusken neuroanen. Tidens it trainingsproses is it neurale netwurk yn steat om komplekse ôfhinklikens te identifisearjen tusken ynfiergegevens en útfiergegevens, en ek generalisaasje útfiere.
Fanút it eachpunt fan masine learen is in neural netwurk in spesjaal gefal fan metoaden foar patroanherkenning, diskriminearjende analyze, klusteringmetoaden en oare metoaden.
Wetter - Agrarwetter
Litte wy earst nei de apparatuer sjen. Wy hawwe in tsjinner nedich mei it Linux-bestjoeringssysteem derop ynstalleare. De apparatuer dy't nedich is om masine-learsystemen te betsjinjen is frij krêftich en, as gefolch, djoer. Foar dyjingen dy't gjin goede masine by de hân hawwe, advisearje ik omtinken te jaan oan de oanbiedingen fan wolkproviders. Jo kinne de fereaske tsjinner fluch hiere en allinich betelje foar de tiid fan gebrûk.
Yn projekten wêr't it nedich is om neurale netwurken te meitsjen, brûk ik de servers fan ien fan 'e Russyske wolkproviders. It bedriuw biedt wolkservers te hier spesifyk foar masine-learen mei krêftige Tesla V100-grafyske processors (GPU) fan NVIDIA. Koartsein: it brûken fan in tsjinner mei in GPU kin tsientallen kearen effisjinter (snel) wêze yn ferliking mei in server fan ferlykbere kosten dy't in CPU (de bekende sintrale ferwurkingsienheid) brûkt foar berekkeningen. Dit wurdt berikt troch de funksjes fan 'e GPU-arsjitektuer, dy't rapper omgaat mei berekkeningen.
Om de hjirûnder beskreaune foarbylden út te fieren, kochten wy de folgjende server foar ferskate dagen:
- SSD skiif 150 GB
- RAM 32 GB
- Tesla V100 16 Gb prosessor mei 4 kearnen
Wy ynstalleare Ubuntu 18.04 op ús masine.
It opsetten fan it miljeu
Litte wy no alles ynstallearje dat nedich is foar wurk op 'e tsjinner. Sûnt ús artikel is benammen foar begjinners, Ik sil prate oer guon punten dy't sil wêze nuttich foar harren.
In protte fan it wurk by it ynstellen fan in omjouwing wurdt dien fia de kommandorigel. De measte brûkers brûke Windows as har wurkjende OS. De standertkonsole yn dit OS lit in protte te winskjen oer. Dêrom sille wy in handich ark brûke
ssh root@server-ip-or-hostname
Ynstee fan server-ip-of-hostnamme, spesifisearje it IP-adres of DNS-namme fan jo server. Fier dan it wachtwurd yn en as de ferbining suksesfol is, moatte wy in berjocht krije dat fergelykber is mei dit.
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-74-generic x86_64)
De haadtaal foar it ûntwikkeljen fan ML-modellen is Python. En it populêrste platfoarm foar syn gebrûk op Linux is
Litte wy it ynstallearje op ús server.
Wy begjinne mei it bywurkjen fan de lokale pakketbehearder:
sudo apt-get update
Ynstallearje curl (kommando-rigelprogramma):
sudo apt-get install curl
Download de lêste ferzje fan Anaconda Distribution:
cd /tmp
curl –O https://repo.anaconda.com/archive/Anaconda3-2019.10-Linux-x86_64.sh
Litte wy de ynstallaasje begjinne:
bash Anaconda3-2019.10-Linux-x86_64.sh
Tidens it ynstallaasjeproses wurde jo frege om de lisinsje-oerienkomst te befêstigjen. Nei suksesfolle ynstallaasje moatte jo dit sjen:
Thank you for installing Anaconda3!
In protte kaders binne no makke foar de ûntwikkeling fan ML-modellen dy't wy wurkje mei de populêrste:
It brûken fan it ramt lit jo de snelheid fan ûntwikkeling ferheegje en klearmakke ark brûke foar standerttaken.
Yn dit foarbyld sille wy wurkje mei PyTorch. Litte wy it ynstallearje:
conda install pytorch torchvision cudatoolkit=10.1 -c pytorch
No moatte wy Jupyter Notebook lansearje, in populêr ûntwikkelingsark foar ML-spesjalisten. It lit jo koade skriuwe en fuortendaliks de resultaten fan syn útfiering sjen. Jupyter Notebook is opnommen mei Anaconda en is al ynstalleare op ús server. Jo moatte dermei ferbine fanút ús buroblêdsysteem.
Om dit te dwaan, sille wy Jupyter earst starte op 'e server dy't poarte 8080 spesifisearret:
jupyter notebook --no-browser --port=8080 --allow-root
Folgjende, iepenje in oare ljepper yn ús Cmder konsole (topmenu - Nije konsole dialooch) wy sille ferbine fia poarte 8080 mei de tsjinner fia SSH:
ssh -L 8080:localhost:8080 root@server-ip-or-hostname
As wy it earste kommando ynfiere, sille wy keppelings wurde oanbean om Jupyter yn ús browser te iepenjen:
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
Litte wy de keppeling brûke foar localhost: 8080. Kopiearje it folsleine paad en plak it yn 'e adresbalke fan jo lokale browser fan jo PC. Jupyter Notebook sil iepenje.
Litte wy in nij notebook oanmeitsje: Nij - Notebook - Python 3.
Litte wy de juste wurking fan alle komponinten kontrolearje dy't wy ynstalleare. Litte wy it foarbyld PyTorch-koade yn Jupyter ynfiere en de útfiering útfiere (knop Run):
from __future__ import print_function
import torch
x = torch.rand(5, 3)
print(x)
It resultaat moat sa'n ding wêze:
As jo in ferlykber resultaat hawwe, dan hawwe wy alles goed konfigureare en kinne wy begjinne mei it ûntwikkeljen fan in neural netwurk!
It meitsjen fan in neural netwurk
Wy sille in neural netwurk meitsje foar ôfbyldingsherkenning. Litte wy dit as basis nimme
Wy sille de publyklik beskikbere CIFAR10-dataset brûke om it netwurk te trenen. It hat klassen: "fleantúch", "auto", "fûgel", "kat", "hert", "hûn", "kikkert", "hynder", "skip", "truck". Ofbyldings yn CIFAR10 binne 3x32x32, dat is 3-kanaal kleurôfbyldings fan 32x32 piksels.
Foar wurk sille wy it pakket brûke dat is makke troch PyTorch foar wurkjen mei ôfbyldings - torchvision.
Wy sille de folgjende stappen yn folchoarder dwaan:
- Laden en normalisearjen fan trainings- en testgegevenssets
- Neural Network Definition
- Netwurktraining op trainingsgegevens
- Netwurk testen op testgegevens
- Litte wy training en testen werhelje mei GPU
Wy sille alle koade hjirûnder útfiere yn Jupyter Notebook.
CIFAR10 laden en normalisearje
Kopiearje en útfiere de folgjende koade yn 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')
It antwurd moat wêze:
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
Litte wy ferskate trainingsôfbyldings werjaan foar testen:
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)))
Neural Network Definition
Litte wy earst beskôgje hoe't in neuraal netwurk foar ôfbyldingsherkenning wurket. Dit is in ienfâldich punt-to-punt netwurk. It nimt ynfiergegevens, giet it troch ferskate lagen ien foar ien, en produsearret dan úteinlik útfiergegevens.
Litte wy in ferlykber netwurk meitsje yn ús omjouwing:
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()
Wy definiearje ek in ferliesfunksje en in optimizer
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
Netwurktraining op trainingsgegevens
Litte wy ús neurale netwurk begjinne te trainen. Tink derom dat jo nei't jo dizze koade útfiere, wat tiid moatte wachtsje oant it wurk foltôge is. It duorre my 5 minuten. It duorret tiid om it netwurk te trenen.
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')
Wy krije it folgjende resultaat:
Wy bewarje ús trained model:
PATH = './cifar_net.pth'
torch.save(net.state_dict(), PATH)
Netwurk testen op testgegevens
Wy trainden it netwurk mei in set trainingsgegevens. Mar wy moatte kontrolearje oft it netwurk al wat leard hat.
Wy sille dit testen troch it klasseetiket te foarsizzen dat it neuronale netwurk útfiert en it testen om te sjen oft it wier is. As de foarsizzing goed is, foegje wy de stekproef ta oan de list mei juste foarsizzings.
Litte wy in ôfbylding sjen litte fan 'e testset:
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)))
Litte wy no it neurale netwurk freegje om ús te fertellen wat op dizze foto's is:
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)))
De resultaten lykje aardich goed: it netwurk hat trije fan de fjouwer foto's korrekt identifisearre.
Litte wy sjen hoe't it netwurk prestearret oer de heule 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))
It liket derop dat it netwurk wat wit en wurket. As hy de klassen willekeurich bepale, soe de krektens 10% wêze.
Litte wy no sjen hokker klassen it netwurk better identifisearret:
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]))
It liket derop dat it netwurk it bêste is om auto's en skippen te identifisearjen: 71% krektens.
Sa wurket it netwurk. Litte wy no besykje har wurk oer te bringen nei de grafyske prosessor (GPU) en sjen wat der feroaret.
Training in neural netwurk op GPU
Earst sil ik koart útlizze wat CUDA is. CUDA (Compute Unified Device Architecture) is in parallel komputerplatfoarm ûntwikkele troch NVIDIA foar algemiene berekkenjen op grafyske ferwurkingsienheden (GPU's). Mei CUDA kinne ûntwikkelders komputerapplikaasjes dramatysk fersnelle troch de krêft fan GPU's te benutten. Dit platfoarm is al ynstalleare op ús server dy't wy kocht hawwe.
Litte wy earst ús GPU definiearje as it earste sichtbere cuda-apparaat.
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 )
It netwurk ferstjoere nei de GPU:
net.to(device)
Wy sille ek ynputs en doelen moatte stjoere by elke stap nei de GPU:
inputs, labels = data[0].to(device), data[1].to(device)
Litte wy it netwurk opnij traine op 'e 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')
Dizze kear duorre de netwurktraining sa'n 3 minuten. Lit ús ûnthâlde dat itselde poadium op in konvinsjonele prosessor duorre 5 minuten. It ferskil is net signifikant, dit bart om't ús netwurk net sa grut is. By it brûken fan grutte arrays foar training sil it ferskil tusken de snelheid fan 'e GPU en in tradisjonele prosessor tanimme.
Dat liket alles te wêzen. Wat wy slagge om te dwaan:
- Wy seagen wat in GPU is en selekteare de tsjinner wêrop it ynstalleare is;
- Wy hawwe in software-omjouwing ynsteld om in neural netwurk te meitsjen;
- Wy makken in neural netwurk foar byld erkenning en trained it;
- Wy werhelle de netwurktraining mei de GPU en krigen in ferheging fan snelheid.
Ik sil bliid wêze om fragen te beantwurdzjen yn 'e kommentaren.
Boarne: www.habr.com