<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>

          基于遷移學(xué)習(xí)的狗狗分類器

          共 11112字,需瀏覽 23分鐘

           ·

          2021-01-22 10:11

          點擊上方小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂

          重磅干貨,第一時間送達

          你以前聽說過深度學(xué)習(xí)這個詞嗎? 或者你剛剛開始學(xué)習(xí)它?


          在本文中,我將引導(dǎo)您構(gòu)建自己的狗狗分類器。在這個項目的最后:


          • 您的代碼將接受任何用戶提供的圖像作為輸入

          • 如果一只狗在圖像中被檢測到,它將提供對該狗狗品種的預(yù)測


          我會讓它盡可能的簡單~


          實現(xiàn)步驟如下:


          • 步驟0:導(dǎo)入數(shù)據(jù)集

          • 步驟1:圖像預(yù)處理

          • 步驟2:選擇遷移學(xué)習(xí)的模式

          • 步驟3:更改預(yù)訓(xùn)練模型的分類器

          • 步驟4:編寫訓(xùn)練算法

          • 步驟5:訓(xùn)練模型

          • 步驟6:測試模型

          • 步驟7:測試你自己的圖片

          步驟0:導(dǎo)入數(shù)據(jù)集


          你可以從下列網(wǎng)址下載你自己的數(shù)據(jù)集:https://www.kaggle.com/c/dog-breed-identification


          然后解壓縮文件!


          由于圖像處理在本地機器上需要大量的時間和資源,因此我將使用 colab 的 GPU 來訓(xùn)練我的模型。所以,如果你沒有自己的 GPU,也可以切換到 colab 來跟進。


          導(dǎo)入必要的庫始終是一個良好的開始,下面代碼展示了我們訓(xùn)練所需要的庫。

          #Importing Librariesimport numpy as npimport pandas as pdimport matplotlib.pyplot as pltfrom PIL import Imagefrom PIL import ImageFileimport cv2 
          # importing Pytorch model librariesimport torchimport torchvision.models as modelsimport torchvision.transforms as transformsfrom torchvision import datasetsimport torch.nn as nnimport torch.nn.functional as Fimport torch.optim as optim

          在下列代碼的圓括號的雙引號中輸入 dog_images 的路徑。

          dog_files = np.array(glob("/data/dog_images/*/*/*"))# print number of images in each datasetprint('There are %d total dog images.' % len(dog_files))
          Output : There are 8351 total dog images.

          步驟1:圖像預(yù)處理

          首先,您需要將訓(xùn)練、驗證和測試集數(shù)據(jù)的目錄加載到一些變量中。

          #Loading images data into the memory and storing them into the variablesdata_dir = '/content/dogImages'train_dir = data_dir + '/train'valid_dir = data_dir + '/valid'test_dir = data_dir + '/test'

          然后需要對加載的圖像進行一些變換,這就是所謂的數(shù)據(jù)預(yù)處理。


          為什么有這個必要?


          • 您的圖像必須與網(wǎng)絡(luò)的輸入大小匹配。如果您需要調(diào)整圖像的大小以匹配網(wǎng)絡(luò),那么您可以將數(shù)據(jù)重新縮放或裁剪到所需的大小

          • 數(shù)據(jù)增強也使您能夠訓(xùn)練網(wǎng)絡(luò)不受圖像數(shù)據(jù)扭曲的影響。為此,我會隨機裁剪和調(diào)整圖像的大小

          • 數(shù)據(jù)歸一化也是一個重要步驟,確保每個輸入?yún)?shù)(本例中為像素)具有類似屬性的數(shù)據(jù),這使得訓(xùn)練網(wǎng)絡(luò)時的收斂速度更快

          #Applying Data Augmentation and Normalization on imagestrain_transforms = transforms.Compose([transforms.RandomRotation(30),                                       transforms.RandomResizedCrop(224),                                       transforms.RandomHorizontalFlip(),                                       transforms.ToTensor(),                                       transforms.Normalize([0.485, 0.456, 0.406],                                                             [0.229, 0.224, 0.225])])

          valid_transforms = transforms.Compose([transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
          test_transforms = transforms.Compose([transforms.Resize(255), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])

          將圖像存儲到數(shù)據(jù)加載器中


          現(xiàn)在我們需要將訓(xùn)練、驗證和測試目錄加載到數(shù)據(jù)加載器中。這將使我們能夠?qū)?shù)據(jù)分成小批量。


          我們將數(shù)據(jù)以key-value的格式進行存儲,這將有助于以后調(diào)用它們。

          # TODO: Load the datasets with ImageFoldertrain_data = datasets.ImageFolder(train_dir, transform=train_transforms)valid_data = datasets.ImageFolder(valid_dir,transform=valid_transforms)test_data = datasets.ImageFolder(test_dir, transform=test_transforms)
          # TODO: Using the image datasets and the trainforms, define the dataloaderstrainloader = torch.utils.data.DataLoader(train_data, batch_size=20, shuffle=True)testloader = torch.utils.data.DataLoader(test_data, batch_size=20,shuffle=False)validloader = torch.utils.data.DataLoader(valid_data, batch_size=20,shuffle=False)loaders_transfer = {'train':trainloader, 'valid':validloader, 'test':testloader}data_transfer = { 'train':trainloader}

          步驟2:選擇遷移學(xué)習(xí)的模式


          什么是預(yù)訓(xùn)練模型,我們?yōu)槭裁匆褂盟?/span>


          預(yù)訓(xùn)練模型是別人為解決類似問題而創(chuàng)建的模型。


          • 與其從零開始構(gòu)建模型來解決類似的問題,不如使用經(jīng)過其他問題訓(xùn)練的模型作為起點

          • 一個預(yù)訓(xùn)練模型在應(yīng)用程序中可能不是100% 準(zhǔn)確,但是它節(jié)省了重新發(fā)明輪子所需的巨大努力

          • 遷移學(xué)習(xí)可以利用在一個問題上學(xué)到的特性,并在一個新的、類似的問題上利用它們。例如,一個已經(jīng)學(xué)會識別小浣熊的模型的特征可能有助于開始訓(xùn)練一個用于識別貓咪的模型


          你可以選擇幾個事先訓(xùn)練過的模特進行模特訓(xùn)練。例如 Densenet,Resnet,VGG 模型。我將使用 VGG-16進行模型訓(xùn)練。

          #Loading vgg11 into the variable model_transfermodel_transfer = models.vgg11(pretrained=True)

          步驟3:更改預(yù)訓(xùn)練模型的分類器


          將采取以下步驟來改變預(yù)訓(xùn)練分類器:


          1. 從以前訓(xùn)練過的模型中取出網(wǎng)絡(luò)層

          2. 凍結(jié)它們,以避免在以后的訓(xùn)練回合中破壞它們所包含的任何信息

          3. 在凍結(jié)層上添加一些新的、可訓(xùn)練的圖層。他們將學(xué)習(xí)在新的數(shù)據(jù)集上將舊的特性轉(zhuǎn)化為預(yù)測

          4. 在你的數(shù)據(jù)集上訓(xùn)練新的網(wǎng)絡(luò)層


          由于特征已經(jīng)學(xué)會了預(yù)訓(xùn)練的模型,所以將凍結(jié)他們在訓(xùn)練期間對狗狗的形象。我們只會改變分類器的尺寸,只會訓(xùn)練它。

          原來的分類器層有25088個維度,但是為了匹配我們的預(yù)處理圖像大小,我們需要更改為4096。


          要在 GPU 上訓(xùn)練模型,我們需要使用以下命令將其移動到 GPU-RAM 上。

          #Freezing the parametersfor param in model_transfer.features.parameters():    param.requires_grad = False   #Changing the classifier layermodel_transfer.classifier[6] = nn.Linear(4096,133,bias=True)    #Moving the model to GPU-RAM spaceif use_cuda:    model_transfer = model_transfer.cuda()print(model_transfer)

          現(xiàn)在我們需要選擇一個損失函數(shù)和優(yōu)化器。


          利用損失函數(shù)計算模型預(yù)測值與實際圖像的誤差。如果你的預(yù)測完全錯誤,你的損失函數(shù)將輸出更高的數(shù)字。如果它們非常好,那么輸出的數(shù)字就會更低。本文將使用交叉熵損失。


          優(yōu)化器是用來改變神經(jīng)網(wǎng)絡(luò)屬性的算法或方法,比如權(quán)重和學(xué)習(xí)速度,以減少損失。本文將使用 SGD 優(yōu)化器。


          0.001的學(xué)習(xí)率對于訓(xùn)練是有好處的,但是你也可以用其他的學(xué)習(xí)率進行實驗。鼓勵大家多多嘗試不同的參數(shù)~

          ### Loading the Loss-Functioncriterion_transfer = nn.CrossEntropyLoss()
          ### Loading the optimizeroptimizer_transfer = optim.SGD(model_transfer.parameters(), lr=0.001, momentum=0.9)

          步驟4:編寫訓(xùn)練算法


          接下來我們將編寫訓(xùn)練函數(shù)。


          我用它編寫了驗證代碼行。所以在訓(xùn)練模型時,我們會同時得到兩種損失。


          每次Loss減少時,我也會存儲這個模型。這樣我就不必在以后每次打開一個新實例時都要訓(xùn)練它。

          def train(n_epochs, loaders, model, optimizer, criterion, use_cuda, save_path):    """returns trained model"""    # initialize tracker for minimum validation loss    valid_loss_min = np.inf   #--->   Max Value (As the loss decreases and becomes less than this value it gets saved)        for epoch in range(1, n_epochs+1):      #Initializing training variables        train_loss = 0.0        valid_loss = 0.0        # Start training the model        model.train()        for batch_idx, (data, target) in enumerate(loaders['train']):            # move to GPU's memory space (if available)            if use_cuda:                data, target = data.cuda(), target.cuda()                model.to('cuda')            optimizer.zero_grad()            output = model(data)            loss = criterion(output,target)            loss.backward()            optimizer.step()            train_loss = train_loss + ((1 / (batch_idx + 1)) * (loss.data - train_loss))         # validate the model #        model.eval()        for batch_idx, (data, target) in enumerate(loaders['valid']):            accuracy=0            # move to GPU's memory space (if available)            if use_cuda:                data, target = data.cuda(), target.cuda()            ## Update the validation loss            logps = model(data)            loss = criterion(logps, target)
          valid_loss += ((1 / (batch_idx + 1)) * (loss.data - valid_loss)) # print both training and validation losses print('Epoch: {} \tTraining Loss: {:.6f} \tValidation Loss: {:.6f}'.format( epoch, train_loss, valid_loss ))
          if valid_loss <= valid_loss_min: print('Validation loss decreased ({:.6f} --> {:.6f}). Saving model ...'.format( valid_loss_min, valid_loss)) #Saving the model torch.save(model.state_dict(), 'model_transfer.pt') valid_loss_min = valid_loss # return the trained model return model

          步驟5:訓(xùn)練模型


          現(xiàn)在,我將開始通過在函數(shù)中提供參數(shù)來訓(xùn)練模型。我將訓(xùn)練10個epoch。

          # train the modelmodel_transfer = train(10, loaders_transfer, model_transfer, optimizer_transfer, criterion_transfer, use_cuda, 'model_transfer.pt')
          # load the model that got the best validation accuracymodel_transfer.load_state_dict(torch.load('model_transfer.pt'))
          OUTPUT:Epoch: 1   Training Loss: 2.443815   Validation Loss: 0.801671Validation loss decreased (inf --> 0.801671).  Saving model ...Epoch: 2   Training Loss: 1.440627   Validation Loss: 0.591050Validation loss decreased (0.801671 --> 0.591050).  Saving model ...Epoch: 3   Training Loss: 1.310158   Validation Loss: 0.560950Validation loss decreased (0.591050 --> 0.560950).  Saving model ...Epoch: 4   Training Loss: 1.200572   Validation Loss: 0.566340Epoch: 5   Training Loss: 1.160727   Validation Loss: 0.530196Validation loss decreased (0.560950 --> 0.530196).  Saving model ...Epoch: 6   Training Loss: 1.088659   Validation Loss: 0.560774Epoch: 7   Training Loss: 1.060936   Validation Loss: 0.503829Validation loss decreased (0.530196 --> 0.503829).  Saving model ...Epoch: 8   Training Loss: 1.010044   Validation Loss: 0.500608Validation loss decreased (0.503829 --> 0.500608).  Saving model ...Epoch: 9   Training Loss: 1.054875   Validation Loss: 0.497319Validation loss decreased (0.500608 --> 0.497319).  Saving model ...Epoch: 10   Training Loss: 1.000547   Validation Loss: 0.545735<All keys matched successfully>

          步驟6:測試模型


          現(xiàn)在我將在模型以前從未見過的新圖像上測試模型,并計算預(yù)測的準(zhǔn)確性。

          def test(loaders, model, criterion, use_cuda):
          # Initializing the variables test_loss = 0. correct = 0. total = 0. model.eval() #So that it doesn't change the model parameters during testing for batch_idx, (data, target) in enumerate(loaders['test']): # move to GPU's memory spave if available if use_cuda: data, target = data.cuda(), target.cuda() # Passing the data to the model (Forward Pass) output = model(data) loss = criterion(output, target) #Test Loss test_loss = test_loss + ((1 / (batch_idx + 1)) * (loss.data - test_loss)) # Output probabilities to the predicted class pred = output.data.max(1, keepdim=True)[1] # Comparing the predicted class to output correct += np.sum(np.squeeze(pred.eq(target.data.view_as(pred))).cpu().numpy()) total += data.size(0) print('Test Loss: {:.6f}\n'.format(test_loss))
          print('\nTest Accuracy: %2d%% (%2d/%2d)' % ( 100. * correct / total, correct, total))test(loaders_transfer, model_transfer, criterion_transfer, use_cuda)

          我已經(jīng)訓(xùn)練了它10個 epoch,得到了83% 的準(zhǔn)確率。并且,得到以下輸出!

          Output:Test Loss: 0.542430 Test Accuracy: 83% (700/836)

          如何提高這個模型的準(zhǔn)確性?


          • 通過訓(xùn)練更多的 epoch(比較訓(xùn)練和驗證損失)

          • 通過改變學(xué)習(xí)率(比如0.01,0.05,0.1)

          • 通過改變預(yù)訓(xùn)練模型(像稠密網(wǎng)絡(luò),但需要更多的訓(xùn)練時間)

          • 通過對圖像的進一步預(yù)處理


          步驟7:測試你自己的圖片


          現(xiàn)在你已經(jīng)訓(xùn)練和測試了你的模型。現(xiàn)在,這是最令人興奮的部分。你能走到這一步真是太好了。


          1.將要測試和保存的新圖像加載到內(nèi)存中

          #Loading the new image directorydog_files_short = np.array(glob("/content/my_dogs/*"))#Loading the modelmodel_transfer.load_state_dict(torch.load('model_transfer.pt'))

          2. 現(xiàn)在我們必須對圖像進行預(yù)處理,并通過測試我們訓(xùn)練好的模型來預(yù)測類

          def predict_breed_transfer(img_path):        #Preprocessing the input image    transform = transforms.Compose([transforms.Resize(255),                               transforms.CenterCrop(224),                               transforms.ToTensor(),                                       transforms.Normalize([0.485, 0.456, 0.406],                                                             [0.229, 0.224, 0.225])])    img = Image.open(img_path)    img = transform(img)[:3,:,:].unsqueeze(0)    if use_cuda:        img = img.cuda()        model_transfer.to('cuda')        # Passing throught the model    model_transfer.eval()    # Checking the name of class by passing the index    class_names = [item[4:].replace("_", " ") for item in data_transfer['train'].dataset.classes]
          idx = torch.argmax(model_transfer(img)) return class_names[idx]

          output = model_transfer(img) # Probabilities to class pred = output.data.max(1, keepdim=True)[1] return pred

          3. 現(xiàn)在,通過將圖像路徑作為參數(shù)傳遞給這個函數(shù),我們可以預(yù)測狗狗的品種。

          我已經(jīng)傳遞了下面的圖像,并得到了下列輸出。

          Output:Norwegian buhund

          總結(jié)


          這只是一個開始,你可以用這個模型做更多的事情。你可以通過部署它來創(chuàng)建一個應(yīng)用程序。我嘗試從零開始創(chuàng)建自己的模型,沒有使用遷移學(xué)習(xí),但測試的準(zhǔn)確率不超過13% 。你也可以嘗試一下,因為這有助于理解概念。


          下載1:OpenCV-Contrib擴展模塊中文版教程
          在「小白學(xué)視覺」公眾號后臺回復(fù):擴展模塊中文教程即可下載全網(wǎng)第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。

          下載2:Python視覺實戰(zhàn)項目31講
          小白學(xué)視覺公眾號后臺回復(fù):Python視覺實戰(zhàn)項目31講即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學(xué)校計算機視覺。

          下載3:OpenCV實戰(zhàn)項目20講
          小白學(xué)視覺公眾號后臺回復(fù):OpenCV實戰(zhàn)項目20講即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學(xué)習(xí)進階。

          下載4:leetcode算法開源書
          小白學(xué)視覺公眾號后臺回復(fù):leetcode即可下載。每題都 runtime beats 100% 的開源好書,你值得擁有!





          交流群


          歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN算法競賽等微信群(以后會逐漸細分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~


          瀏覽 51
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  熟妇13p | 国产真实露脸乱子伦对白高清视频 | 天天日天天操天天干天天 | 岛国电影av | 校花一区二区三区 |