PyTorch Transfer Learning Tutorial med eksempler
Hvad er Transfer Learning?
Overfรธr lรฆring er en teknik til at bruge en trรฆnet model til at lรธse en anden relateret opgave. Det er en Machine Learning-forskningsmetode, der gemmer den opnรฅede viden, mens du lรธser et bestemt problem, og bruger den samme viden til at lรธse et andet andet, men relateret problem. Dette forbedrer effektiviteten ved at genbruge informationen indsamlet fra den tidligere lรฆrte opgave.
Det er populรฆrt at bruge andre netvรฆrksmodelvรฆgte til at reducere din trรฆningstid, fordi du har brug for en masse data for at trรฆne en netvรฆrksmodel. For at reducere trรฆningstiden bruger du andre netvรฆrk og dets vรฆgt og รฆndrer det sidste lag for at lรธse vores problem. Fordelen er, at du kan bruge et lille datasรฆt til at trรฆne det sidste lag.
Nรฆste i denne PyTorch Transfer learning tutorial, vi lรฆrer, hvordan man bruger Transfer Learning med PyTorch.
Indlรฆser datasรฆt
Kilde: Alien vs Predator Kaggle
Fรธr du begynder at bruge Transfer Learning PyTorch, skal du forstรฅ det datasรฆt, du skal bruge. I denne Transfer Learning PyTorFor eksempel skal du klassificere en Alien og en Predator ud fra nรฆsten 700 billeder. Til denne teknik behรธver du ikke rigtig en stor mรฆngde data at trรฆne. Du kan downloade datasรฆttet fra Kaggle: Alien vs. Predator.
Hvordan bruger man Transfer Learning?
Her er en trin-for-trin proces til, hvordan man bruger Transfer Learning til Deep Learning med PyTorch:
Trin 1) Indlรฆs dataene
Det fรธrste skridt er at indlรฆse vores data og lave nogle transformationer til billeder, sรฅ de matcher netvรฆrkskravene.
Du vil indlรฆse data fra en mappe med torchvision.dataset. Modulet vil iterere i mappen for at opdele dataene til tog og validering. Transformationsprocessen vil beskรฆre billederne fra midten, udfรธre en vandret vending, normalisere og til sidst konvertere dem til tensor ved hjรฆlp af 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")
Lad os visualisere vores datasรฆt for PyTorch Transfer Learning. Visualiseringsprocessen vil hente den nรฆste batch af billeder fra togets dataindlรฆsere og etiketter og vise dem med matplot.
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()

Trin 2) Definer model
I denne Deep Learning proces, vil du bruge ResNet18 fra torchvision-modulet.
Du skal bruge torchvision.models til at indlรฆse resnet18 med den forudtrรฆnede vรฆgt sat til True. Derefter fryser du lagene, sรฅ disse lag ikke kan trรฆnes. Du รฆndrer ogsรฅ det sidste lag med et lineรฆrt lag, sรฅ det passer til vores behov, dvs. 2 klasser. Du bruger ogsรฅ CrossEntropyLoss til en multiklasse-tabsfunktion, og til optimeringsvรฆrktรธjet bruger du SGD med en lรฆringsrate pรฅ 0.0001 og et momentum pรฅ 0.9, som vist i Py-diagrammet nedenfor.Torch Eksempel pรฅ transferlรฆring.
## 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)
Outputmodellens struktur
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) ) )
Trin 3) Trรฆn og test model
Vi vil bruge nogle af funktionerne fra Transfer Learning PyTorch-vejledning at hjรฆlpe os med at trรฆne og evaluere vores model.
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)
Endelig i denne Transfer Learning i PyTorFor eksempel, lad os starte vores trรฆningsproces med antallet af epoker sat til 25 og evaluere efter trรฆningsprocessen. Ved hvert trรฆningstrin vil modellen tage input og forudsige outputtet. Derefter vil det forudsagte output blive sendt til kriteriet for at beregne tabene. Derefter vil tabene udfรธre en backprop-beregning for at beregne gradienten og endelig beregne vรฆgtene og optimere parametrene med autograd.
Ved visualiseringsmodellen vil det trรฆnede netvรฆrk blive testet med en batch af billeder for at forudsige etiketterne. Derefter vil det blive visualiseret ved hjรฆlp af matplotlib.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25) visualize_model(vgg_based) plt.show()
Trin 4) Resultater
Det endelige resultat er, at du opnรฅede en nรธjagtighed pรฅ 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
Slut sรฅ vil output fra vores model blive visualiseret med matplot nedenfor:

Resumรฉ
Sรฅ lad os opsummere det hele! Den fรธrste faktor er PyTorch er et voksende deep learning-framework for begyndere eller forskningsformรฅl. Det tilbyder hรธj beregningstid, dynamisk graf, GPU-understรธttelse og er fuldstรฆndig skrevet i ... PythonDu kan nemt definere dit eget netvรฆrksmodul og udfรธre trรฆningsprocessen med en nem iteration. Det er tydeligt, at PyTorch er ideelt for begyndere, der รธnsker at lรฆre deep learning, og for professionelle forskere er det meget nyttigt med hurtigere beregningstid og den meget nyttige autograd-funktion, der understรธtter dynamiske grafer.

