„PyTorch“ mokymasis giliam mokymuisi su pavyzdžiu

Kas yra mokymasis perkėlimu?

Mokymasis perkėlimu yra apmokyto modelio panaudojimo technika, sprendžiant kitą susijusią užduotį. Tai yra mašininio mokymosi tyrimo metodas, kuriame kaupiamos žinios, įgytos sprendžiant tam tikrą problemą, ir tos pačios žinios naudojamos kitai, tačiau dar susijusiai problemai išspręsti. Tai pagerina efektyvumą pakartotinai panaudojant informaciją, surinktą iš anksčiau išmoktos užduoties.

Norint sutrumpinti treniruočių laiką, populiaru naudoti kitą tinklo modelio svorį, nes norint mokyti tinklo modelį reikia daug duomenų. Norėdami sutrumpinti treniruočių laiką, naudokite kitus tinklus ir jo svorį bei modifikuokite paskutinį sluoksnį, kad išspręstumėte mūsų problemą. Privalumas yra tas, kad paskutiniam sluoksniui mokyti galite naudoti nedidelį duomenų rinkinį.

Toliau šioje „PyTorch Transfer“ mokymosi pamokoje sužinosime, kaip naudotis „Transfer Learning“ su „PyTorch“.

Įkeliamas duomenų rinkinys

Šaltinis: Ateivis prieš plėšrūną Kaggle

Prieš pradėdami naudoti „Transfer Learning PyTorch“, turite suprasti duomenų rinkinį, kurį ketinate naudoti. Šiame „Transfer Learning PyTorch“ pavyzdyje klasifikuosite ateivį ir plėšrūną iš beveik 700 vaizdų. Norint mokytis šios technikos, jums tikrai nereikia didelio duomenų kiekio. Duomenų rinkinį galite atsisiųsti iš „Kaggle: Alien vs. Predator“.

Kaip naudotis perkėlimu?

Tai žingsnis po žingsnio, kaip naudoti „Transfer Learning“ giliam mokymuisi naudojant „PyTorch“:

1 žingsnis. Įkelkite duomenis

Pirmas žingsnis - įkelti duomenis ir šiek tiek pakeisti vaizdus, ​​kad jie atitiktų tinklo reikalavimus.

Duomenis įkelsite iš aplanko su torchvision.dataset. Modulis kartojasi aplanke, kad padalintų traukinio ir patvirtinimo duomenis. Transformacijos procesas apkarpys vaizdus iš centro, atliks horizontalų apvertimą, normalizuos ir galiausiai pavers jį tensoriumi naudodamasis „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")

Vaizduokime savo „PyTorch Transfer Learning“ duomenų rinkinį. Vizualizacijos procesas gaus kitą vaizdų partiją iš traukinio duomenų krautuvų ir etikečių ir parodys ją 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()

2 žingsnis) Apibrėžkite modelį

Šiame gilaus mokymosi procese naudosite „ResNet18 from torchvision“ modulį.

Norėdami įkrauti „resnet18“ naudosite „torchvision.models“, o iš anksto išmokytas svoris bus „True“. Po to jūs užšaldysite sluoksnius, kad šie sluoksniai nebūtų treniruojami. Jūs taip pat modifikuojate paskutinį sluoksnį tiesiniu sluoksniu, kad jis atitiktų mūsų poreikius, tai yra 2 klasės. „CrossEntropyLoss“ taip pat naudojate kelių klasių praradimo funkcijai, o optimizatoriui naudosite SGD, kurio mokymosi greitis yra 0,0001, o impulsas - 0,9, kaip parodyta toliau pateiktame „PyTorch Transfer Learning“ pavyzdyje.

## 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)

Išvesties modelio struktūra

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 žingsnis) Traukinys ir bandymo modelis

Mes naudosime dalį „Transfer Learning PyTorch Tutorial“ funkcijos, kad padėtų mums mokyti ir įvertinti savo 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)

Pagaliau šiame „Transfer Learning in PyTorch“ pavyzdyje pradėkime savo mokymo procesą nuo 25 epochų skaičiaus ir įvertinkime po mokymo. Kiekviename mokymo etape modelis imsis įvesties ir numatys rezultatą. Po to prognozuojama produkcija bus perduodama kriterijams nuostoliams apskaičiuoti. Tada nuostoliai atliks „backprop“ skaičiavimą, kad būtų galima apskaičiuoti gradientą ir galiausiai apskaičiuoti svorį bei optimizuoti parametrus naudojant „Autograd“.

Vizualizuojant modelį, apmokytas tinklas bus išbandytas su vaizdų grupe, kad būtų galima numatyti etiketes. Tada jis bus vizualizuojamas matplotlib pagalba.

vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25)visualize_model(vgg_based)plt.show()

4 žingsnis) Rezultatai

Galutinis rezultatas - pasiekėte 92% tikslumą.

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

Pabaiga tada mūsų modelio išvestis bus vizualizuota matplot žemiau:

Santrauka

Taigi, apibendrinkime viską! Pirmasis veiksnys yra „PyTorch“ - tai vis gilesnė mokymosi sistema pradedantiesiems arba tyrimams. Jis siūlo ilgą skaičiavimo laiką, „Dynamic Graph“, GPU palaikymą ir visiškai parašytas „Python“. Jūs galite lengvai apibrėžti savo tinklo modulį ir lengvai atlikti mokymo procesą. Akivaizdu, kad „PyTorch“ yra idealus pradedantiesiems, norintiems sužinoti gilų mokymąsi, o profesionaliems tyrėjams - labai naudingas greitesnis skaičiavimo laikas ir labai naudinga automatinio keitimo funkcija, padedanti dinamiškam grafikui.

Įdomios straipsniai...