Hướng dẫn học chuyển giao PyTorch kèm ví dụ
Học chuyển tiếp là gì?
Chuyển giao học tập là một kỹ thuật sử dụng mô hình đã được huấn luyện để giải quyết một nhiệm vụ liên quan khác. Đó là một phương pháp nghiên cứu Machine Learning lưu trữ kiến thức thu được trong khi giải quyết một vấn đề cụ thể và sử dụng kiến thức tương tự để giải quyết một vấn đề khác có liên quan. Điều này cải thiện hiệu quả bằng cách sử dụng lại thông tin thu thập được từ nhiệm vụ đã học trước đó.
Việc sử dụng trọng lượng mô hình mạng khác để giảm thời gian đào tạo là điều phổ biến vì bạn cần nhiều dữ liệu để đào tạo mô hình mạng. Để giảm thời gian đào tạo, bạn sử dụng các mạng khác và trọng lượng của nó, đồng thời sửa đổi lớp cuối cùng để giải quyết vấn đề của chúng ta. Ưu điểm là bạn có thể sử dụng một tập dữ liệu nhỏ để huấn luyện lớp cuối cùng.
Tiếp theo trong hướng dẫn học Chuyển giao PyTorch này, chúng ta sẽ tìm hiểu cách sử dụng Học chuyển giao với PyTorch.
Đang tải tập dữ liệu
Nguồn: Alien vs. Predator Kaggle
Trước khi bắt đầu sử dụng Transfer Learning PyTorch, bạn cần hiểu tập dữ liệu mà bạn sắp sử dụng. Trong ví dụ về Transfer Learning PyTorch này, bạn sẽ phân loại Người ngoài hành tinh và Động vật ăn thịt từ gần 700 hình ảnh. Đối với kỹ thuật này, bạn không thực sự cần một lượng lớn dữ liệu để đào tạo. Bạn có thể tải xuống tập dữ liệu từ Kaggle: Người ngoài hành tinh vs. Kẻ săn mồi.
Làm thế nào để sử dụng phương pháp học chuyển tiếp?
Dưới đây là quy trình từng bước về cách sử dụng Transfer Learning cho Deep Learning với PyTorch:
Bước 1) Tải dữ liệu
Bước đầu tiên là tải dữ liệu của chúng tôi và thực hiện một số chuyển đổi thành hình ảnh sao cho phù hợp với yêu cầu của mạng.
Bạn sẽ tải dữ liệu từ một thư mục có torchvision.dataset. Mô-đun sẽ lặp lại trong thư mục để phân chia dữ liệu để đào tạo và xác thực. Quá trình chuyển đổi sẽ cắt hình ảnh từ trung tâm, thực hiện lật ngang, chuẩn hóa và cuối cùng chuyển đổi nó thành tensor bằng Deep Learning.
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")
Hãy trực quan hóa tập dữ liệu của chúng tôi về PyTorch Transfer Learning. Quá trình trực quan hóa sẽ lấy lô hình ảnh tiếp theo từ bộ tải dữ liệu và nhãn của tàu rồi hiển thị nó bằng 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()
Bước 2) Xác định mô hình
Với Học kĩ càng quá trình này, bạn sẽ sử dụng ResNet18 từ mô-đun torchvision.
Bạn sẽ sử dụng torchvision.models để tải resnet18 với trọng số được đào tạo trước được đặt thành True. Sau đó, bạn sẽ đóng băng các lớp để các lớp này không thể huấn luyện được. Bạn cũng sửa đổi lớp cuối cùng bằng một lớp Tuyến tính để phù hợp với nhu cầu của chúng tôi đó là 2 lớp. Bạn cũng sử dụng CrossEntropyLoss cho hàm mất nhiều lớp và đối với trình tối ưu hóa, bạn sẽ sử dụng SGD với tốc độ học là 0.0001 và xung lượng là 0.9 như trong ví dụ Học chuyển giao PyTorch bên dưới.
## 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)
Cấu trúc mô hình đầu ra
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) ) )
Bước 3) Đào tạo và thử nghiệm mô hình
Chúng ta sẽ sử dụng một số chức năng từ Transfer Learning Hướng dẫn PyTorch để giúp chúng tôi đào tạo và đánh giá mô hình của mình.
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)
Cuối cùng, trong ví dụ Transfer Learning in PyTorch này, hãy bắt đầu quá trình đào tạo của chúng ta với số kỷ nguyên được đặt thành 25 và đánh giá sau quá trình đào tạo. Ở mỗi bước huấn luyện, mô hình sẽ lấy đầu vào và dự đoán đầu ra. Sau đó, sản lượng dự đoán sẽ được chuyển đến tiêu chí để tính toán tổn thất. Sau đó, tổn thất sẽ thực hiện phép tính backprop để tính gradient và cuối cùng là tính trọng số và tối ưu hóa các tham số bằng autograd.
Ở mô hình trực quan hóa, mạng được đào tạo sẽ được kiểm tra với một loạt hình ảnh để dự đoán nhãn. Sau đó, nó sẽ được hiển thị với sự trợ giúp của matplotlib.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25) visualize_model(vgg_based) plt.show()
Bước 4) Kết quả
Kết quả cuối cùng là bạn đạt được độ chính xác là 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
Kết thúc thì đầu ra của mô hình của chúng ta sẽ được hiển thị bằng matplot bên dưới:
Tổng kết
Vậy, chúng ta hãy tóm tắt mọi thứ! Yếu tố đầu tiên là PyTorch là một khuôn khổ học sâu đang phát triển dành cho người mới bắt đầu hoặc cho mục đích nghiên cứu. Nó cung cấp thời gian tính toán cao, Đồ thị động, hỗ trợ GPU và được viết hoàn toàn bằng Python. Bạn có thể xác định mô-đun mạng của riêng mình một cách dễ dàng và thực hiện quy trình đào tạo một cách dễ dàng. Rõ ràng rằng PyTorch lý tưởng cho những người mới bắt đầu tìm hiểu deep learning và đối với các nhà nghiên cứu chuyên nghiệp, nó rất hữu ích với thời gian tính toán nhanh hơn và chức năng autograd rất hữu ích để hỗ trợ biểu đồ động.