<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【小白學習PyTorch教程】十二、遷移學習:微調(diào)VGG19實現(xiàn)圖像分類

          共 12916字,需瀏覽 26分鐘

           ·

          2021-08-15 11:57

          「@Author:Runsen」

          前言:遷移學習就是利用數(shù)據(jù)、任務(wù)或模型之間的相似性,將在舊的領(lǐng)域?qū)W習過或訓練好的模型,應(yīng)用于新的領(lǐng)域這樣的一個過程。從這段定義里面,我們可以窺見遷移學習的關(guān)鍵點所在,即新的任務(wù)與舊的任務(wù)在數(shù)據(jù)、任務(wù)和模型之間的相似性。

          假設(shè)有兩個任務(wù)系統(tǒng)A和B,任務(wù)A擁有海量的數(shù)據(jù)資源且已訓練好,但并不是我們的目標任務(wù),任務(wù)B是我們的目標任務(wù),但數(shù)據(jù)量少且極為珍貴,這種場景便是典型的遷移學習的應(yīng)用場景

          接下來在博客中,我們將學習如何將遷移學習與 PyTorch 結(jié)合使用。

          在這個遷移學習 PyTorch 圖像二分類Vgg19 示例中,數(shù)據(jù)來源:https://www.kaggle.com/pmigdal/alien-vs-predator-images/home

          這是我在kaggle找到的關(guān)于遷移學習的入門案例

          1) 加載數(shù)據(jù)

          第一步是加載數(shù)據(jù)并對圖像進行一些轉(zhuǎn)換,使其符合網(wǎng)絡(luò)要求。

          使用 torchvision.dataset ,在文件夾中加載數(shù)據(jù)。該模塊將在文件夾中迭代以拆分數(shù)據(jù)以進行訓練和驗證。

          轉(zhuǎn)換過程進行基本的圖片處理操作。

          將從中心裁剪圖像,執(zhí)行水平翻轉(zhuǎn),歸一化,最后使用將其轉(zhuǎn)換為張量。

          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.50.50.5]
          std = [0.50.50.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)
          # {'train': 694, 'validation': 200}

          class_names = image_datasets['train'].classes

          device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

          可視化 PyTorch 遷移學習數(shù)據(jù)集??梢暬^程將從訓練數(shù)據(jù)加載器和標簽中獲取下一批圖像,并用 matplot 顯示它。

          images, labels = next(iter(dataloaders['train']))



          rows = 4
          columns = 4
          fig=plt.figure(figsize=(15,15))


          for i in range(16):
             fig.add_subplot(rows, columns, i+1)
             plt.title(class_names[labels[i]])
             img = images[i].numpy().transpose((120))
             img = std * img + mean
             plt.imshow(img)
          plt.show()

          2) 定義模型

          VGG19有兩個部分,分別是VGG19.features和VGG19.classifier。

          • vgg19.features有卷積層和池化層
          • vgg19.features有三個線性層,最后是softmax分類器

          下面將使用 torchvision.models 加載 VGG19,并將預(yù)訓練權(quán)重設(shè)置為 True之后,將凍結(jié)層,使這些層不可訓練。

          對 Linear 層修改最后一層,以滿足我們 2 個類的需求。

          也可以將 CrossEntropyLoss 用于多類損失函數(shù),對于優(yōu)化器,使用學習率為 0.0001 和動量為 0.9 的 SGD,如下面的 PyTorch 遷移學習示例所示。

          ##加載基于VGG19的模型
          vgg_based = torchvision.models.vgg19(pretrained=True

          for param in vgg_based.parameters():
             param.requires_grad = False

          #修改最后一層
          number_features = vgg_based.classifier[6].in_features 
          features = list(vgg_based.classifier.children())[:-1# 移除最后一層
          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_based輸出如下

          VGG(
            (features): Sequential(
           (0): Conv2d(364, kernel_size=(33), stride=(11), padding=(11))
           (1): ReLU(inplace)
           (2): Conv2d(6464, kernel_size=(33), stride=(11), padding=(11))
           (3): ReLU(inplace)
           (4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
           (5): Conv2d(64128, kernel_size=(33), stride=(11), padding=(11))
           (6): ReLU(inplace)
           (7): Conv2d(128128, kernel_size=(33), stride=(11), padding=(11))
           (8): ReLU(inplace)
           (9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
           (10): Conv2d(128256, kernel_size=(33), stride=(11), padding=(11))
           (11): ReLU(inplace)
           (12): Conv2d(256256, kernel_size=(33), stride=(11), padding=(11))
           (13): ReLU(inplace)
           (14): Conv2d(256256, kernel_size=(33), stride=(11), padding=(11))
           (15): ReLU(inplace)
           (16): Conv2d(256256, kernel_size=(33), stride=(11), padding=(11))
           (17): ReLU(inplace)
           (18): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
           (19): Conv2d(256512, kernel_size=(33), stride=(11), padding=(11))
           (20): ReLU(inplace)
           (21): Conv2d(512512, kernel_size=(33), stride=(11), padding=(11))
           (22): ReLU(inplace)
           (23): Conv2d(512512, kernel_size=(33), stride=(11), padding=(11))
           (24): ReLU(inplace)
           (25): Conv2d(512512, kernel_size=(33), stride=(11), padding=(11))
           (26): ReLU(inplace)
           (27): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
           (28): Conv2d(512512, kernel_size=(33), stride=(11), padding=(11))
           (29): ReLU(inplace)
           (30): Conv2d(512512, kernel_size=(33), stride=(11), padding=(11))
           (31): ReLU(inplace)
           (32): Conv2d(512512, kernel_size=(33), stride=(11), padding=(11))
           (33): ReLU(inplace)
           (34): Conv2d(512512, kernel_size=(33), stride=(11), padding=(11))
           (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  中的一些功能來幫助我們訓練和評估我們的模型。

          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)

                  # 迭代數(shù)據(jù)
                 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


          最后, epoch 數(shù)設(shè)置為 25 開始我們的模型訓練過程,并在訓練過程結(jié)束后進行評估。

          在每個訓練步驟中,模型接受輸入并預(yù)測輸出。之后預(yù)測輸出將傳遞給計算損失。然后損失將執(zhí)行反向傳播來計算得到梯度,最后計算權(quán)重并使用 autograd 不斷的優(yōu)化參數(shù)。

          vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25)

          4) 測試模型

          在可視化模型中,將訓練好的模型,使用一批圖像進行測試和預(yù)測標簽

          def visualize_model(model, num_images=6):
             was_training = model.training
             model.eval()
             images_so_far = 0
             fig=plt.figure(figsize=(15,15))


             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//22, 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((120))
                         img = std * img + mean
                         ax.imshow(img)

                         if images_so_far == num_images:
                             model.train(mode=was_training)
                             return
                 model.train(mode=was_training)
          visualize_model(vgg_based)
          plt.show()

          往期精彩回顧




          本站qq群851320808,加入微信群請掃碼:
          瀏覽 64
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天干 天天日 | 日韩性爱中文字幕 | 国产人妻精品一区二区三区不卡 | 国内精品毛片 | 日日av影院 |