Tutoriel d'apprentissage par transfert PyTorch avec exemples
Qu'est-ce que l'apprentissage par transfert ?
Transfert d'apprentissage est une technique consistant ร utiliser un modรจle entraรฎnรฉ pour rรฉsoudre une autre tรขche connexe. Il s'agit d'une mรฉthode de recherche d'apprentissage automatique qui stocke les connaissances acquises lors de la rรฉsolution d'un problรจme particulier et utilise les mรชmes connaissances pour rรฉsoudre un autre problรจme diffรฉrent mais connexe. Cela amรฉliore l'efficacitรฉ en rรฉutilisant les informations recueillies ร partir de la tรขche prรฉcรฉdemment apprise.
Il est courant d'utiliser une autre pondรฉration de modรจle de rรฉseau pour rรฉduire votre temps de formation, car vous avez besoin de beaucoup de donnรฉes pour former un modรจle de rรฉseau. Pour rรฉduire le temps de formation, vous utilisez d'autres rรฉseaux et son poids et modifiez la derniรจre couche pour rรฉsoudre notre problรจme. L'avantage est que vous pouvez utiliser un petit ensemble de donnรฉes pour entraรฎner la derniรจre couche.
Ensuite, dans ce didacticiel d'apprentissage PyTorch Transfer, nous apprendrons comment utiliser Transfer Learning avec PyTorch.
Chargement de l'ensemble de donnรฉes
Source : Alien contre Predator Kaggle
Avant de commencer ร utiliser Transfer Learning PyTorch, vous devez comprendre l'ensemble de donnรฉes que vous allez utiliser. Dans cet exemple de Transfer Learning PyTorch, vous classerez un Alien et un Predator ร partir de prรจs de 700 images. Pour cette technique, vous nโavez pas vraiment besoin dโune grande quantitรฉ de donnรฉes pour vous entraรฎner. Vous pouvez tรฉlรฉcharger l'ensemble de donnรฉes ร partir de Kaggle : Alien contre prรฉdateur.
Comment utiliser lโapprentissage par transfert ?
Voici un processus รฉtape par รฉtape sur la faรงon d'utiliser Transfer Learning pour le Deep Learning avec PyTorch :
รtape 1) Charger les donnรฉes
La premiรจre รฉtape consiste ร charger nos donnรฉes et ร transformer les images afin qu'elles correspondent aux exigences du rรฉseau.
Vous chargerez les donnรฉes d'un dossier avec torchvision.dataset. Le module parcourra le dossier pour diviser les donnรฉes pour l'entraรฎnement et la validation. Le processus de transformation recadrera les images ร partir du centre, effectuera un retournement horizontal, les normalisera et enfin les convertira en tenseur ร l'aide du 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")
Visualisons notre ensemble de donnรฉes pour PyTorch Transfer Learning. Le processus de visualisation obtiendra le prochain lot d'images des chargeurs de donnรฉes et des รฉtiquettes du train et l'affichera avec 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()

รtape 2) Dรฉfinir le modรจle
Dans ce nouvel article concernant notre nouveau projet L'apprentissage en profondeur processus, vous utiliserez ResNet18 du module torchvision.
Vous utiliserez torchvision.models pour charger resnet18 avec le poids prรฉ-entraรฎnรฉ dรฉfini sur True. Aprรจs cela, vous gelerez les calques afin quโils ne puissent pas รชtre entraรฎnรฉs. Vous modifiez รฉgalement le dernier calque avec un calque linรฉaire pour l'adapter ร nos besoins, soit 2 classes. Vous utilisez รฉgalement CrossEntropyLoss pour la fonction de perte multi-classe et pour l'optimiseur, vous utiliserez SGD avec un taux d'apprentissage de 0.0001 et un รฉlan de 0.9, comme indiquรฉ dans l'exemple d'apprentissage par transfert PyTorch ci-dessous.
## 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)
La structure du modรจle de sortie
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) ) )
รtape 3) Former et tester le modรจle
Nous utiliserons certaines des fonctions de Transfer Learning Tutoriel PyTorch pour nous aider ร former et ร รฉvaluer notre modรจle.
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)
Enfin, dans cet exemple d'apprentissage par transfert dans PyTorch, commenรงons notre processus de formation avec le nombre d'รฉpoques fixรฉ ร 25 et รฉvaluons aprรจs le processus de formation. ร chaque รฉtape de formation, le modรจle prendra en compte les entrรฉes et prรฉdira la sortie. Aprรจs cela, la production prรฉvue sera transmise au critรจre permettant de calculer les pertes. Ensuite, les pertes effectueront un calcul de backprop pour calculer le gradient et enfin calculer les poids et optimiser les paramรจtres avec autograd.
Au niveau du modรจle de visualisation, le rรฉseau formรฉ sera testรฉ avec un lot d'images pour prรฉdire les รฉtiquettes. Ensuite, il sera visualisรฉ ร l'aide de matplotlib.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25) visualize_model(vgg_based) plt.show()
รtape 4) Rรฉsultats
Le rรฉsultat final est que vous avez atteint une prรฉcision de 92 %.
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
Terminez ensuite la sortie de notre modรจle sera visualisรฉe avec matplot ci-dessous :

Rรฉsumรฉ
Alors, rรฉsumons tout ! Le premier facteur est que PyTorch est un framework d'apprentissage profond en pleine croissance pour les dรฉbutants ou ร des fins de recherche. Il offre un temps de calcul รฉlevรฉ, un graphique dynamique, un support GPU et il est entiรจrement รฉcrit en Python. Vous รชtes capable de dรฉfinir facilement votre propre module rรฉseau et dโeffectuer le processus de formation avec une itรฉration simple. Il est clair que PyTorch est idรฉal pour les dรฉbutants qui souhaitent dรฉcouvrir l'apprentissage en profondeur et pour les chercheurs professionnels, il est trรจs utile avec un temps de calcul plus rapide et รฉgalement la fonction autograd trรจs utile pour assister les graphiques dynamiques.

