PyTorch Vodič za učenje transfera s primjerima

Što je transferno učenje?

Prijenos učenja je tehnika korištenja uvježbanog modela za rješavanje drugog srodnog zadatka. To je istraživačka metoda strojnog učenja koja pohranjuje znanje stečeno tijekom rješavanja određenog problema i koristi isto znanje za rješavanje drugog različitog, ali povezanog problema. To poboljšava učinkovitost ponovnim korištenjem informacija prikupljenih iz prethodno naučenog zadatka.

Popularno je koristiti drugu težinu mrežnog modela kako biste smanjili vrijeme vježbanja jer vam je potrebno mnogo podataka za treniranje mrežnog modela. Da biste smanjili vrijeme treninga, koristite druge mreže i njihovu težinu i modificirajte posljednji sloj kako biste riješili naš problem. Prednost je što možete koristiti mali skup podataka za obuku posljednjeg sloja.

Sljedeće u ovom Py-uTorch Uvod u transferno učenje, naučit ćemo kako koristiti transferno učenje s Py-jemTorch.

Učitavanje skupa podataka

Učitavanje skupa podataka

Izvor: Alien vs. Predator Kaggle

Prije nego što počnete koristiti Transfer Learning PyTorch, morate razumjeti skup podataka koji ćete koristiti. U ovom Transfer Learning PyTorNa primjer, klasificirat ćete izvanzemaljca i predatora iz gotovo 700 slika. Za ovu tehniku ​​vam zapravo ne treba velika količina podataka za treniranje. Skup podataka možete preuzeti s Kaggle: Alien protiv Predatora.

Kako koristiti prijenos učenja?

Evo korak-po-korak postupka o tome kako koristiti transferno učenje za duboko učenje s Py-jemTorCH:

Korak 1) Učitajte podatke

Prvi korak je učitavanje naših podataka i neka transformacija slika tako da odgovaraju zahtjevima mreže.

Učitat ćete podatke iz mape s torchvision.dataset. Modul će ponavljati u mapi kako bi podijelio podatke za obuku i provjeru valjanosti. Proces transformacije izrezat će slike iz središta, izvršiti horizontalno okretanje, normalizirati i konačno pretvoriti u tenzor koristeći Deep Learning.

from __future__ import print_function, division
import os
import time
import torch
import torchvision
from torchvision import datasets, models, transforms
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt

data_dir = "alien_pred"
input_shape = 224
mean = [0.5, 0.5, 0.5]
std = [0.5, 0.5, 0.5]

#data transformation
data_transforms = {
   'train': transforms.Compose([
       transforms.CenterCrop(input_shape),
       transforms.ToTensor(),
       transforms.Normalize(mean, std)
   ]),
   'validation': transforms.Compose([
       transforms.CenterCrop(input_shape),
       transforms.ToTensor(),
       transforms.Normalize(mean, std)
   ]),
}

image_datasets = {
   x: datasets.ImageFolder(
       os.path.join(data_dir, x),
       transform=data_transforms[x]
   )
   for x in ['train', 'validation']
}

dataloaders = {
   x: torch.utils.data.DataLoader(
       image_datasets[x], batch_size=32,
       shuffle=True, num_workers=4
   )
   for x in ['train', 'validation']
}

dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'validation']}

print(dataset_sizes)
class_names = image_datasets['train'].classes

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

Vizualizirajmo naš skup podataka za PyTorch Prijenos učenja. Proces vizualizacije će dobiti sljedeću seriju slika iz učitavača podataka vlaka i oznaka te ih prikazati pomoću matplota.

images, labels = next(iter(dataloaders['train']))

rows = 4
columns = 4
fig=plt.figure()
for i in range(16):
   fig.add_subplot(rows, columns, i+1)
   plt.title(class_names[labels[i]])
   img = images[i].numpy().transpose((1, 2, 0))
   img = std * img + mean
   plt.imshow(img)
