Hvad er Transfer Learning?
Transfer Learning er en teknik til at bruge en uddannet model til at løse en anden relateret opgave. Det er en maskinindlæringsforskningsmetode, der gemmer den opnåede viden, mens man løser et bestemt problem og bruger den samme viden til at løse et andet, men alligevel relateret problem. Dette forbedrer effektiviteten ved at genbruge de oplysninger, der er indsamlet fra den tidligere lærte opgave.
Det er populært at bruge anden netværksmodelvægt for 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 dens 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-læringsvejledning lærer vi, hvordan du 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 dette eksempel på Transfer Learning PyTorch klassificerer du en fremmed og en rovdyr fra næsten 700 billeder. Til denne teknik behøver du ikke rigtig en stor mængde data for at træne. Du kan downloade datasættet fra Kaggle: Alien vs. Predator.
Hvordan bruges Transfer Learning?
Her er en trinvis proces til, hvordan du bruger Transfer Learning til Deep Learning med PyTorch:
Trin 1) Indlæs dataene
Det første trin er at indlæse vores data og foretage en vis transformation til billeder, så de svarer til netværkskravene.
Du indlæser dataene fra en mappe med torchvision.dataset. Modulet gentages i mappen for at opdele data til tog og validering. Transformationsprocessen beskærer billederne fra midten, udfører en vandret flip, normaliserer og konverterer den til tensor ved hjælp af 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")
Lad os visualisere vores datasæt til PyTorch Transfer Learning. Visualiseringsprocessen får det næste batch af billeder fra togdataindlæsere og etiketter og viser det 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()
Trin 2) Definer model
I denne Deep Learning-proces bruger du ResNet18 fra torchvision-modulet.
Du bruger torchvision.models til at indlæse resnet18 med den foruddannede vægt indstillet til at være sand. 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, der er 2 klasser. Du bruger også CrossEntropyLoss til multi-class tabsfunktion, og til optimizer bruger du SGD med indlæringshastigheden på 0,0001 og et momentum på 0,9 som vist i nedenstående eksempel på 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)
Outputmodelstrukturen
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 bruger en del af funktionen fra Transfer Learning PyTorch Tutorial til 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 = 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)
Endelig i dette Transfer Learning i PyTorch-eksempel, lad os starte vores træningsproces med antallet af epoker indstillet til 25 og evaluere efter træningsprocessen. Ved hvert træningstrin tager modellen input og forudsiger output. Derefter overføres den forudsagte output til kriteriet for beregning af tabene. Derefter udfører tabene en backprop-beregning for at beregne gradienten og endelig beregne vægten og optimere parametrene med autograd.
Ved visualiseringsmodellen testes det uddannede netværk med et antal billeder for at forudsige etiketterne. Derefter visualiseres det 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.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
Afslut, så vil output fra vores model blive visualiseret med matplot nedenfor:
Resumé
Så lad os sammenfatte alt! Den første faktor er PyTorch er en voksende dyb læringsramme for begyndere eller til forskningsformål. Det tilbyder høj beregningstid, dynamisk graf, understøttelse af GPU'er, og det er helt skrevet i Python. Du er i stand til let at definere vores eget netværksmodul og udføre træningsprocessen med en let iteration. Det er klart, at PyTorch er ideel til begyndere at finde ud af dyb læring, og for professionelle forskere er det meget nyttigt med hurtigere beregningstid og også den meget hjælpsomme autograd-funktion til at hjælpe dynamisk graf.