PyTorch Підручник з перенесення навчання з прикладами

Що таке трансферне навчання?

Трансферне навчання це техніка використання навченої моделі для вирішення іншого пов’язаного завдання. Це метод дослідження машинного навчання, який зберігає знання, отримані під час вирішення конкретної проблеми, і використовує ті самі знання для вирішення іншої, але пов’язаної проблеми. Це покращує ефективність шляхом повторного використання інформації, зібраної під час виконання попереднього завдання.

Популярно використовувати іншу вагу моделі мережі, щоб скоротити час навчання, оскільки для навчання моделі мережі потрібно багато даних. Щоб скоротити час навчання, ви використовуєте інші мережі та їх вагу та змінюєте останній шар, щоб вирішити нашу проблему. Перевагою є те, що ви можете використовувати невеликий набір даних для навчання останнього рівня.

Далі в цьому PyTorch Підручник з трансферного навчання, ми навчимося використовувати трансферне навчання з PyTorглава

Завантаження набору даних

Завантаження набору даних

Джерело: Alien vs. Predator Kaggle

Перш ніж почати використовувати Transfer Learning PyTorch, вам потрібно розуміти набір даних, який ви збираєтеся використовувати. У цьому Transfer Learning PyTorНаприклад, ви класифікуєте Чужого та Хижака майже з 700 зображень. Для цього методу вам насправді не потрібна велика кількість даних для навчання. Ви можете завантажити набір даних з Kaggle: Чужий проти Хижака.

Як використовувати Transfer Learning?

Ось покроковий процес використання трансферного навчання для глибокого навчання з PyTorч:

Крок 1) Завантажте дані

Першим кроком є ​​завантаження наших даних і перетворення зображень, щоб вони відповідали вимогам мережі.

Ви завантажите дані з папки torchvision.dataset. Модуль виконуватиме ітерацію в папці, щоб розділити дані для підготовки та перевірки. Процес трансформації обрізає зображення з центру, виконує горизонтальне відображення, нормалізує та, нарешті, перетворює зображення на тензор за допомогою глибокого навчання.

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 Передача навчання. Процес візуалізації отримає наступну партію зображень із завантажувачів даних поїзда та міток і відобразить її за допомогою 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()
Пакет зображень
Пакет зображень

Крок 2) Визначте модель

В цьому Глибоке навчання ви будете використовувати ResNet18 з модуля torchvision.

Ви будете використовувати torchvision.models для завантаження resnet18 з попередньо навченою вагою, встановленою на True. Після цього ви заморозите шари, щоб вони не могли навчатися. Ви також модифікуєте останній шар лінійним шаром, щоб він відповідав нашим потребам, тобто 2 класам. Ви також використовуєте CrossEntropyLoss для багатокласової функції втрат, а для оптимізатора ви використовуєте SGD з коефіцієнтом навчання 0.0001 та імпульсом 0.9, як показано на рисунку Py нижче.TorПриклад трансферного навчання.

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

Структура вихідної моделі

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 Підручник щоб допомогти нам навчити та оцінити нашу модель.

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)

Нарешті, у цьому трансферному навчанні в PyTorНаприклад, давайте почнемо наш процес навчання з кількості епох, встановленої на 25, та оцінимо результат після завершення процесу навчання. На кожному кроці навчання модель прийматиме вхідні дані та прогнозуватиме вихідні дані. Після цього прогнозовані вихідні дані будуть передані критерію для розрахунку втрат. Потім втрати виконають розрахунок зворотного просування для розрахунку градієнта, і, нарешті, розрахують ваги та оптимізують параметри за допомогою автоградації.

У моделі візуалізації навчену мережу буде перевірено за допомогою пакета зображень, щоб передбачити мітки. Потім він візуалізується за допомогою 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.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

Після цього результат нашої моделі буде візуалізовано за допомогою matplot нижче:

Візуалізовано за допомогою Matplot
Візуалізовано за допомогою Matplot

Резюме

Отже, підсумуємо все! Перший множник – це PyTorch — це фреймворк глибокого навчання, що розвивається, для початківців або для дослідницьких цілей. Він пропонує високий час обчислень, динамічний графік, підтримку графічних процесорів і повністю написаний на... PythonВи можете легко визначити власний мережевий модуль та виконати процес навчання за допомогою простої ітерації. Зрозуміло, що PyTorch ідеально підходить для початківців, щоб ознайомитися з глибоким навчанням, а для професійних дослідників він дуже корисний завдяки швидшому часу обчислення, а також дуже корисній функції автоградації для допомоги у побудові динамічного графіка.

Підсумуйте цей пост за допомогою: