Що таке трансферне навчання?
Трансферне навчання - це техніка використання навченої моделі для вирішення іншого пов'язаного із цим завдання. Це метод дослідження машинного навчання, який зберігає знання, отримані під час вирішення певної проблеми, і використовує ті самі знання для вирішення іншої, але супутньої проблеми. Це підвищує ефективність за рахунок повторного використання інформації, зібраної з раніше вивченого завдання.
Популярно використовувати іншу вагу мережевої моделі, щоб скоротити час навчання, оскільки для підготовки моделі мережі вам потрібно багато даних. Щоб зменшити час навчання, ви використовуєте інші мережі та їх вагу та модифікуєте останній рівень, щоб вирішити нашу проблему. Перевага полягає в тому, що ви можете використовувати невеликий набір даних для навчання останнього шару.
Далі в цьому навчальному посібнику з навчання PyTorch Transfer ми дізнаємось, як користуватися навчанням із передачею з PyTorch.
Завантаження набору даних
Джерело: Alien vs. Predator Kaggle
Перш ніж почати використовувати Transfer Learning PyTorch, вам слід зрозуміти набір даних, який ви збираєтеся використовувати. У цьому прикладі Transfer Learning PyTorch ви класифікуєте Чужого та Хижака з майже 700 зображень. Для цього методу вам не потрібен великий обсяг даних для навчання. Ви можете завантажити набір даних з Kaggle: Alien vs. Predator.
Як користуватися навчанням за допомогою трансферу?
Ось покроковий процес, як використовувати Transfer 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) Визначте модель
У цьому процесі глибокого навчання ви будете використовувати ResNet18 з модуля torchvision.
Ви будете використовувати torchvision.models для завантаження resnet18 із попередньо навченою вагою, встановленою на True. Після цього ви заморозите шари, щоб ці шари не піддавалися навчанню. Ви також модифікуєте останній шар за допомогою Лінійного шару, щоб відповідати нашим потребам - це 2 класи. Ви також використовуєте CrossEntropyLoss для мультикласової функції втрат, а для оптимізатора ви будете використовувати SGD із швидкістю навчання 0,0001 та імпульсом 0,9, як показано в наведеному нижче прикладі PyTorch Transfer 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) Модель підготовки та тестування
Ми скористаємося деякою функцією з Підручника з трансферу навчання 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 = 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)
Нарешті, у цьому прикладі передачі навчання в PyTorch, давайте почнемо наш тренувальний процес з кількості епох, встановлених на 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.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 - це зростаюча система глибокого навчання для початківців або для дослідницьких цілей. Він пропонує тривалий час обчислень, Dynamic Graph, підтримку графічних процесорів і повністю написаний на Python. Ви можете легко визначити наш власний мережевий модуль та виконати навчальний процес із легкою ітерацією. Зрозуміло, що PyTorch ідеально підходить для початківців, щоб дізнатись глибоке навчання, а для професійних дослідників він дуже корисний із швидшим часом обчислення, а також дуже корисною функцією автограду для сприяння динамічному графіку.