PyTorch-veiledning: Regresjon, eksempel på bildeklassifisering

Pytorch opplæringssammendrag

I denne pytorch-opplæringen lærer du alle konseptene fra bunnen av. Denne opplæringen dekker grunnleggende til avanserte emner som pytorch-definisjon, fordeler og ulemper med pytorch, sammenligning, installasjon, pytorch-rammeverk, regresjon og bildeklassifisering. Denne pytorch-opplæringen er helt gratis.

Hva er PyTorch?

PyTorch er et åpen kildekode Torch-basert maskinlæringsbibliotek for naturlig språkbehandling ved hjelp av Python. Det ligner på NumPy, men med kraftig GPU-støtte. Den tilbyr Dynamic Computational Graphs som du kan endre mens du er på farten ved hjelp av autograd. PyTorch er også raskere enn noen andre rammeverk. Den ble utviklet av Facebooks AI Research Group i 2016.

PyTorch fordeler og ulemper

Følgende er fordelene og ulempene med PyTorch:

Fordeler med PyTorch

  1. Enkelt bibliotek
    PyTorch-koden er enkel. Det er lett å forstå, og du bruker biblioteket umiddelbart. Ta for eksempel en titt på kodebiten nedenfor:
class Net(torch.nn.Module):
   def __init__(self):
       super(Net, self).__init__()
       self.layer = torch.nn.Linear(1, 1)

   def forward(self, x):
       x = self.layer(x)      
       return x

Som nevnt ovenfor kan du enkelt definere nettverksmodellen, og du kan raskt forstå koden uten mye trening.

  1. Dynamisk beregningsgraf

Dynamisk beregningsgraf

Bildekilde: Exploring Deep Learning med PyTorch

Pytorch tilbyr Dynamic Computational Graph (DAG). Beregningsgrafer er en måte å uttrykke matematiske uttrykk i grafmodeller eller teorier som noder og kanter. Noden vil utføre den matematiske operasjonen, og kanten er en Tensor som vil mates inn i nodene og bærer utgangen fra noden i Tensor.

DAG er en graf som har vilkårlig form og i stand til å utføre operasjoner mellom forskjellige inndatagrafer. Hver iterasjon opprettes en ny graf. Så det er mulig å ha samme grafstruktur eller lage en ny graf med en annen operasjon, eller vi kan kalle det en dynamisk graf.

  1. Bedre ytelse

Fellesskap og forskere, benchmark og sammenligne rammeverk for å se hvilken som er raskere. En GitHub-repo Benchmark på Deep Learning Frameworks og GPUer rapporterte at PyTorch er raskere enn det andre rammeverket når det gjelder bilder behandlet per sekund.

Som du kan se nedenfor, viser sammenligningsgrafene med vgg16 og resnet152

Fordeler med PyTorch

Fordeler med PyTorch

  1. Innfødt Python

PyTorch er mer pythonbasert. Hvis du for eksempel ønsker å trene en modell, kan du bruke innfødt kontrollflyt som looping og rekursjoner uten å måtte legge til flere spesielle variabler eller økter for å kunne kjøre dem. Dette er veldig nyttig for opplæringsprosessen.

Pytorch implementerer også imperativ programmering, og det er definitivt mer fleksibelt. Så det er mulig å skrive ut tensorverdien midt i en beregningsprosess.

Ulempen med PyTorch

PyTorch krever tredjepartsapplikasjoner for visualisering. Den trenger også en API-server for produksjon.

Neste i denne PyTorch-opplæringen vil vi lære om forskjellen mellom PyTorch og TensorFlow.

PyTorch vs. Tensorflow

Parameter PyTorch tensorflow
Modelldefinisjon Modellen er definert i en underklasse og tilbyr en brukervennlig pakke Modellen er definert med mange, og du må forstå syntaksen
GPU-støtte Ja Ja
Graftype Dynamisk Statisk
verktøy Ingen visualiseringsverktøy Du kan bruke Tensorboard visualiseringsverktøy
fellesskapet Samfunnet vokser fortsatt Store aktive samfunn

Installerer PyTorch

Linux

Det er enkelt å installere det i Linux. Du kan velge å bruke et virtuelt miljø eller installere det direkte med root-tilgang. Skriv inn denne kommandoen i terminalen

pip3 install --upgrade torch torchvision

