예제가 포함된 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단계) 모델 정의
이번에 깊은 학습 프로세스에서는 torchvision 모듈의 ResNet18을 사용하게 됩니다.
torchvision.models를 사용하여 사전 학습된 가중치를 True로 설정하여 resnet18을 로드합니다. 그런 다음 레이어를 동결하여 이러한 레이어가 학습되지 않도록 합니다. 또한 마지막 레이어를 선형 레이어로 수정하여 2개 클래스라는 요구 사항에 맞춥니다. 또한 다중 클래스 손실 함수에 CrossEntropyLoss를 사용하고 최적화 도구에 아래 PyTorch Transfer Learning 예제에서 볼 수 있듯이 학습률이 0.0001이고 모멘텀이 0.9인 SGD를 사용합니다.
## 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의 일부 기능을 사용하겠습니다. 파이토치 튜토리얼 모델을 훈련하고 평가하는 데 도움이 됩니다.
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
종료되면 모델의 출력이 아래 matplot으로 시각화됩니다.
요약
그럼, 모든 것을 요약해 봅시다! 첫 번째 요소는 PyTorch가 초보자 또는 연구 목적을 위한 성장하는 딥 러닝 프레임워크라는 것입니다. 높은 계산 시간, 동적 그래프, GPU 지원을 제공하며 완전히 작성되었습니다. Python. 자신만의 네트워크 모듈을 쉽게 정의하고 쉬운 반복으로 교육 프로세스를 수행할 수 있습니다. PyTorch는 초보자가 딥 러닝을 배우는 데 이상적이며 전문 연구자들에게는 더 빠른 계산 시간과 동적 그래프를 지원하는 매우 유용한 autograd 기능으로 매우 유용합니다.