PyTorch Transfer Learning-tutorial met voorbeelden
Wat is transferleren?
Transfer leren is een techniek waarbij een getraind model wordt gebruikt om een andere gerelateerde taak op te lossen. Het is een Machine Learning-onderzoeksmethode die de kennis opslaat die is opgedaan bij het oplossen van een bepaald probleem en dezelfde kennis gebruikt om een ander ander, maar gerelateerd probleem op te lossen. Dit verbetert de efficiëntie door de informatie die is verzameld uit de eerder geleerde taak opnieuw te gebruiken.
Het is populair om andere netwerkmodellen te gebruiken om uw trainingstijd te verkorten, omdat u veel gegevens nodig heeft om een netwerkmodel te trainen. Om de trainingstijd te verkorten, gebruikt u andere netwerken en het gewicht ervan en past u de laatste laag aan om ons probleem op te lossen. Het voordeel is dat je een kleine dataset kunt gebruiken om de laatste laag te trainen.
Vervolgens leren we in deze PyTorch Transfer-leertutorial hoe u Transfer Learning met PyTorch kunt gebruiken.
Gegevensset laden
Bron: Alien versus Predator Kaggle
Voordat u Transfer Learning PyTorch gaat gebruiken, moet u de dataset begrijpen die u gaat gebruiken. In dit Transfer Learning PyTorch-voorbeeld classificeer je een Alien en een Predator uit bijna 700 afbeeldingen. Voor deze techniek heb je niet echt een grote hoeveelheid gegevens nodig om te trainen. U kunt de dataset downloaden van Kaggle: Alien versus roofdier.
Hoe gebruik je transferleren?
Hier is een stapsgewijs proces voor het gebruik van Transfer Learning voor Deep Learning met PyTorch:
Stap 1) Laad de gegevens
De eerste stap is het laden van onze gegevens en het uitvoeren van enige transformatie naar afbeeldingen, zodat ze voldoen aan de netwerkvereisten.
U laadt de gegevens uit een map met torchvision.dataset. De module itereert in de map om de gegevens voor trein en validatie te splitsen. Het transformatieproces zal de afbeeldingen vanuit het midden bijsnijden, een horizontale spiegeling uitvoeren, normaliseren en uiteindelijk converteren naar tensor met behulp van 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")
Laten we onze dataset voor PyTorch Transfer Learning visualiseren. Het visualisatieproces haalt de volgende batch afbeeldingen uit de gegevensladers en labels van de trein en geeft deze weer met 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()
Stap 2) Model definiëren
In deze Diepe leren proces, gebruikt u ResNet18 van de Torchvision-module.
U gebruikt torchvision.models om resnet18 te laden met het vooraf getrainde gewicht ingesteld op True. Daarna bevriest u de lagen zodat deze lagen niet trainbaar zijn. U wijzigt ook de laatste laag met een lineaire laag om aan onze behoeften te voldoen, namelijk 2 klassen. U gebruikt ook CrossEntropyLoss voor multi-class verliesfunctie en voor de optimizer gebruikt u SGD met de leersnelheid van 0.0001 en een momentum van 0.9, zoals weergegeven in het onderstaande PyTorch Transfer Learning-voorbeeld.
## 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)
De uitvoermodelstructuur
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) ) )
Stap 3) Model trainen en testen
We zullen enkele functies van Transfer Learning gebruiken PyTorch-zelfstudie om ons te helpen ons model te trainen en te evalueren.
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)
Laten we tot slot in dit voorbeeld van Transfer Learning in PyTorch ons trainingsproces starten met het aantal tijdperken ingesteld op 25 en evalueren na het trainingsproces. Bij elke trainingsstap neemt het model de input en voorspelt het de output. Daarna wordt de voorspelde output doorgegeven aan het criterium om de verliezen te berekenen. Vervolgens zullen de verliezen een backprop-berekening uitvoeren om de gradiënt te berekenen en uiteindelijk de gewichten te berekenen en de parameters te optimaliseren met autograd.
Bij het visualisatiemodel wordt het getrainde netwerk getest met een reeks afbeeldingen om de labels te voorspellen. Vervolgens wordt het gevisualiseerd met behulp van matplotlib.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25) visualize_model(vgg_based) plt.show()
Stap 4) Resultaten
Het eindresultaat is dat je een nauwkeurigheid van 92% hebt behaald.
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
Eindig, dan zal de uitvoer van ons model worden gevisualiseerd met onderstaande matplot:
Samenvatting
Dus, laten we alles samenvatten! De eerste factor is dat PyTorch een groeiend deep learning framework is voor beginners of voor onderzoeksdoeleinden. Het biedt hoge rekentijd, Dynamic Graph, GPU-ondersteuning en het is volledig geschreven in Python. U kunt eenvoudig uw eigen netwerkmodule definiëren en het trainingsproces in een eenvoudige iteratie uitvoeren. Het is duidelijk dat PyTorch ideaal is voor beginners om diepgaand leren te ontdekken en voor professionele onderzoekers is het erg handig met snellere rekentijd en ook de zeer nuttige autograd-functie om dynamische grafieken te ondersteunen.