AWS Sagemaker

Sagemaker er en av plattformene i Amazon Nettjeneste som tilbyr en kraftig maskinlæringsmotor med forhåndsinstallerte dyplæringskonfigurasjoner for dataforskere eller utviklere for å bygge, trene og distribuere modeller i alle skalaer.

Først Åpne Amazon Sagemaker konsollen og klikk på Opprett notatbokforekomst og fyll ut alle detaljene for notatboken.

AWS Sagemaker

Neste trinn, klikk på Åpne for å starte din bærbare forekomst.

AWS Sagemaker

Til slutt, In Jupyter, Klikk på Ny og velg conda_pytorch_p36 og du er klar til å bruke din bærbare instans med Pytorch installert.

Neste i denne PyTorch-opplæringen vil vi lære om grunnleggende PyTorch-rammeverk.

Grunnleggende om PyTorch Framework

La oss lære de grunnleggende konseptene til PyTorch før vi dypdykker. PyTorch bruker Tensor for hver variabel som ligner på numpys ndarray, men med GPU-beregningsstøtte. Her vil vi forklare nettverksmodellen, tapsfunksjonen, Backprop og Optimizer.

Nettverksmodell

Nettverket kan konstrueres ved å underklassifisere fakkelen.nn. Det er 2 hoveddeler,

  1. Den første delen er å definere parameterne og lagene du skal bruke
  2. Den andre delen er hovedoppgaven kalt foroverprosessen som vil ta et input og forutsi utgangen.
Import torch
import torch.nn as nn
import torch.nn.functional as F

class Model(nn.Module):
 def __init__(self):
        super(Model, self).__init__()
        self.conv1 = nn.Conv2d(3, 20, 5)
        self.conv2 = nn.Conv2d(20, 40, 5)
self.fc1 = nn.Linear(320, 10)

def forward(self, x):
       x = F.relu(self.conv1(x))
       x = F.relu(self.conv2(x))
       x = x.view(-1, 320)
       x = F.relu(self.fc1(x))
       return F.log_softmax(x)

net = Model()

Som du kan se ovenfor, oppretter du en klasse av nn.Module kalt Model. Den inneholder 2 Conv2d-lag og et lineært lag. Det første conv2d-laget tar en inngang på 3 og utgangsformen på 20. Det andre laget vil ha en input på 20 og vil produsere en utgangsform på 40. Det siste laget er et fullstendig koblet lag i form av 320 og vil produsere en utgang på 10.

Fremoverprosessen vil ta en inngang fra X og mate den til conv1-laget og utføre ReLU-funksjonen,

På samme måte vil den også mate conv2-laget. Etter det vil x-en omformes til (-1, 320) og føres inn i det endelige FC-laget. Før du sender utdataene, vil du bruke softmax aktiveringsfunksjonen.

Bakover prosessen er automatisk definert av autograd, så du trenger bare å definere fremover prosessen.

Tap Funksjon

Tapsfunksjonen brukes til å måle hvor godt prediksjonsmodellen er i stand til å forutsi de forventede resultatene. PyTorch har allerede mange standard tapsfunksjoner i torch.nn-modulen. For eksempel kan du bruke Cross-Entropy Loss for å løse et flerklasses PyTorch-klassifiseringsproblem. Det er enkelt å definere tapsfunksjonen og beregne tapene:

loss_fn = nn.CrossEntropyLoss()

#training process
loss = loss_fn(out, target)

Det er enkelt å bruke din egen tapsfunksjonsberegning med PyTorch.

Ryggpropp

For å utføre tilbakepropageringen kaller du ganske enkelt los.backward(). Feilen vil bli beregnet, men husk å fjerne den eksisterende gradienten med zero_grad()

net.zero_grad() # to clear the existing gradient
loss.backward() # to perform backpropragation

Optimizer

Torch.optim gir vanlige optimaliseringsalgoritmer. Du kan definere en optimizer med et enkelt trinn:

optimizer = torch.optim.SGD(net.parameters(), lr = 0.01, momentum=0.9)

Du må sende nettverksmodellparametrene og læringshastigheten slik at parameterne ved hver iterasjon vil bli oppdatert etter backprop-prosessen.

Enkel regresjon med PyTorch

La oss lære enkel regresjon med PyTorch-eksempler:

Trinn 1) Opprette vår nettverksmodell

