PyTorch Transfer læringsopplæring med eksempler
Hva er overføringslæring?
Overfør læring er en teknikk for å bruke en trent modell for å løse en annen relatert oppgave. Det er en forskningsmetode for maskinlæring som lagrer kunnskapen som er oppnådd mens du løser et bestemt problem og bruker den samme kunnskapen til å løse et annet, men relatert problem. Dette forbedrer effektiviteten ved å gjenbruke informasjonen som er samlet inn fra den tidligere lærte oppgaven.
Det er populært å bruke andre nettverksmodellvekter for å redusere treningstiden din fordi du trenger mye data for å trene en nettverksmodell. For å redusere treningstiden bruker du andre nettverk og dets vekt og modifiserer det siste laget for å løse problemet vårt. Fordelen er at du kan bruke et lite datasett for å trene det siste laget.
Neste i denne PyTorch Transfer læringsopplæringen vil vi lære hvordan du bruker Transfer Learning med PyTorch.
Laster inn datasett
Kilde: Alien vs Predator Kaggle
Før du begynner å bruke Transfer Learning PyTorch, må du forstå datasettet du skal bruke. I dette Transfer Learning PyTorch-eksemplet vil du klassifisere et romvesen og et rovdyr fra nesten 700 bilder. For denne teknikken trenger du egentlig ikke en stor mengde data for å trene. Du kan laste ned datasettet fra Kaggle: Alien vs. Predator.
Hvordan bruke overføringslæring?
Her er en trinnvis prosess for hvordan du bruker Transfer Learning for Deep Learning med PyTorch:
Trinn 1) Last inn dataene
Det første trinnet er å laste inn dataene våre og gjøre litt transformasjon til bilder slik at de samsvarer med nettverkskravene.
Du vil laste inn dataene fra en mappe med torchvision.dataset. Modulen vil iterere i mappen for å dele dataene for tog og validering. Transformasjonsprosessen vil beskjære bildene fra midten, utføre en horisontal flipp, normalisere og til slutt konvertere den til tensor ved hjelp 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")
La oss visualisere datasettet vårt for PyTorch Transfer Learning. Visualiseringsprosessen vil hente neste parti med bilder fra togdatalasterne og etikettene og vise det med matplott.
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()
Trinn 2) Definer modell
I dette Dyp læring prosess, vil du bruke ResNet18 fra torchvision-modulen.
Du vil bruke torchvision.models for å laste resnet18 med den forhåndstrente vekten satt til å være True. Etter det vil du fryse lagene slik at disse lagene ikke er trenbare. Du endrer også det siste laget med et lineært lag for å passe med våre behov, som er 2 klasser. Du bruker også CrossEntropyLoss for multi-class tapsfunksjon, og for optimizeren vil du bruke SGD med læringsraten på 0.0001 og et momentum på 0.9 som vist i PyTorch Transfer Learning-eksemplet nedenfor.
## 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)
Utgangsmodellens 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) ) )
Trinn 3) Tren og test modell
Vi skal bruke noen av funksjonene fra Transfer Learning PyTorch veiledning for å hjelpe oss med å trene og evaluere modellen vår.
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)
Til slutt i dette Transfer Learning in PyTorch-eksemplet, la oss starte treningsprosessen vår med antall epoker satt til 25 og evaluere etter treningsprosessen. Ved hvert treningstrinn vil modellen ta innspillene og forutsi resultatet. Etter det vil den forutsagte produksjonen overføres til kriteriet for å beregne tapene. Deretter vil tapene utføre en bakstøtteberegning for å beregne gradienten og til slutt beregne vektene og optimere parameterne med autograd.
Ved visualiseringsmodellen vil det trente nettverket bli testet med en gruppe bilder for å forutsi etikettene. Deretter vil det bli visualisert ved hjelp av matplotlib.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25) visualize_model(vgg_based) plt.show()
Trinn 4) Resultater
Sluttresultatet er at du oppnådde en nøyaktighet 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
Avslutt da vil utdataene til modellen vår bli visualisert med matplott nedenfor:
Oppsummering
Så, la oss oppsummere alt! Den første faktoren er PyTorch er et voksende rammeverk for dyp læring for nybegynnere eller for forskningsformål. Den tilbyr høy beregningstid, Dynamic Graph, GPU-støtte og den er fullstendig skrevet inn Python. Du er i stand til å definere din egen nettverksmodul med letthet og utføre opplæringsprosessen med en enkel iterasjon. Det er tydelig at PyTorch er ideell for nybegynnere for å finne ut dyp læring, og for profesjonelle forskere er det veldig nyttig med raskere beregningstid og også den svært nyttige autograd-funksjonen for å hjelpe dynamisk graf.