plt.show()
Serija slika
Serija slika

Korak 2) Definirajte model

U ovom Duboko učenje procesu, koristit ćete ResNet18 iz torchvision modula.

Koristit ćete torchvision.models za učitavanje resnet18 s prethodno obučenom težinom postavljenom na True. Nakon toga, zamrznut ćete slojeve tako da se ti slojevi ne mogu obučavati. Također ćete modificirati posljednji sloj s linearnim slojem kako bi odgovarao našim potrebama, odnosno 2 klase. Također ćete koristiti CrossEntropyLoss za funkciju gubitka s više klasa, a za optimizator ćete koristiti SGD s brzinom učenja od 0.0001 i momentom od 0.9 kao što je prikazano na donjoj Py slici.TorPrimjer transfera učenja.

## Load the model based on VGG19
vgg_based = torchvision.models.vgg19(pretrained=True)

## freeze the layers
for param in vgg_based.parameters():
   param.requires_grad = False

# Modify the last layer
number_features = vgg_based.classifier[6].in_features
features = list(vgg_based.classifier.children())[:-1] # Remove last layer
features.extend([torch.nn.Linear(number_features, len(class_names))])
vgg_based.classifier = torch.nn.Sequential(*features)

vgg_based = vgg_based.to(device)

print(vgg_based)

criterion = torch.nn.CrossEntropyLoss()
optimizer_ft = optim.SGD(vgg_based.parameters(), lr=0.001, momentum=0.9)

Struktura izlaznog modela