Nettverksmodellen vår er et enkelt lineært lag med en inngangs- og utgangsform på 1.

from __future__ import print_function

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.autograd import Variable

class Net(nn.Module):
   def __init__(self):
       super(Net, self).__init__()
       self.layer = torch.nn.Linear(1, 1)

   def forward(self, x):
       x = self.layer(x)      
       return x

net = Net()
print(net)

Og nettverksutgangen skal være slik

Net(
  (hidden): Linear(in_features=1, out_features=1, bias=True)
)

Trinn 2) Testdata

Før du starter opplæringsprosessen, må du kjenne til dataene våre. Du lager en tilfeldig funksjon for å teste modellen vår. Y = x3 sin(x)+ 3x+0.8 rand(100)

# Visualize our data
import matplotlib.pyplot as plt
import numpy as np

x = np.random.rand(100)
y = np.sin(x) * np.power(x,3) + 3*x + np.random.rand(100)*0.8

plt.scatter(x, y)
plt.show()

Her er spredningsplottet for funksjonen vår:

Spredningsplott med enkel regresjon med PyTorch

Før du starter treningsprosessen, må du konvertere numpy-matrisen til variabler som støttes av Torch og autograd som vist i PyTorch-regresjonseksemplet nedenfor.

# convert numpy array to tensor in shape of input size
x = torch.from_numpy(x.reshape(-1,1)).float()
y = torch.from_numpy(y.reshape(-1,1)).float()
print(x, y)

Trinn 3) Optimalisering og tap

Deretter bør du definere optimaliserings- og tapsfunksjonen for treningsprosessen vår.

# Define Optimizer and Loss Function
optimizer = torch.optim.SGD(net.parameters(), lr=0.2)
loss_func = torch.nn.MSELoss()

Trinn 4) Trening

La oss nå starte treningsprosessen. Med en epoke på 250 vil du iterere dataene våre for å finne den beste verdien for hyperparametrene våre.

inputs = Variable(x)
outputs = Variable(y)
for i in range(250):
   prediction = net(inputs)
   loss = loss_func(prediction, outputs) 
   optimizer.zero_grad()
   loss.backward()        
   optimizer.step()       

   if i % 10 == 0:
       # plot and show learning process
       plt.cla()
       plt.scatter(x.data.numpy(), y.data.numpy())
       plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=2)
       plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 10, 'color':  'red'})
       plt.pause(0.1)

plt.show()

Trinn 5) Resultat

Som du kan se nedenfor, utførte du PyTorch-regresjon med et nevralt nettverk. Faktisk, ved hver iterasjon, vil den røde linjen i plottet oppdatere og endre posisjonen for å passe til dataene. Men i dette bildet viser det deg bare det endelige resultatet som vist i PyTorch-eksemplet nedenfor:

Spredningsplott med enkelt regresjonsresultat

Eksempel på bildeklassifisering med PyTorch

En av de populære metodene å lære det grunnleggende om dyp læring er med MNIST-datasettet. Det er "Hello World" innen dyp læring. Datasettet inneholder håndskrevne tall fra 0 – 9 med totalt 60,000 10,000 treningsprøver og 28 28 testprøver som allerede er merket med størrelsen XNUMX×XNUMX piksler.

Bildeklassifisering med PyTorch

Trinn 1) Forbehandle dataene

I det første trinnet i dette PyTorch-klassifiseringseksemplet vil du laste inn datasettet ved hjelp av torchvision-modulen.

Før du starter opplæringsprosessen, må du forstå dataene. Torchvision vil laste inn datasettet og transformere bildene med passende krav til nettverket, for eksempel form og normalisering av bildene.

import torch
import torchvision
import numpy as np
from torchvision import datasets, models, transforms

