PyTorTutorial zum Transferlernen mit Beispielen

Was ist Transferlernen?

Lernen รผbertragen ist eine Technik, bei der ein trainiertes Modell verwendet wird, um eine andere verwandte Aufgabe zu lรถsen. Es handelt sich um eine Forschungsmethode des maschinellen Lernens, die das bei der Lรถsung eines bestimmten Problems gewonnene Wissen speichert und dasselbe Wissen zur Lรถsung eines anderen, aber verwandten Problems verwendet. Dies verbessert die Effizienz, indem die aus der zuvor erlernten Aufgabe gesammelten Informationen wiederverwendet werden.

Es ist beliebt, eine andere Netzwerkmodellgewichtung zu verwenden, um die Trainingszeit zu verkรผrzen, da Sie zum Trainieren eines Netzwerkmodells viele Daten benรถtigen. Um die Trainingszeit zu verkรผrzen, nutzen Sie andere Netzwerke und deren Gewicht und modifizieren die letzte Schicht, um unser Problem zu lรถsen. Der Vorteil besteht darin, dass Sie einen kleinen Datensatz verwenden kรถnnen, um die letzte Ebene zu trainieren.

Als nรคchstes in diesem PyTorIn diesem Tutorial zum Transferlernen lernen wir, wie man Transferlernen mit Py anwendet.Torch.

Datensatz laden

Datensatz laden

Quelle: Alien vs. Predator Kaggle

Bevor Sie mit Transfer Learning Py beginnenTorHallo, du musst den Datensatz verstehen, den du verwenden wirst. In diesem Transfer Learning PyTorIn diesem Beispiel sollen Sie anhand von fast 700 Bildern ein Alien und einen Predator klassifizieren. Fรผr diese Methode benรถtigen Sie keine groรŸen Trainingsdaten. Sie kรถnnen den Datensatz hier herunterladen: Kaggle: Alien vs. Predator.

Wie nutzt man Transferlernen?

Hier ist eine schrittweise Anleitung zur Verwendung von Transfer Learning fรผr Deep Learning mit Py.Torch:

Schritt 1) โ€‹โ€‹Laden Sie die Daten

Der erste Schritt besteht darin, unsere Daten zu laden und die Bilder so umzuwandeln, dass sie den Netzwerkanforderungen entsprechen.

Sie laden die Daten aus einem Ordner mit Torchvision.dataset. Das Modul durchlรคuft den Ordner, um die Daten fรผr Training und Validierung aufzuteilen. Der Transformationsprozess schneidet die Bilder von der Mitte aus zu, fรผhrt eine horizontale Spiegelung durch, normalisiert sie und wandelt sie schlieรŸlich mithilfe von Deep Learning in einen Tensor um.

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

Visualisieren wir unseren Datensatz fรผr PyTorTransfer Learning. Der Visualisierungsprozess ruft die nรคchste Bilderserie aus den Trainingsdaten und den zugehรถrigen Labels ab und visualisiert sie mit 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()
Stapel von Bildern
Stapel von Bildern

Schritt 2) Modell definieren

In dieser Tiefes Lernen Im Prozess verwenden Sie ResNet18 aus dem Torchvision-Modul.

Sie verwenden `torchvision.models`, um ResNet18 mit den vortrainierten Gewichten (auf `True` gesetzt) โ€‹โ€‹zu laden. AnschlieรŸend frieren Sie die Layer ein, sodass diese nicht trainierbar sind. Die letzte Schicht wird durch eine lineare Schicht ersetzt, um den Anforderungen von zwei Klassen gerecht zu werden. Als Verlustfunktion fรผr Mehrklassenanalyse verwenden Sie `CrossEntropyLoss` und als Optimierer `SGD` mit einer Lernrate von 0.0001 und einem Momentum von 0.9 (siehe untenstehender Py-Code).TorBeispiel fรผr Transferlernen.

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

Die Struktur des Ausgabemodells

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

Schritt 3) Modell trainieren und testen

Wir werden einige der Funktionen von Transfer Learning nutzen PyTorch Tutorial um uns beim Trainieren und Bewerten unseres Modells zu helfen.

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)

AbschlieรŸend zum Transferlernen in PyTorNehmen wir als Beispiel den Trainingsprozess mit 25 Epochen und fรผhren anschlieรŸend eine Auswertung durch. In jedem Trainingsschritt verarbeitet das Modell die Eingabe und sagt die Ausgabe voraus. Diese vorhergesagte Ausgabe wird dann an das Kriterium รผbergeben, um die Verluste zu berechnen. AnschlieรŸend wird mithilfe der Verluste eine Backpropagation durchgefรผhrt, um den Gradienten zu ermitteln und schlieรŸlich die Gewichte zu berechnen und die Parameter mit Autograd zu optimieren.

Beim Visualisierungsmodell wird das trainierte Netzwerk mit einer Reihe von Bildern getestet, um die Beschriftungen vorherzusagen. AnschlieรŸend wird es mit Hilfe von Matplotlib visualisiert.

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

visualize_model(vgg_based)

plt.show()

Schritt 4) Ergebnisse

Das Endergebnis ist, dass Sie eine Genauigkeit von 92 % erreicht haben.

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

Am Ende wird die Ausgabe unseres Modells mit Matplot unten visualisiert:

Visualisiert mit Matplot
Visualisiert mit Matplot

Zusammenfassung

Fassen wir also alles zusammen! Der erste Faktor ist Py.Torch ist ein wachsendes Deep-Learning-Framework fรผr Einsteiger und Forschungszwecke. Es bietet hohe Rechenzeit, dynamische Graphen, GPU-Unterstรผtzung und ist vollstรคndig in ch geschrieben. PythonSie kรถnnen Ihr eigenes Netzwerkmodul problemlos definieren und den Trainingsprozess mit einfachen Iterationen durchfรผhren. Es ist klar, dass PyTorch eignet sich ideal fรผr Anfรคnger, um Deep Learning kennenzulernen, und ist auch fรผr professionelle Forscher sehr nรผtzlich, da es schnellere Rechenzeiten und die รคuรŸerst hilfreiche Autograd-Funktion zur Unterstรผtzung dynamischer Graphen bietet.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: