PyTorch Transfer Learning για βαθιά μάθηση με παράδειγμα

Πίνακας περιεχομένων:

Anonim

Τι είναι η εκμάθηση μεταφοράς;

Το Transfer Learning είναι μια τεχνική χρήσης ενός εκπαιδευμένου μοντέλου για την επίλυση μιας άλλης σχετικής εργασίας. Είναι μια μέθοδος μηχανικής μάθησης που αποθηκεύει τις γνώσεις που αποκτώνται κατά την επίλυση ενός συγκεκριμένου προβλήματος και χρησιμοποιεί την ίδια γνώση για να λύσει ένα άλλο διαφορετικό αλλά σχετικό πρόβλημα. Αυτό βελτιώνει την αποτελεσματικότητα επαναχρησιμοποιώντας τις πληροφορίες που συλλέχθηκαν από την προηγούμενη εργασία.

Είναι δημοφιλές να χρησιμοποιείτε άλλο βάρος μοντέλου δικτύου για να μειώσετε τον χρόνο προπόνησής σας, επειδή χρειάζεστε πολλά δεδομένα για την εκπαίδευση ενός μοντέλου δικτύου. Για να μειώσετε τον χρόνο εκπαίδευσης, χρησιμοποιείτε άλλα δίκτυα και το βάρος του και τροποποιείτε το τελευταίο επίπεδο για να λύσετε το πρόβλημά μας. Το πλεονέκτημα είναι ότι μπορείτε να χρησιμοποιήσετε ένα μικρό σύνολο δεδομένων για να εκπαιδεύσετε το τελευταίο επίπεδο.

Στη συνέχεια, σε αυτό το σεμινάριο μάθησης PyTorch Transfer, θα μάθουμε πώς να χρησιμοποιούμε το Transfer Learning με το PyTorch

Φόρτωση συνόλου δεδομένων

Πηγή: Alien εναντίον Predator Kaggle

Πριν ξεκινήσετε να χρησιμοποιείτε το Transfer Learning PyTorch, πρέπει να κατανοήσετε το σύνολο δεδομένων που πρόκειται να χρησιμοποιήσετε. Σε αυτό το παράδειγμα Transfer Learning PyTorch, θα ταξινομήσετε έναν Alien και έναν Predator από σχεδόν 700 εικόνες. Για αυτήν την τεχνική, δεν χρειάζεστε πραγματικά μεγάλο αριθμό δεδομένων για να εκπαιδεύσετε. Μπορείτε να κατεβάσετε το σύνολο δεδομένων από το Kaggle: Alien εναντίον Predator.

Πώς να χρησιμοποιήσετε τη μεταφορά εκμάθησης;

Ακολουθεί μια διαδικασία βήμα προς βήμα σχετικά με τον τρόπο χρήσης του Transfer Learning για Deep Learning με το PyTorch:

Βήμα 1) Φορτώστε τα δεδομένα

Το πρώτο βήμα είναι να φορτώσουμε τα δεδομένα μας και να κάνουμε κάποια μεταμόρφωση σε εικόνες έτσι ώστε να ταιριάζει με τις απαιτήσεις του δικτύου.

Θα φορτώσετε τα δεδομένα από ένα φάκελο με το torchvision.dataset. Η ενότητα θα επαναληφθεί στο φάκελο για να διαχωρίσει τα δεδομένα για τρένο και επικύρωση. Η διαδικασία μετασχηματισμού θα περικόψει τις εικόνες από το κέντρο, θα πραγματοποιήσει οριζόντια αναστροφή, θα ομαλοποιήσει και τελικά θα τη μετατρέψει σε τάνυση χρησιμοποιώντας 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")

Ας απεικονίσουμε το σύνολο δεδομένων μας για το PyTorch Transfer Learning. Η διαδικασία οπτικοποίησης θα πάρει την επόμενη παρτίδα εικόνων από τους φορτωτές δεδομένων και τις ετικέτες του τρένου και θα την εμφανίσει με 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()

