Что такое трансферное обучение?
Трансферное обучение - это метод использования обученной модели для решения другой связанной задачи. Это метод исследования машинного обучения, который сохраняет знания, полученные при решении конкретной проблемы, и использует те же знания для решения другой, но связанной проблемы. Это повышает эффективность за счет повторного использования информации, собранной из ранее изученной задачи.
Популярно использовать другие веса сетевой модели, чтобы сократить время обучения, потому что вам нужно много данных для обучения сетевой модели. Чтобы сократить время обучения, вы используете другие сети и их вес и модифицируете последний слой для решения нашей проблемы. Преимущество состоит в том, что вы можете использовать небольшой набор данных для обучения последнего слоя.
Далее в этом учебном пособии по передаче PyTorch мы узнаем, как использовать обучение передачи с PyTorch.
Загрузка набора данных
Источник: Alien vs. Predator Kaggle
Прежде чем вы начнете использовать PyTorch Transfer Learning, вам необходимо понять набор данных, который вы собираетесь использовать. В этом примере PyTorch Transfer Learning вы классифицируете Чужого и Хищника по почти 700 изображениям. Для этого метода вам действительно не нужен большой объем данных для обучения. Вы можете скачать набор данных из Kaggle: Alien vs. Predator.
Как использовать трансферное обучение?
Вот пошаговый процесс использования Transfer Learning для Deep Learning с PyTorch:
Шаг 1) Загрузите данные
Первый шаг - загрузить наши данные и выполнить некоторое преобразование изображений, чтобы они соответствовали требованиям сети.
Вы загрузите данные из папки с torchvision.dataset. Модуль будет выполнять итерацию в папке, чтобы разделить данные для обучения и проверки. Процесс преобразования обрежет изображения из центра, выполнит горизонтальное отражение, нормализует и, наконец, преобразует его в тензор с помощью глубокого обучения.
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 Transfer Learning, чтобы помочь нам обучить и оценить нашу модель.
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
В конце, вывод нашей модели будет визуализирован с помощью графика ниже:
Резюме
Итак, подведем итоги! Во-первых, PyTorch - это растущая платформа глубокого обучения для начинающих или для исследовательских целей. Он предлагает высокое время вычислений, динамический график, поддержку графических процессоров и полностью написан на Python. Вы можете легко определить наш собственный сетевой модуль и выполнить процесс обучения с простой итерацией. Понятно, что PyTorch идеально подходит для начинающих, чтобы узнать о глубоком обучении, а для профессиональных исследователей он очень полезен благодаря более быстрому времени вычислений, а также очень полезной функции автограда для поддержки динамического графика.