Hva er transfer learning?
Transfer Learning er en teknikk for å bruke en trent modell for å løse en annen relatert oppgave. Det er en maskinlæringsforskningsmetode som lagrer kunnskapen som oppnås mens du løser et bestemt problem, og bruker den samme kunnskapen til å løse et annet, men likevel relatert problem. Dette forbedrer effektiviteten ved å gjenbruke informasjonen samlet fra den tidligere lærte oppgaven.
Det er populært å bruke annen nettverksmodellvekt for å redusere treningstiden fordi du trenger mye data for å trene en nettverksmodell. For å redusere treningstiden bruker du andre nettverk og dens vekt og endrer det siste laget for å løse problemet vårt. Fordelen er at du kan bruke et lite datasett til å 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 eksempelet Transfer Learning PyTorch vil du klassifisere en fremmed og en rovdyr fra nesten 700 bilder. For denne teknikken trenger du ikke veldig mye data for å trene. Du kan laste ned datasettet fra Kaggle: Alien vs. Predator.
Hvordan bruke Transfer Learning?
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 noen transformasjoner til bilder slik at de samsvarer med nettverkskravene.
Du vil laste inn dataene fra en mappe med torchvision.dataset. Modulen vil gjenta i mappen for å dele dataene for tog og validering. Transformasjonsprosessen vil beskjære bildene fra midten, utføre en horisontal snu, normalisere og til slutt konvertere den til tensor ved hjelp av Deep Learning.
from __future__ import print_function, divisionimport osimport timeimport torchimport torchvisionfrom torchvision import datasets, models, transformsimport torch.optim as optimimport numpy as npimport matplotlib.pyplot as pltdata_dir = "alien_pred"input_shape = 224mean = [0.5, 0.5, 0.5]std = [0.5, 0.5, 0.5]#data transformationdata_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'].classesdevice = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
La oss visualisere datasettet vårt for PyTorch Transfer Learning. Visualiseringsprosessen vil få neste serie bilder fra togdata-lastere og etiketter og vise den med matplot.
images, labels = next(iter(dataloaders['train']))rows = 4columns = 4fig=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 + meanplt.imshow(img)plt.show()
Trinn 2) Definer modell
I denne Deep Learning-prosessen vil du bruke ResNet18 fra torchvision-modulen.
Du vil bruke torchvision.models til å laste resnet18 med den forhåndstrente vekten satt til å være True. Etter det vil du fryse lagene slik at disse lagene ikke kan trenes. Du endrer også det siste laget med et Lineært lag for å passe til våre behov som er to klasser. Du bruker også CrossEntropyLoss for tapsfunksjon i flere klasser, og for optimalisereren vil du bruke SGD med læringsgraden på 0,0001 og et momentum på 0,9 som vist i eksemplet nedenfor PyTorch Transfer Learning.
## Load the model based on VGG19vgg_based = torchvision.models.vgg19(pretrained=True)## freeze the layersfor param in vgg_based.parameters():param.requires_grad = False# Modify the last layernumber_features = vgg_based.classifier[6].in_featuresfeatures = list(vgg_based.classifier.children())[:-1] # Remove last layerfeatures.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)
Produksjonsmodellstrukturen
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 vil bruke noe av funksjonen fra Transfer Learning PyTorch Tutorial 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 = datainputs = 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() - sinceprint('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))return modeldef visualize_model(model, num_images=6):was_training = model.trainingmodel.eval()images_so_far = 0fig = 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 += 1ax = 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 + meanax.imshow(img)if images_so_far == num_images:model.train(mode=was_training)returnmodel.train(mode=was_training)
Til slutt i dette eksempelet Transfer Learning in PyTorch, la oss starte opplæringsprosessen med antall epoker satt til 25 og evaluere etter opplæringsprosessen. Ved hvert treningstrinn vil modellen ta input og forutsi output. Etter det vil den forventede produksjonen overføres til kriteriet for å beregne tapene. Deretter vil tapene utføre en backprop-beregning for å beregne gradienten og til slutt beregne vektene og optimalisere parametrene med autograd.
På visualiseringsmodellen vil det trente nettverket bli testet med en serie bilder for å forutsi etikettene. Deretter vil den 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
Det endelige resultatet er at du oppnådde en nøyaktighet på 92%.
Epoch 23/24----------train Loss: 0.0044train Loss: 0.0078train Loss: 0.0141train Loss: 0.0221train Loss: 0.0306train Loss: 0.0336train Loss: 0.0442train Loss: 0.0482train Loss: 0.0557train Loss: 0.0643train Loss: 0.0763train Loss: 0.0779train Loss: 0.0843train Loss: 0.0910train Loss: 0.0990train Loss: 0.1063train Loss: 0.1133train Loss: 0.1220train Loss: 0.1344train Loss: 0.1382train Loss: 0.1429train Loss: 0.1500Epoch 24/24----------train Loss: 0.0076train Loss: 0.0115train Loss: 0.0185train Loss: 0.0277train Loss: 0.0345train Loss: 0.0420train Loss: 0.0450train Loss: 0.0490train Loss: 0.0644train Loss: 0.0755train Loss: 0.0813train Loss: 0.0868train Loss: 0.0916train Loss: 0.0980train Loss: 0.1008train Loss: 0.1101train Loss: 0.1176train Loss: 0.1282train Loss: 0.1323train Loss: 0.1397train Loss: 0.1436train Loss: 0.1467Training complete in 2m 47s
Avslutt så vil produksjonen av modellen vår bli visualisert med matplot nedenfor:
Sammendrag
Så, la oss oppsummere alt! Den første faktoren er at PyTorch er et voksende rammeverk for dyp læring for nybegynnere eller for forskningsformål. Den tilbyr høy beregningstid, Dynamisk graf, GPU-støtte, og den er helt skrevet i Python. Du kan enkelt definere vår egen nettverksmodul og gjøre opplæringsprosessen med en enkel iterasjon. Det er klart at PyTorch er ideelt for nybegynnere å finne ut av 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.