Βήμα 2) Ορισμός μοντέλου

Σε αυτήν τη διαδικασία Deep Learning, θα χρησιμοποιήσετε το ResNet18 από τη μονάδα torchvision.

Θα χρησιμοποιήσετε το torchvision.models για να φορτώσετε το resnet18 με το προ-εκπαιδευμένο βάρος να είναι True. Μετά από αυτό, θα παγώσετε τα επίπεδα έτσι ώστε αυτά τα στρώματα να μην μπορούν να εκπαιδευτούν. Μπορείτε επίσης να τροποποιήσετε το τελευταίο επίπεδο με ένα γραμμικό επίπεδο για να ταιριάζει με τις ανάγκες μας που είναι 2 τάξεις. Χρησιμοποιείτε επίσης CrossEntropyLoss για λειτουργία απώλειας πολλαπλών τάξεων και για το εργαλείο βελτιστοποίησης θα χρησιμοποιήσετε SGD με ρυθμό εκμάθησης 0,0001 και ορμή 0,9 όπως φαίνεται στο παρακάτω παράδειγμα PyTorch Transfer Learning Learning.

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

Η δομή του μοντέλου εξόδου

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

Βήμα 3) Εκπαίδευση και μοντέλο δοκιμής

Θα χρησιμοποιήσουμε κάποια από τη λειτουργία από το Transfer Learning PyTorch Tutorial για να μας βοηθήσουν να εκπαιδεύσουμε και να αξιολογήσουμε το μοντέλο μας.

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)

Τέλος, σε αυτό το παράδειγμα Transfer Learning in PyTorch, ας ξεκινήσουμε την εκπαιδευτική μας διαδικασία με τον αριθμό των εποχών που ορίζονται σε 25 και να αξιολογήσουμε μετά τη διαδικασία προπόνησης. Σε κάθε βήμα προπόνησης, το μοντέλο θα λάβει την είσοδο και θα προβλέψει την έξοδο. Μετά από αυτό, η προβλεπόμενη έξοδος θα περάσει στο κριτήριο για τον υπολογισμό των απωλειών. Στη συνέχεια, οι απώλειες θα πραγματοποιήσουν έναν υπολογισμό backprop για να υπολογίσουν την κλίση και τελικά να υπολογίσουν τα βάρη και να βελτιστοποιήσουν τις παραμέτρους με το autograd.

Στο μοντέλο οπτικοποίησης, το εκπαιδευμένο δίκτυο θα δοκιμαστεί με μια παρτίδα εικόνων για την πρόβλεψη των ετικετών. Τότε θα απεικονιστεί με τη βοήθεια του matplotlib.

vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25)visualize_model(vgg_based)plt.show()

Βήμα 4) Αποτελέσματα

Το τελικό αποτέλεσμα είναι ότι έχετε επιτύχει ακρίβεια 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

Τελειώστε τότε η έξοδος του μοντέλου μας θα απεικονιστεί με matplot παρακάτω:

Περίληψη

Ας συνοψίσουμε λοιπόν τα πάντα! Ο πρώτος παράγοντας είναι το PyTorch είναι ένα αναπτυσσόμενο πλαίσιο βαθιάς μάθησης για αρχάριους ή για ερευνητικούς σκοπούς. Προσφέρει υψηλό χρόνο υπολογισμού, δυναμικό γράφημα, υποστήριξη GPU και είναι εντελώς γραμμένο σε Python. Μπορείτε να ορίσετε εύκολα τη δική μας ενότητα δικτύου και να κάνετε τη διαδικασία εκπαίδευσης με εύκολη επανάληψη. Είναι σαφές ότι το PyTorch είναι ιδανικό για αρχάριους για να μάθουν τη βαθιά μάθηση και για επαγγελματίες ερευνητές είναι πολύ χρήσιμο με ταχύτερο χρόνο υπολογισμού και επίσης με την πολύ χρήσιμη λειτουργία autograd για να βοηθήσει το δυναμικό γράφημα.