Навчальний посібник із передавання PyTorch із прикладами
Що таке трансферне навчання?
Трансферне навчання це техніка використання навченої моделі для вирішення іншого пов’язаного завдання. Це метод дослідження машинного навчання, який зберігає знання, отримані під час вирішення конкретної проблеми, і використовує ті самі знання для вирішення іншої, але пов’язаної проблеми. Це покращує ефективність шляхом повторного використання інформації, зібраної під час виконання попереднього завдання.
Популярно використовувати іншу вагу моделі мережі, щоб скоротити час навчання, оскільки для навчання моделі мережі потрібно багато даних. Щоб скоротити час навчання, ви використовуєте інші мережі та їх вагу та змінюєте останній шар, щоб вирішити нашу проблему. Перевагою є те, що ви можете використовувати невеликий набір даних для навчання останнього рівня.
Далі в цьому підручнику з навчання PyTorch Transfer ми навчимося використовувати Transfer Learning із PyTorch.
Завантаження набору даних
Джерело: Alien vs. Predator Kaggle
Перш ніж почати використовувати Transfer Learning PyTorch, вам потрібно зрозуміти набір даних, який ви збираєтеся використовувати. У цьому прикладі Transfer Learning PyTorch ви класифікуєте прибульця та хижака з майже 700 зображень. Для навчання цієї методики вам не потрібен великий обсяг даних. Ви можете завантажити набір даних з Kaggle: Чужий проти Хижака.
Як використовувати Transfer Learning?
Ось крок за кроком, як використовувати Transfer Learning для глибокого навчання з PyTorch:
Крок 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 Transfer Learning. Процес візуалізації отримає наступну партію зображень із завантажувачів даних поїзда та міток і відобразить їх за допомогою 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, як показано в наведеному нижче прикладі PyTorch Transfer Learning.
## 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)
Нарешті, у цьому прикладі Transfer Learning у PyTorch давайте почнемо наш навчальний процес із установленою кількістю епох 25 і оцінимо після процесу навчання. На кожному кроці навчання модель прийматиме вхідні дані та прогнозуватиме результати. Після цього прогнозований вихід буде передано критерію для розрахунку втрат. Потім втрати виконають розрахунок опорної опори для обчислення градієнта та, нарешті, обчислення ваг і оптимізації параметрів за допомогою 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.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 нижче:
Підсумки
Отже, підсумовуємо все! Перший фактор: PyTorch — це платформа глибокого навчання, що розвивається, для початківців або для дослідницьких цілей. Він пропонує великий час обчислень, Dynamic Graph, підтримку графічних процесорів і повністю написаний Python. Ви можете легко визначити свій власний мережевий модуль і виконати процес навчання за допомогою легкої ітерації. Зрозуміло, що PyTorch ідеально підходить для початківців, щоб дізнатися про глибоке навчання, а для професійних дослідників він дуже корисний завдяки швидшому часу обчислень, а також дуже корисній функції автоградації для підтримки динамічного графіка.