VGG(
  (features): Sequential(
	(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(1): ReLU(inplace)
	(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(3): ReLU(inplace)
	(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
	(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(6): ReLU(inplace)
	(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(8): ReLU(inplace)
	(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
	(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(11): ReLU(inplace)
	(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(13): ReLU(inplace)
	(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(15): ReLU(inplace)
	(16): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(17): ReLU(inplace)
	(18): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
	(19): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(20): ReLU(inplace)
	(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(22): ReLU(inplace)
	(23): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(24): ReLU(inplace)
	(25): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(26): ReLU(inplace)
	(27): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
	(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(29): ReLU(inplace)
	(30): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(31): ReLU(inplace)
	(32): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(33): ReLU(inplace)
	(34): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
	(35): ReLU(inplace)
	(36): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (classifier): Sequential(
	(0): Linear(in_features=25088, out_features=4096, bias=True)
	(1): ReLU(inplace)
	(2): Dropout(p=0.5)
	(3): Linear(in_features=4096, out_features=4096, bias=True)
	(4): ReLU(inplace)
	(5): Dropout(p=0.5)
	(6): Linear(in_features=4096, out_features=2, bias=True)
  )
)

Korak 3) Obuka i testiranje modela

Koristit ćemo neke od funkcija iz Transfer Learninga PyTorch Vodič da nam pomognu u obuci i procjeni našeg modela.

def train_model(model, criterion, optimizer, num_epochs=25):
   since = time.time()

   for epoch in range(num_epochs):
       print('Epoch {}/{}'.format(epoch, num_epochs - 1))
       print('-' * 10)

       #set model to trainable
       # model.train()

       train_loss = 0

       # Iterate over data.
       for i, data in enumerate(dataloaders['train']):
           inputs , labels = data
           inputs = inputs.to(device)
           labels = labels.to(device)

           optimizer.zero_grad()
          
           with torch.set_grad_enabled(True):
               outputs  = model(inputs)
               loss = criterion(outputs, labels)

           loss.backward()
           optimizer.step()

           train_loss += loss.item() * inputs.size(0)

           print('{} Loss: {:.4f}'.format(
               'train', train_loss / dataset_sizes['train']))
          
   time_elapsed = time.time() - since
   print('Training complete in {:.0f}m {:.0f}s'.format(
       time_elapsed // 60, time_elapsed % 60))

   return model

def visualize_model(model, num_images=6):
   was_training = model.training
   model.eval()
   images_so_far = 0
   fig = plt.figure()

   with torch.no_grad():
       for i, (inputs, labels) in enumerate(dataloaders['validation']):
           inputs = inputs.to(device)
           labels = labels.to(device)

           outputs = model(inputs)
           _, preds = torch.max(outputs, 1)

           for j in range(inputs.size()[0]):
               images_so_far += 1
               ax = plt.subplot(num_images//2, 2, images_so_far)
               ax.axis('off')
               ax.set_title('predicted: {} truth: {}'.format(class_names[preds[j]], class_names[labels[j]]))
               img = inputs.cpu().data[j].numpy().transpose((1, 2, 0))
               img = std * img + mean
               ax.imshow(img)

               if images_so_far == num_images:
                   model.train(mode=was_training)
                   return
       model.train(mode=was_training)

Konačno u ovom transferu učenja u Py-uTorNa primjer, započnimo naš proces treniranja s brojem epoha postavljenim na 25 i evaluirajmo nakon procesa treniranja. U svakom koraku treniranja, model će uzeti ulaz i predvidjeti izlaz. Nakon toga, predviđeni izlaz će se proslijediti kriteriju za izračun gubitaka. Zatim će se gubici izvršiti izračun povratnog prop-a za izračun nagiba i na kraju izračunati težine i optimizirati parametre s autogradom.

Na modelu vizualizacije, obučena mreža će se testirati sa serijom slika za predviđanje oznaka. Zatim će se vizualizirati uz pomoć matplotliba.

vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25)

visualize_model(vgg_based)

plt.show()

Korak 4) Rezultati

Konačni rezultat je da ste postigli točnost od 92%.

Epoch 23/24
----------
train Loss: 0.0044
train Loss: 0.0078
train Loss: 0.0141
train Loss: 0.0221
train Loss: 0.0306
train Loss: 0.0336
train Loss: 0.0442
train Loss: 0.0482
train Loss: 0.0557
train Loss: 0.0643
train Loss: 0.0763
train Loss: 0.0779
train Loss: 0.0843
train Loss: 0.0910
train Loss: 0.0990
train Loss: 0.1063
train Loss: 0.1133
train Loss: 0.1220
train Loss: 0.1344
train Loss: 0.1382
train Loss: 0.1429
train Loss: 0.1500
Epoch 24/24
----------
train Loss: 0.0076
train Loss: 0.0115
train Loss: 0.0185
train Loss: 0.0277
train Loss: 0.0345
train Loss: 0.0420
train Loss: 0.0450
train Loss: 0.0490
train Loss: 0.0644
train Loss: 0.0755
train Loss: 0.0813
train Loss: 0.0868
train Loss: 0.0916
train Loss: 0.0980
train Loss: 0.1008
train Loss: 0.1101
train Loss: 0.1176
train Loss: 0.1282
train Loss: 0.1323
train Loss: 0.1397
train Loss: 0.1436
train Loss: 0.1467
Training complete in 2m 47s

Kraj, tada će se izlaz našeg modela vizualizirati s matplotom ispod:

Vizualizirano s Matplotom
Vizualizirano s Matplotom

Rezime

Dakle, rezimirajmo sve! Prvi faktor je PyTorch je rastući okvir za duboko učenje za početnike ili u istraživačke svrhe. Nudi veliko vrijeme izračuna, dinamički graf, podršku za GPU-ove i u potpunosti je napisan u PythonMožete s lakoćom definirati vlastiti mrežni modul i provesti proces treniranja jednostavnom iteracijom. Jasno je da PyTorch je idealan za početnike za učenje dubokog učenja, a za profesionalne istraživače je vrlo koristan zbog bržeg vremena izračuna i vrlo korisne funkcije autograda za pomoć pri dinamičkom grafu.

Sažmite ovu objavu uz: