PyTorch Transfer Learning Handledning med exempel
Vad är Transfer Learning?
Överför lärande är en teknik för att använda en tränad modell för att lösa en annan relaterad uppgift. Det är en forskningsmetod för maskininlärning som lagrar den kunskap som erhållits när man löser ett visst problem och använder samma kunskap för att lösa ett annat annat men relaterat problem. Detta förbättrar effektiviteten genom att återanvända informationen från den tidigare inlärda uppgiften.
Det är populärt att använda andra nätverksmodeller för att minska din träningstid eftersom du behöver mycket data för att träna en nätverksmodell. För att minska träningstiden använder du andra nätverk och dess vikt och modifierar det sista lagret för att lösa vårt problem. Fördelen är att du kan använda en liten datauppsättning för att träna det sista lagret.
Nästa i denna PyTorch Transfer learning handledning, vi lär oss hur man använder Transfer Learning med PyTorch.
Laddar datauppsättning
Källa: Alien vs Predator Kaggle
Innan du börjar använda Transfer Learning PyTorch, du behöver förstå den datauppsättning du ska använda. I denna Transfer Learning PyTorTill exempel kommer du att klassificera en Alien och en Predator från nästan 700 bilder. För den här tekniken behöver du egentligen inte en stor mängd data för att träna. Du kan ladda ner datasetet från Kaggle: Alien vs. Predator.
Hur använder man Transfer Learning?
Här är en steg-för-steg-process för hur man använder Transfer Learning för djupinlärning med PyTorch:
Steg 1) Ladda data
Det första steget är att ladda vår data och göra lite omvandling till bilder så att de matchar nätverkskraven.
Du kommer att ladda data från en mapp med torchvision.dataset. Modulen kommer att iterera i mappen för att dela upp data för tåg och validering. Transformationsprocessen kommer att beskära bilderna från mitten, utföra en horisontell vändning, normalisera och slutligen konvertera den till tensor med hjälp av 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")
Låt oss visualisera vår datauppsättning för PyTorch Transfer Learning. Visualiseringsprocessen hämtar nästa omgång bilder från tågets dataladdare och etiketter och visar 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()

Steg 2) Definiera modell
I detta Deep Learning process kommer du att använda ResNet18 från torchvision-modulen.
Du kommer att använda torchvision.models för att ladda resnet18 med den förtränade vikten satt till True. Efter det kommer du att frysa lagren så att dessa lager inte är träningsbara. Du modifierar också det sista lagret med ett linjärt lager för att passa våra behov, det vill säga 2 klasser. Du använder också CrossEntropyLoss för flerklassförlustfunktioner och för optimeraren använder du SGD med inlärningshastigheten 0.0001 och ett momentum på 0.9 som visas i Py nedan.Torch Exempel på överföring av lärande.
## 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)
Utgångsmodellens 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) ) )
Steg 3) Träna och testa modell
Vi kommer att använda några av funktionerna från Transfer Learning PyTorch-handledning för att hjälpa oss att träna och utvärdera vår modell.
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)
Slutligen i denna överföringslärande i PyTorTill exempel, låt oss börja vår träningsprocess med antalet epoker satt till 25 och utvärdera efter träningsprocessen. Vid varje träningssteg kommer modellen att ta indata och förutsäga utdata. Därefter skickas den förutspådda utdata till kriteriet för att beräkna förlusterna. Sedan kommer förlusterna att utföra en backprop-beräkning för att beräkna gradienten och slutligen beräkna vikterna och optimera parametrarna med autograd.
Vid visualiseringsmodellen kommer det utbildade nätverket att testas med en grupp bilder för att förutsäga etiketterna. Sedan kommer det att visualiseras med hjälp av matplotlib.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25) visualize_model(vgg_based) plt.show()
Steg 4) Resultat
Slutresultatet är att du uppnådde en noggrannhet 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
Sluta då kommer produktionen av vår modell att visualiseras med matplot nedan:

Sammanfattning
Så, låt oss sammanfatta allt! Den första faktorn är PyTorch är ett växande ramverk för djupinlärning för nybörjare eller forskningsändamål. Det erbjuder hög beräkningstid, dynamisk graf, stöd för GPU:er och är helt skrivet i PythonDu kan enkelt definiera din egen nätverksmodul och genomföra träningsprocessen med en enkel iteration. Det är tydligt att PyTorch är idealiskt för nybörjare som vill lära sig djupinlärning och för professionella forskare är det mycket användbart med snabbare beräkningstid och även den mycket hjälpsamma autograd-funktionen som hjälper till med dynamiska grafer.

