Учебное пособие по переносу обучения PyTorch с примерами
Что такое трансферное обучение?
Передача обучения — это метод использования обученной модели для решения другой связанной задачи. Это метод исследования машинного обучения, который сохраняет знания, полученные при решении конкретной проблемы, и использует те же знания для решения другой, но связанной с ней проблемы. Это повышает эффективность за счет повторного использования информации, полученной из ранее изученной задачи.
Популярно использовать другие веса сетевой модели, чтобы сократить время обучения, поскольку для обучения сетевой модели требуется много данных. Чтобы сократить время обучения, вы используете другие сети и их вес и модифицируете последний слой для решения нашей задачи. Преимущество в том, что вы можете использовать небольшой набор данных для обучения последнего слоя.
Далее в этом руководстве по обучению переносу PyTorch мы узнаем, как использовать перенос обучения с PyTorch.
Загрузка набора данных
Источник: Чужой против Хищника Кэггл.
Прежде чем начать использовать Transfer Learning PyTorch, вам необходимо понять, какой набор данных вы собираетесь использовать. В этом примере PyTorch для трансферного обучения вы классифицируете Чужого и Хищника по почти 700 изображениям. Для этого метода вам не нужен большой объем данных для обучения. Вы можете скачать набор данных с Kaggle: Чужой против Хищника.
Как использовать трансферное обучение?
Вот пошаговый процесс использования трансферного обучения для глубокого обучения с 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. После этого вы заморозите слои, чтобы эти слои не поддавались обучению. Вы также модифицируете последний слой с помощью линейного слоя, чтобы он соответствовал нашим потребностям, то есть двух классов. Вы также используете CrossEntropyLoss для функции потерь нескольких классов, а для оптимизатора вы будете использовать SGD со скоростью обучения 2 и импульсом 0.0001, как показано в приведенном ниже примере переноса обучения PyTorch.
## 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)
Наконец, в этом примере переноса обучения в 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
Закончите, тогда выходные данные нашей модели будут визуализированы с помощью матплота ниже:

Резюме
Итак, давайте подведем итоги! Первый фактор — PyTorch — это растущий фреймворк глубокого обучения для новичков или для исследовательских целей. Он предлагает высокое время вычислений, Dynamic Graph, поддержку GPU и полностью написан на Python. Вы можете легко определить свой собственный сетевой модуль и выполнить процесс обучения с помощью простой итерации. Понятно, что PyTorch идеально подходит для новичков, желающих изучить глубокое обучение, а для профессиональных исследователей он очень полезен благодаря более быстрому времени вычислений, а также очень полезной функции автоградации для поддержки динамического графика.

