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

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:

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.

