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ột mô hình được đào tạo để giải quyết một nhiệm vụ liên quan khác. Đây là một phương pháp nghiên cứu Máy học nhằm 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 nhưng 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 số mô hình mạng khác để giảm thời gian đào tạo là 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ó và sửa đổi lớp cuối cùng để giải quyết vấn đề của chúng tôi. Ưu điểm là bạn có thể sử dụng một tập dữ liệu nhỏ để đào tạo lớp cuối cùng.
Tiếp theo trong hướng dẫn học Chuyển giao bằng 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 PyTorch Transfer Learning, bạn cần hiểu tập dữ liệu mà bạn sẽ sử dụng. Trong ví dụ PyTorch về Học chuyển giao này, bạn sẽ phân loại Người ngoài hành tinh và Người ă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 bộ dữ liệu từ Kaggle: Alien vs. Predator.
Làm thế nào để sử dụng Học chuyển giao?
Dưới đây là quy trình từng bước về cách sử dụng Học chuyển tiếp cho Học sâu 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 sang hình ảnh để phù hợp với yêu cầu 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 để chia nhỏ dữ liệu cho việc đào tạo và xác nhận. 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 cách sử dụng 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")
Hãy hình dung tập dữ liệu của chúng tôi cho Học chuyển tiếp PyTorch. Quá trình trực quan hóa sẽ nhận được lô hình ảnh tiếp theo từ bộ tải dữ liệu tàu và nhãn và hiển thị nó bằng 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()
Bước 2) Xác định mô hình
Trong quá trình Học sâu 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 là True. Sau đó, bạn sẽ đóng băng các lớp để các lớp này không thể đào tạo được. Bạn cũng sửa đổi lớp cuối cùng với 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 chức năng 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ỷ lệ học tập là 0,0001 và động lượng là 0,9 như được hiển thị trong ví dụ bên dưới 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)
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à kiểm tra mô hình
Chúng tôi sẽ sử dụng một số chức năng từ Hướng dẫn PyTorch Chuyển giao Học tập để 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 = 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)
Cuối cùng trong ví dụ về Học chuyển giao trong PyTorch này, chúng ta hãy bắt đầu quá trình đào tạo của mình 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 đào tạo, 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 sang tiêu chí để tính toán các khoản lỗ. Sau đó, các khoản lỗ sẽ thực hiện phép tính backprop để tính toán gradient và cuối cùng là tính trọng số và tối ưu hóa các thông số bằng autograd.
Tại 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 các nhãn. Sau đó, nó sẽ được hình dung 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.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
Kết thúc, đầu ra của mô hình của chúng tôi sẽ được hiển thị bằng matplot bên dưới:
Tóm lược
Vì vậy, chúng ta hãy tóm tắt tất cả mọi thứ! Yếu tố đầu tiên là PyTorch là một khung học sâu đang phát triển 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à nó hoàn toàn được viết bằng Python. Bạn có thể dễ dàng xác định mô-đun mạng của chúng tôi và thực hiện quá trình đào tạo với một lần lặp lại dễ dàng. Rõ ràng là PyTorch lý tưởng cho người mới bắt đầu tìm hiểu về học sâu 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à cũng có chức năng autograd rất hữu ích để hỗ trợ đồ thị động.