Tutorial di apprendimento sul trasferimento di PyTorch con esempi
Che cos'รจ il trasferimento di apprendimento?
Trasferimento di apprendimento รจ una tecnica che consiste nell'utilizzare un modello addestrato per risolvere un'altra attivitร correlata. ร un metodo di ricerca di Machine Learning che memorizza la conoscenza acquisita durante la risoluzione di un particolare problema e utilizza la stessa conoscenza per risolvere un altro problema diverso ma correlato. Ciรฒ migliora l'efficienza riutilizzando le informazioni raccolte dall'attivitร appresa in precedenza.
ร prassi comune utilizzare un altro peso del modello di rete per ridurre i tempi di addestramento perchรฉ sono necessari molti dati per addestrare un modello di rete. Per ridurre il tempo di allenamento, utilizzi altre reti e il loro peso e modifichi l'ultimo strato per risolvere il nostro problema. Il vantaggio รจ che puoi utilizzare un piccolo set di dati per addestrare l'ultimo livello.
Successivamente in questo tutorial di apprendimento di PyTorch Transfer, impareremo come utilizzare Transfer Learning con PyTorch.
Caricamento set di dati
Fonte: Alien vs. Predator Kaggle
Prima di iniziare a utilizzare Transfer Learning PyTorch, devi comprendere il set di dati che utilizzerai. In questo esempio di Transfer Learning PyTorch, classificherai un alieno e un predatore da quasi 700 immagini. Per questa tecnica non รจ necessaria una grande quantitร di dati per l'addestramento. ร possibile scaricare il set di dati da Kaggle: Alieno contro predatore.
Come utilizzare il Transfer Learning?
Ecco una procedura passo passo su come utilizzare Transfer Learning per Deep Learning con PyTorch:
Passaggio 1) Caricare i dati
Il primo passo รจ caricare i nostri dati e apportare alcune trasformazioni alle immagini in modo che corrispondano ai requisiti di rete.
Caricherai i dati da una cartella con torchvision.dataset. Il modulo eseguirร un'iterazione nella cartella per suddividere i dati per il training e la convalida. Il processo di trasformazione ritaglierร le immagini dal centro, eseguirร un capovolgimento orizzontale, le normalizzerร e infine le convertirร in tensore utilizzando il 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")
Visualizziamo il nostro set di dati per PyTorch Transfer Learning. Il processo di visualizzazione otterrร il successivo batch di immagini dai caricatori di dati e dalle etichette del treno e lo visualizzerร con 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()

Passaggio 2) Definire il modello
In questa Deep Learning processo, utilizzerai ResNet18 dal modulo torchvision.
Utilizzerai torchvision.models per caricare resnet18 con il peso pre-addestrato impostato su True. Successivamente, congelerai i livelli in modo che questi livelli non siano addestrabili. Modifichi anche l'ultimo livello con un livello Lineare per adattarlo alle nostre esigenze ovvero 2 classi. Utilizzi anche CrossEntropyLoss per la funzione di perdita multi-classe e per l'ottimizzatore utilizzerai SGD con un tasso di apprendimento di 0.0001 e uno slancio di 0.9 come mostrato nell'esempio di apprendimento di trasferimento PyTorch di seguito.
## 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 struttura del modello di output
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) ) )
Passaggio 3) Formazione e test del modello
Utilizzeremo alcune delle funzioni di Transfer Learning Esercitazione su PyTorch per aiutarci ad addestrare e valutare il nostro modello.
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)
Infine, in questo esempio di Transfer Learning in PyTorch, iniziamo il nostro processo di addestramento con il numero di epoche impostato su 25 e valutiamo dopo il processo di addestramento. Ad ogni fase dell'addestramento, il modello prenderร l'input e prevederร l'output. Successivamente, la produzione prevista verrร utilizzata come criterio per calcolare le perdite. Successivamente verrร eseguito un calcolo delle perdite per calcolare il gradiente e infine calcolare i pesi e ottimizzare i parametri con autograd.
Nel modello di visualizzazione, la rete addestrata verrร testata con un batch di immagini per prevedere le etichette. Quindi verrร visualizzato con l'aiuto di matplotlib.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25) visualize_model(vgg_based) plt.show()
Passaggio 4) Risultati
Il risultato finale รจ che hai raggiunto una precisione del 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
Al termine quindi l'output del nostro modello verrร visualizzato con matplot di seguito:

Sintesi
Quindi, riassumiamo tutto! Il primo fattore รจ che PyTorch รจ un framework di deep learning in crescita per principianti o per scopi di ricerca. Offre un tempo di calcolo elevato, Dynamic Graph, supporto GPU ed รจ completamente scritto in Python. Puoi definire facilmente il tuo modulo di rete ed eseguire il processo di formazione con una semplice iterazione. ร chiaro che PyTorch รจ l'ideale per i principianti per scoprire l'apprendimento profondo e per i ricercatori professionisti รจ molto utile con tempi di calcolo piรน rapidi e anche l'utilissima funzione autograd per assistere il grafico dinamico.