# This is used to transform the images to Tensor and normalize it
transform = transforms.Compose(
   [transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

training = torchvision.datasets.MNIST(root='./data', train=True,
                                       download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(training, batch_size=4,
                                         shuffle=True, num_workers=2)

testing = torchvision.datasets.MNIST(root='./data', train=False,
                                      download=True, transform=transform)
test_loader = torch.utils.data.DataLoader(testing, batch_size=4,
                                        shuffle=False, num_workers=2)

classes = ('0', '1', '2', '3',
          '4', '5', '6', '7', '8', '9')
         
import matplotlib.pyplot as plt
import numpy as np

#create an iterator for train_loader
# get random training images
data_iterator = iter(train_loader)
images, labels = data_iterator.next()

#plot 4 images to visualize the data
rows = 2
columns = 2
fig=plt.figure()
for i in range(4):
   fig.add_subplot(rows, columns, i+1)
   plt.title(classes[labels[i]])
   img = images[i] / 2 + 0.5     # this is for unnormalize the image
   img = torchvision.transforms.ToPILImage()(img)
   plt.imshow(img)
plt.show()

Transformasjonsfunksjonen konverterer bildene til tensor og normaliserer verdien. Funksjonen torchvision.transforms.MNIST vil laste ned datasettet (hvis det ikke er tilgjengelig) i katalogen, sette datasettet for opplæring om nødvendig og utføre transformasjonsprosessen.

For å visualisere datasettet bruker du data_iterator for å få den neste gruppen med bilder og etiketter. Du bruker matplott til å plotte disse bildene og deres passende etikett. Som du kan se nedenfor bildene våre og deres etiketter.

Eksempel på bildeklassifisering med PyTorch

Trinn 2) Nettverksmodellkonfigurasjon

Nå i dette PyTorch-eksemplet vil du lage et enkelt nevralt nettverk for PyTorch-bildeklassifisering.

Her introduserer vi deg en annen måte å lage nettverksmodellen på i PyTorch. Vi vil bruke nn.Sequential for å lage en sekvensmodell i stedet for å lage en underklasse av nn.Module.

import torch.nn as nn

# flatten the tensor into 
class Flatten(nn.Module):
   def forward(self, input):
       return input.view(input.size(0), -1)

#sequential based model
seq_model = nn.Sequential(
           nn.Conv2d(1, 10, kernel_size=5),
           nn.MaxPool2d(2),
           nn.ReLU(),
           nn.Dropout2d(),
           nn.Conv2d(10, 20, kernel_size=5),
           nn.MaxPool2d(2),
           nn.ReLU(),
           Flatten(),
           nn.Linear(320, 50),
           nn.ReLU(),
           nn.Linear(50, 10),
           nn.Softmax(),
         )

net = seq_model
print(net)

Her er resultatet av nettverksmodellen vår

Sequential(
  (0): Conv2d(1, 10, kernel_size=(5, 5), stride=(1, 1))
  (1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (2): ReLU()
  (3): Dropout2d(p=0.5)
  (4): Conv2d(10, 20, kernel_size=(5, 5), stride=(1, 1))
  (5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (6): ReLU()
  (7): Flatten()
  (8): Linear(in_features=320, out_features=50, bias=True)
  (9): ReLU()
  (10): Linear(in_features=50, out_features=10, bias=True)
  (11): Softmax()
)

Nettverksforklaring

  1. Sekvensen er at det første laget er et Conv2D-lag med en inngangsform på 1 og utgangsform på 10 med en kjernestørrelse på 5
  2. Deretter har du et MaxPool2D-lag
  3. En ReLU-aktiveringsfunksjon
  4. et frafallslag for å slippe lave sannsynlighetsverdier.
  5. Deretter en andre Conv2d med inngangsformen 10 fra det siste laget og utgangsformen 20 med en kjernestørrelse på 5
  6. Neste et MaxPool2d-lag
  7. ReLU aktiveringsfunksjon.
  8. Etter det vil du flate ut tensoren før du mater den inn i det lineære laget
  9. Linear Layer vil kartlegge produksjonen vår ved det andre lineære laget med softmax aktiveringsfunksjon

Trinn 3) Tren opp modellen

Før du starter treningsprosessen, er det nødvendig å sette opp kriteriet og optimaliseringsfunksjonen.

For kriteriet vil du bruke CrossEntropyLoss. For Optimizer vil du bruke SGD med en læringsrate på 0.001 og et momentum på 0.9 som vist i PyTorch-eksemplet nedenfor.

import torch.optim as optim

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

Fremoverprosessen vil ta inndataformen og sende den til det første conv2d-laget. Derfra vil den mates inn i maxpool2d og til slutt settes inn i ReLU-aktiveringsfunksjonen. Den samme prosessen vil skje i det andre conv2d-laget. Etter det vil inngangen omformes til (-1,320 XNUMX) og føres inn i fc-laget for å forutsi utgangen.

Nå starter du treningsprosessen. Du vil iterere gjennom datasettet vårt 2 ganger eller med en epoke på 2 og skrive ut gjeldende tap for hver 2000 batch.

for epoch in range(2): 

#set the running loss at each epoch to zero
   running_loss = 0.0
# we will enumerate the train loader with starting index of 0
# for each iteration (i) and the data (tuple of input and labels)
   for i, data in enumerate(train_loader, 0):
       inputs, labels = data

# clear the gradient
       optimizer.zero_grad()

#feed the input and acquire the output from network
       outputs = net(inputs)

#calculating the predicted and the expected loss
       loss = criterion(outputs, labels)

#compute the gradient
       loss.backward()

#update the parameters
       optimizer.step()

       # print statistics
       running_loss += loss.item()
       if i % 1000 == 0:
           print('[%d, %5d] loss: %.3f' %
                 (epoch + 1, i + 1, running_loss / 1000))
           running_loss = 0.0

Ved hver epoke vil telleren få neste tuppel med inndata og tilsvarende etiketter. Før vi mater input til nettverksmodellen vår, må vi fjerne den forrige gradienten. Dette er nødvendig fordi etter bakoverprosessen (tilbakeforplantningsprosessen), vil gradienten akkumuleres i stedet for å bli erstattet. Deretter vil vi beregne tapene fra den forutsagte produksjonen fra den forventede produksjonen. Etter det vil vi gjøre en backpropagation for å beregne gradienten, og til slutt vil vi oppdatere parametrene.

Her er resultatet av treningsprosessen

[1, 	1] loss: 0.002
[1,  1001] loss: 2.302
[1,  2001] loss: 2.295
[1,  3001] loss: 2.204
[1,  4001] loss: 1.930
[1,  5001] loss: 1.791
[1,  6001] loss: 1.756
[1,  7001] loss: 1.744
[1,  8001] loss: 1.696
[1,  9001] loss: 1.650
[1, 10001] loss: 1.640
[1, 11001] loss: 1.631
[1, 12001] loss: 1.631
[1, 13001] loss: 1.624
[1, 14001] loss: 1.616
[2, 	1] loss: 0.001
[2,  1001] loss: 1.604
[2,  2001] loss: 1.607
[2,  3001] loss: 1.602
[2,  4001] loss: 1.596
[2,  5001] loss: 1.608
[2,  6001] loss: 1.589
[2,  7001] loss: 1.610
[2,  8001] loss: 1.596
[2,  9001] loss: 1.598
[2, 10001] loss: 1.603
[2, 11001] loss: 1.596
[2, 12001] loss: 1.587
[2, 13001] loss: 1.596
[2, 14001] loss: 1.603

Trinn 4) Test modellen

Etter at du har trent modellen vår, må du teste eller evaluere med andre sett med bilder.

Vi vil bruke en iterator for test_loader, og den vil generere en gruppe bilder og etiketter som sendes til den trente modellen. Den forutsagte utgangen vil vises og sammenlignes med den forventede utgangen.

#make an iterator from test_loader
#Get a batch of training images
test_iterator = iter(test_loader)
images, labels = test_iterator.next()

results = net(images)
_, predicted = torch.max(results, 1)

print('Predicted: ', ' '.join('%5s' % classes[predicted[j]] for j in range(4)))

fig2 = plt.figure()
for i in range(4):
   fig2.add_subplot(rows, columns, i+1)
   plt.title('truth ' + classes[labels[i]] + ': predict ' + classes[predicted[i]])
   img = images[i] / 2 + 0.5     # this is to unnormalize the image
   img = torchvision.transforms.ToPILImage()(img)
   plt.imshow(img)
plt.show()

Eksempel på bildeklassifisering med PyTorch

Oppsummering

  • PyTorch er en åpen kildekode Torch-basert Maskinlæring bibliotek for naturlig språkbehandling ved hjelp av Python.
  • Fordeler med PyTorch: 1) Enkelt bibliotek, 2) Dynamic Computational Graph, 3) Bedre ytelse, 4) Native Python
  • PyTorch bruker Tensor for hver variabel som ligner på numpys ndarray, men med GPU-beregningsstøtte.
  • En av de populære metodene for å lære det grunnleggende om dyp læring er med MNIST-datasettet.