PyTorch Transfer Learning per Deep Learning con esempio

Sommario:

Anonim

Cos'è il Transfer Learning?

Transfer Learning è una tecnica che utilizza un modello addestrato per risolvere un'altra attività correlata. È un metodo di ricerca di Machine Learning che memorizza le conoscenze acquisite 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.

È molto comune utilizzare un altro modello di rete per ridurre il tempo di addestramento perché sono necessari molti dati per addestrare un modello di rete. Per ridurre il tempo di allenamento, usi altre reti e il suo 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 sul trasferimento di PyTorch, impareremo come utilizzare l'apprendimento del trasferimento con PyTorch.

Caricamento del set di dati

Fonte: Alien vs. Predator Kaggle

Prima di iniziare a utilizzare Transfer Learning PyTorch, è necessario comprendere il set di dati che si intende utilizzare. In questo esempio di Transfer Learning PyTorch, classificherai un alieno e un predatore da quasi 700 immagini. Per questa tecnica, non hai davvero bisogno di una grande quantità di dati per l'addestramento. Puoi scaricare il set di dati da Kaggle: Alien vs. Predator.

Come utilizzare Transfer Learning?

Ecco una procedura passo passo su come utilizzare Transfer Learning per Deep Learning con PyTorch:

Passaggio 1) Carica i dati

Il primo passo è caricare i nostri dati ed eseguire alcune trasformazioni in immagini in modo che soddisfino i requisiti di rete.

Caricherai i dati da una cartella con torchvision.dataset. Il modulo itererà nella cartella per dividere i dati per l'addestramento e la convalida. Il processo di trasformazione ritaglierà le immagini dal centro, eseguirà un capovolgimento orizzontale, normalizzerà e infine le convertirà in tensore utilizzando il 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")

Visualizziamo il nostro set di dati per PyTorch Transfer Learning. Il processo di visualizzazione otterrà il prossimo lotto di immagini dai caricatori di dati del treno e dalle etichette e lo visualizzerà con 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()

Passaggio 2) Definisci modello

In questo processo di Deep Learning, utilizzerai ResNet18 dal modulo torchvision.

Utilizzerai torchvision.models per caricare resnet18 con il peso pre-addestrato impostato su True. Dopodiché, congelerai gli strati in modo che questi strati non siano allenabili. Puoi anche modificare l'ultimo livello con un livello lineare per adattarlo alle nostre esigenze, ovvero 2 classi. Usi anche CrossEntropyLoss per la funzione di perdita multi-classe e per l'ottimizzatore utilizzerai SGD con il tasso di apprendimento di 0,0001 e uno slancio di 0,9 come mostrato nell'esempio di PyTorch Transfer Learning di seguito.

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

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) Addestrare e testare il modello

Useremo alcune delle funzioni del Transfer Learning PyTorch Tutorial 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 = 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)

Infine, in questo esempio di trasferimento dell'apprendimento in PyTorch, iniziamo il nostro processo di formazione con il numero di epoche impostato su 25 e valutiamo dopo il processo di formazione. In ogni fase dell'addestramento, il modello prenderà l'input e prevederà l'output. Dopodiché, l'output previsto verrà passato al criterio per calcolare le perdite. Quindi le perdite eseguiranno un calcolo backprop per calcolare il gradiente e infine calcolare i pesi e ottimizzare i parametri con autograd.

Al modello di visualizzazione, la rete addestrata verrà testata con un lotto 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.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

Termina quindi l'output del nostro modello verrà visualizzato con matplot di seguito:

Sommario

Quindi, riassumiamo tutto! Il primo fattore è che PyTorch è un framework di apprendimento profondo in crescita per principianti o per scopi di ricerca. Offre tempi di calcolo elevati, grafico dinamico, supporto per GPU ed è completamente scritto in Python. Sei in grado di definire il nostro modulo di rete con facilità e di eseguire il processo di formazione con una facile iterazione. È chiaro che PyTorch è l'ideale per i principianti per scoprire il deep learning e per i ricercatori professionisti è molto utile con tempi di calcolo più rapidi e anche l'utilissima funzione autograd per assistere il grafico dinamico.