Örneklerle PyTorch Transfer Öğrenme Eğitimi

Transfer Öğrenme Nedir?

Transfer Öğrenimi ilgili başka bir görevi çözmek için eğitilmiş bir model kullanma tekniğidir. Belirli bir problemi çözerken kazanılan bilgiyi saklayan ve aynı bilgiyi farklı fakat ilgili başka bir problemi çözmek için kullanan bir Makine Öğrenimi araştırma yöntemidir. Bu, daha önce öğrenilen görevden toplanan bilgilerin yeniden kullanılmasıyla verimliliği artırır.

Bir ağ modelini eğitmek için çok fazla veriye ihtiyacınız olduğundan, eğitim sürenizi azaltmak için diğer ağ modeli ağırlığını kullanmak popülerdir. Eğitim süresini azaltmak için diğer ağları ve ağırlığını kullanırsınız ve sorunumuzu çözmek için son katmanı değiştirirsiniz. Avantajı, son katmanı eğitmek için küçük bir veri kümesi kullanabilmenizdir.

Bu PyTorch Transfer öğrenme öğreticisinin bir sonraki bölümünde, Transfer Öğrenimini PyTorch ile nasıl kullanacağımızı öğreneceğiz.

Veri Kümesi Yükleniyor

Veri Kümesi Yükleniyor

Kaynak: Alien vs. Predator Kaggle

Transfer Learning PyTorch'u kullanmaya başlamadan önce kullanacağınız veri kümesini anlamanız gerekir. Bu Transfer Learning PyTorch örneğinde, yaklaşık 700 görüntüden bir Uzaylıyı ve bir Yırtıcıyı sınıflandıracaksınız. Bu tekniği eğitmek için gerçekten büyük miktarda veriye ihtiyacınız yok. Veri setini şuradan indirebilirsiniz: Kaggle: Uzaylı Yırtıcıya Karşı.

Transfer Öğrenme Nasıl Kullanılır?

PyTorch ile Derin Öğrenme için Transfer Öğrenmenin nasıl kullanılacağına ilişkin adım adım süreç aşağıda verilmiştir:

Adım 1) Verileri Yükleyin

İlk adım, verilerimizi yüklemek ve ağ gereksinimleriyle eşleşmeleri için görüntülerde bazı dönüşümler yapmaktır.

Verileri torchvision.dataset içeren bir klasörden yükleyeceksiniz. Modül, verileri eğitim ve doğrulama için bölmek üzere klasörde yinelenecektir. Dönüşüm süreci, görüntüleri merkezden kırpacak, yatay bir çevirme gerçekleştirecek, normalleştirecek ve son olarak Derin Öğrenmeyi kullanarak onu tensöre dönüştürecek.

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

PyTorch Transfer Learning için veri setimizi görselleştirelim. Görselleştirme süreci, tren veri yükleyicilerinden ve etiketlerinden bir sonraki görüntü grubunu alacak ve bunu matplot ile görüntüleyecektir.

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()
Toplu Görüntü
Toplu Görüntü

Adım 2) Modeli Tanımlayın

Bu Derin Öğrenme İşlem sırasında torchvision modülünden ResNet18'i kullanacaksınız.

Resnet18'i önceden eğitilmiş ağırlık True olarak ayarlanmış şekilde yüklemek için torchvision.models'i kullanacaksınız. Bundan sonra katmanları donduracaksınız, böylece bu katmanlar eğitilemez hale gelecektir. Ayrıca son katmanı, 2 sınıf olan ihtiyaçlarımıza uyacak şekilde Doğrusal bir katmanla değiştirirsiniz. Ayrıca çoklu sınıf kaybı işlevi için CrossEntropyLoss'u kullanacaksınız ve optimize edici için aşağıdaki PyTorch Transfer Öğrenme örneğinde gösterildiği gibi 0.0001 öğrenme oranı ve 0.9 momentum ile SGD'yi kullanacaksınız.

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

Çıkış modeli yapısı

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

Adım 3) Modeli Eğitin ve Test Edin

Transfer Learning'in bazı fonksiyonlarını kullanacağız PyTorch Eğitimi modelimizi eğitmemize ve değerlendirmemize yardımcı olmak için.

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)

Son olarak PyTorch'taki bu Transfer Learning örneğinde epoch sayısını 25 olarak ayarlayarak eğitim sürecimize başlayalım ve eğitim süreci sonrasında değerlendirme yapalım. Her eğitim adımında model girdiyi alacak ve çıktıyı tahmin edecektir. Bundan sonra tahmin edilen çıktı, kayıpları hesaplamak için kritere aktarılacaktır. Daha sonra kayıplar, eğimi hesaplamak için bir backprop hesaplaması gerçekleştirecek ve son olarak ağırlıkları hesaplayacak ve parametreleri autograd ile optimize edecektir.

Görselleştirme modelinde, eğitilen ağ, etiketleri tahmin etmek için bir dizi görüntüyle test edilecektir. Daha sonra matplotlib yardımıyla görselleştirilecektir.

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

visualize_model(vgg_based)

plt.show()

Adım 4) Sonuçlar

Nihai sonuç, %92'lik bir doğruluk elde ettiğinizdir.

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

Bittiğinde modelimizin çıktısı aşağıdaki matplot ile görselleştirilecektir:

Matplot ile görselleştirildi
Matplot ile görselleştirildi

ÖZET

Öyleyse her şeyi özetleyelim! İlk etken, PyTorch'un yeni başlayanlar veya araştırma amaçları için büyüyen bir derin öğrenme çerçevesi olmasıdır. Yüksek hesaplama süresi, Dinamik Grafik, GPU desteği sunar ve tamamen Python. Kendi ağ modülünüzü kolaylıkla tanımlayabilir ve eğitim sürecini kolay bir iterasyonla gerçekleştirebilirsiniz. PyTorch'un yeni başlayanlar için derin öğrenmeyi keşfetmeleri için ideal olduğu ve profesyonel araştırmacılar için daha hızlı hesaplama süresi ve ayrıca dinamik grafiğe yardımcı olan çok yararlı otomatik derecelendirme işlevi ile çok faydalı olduğu açıktır.

Bu yazıyı şu şekilde özetleyin: