PyTorHoofdstuk: Handleiding voor transferleren met voorbeelden

Wat is transferleren?

Transfer leren is een techniek waarbij een getraind model wordt gebruikt om een โ€‹โ€‹andere gerelateerde taak op te lossen. Het is een Machine Learning-onderzoeksmethode die de kennis opslaat die is opgedaan bij het oplossen van een bepaald probleem en dezelfde kennis gebruikt om een โ€‹โ€‹ander ander, maar gerelateerd probleem op te lossen. Dit verbetert de efficiรซntie door de informatie die is verzameld uit de eerder geleerde taak opnieuw te gebruiken.

Het is populair om andere netwerkmodellen te gebruiken om uw trainingstijd te verkorten, omdat u veel gegevens nodig heeft om een โ€‹โ€‹netwerkmodel te trainen. Om de trainingstijd te verkorten, gebruikt u andere netwerken en het gewicht ervan en past u de laatste laag aan om ons probleem op te lossen. Het voordeel is dat je een kleine dataset kunt gebruiken om de laatste laag te trainen.

Volgende in deze PyTorIn deze tutorial over transfer learning leren we hoe we transfer learning met Python kunnen gebruiken.Torch.

Gegevensset laden

Gegevensset laden

Bron: Alien versus Predator Kaggle

Voordat je Transfer Learning Py gaat gebruikenTorOm dit te begrijpen, moet je de dataset die je gaat gebruiken goed kennen. In deze Transfer Learning PyTorIn dit voorbeeld ga je een alien en een roofdier classificeren aan de hand van bijna 700 afbeeldingen. Voor deze techniek heb je geen grote hoeveelheid data nodig om te trainen. Je kunt de dataset downloaden van Kaggle: Alien versus roofdier.

Hoe gebruik je transferleren?

Hieronder volgt een stapsgewijze handleiding voor het gebruik van transfer learning voor deep learning met Python.Torch:

Stap 1) Laad de gegevens

De eerste stap is het laden van onze gegevens en het uitvoeren van enige transformatie naar afbeeldingen, zodat ze voldoen aan de netwerkvereisten.

U laadt de gegevens uit een map met torchvision.dataset. De module itereert in de map om de gegevens voor trein en validatie te splitsen. Het transformatieproces zal de afbeeldingen vanuit het midden bijsnijden, een horizontale spiegeling uitvoeren, normaliseren en uiteindelijk converteren naar tensor met behulp van Deep Learning.

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

Laten we onze dataset voor Py visualiseren.Torch Transfer Learning. Het visualisatieproces haalt de volgende reeks afbeeldingen op uit de trainingsdataset en labelt deze met Matplot.

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()
Partij afbeeldingen
Partij afbeeldingen

Stap 2) Model definiรซren

In deze Diepe leren proces, gebruikt u ResNet18 van de Torchvision-module.

Je gebruikt torchvision.models om ResNet18 te laden met de vooraf getrainde gewichten ingesteld op True. Daarna bevries je de lagen zodat deze niet trainbaar zijn. Je past ook de laatste laag aan met een lineaire laag om aan onze behoeften te voldoen, namelijk 2 klassen. Je gebruikt CrossEntropyLoss als verliesfunctie voor meerdere klassen en als optimizer gebruik je SGD met een leerfrequentie van 0.0001 en een momentum van 0.9, zoals weergegeven in de onderstaande Py-code.Torch. Voorbeeld van transferleren.

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

De uitvoermodelstructuur

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

Stap 3) Model trainen en testen

We zullen enkele functies van Transfer Learning gebruiken PyTorch Handleiding om ons te helpen ons model te trainen en te evalueren.

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)

Tot slot, in deze Transfer Learning in PyTorLaten we bijvoorbeeld ons trainingsproces starten met 25 epochs en na afloop evalueren. Bij elke trainingsstap neemt het model de invoer en voorspelt de uitvoer. Vervolgens wordt de voorspelde uitvoer doorgegeven aan het criterium om de verliezen te berekenen. De verliezen worden vervolgens gebruikt voor een backprop-berekening om de gradiรซnt te berekenen, waarna de gewichten worden berekend en de parameters worden geoptimaliseerd met autograd.

Bij het visualisatiemodel wordt het getrainde netwerk getest met een reeks afbeeldingen om de labels te voorspellen. Vervolgens wordt het gevisualiseerd met behulp van matplotlib.

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

visualize_model(vgg_based)

plt.show()

Stap 4) Resultaten

Het eindresultaat is dat je een nauwkeurigheid van 92% hebt behaald.

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

Eindig, dan zal de uitvoer van ons model worden gevisualiseerd met onderstaande matplot:

Gevisualiseerd met Matplot
Gevisualiseerd met Matplot

Samenvatting

Laten we alles even samenvatten! De eerste factor is PyTorch is een groeiend deep learning-framework voor beginners of voor onderzoeksdoeleinden. Het biedt hoge rekentijden, dynamische grafieken, GPU-ondersteuning en is volledig in ch geschreven. PythonJe kunt eenvoudig je eigen netwerkmodule definiรซren en het trainingsproces met een simpele iteratie uitvoeren. Het is duidelijk dat PyTorch is ideaal voor beginners die meer willen weten over deep learning, en voor professionele onderzoekers is het zeer nuttig vanwege de snellere rekentijd en de handige autograd-functie die dynamische grafieken ondersteunt.

Vat dit bericht samen met: