Was ist Transferlernen?
Transfer Learning ist eine Technik zur Verwendung eines trainierten Modells zur Lösung einer anderen verwandten Aufgabe. Es handelt sich um eine Forschungsmethode für maschinelles Lernen, bei der das bei der Lösung eines bestimmten Problems gewonnene Wissen gespeichert und dasselbe Wissen zur Lösung eines anderen, jedoch verwandten Problems verwendet wird. Dies verbessert die Effizienz, indem die aus der zuvor erlernten Aufgabe gesammelten Informationen wiederverwendet werden.
Es ist beliebt, ein anderes Netzwerkmodellgewicht zu verwenden, um Ihre Trainingszeit zu verkürzen, da Sie viele Daten benötigen, um ein Netzwerkmodell zu trainieren. Um die Trainingszeit zu verkürzen, verwenden Sie andere Netzwerke und deren Gewicht und ändern die letzte Schicht, um unser Problem zu lösen. Der Vorteil ist, dass Sie einen kleinen Datensatz verwenden können, um die letzte Ebene zu trainieren.
In diesem Lernprogramm für PyTorch Transfer lernen wir, wie Sie Transfer Learning mit PyTorch verwenden.
Datensatz wird geladen
Quelle: Alien vs. Predator Kaggle
Bevor Sie Transfer Learning PyTorch verwenden, müssen Sie das zu verwendende Dataset verstehen. In diesem Beispiel für Transfer Learning PyTorch klassifizieren Sie einen Alien und einen Predator aus fast 700 Bildern. Für diese Technik benötigen Sie nicht wirklich eine große Datenmenge, um zu trainieren. Sie können den Datensatz von Kaggle: Alien vs. Predator herunterladen.
Wie verwende ich Transfer Learning?
Hier finden Sie eine schrittweise Anleitung zur Verwendung von Transfer Learning für Deep Learning mit PyTorch:
Schritt 1) Laden Sie die Daten
Der erste Schritt besteht darin, unsere Daten zu laden und einige Bilder zu transformieren, damit sie den Netzwerkanforderungen entsprechen.
Sie laden die Daten aus einem Ordner mit torchvision.dataset. Das Modul wird im Ordner iteriert, um die Daten für Zug und Validierung aufzuteilen. Der Transformationsprozess schneidet die Bilder von der Mitte aus zu, führt einen horizontalen Flip durch, normalisiert sie und konvertiert sie schließlich mithilfe von Deep Learning in einen Tensor.
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")
Lassen Sie uns unseren Datensatz für PyTorch Transfer Learning visualisieren. Der Visualisierungsprozess erhält den nächsten Bildstapel von den Zugdatenladern und -etiketten und zeigt ihn mit Matplot an.
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()
Schritt 2) Modell definieren
In diesem Deep Learning-Prozess verwenden Sie ResNet18 aus dem Torchvision-Modul.
Sie werden torchvision.models verwenden, um resnet18 mit dem voreingestellten Gewicht True zu laden. Danach frieren Sie die Ebenen ein, sodass diese Ebenen nicht trainiert werden können. Sie können auch die letzte Ebene mit einer linearen Ebene ändern, um sie an unsere Anforderungen anzupassen, dh 2 Klassen. Sie verwenden CrossEntropyLoss auch für die Verlustfunktion für mehrere Klassen und für den Optimierer verwenden Sie SGD mit einer Lernrate von 0,0001 und einem Impuls von 0,9, wie im folgenden PyTorch Transfer Learning-Beispiel gezeigt.
## 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)
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 aus dem Transfer Learning PyTorch Tutorial verwenden, um unser Modell zu trainieren und zu bewerten.
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)
Beginnen wir in diesem Beispiel für das Transferlernen in PyTorch mit unserem Trainingsprozess mit der Anzahl der auf 25 eingestellten Epochen und werten Sie ihn nach dem Trainingsprozess aus. Bei jedem Trainingsschritt nimmt das Modell die Eingabe und sagt die Ausgabe voraus. Danach wird die vorhergesagte Ausgabe an das Kriterium übergeben, um die Verluste zu berechnen. Dann führen die Verluste eine Backprop-Berechnung durch, um den Gradienten zu berechnen 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.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
Am Ende wird die Ausgabe unseres Modells mit dem folgenden Matplot visualisiert:
Zusammenfassung
Fassen wir also alles zusammen! Der erste Faktor ist, dass PyTorch ein wachsendes Deep-Learning-Framework für Anfänger oder zu Forschungszwecken ist. Es bietet hohe Rechenzeit, Dynamic Graph, GPU-Unterstützung und ist vollständig in Python geschrieben. Sie können problemlos unser eigenes Netzwerkmodul definieren und den Schulungsprozess mit einer einfachen Iteration durchführen. Es ist klar, dass PyTorch ideal für Anfänger ist, um tiefes Lernen zu erlernen, und für professionelle Forscher ist es sehr nützlich mit einer schnelleren Rechenzeit und der sehr hilfreichen Autograd-Funktion zur Unterstützung dynamischer Graphen.