PyTorchi ülekande õppimise õpetus koos näidetega
Mis on ülekandeõpe?
Ülekandeõpe on tehnika, mille abil kasutatakse koolitatud mudelit mõne muu seotud ülesande lahendamiseks. See on masinõppe uurimismeetod, mis salvestab konkreetse probleemi lahendamisel saadud teadmised ja kasutab samu teadmisi teise erineva, kuid samas seotud probleemi lahendamiseks. See suurendab tõhusust, kasutades eelnevalt õpitud ülesandest kogutud teavet.
Treeningaja vähendamiseks on populaarne kasutada teisi võrgumudeli kaalu, kuna võrgumudeli treenimiseks on vaja palju andmeid. Treeningaja vähendamiseks kasutate teisi võrke ja selle kaalu ning muudate meie probleemi lahendamiseks viimast kihti. Eeliseks on see, et saate viimase kihi treenimiseks kasutada väikest andmekogumit.
Järgmisena selles PyTorch Transferi õppeõpetuses õpime, kuidas kasutada PyTorchiga ülekandeõpet.
Andmestiku laadimine
Allikas: Alien vs Predator Kaggle
Enne Transfer Learning PyTorchi kasutamise alustamist peate mõistma kasutatavat andmekogumit. Selles Transfer Learning PyTorchi näites liigitate ligi 700 pildi hulgast tulnuka ja kiskja. Selle tehnika jaoks ei vaja te treenimiseks suurt hulka andmeid. Andmestiku saate alla laadida aadressilt Kaggle: Tulnukas vs. kiskja.
Kuidas kasutada ülekandeõpet?
Siin on samm-sammuline protsess, kuidas kasutada PyTorchiga süvaõppeks mõeldud ülekandeõpet:
Samm 1) Laadige andmed
Esimene samm on meie andmete laadimine ja piltide muutmine, et need vastaksid võrgunõuetele.
Laadite andmed kaustast torchvision.dataset. Moodul korrutab kaustas, et jagada andmed rongi ja valideerimise jaoks. Teisendusprotsess kärbib pilte keskelt, sooritab horisontaalse ümberpööramise, normaliseerib ja lõpuks teisendab need süvaõppe abil tensoriks.
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")
Visualiseerime oma PyTorch Transfer Learningi andmestikku. Visualiseerimisprotsess võtab rongi andmelaadijatelt ja siltidelt järgmise pildipartii ning kuvab selle matplotiga.
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()
Samm 2) Määratlege mudel
Selle Sügav õppimine protsessi, kasutate torchvisioni moodulist ResNet18.
Kasutate faili resnet18 laadimiseks torchvision.models, mille eeltreenitud kaal on seatud väärtusele Tõene. Pärast seda külmutate kihid, nii et need kihid pole treenitavad. Samuti muudate viimast kihti lineaarse kihiga, et see sobiks meie vajadustega, mis on 2 klassi. Kasutate ka CrossEntropyLossi mitme klassi kadufunktsiooni jaoks ja optimeerija jaoks kasutate SGD-d õppimiskiirusega 0.0001 ja impulsiga 0.9, nagu on näidatud allolevas PyTorchi ülekande õppimise näites.
## 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)
Väljundmudeli struktuur
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) ) )
3. samm) Treenige ja katsetage mudelit
Kasutame mõnda Transfer Learningi funktsiooni PyTorchi õpetus et aidata meil oma mudelit koolitada ja hinnata.
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)
Lõpuks selles PyTorchis õppimise ülekandmise näites alustame oma koolitusprotsessi ajastute arvuga 25 ja hindame pärast koolitusprotsessi. Igal koolitusetapil võtab mudel sisendi ja ennustab väljundit. Pärast seda suunatakse prognoositav toodang kahjude arvutamise kriteeriumile. Seejärel teostavad kaod gradiendi arvutamiseks backprop-arvutuse ja lõpuks kaalude arvutamise ning parameetrite optimeerimise autogradiga.
Visualiseerimismudelis testitakse koolitatud võrku piltide partiiga, et sildid ennustada. Seejärel visualiseeritakse see matplotlibi abil.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25) visualize_model(vgg_based) plt.show()
4. samm) Tulemused
Lõpptulemus on see, et saavutasite 92% täpsuse.
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
Lõpeta, siis visualiseeritakse meie mudeli väljund alloleva matplotiga:
kokkuvõte
Niisiis, võtame kõik kokku! Esimene tegur on see, et PyTorch on kasvav süvaõpperaamistik algajatele või uurimiseesmärkidel. See pakub pikka arvutusaega, dünaamilist graafikut, GPU-de tuge ja see on täielikult sisse kirjutatud Python. Saate hõlpsasti määratleda oma võrgumooduli ja teha koolitusprotsessi lihtsa iteratsiooniga. On selge, et PyTorch on ideaalne algajatele süvaõppe õppimiseks ning professionaalsetele teadlastele on see väga kasulik kiirema arvutusaja ja ka väga kasuliku autogradi funktsiooniga dünaamilise graafiku abistamiseks.