PyTorch Siirto-oppimisen opetusohjelma esimerkkien kera

Mitรค on Transfer Learning?

Siirrรค oppiminen on tekniikka, jossa kรคytetรครคn koulutettua mallia toisen asiaan liittyvรคn tehtรคvรคn ratkaisemiseen. Se on koneoppimisen tutkimusmenetelmรค, joka tallentaa tietyn ongelman ratkaisemisen aikana saadun tiedon ja kรคyttรครค samaa tietoa toisen erilaisen, mutta siihen liittyvรคn ongelman ratkaisemiseen. Tรคmรค parantaa tehokkuutta kรคyttรคmรคllรค uudelleen aiemmin opitusta tehtรคvรคstรค kerรคttyรค tietoa.

On suosittua kรคyttรครค muita verkkomallipainoja harjoitusajan lyhentรคmiseen, koska tarvitset paljon dataa verkkomallin harjoittamiseen. Harjoitusajan lyhentรคmiseksi kรคytรคt muita verkkoja ja niiden painoa ja muokkaat viimeistรค kerrosta ongelmamme ratkaisemiseksi. Etuna on, ettรค voit kรคyttรครค pientรค tietojoukkoa viimeisen kerroksen kouluttamiseen.

Seuraava tรคssรค Py:ssรคTorch Siirto-oppimisen tutoriaali, opimme kรคyttรคmรครคn siirto-oppimista Py:n kanssaTorch.

Ladataan tietojoukkoa

Ladataan tietojoukkoa

Lรคhde: Alien vs. Predator Kaggle

Ennen kuin aloitat Transfer Learning Py:n kรคytรถnTorch, sinun on ymmรคrrettรคvรค kรคyttรคmรคsi tietojoukko. Tรคssรค siirto-oppimisen py-osiossaTorEsimerkissรค luokittelet avaruusolennon ja saalistajan lรคhes 700 kuvan perusteella. Tรคssรค tekniikassa et oikeastaan โ€‹โ€‹tarvitse suurta mรครคrรครค dataa kouluttamista varten. Voit ladata datajoukon osoitteesta Kaggle: Alien vs. Predator.

Kuinka kรคyttรครค siirtooppimista?

Tรคssรค on vaiheittainen prosessi siirto-oppimisen kรคyttรคmiseksi syvรคoppimisessa Py:n avullaTorch:

Vaihe 1) Lataa tiedot

Ensimmรคinen askel on ladata tietomme ja tehdรค kuviksi jonkin verran muunnoksia, jotta ne vastasivat verkkovaatimuksia.

Lataat tiedot kansiosta, jossa on torchvision.dataset. Moduuli toistuu kansiossa jakaakseen tiedot junaa ja validointia varten. Muunnosprosessi rajaa kuvat keskeltรค, suorittaa vaakasuoran kรครคnnรถn, normalisoi ja lopuksi muuntaa sen tensoriksi Deep Learningin avulla.

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

Visualisoidaan Py-tietokantaTorch Siirto-oppiminen. Visualisointiprosessi hakee seuraavan kuvaerรคn junan datalataajilta ja -tunnisteilta ja nรคyttรครค sen matplot-loitolla.

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()
Joukko kuvia
Joukko kuvia

Vaihe 2) Mรครคritรค malli

Tรคssรค Deep Learning prosessissa, kรคytรคt ResNet18:aa torchvision-moduulista.

Kรคytรคt torchvision.models-tiedostoa ladataksesi resnet18:n esikoulutetulla painotuksella, joka on asetettu arvoon True. Tรคmรคn jรคlkeen jรครคdytรคt tasot niin, ettรค niitรค ei voi kouluttaa. Muokkaat myรถs viimeistรค tasoa lineaarisella tasolla vastaamaan tarpeitamme, jotka ovat kaksi luokkaa. Kรคytรคt myรถs CrossEntropyLossia moniluokkaiseen hรคviรถfunktioon ja optimoijana kรคytรคt SGD:tรค oppimisnopeudella 0.0001 ja momentumilla 0.9, kuten alla olevassa Py-kaaviossa on esitetty.Torch Siirto-oppimisen esimerkki.

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

Tulosmallin rakenne

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

Vaihe 3) Kouluta ja testaa malli

Kรคytรคmme joitain Transfer Learningin toimintoja PyTorch-opetusohjelma auttaa meitรค kouluttamaan ja arvioimaan malliamme.

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)

Viimeinkin tรคssรค siirto-oppimisessa Py:ssรคTorEsimerkissรค aloitetaan harjoitusprosessi asettamalla epookkien mรครคrรคksi 25 ja arvioidaan harjoitusprosessin jรคlkeen. Jokaisessa harjoitusvaiheessa malli ottaa syรถtteen ja ennustaa tulosteen. Sen jรคlkeen ennustettu tuloste vรคlitetรครคn kriteerille hรคviรถiden laskemiseksi. Sitten hรคviรถt suorittavat backprop-laskelman gradientin laskemiseksi ja lopuksi painotusten laskemiseksi ja parametrien optimoimiseksi autogradilla.

Visualisointimallissa koulutettua verkkoa testataan kuvaerรคllรค tarrojen ennustamiseksi. Sitten se visualisoidaan matplotlibin avulla.

vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25)

visualize_model(vgg_based)

plt.show()

Vaihe 4) Tulokset

Lopputulos on, ettรค saavutit 92 %:n tarkkuuden.

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

Lopuksi mallimme tulos visualisoidaan alla olevalla matplotilla:

Visualisoitu Matplotilla
Visualisoitu Matplotilla

Yhteenveto

Joten, tiivistetรครคn kaikki! Ensimmรคinen tekijรค on PyTorch on kasvava syvรคoppimiskehys aloittelijoille tai tutkimuskรคyttรถรถn. Se tarjoaa paljon laskenta-aikaa, dynaamisen graafin, nรคytรถnohjaintuen ja on kokonaan kirjoitettu kielellรค PythonVoit helposti mรครคritellรค oman verkkomoduulisi ja suorittaa koulutusprosessin helpolla iteraatiolla. On selvรครค, ettรค PyTorch on ihanteellinen aloittelijoille syvรคoppimisen tutkimiseen ja ammattitutkijoille se on erittรคin hyรถdyllinen nopeamman laskenta-ajan ja myรถs erittรคin hyรถdyllisen autograd-toiminnon ansiosta dynaamisen graafin avuksi.

Tiivistรค tรคmรค viesti seuraavasti: