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

          IOS 上的圖像分割 DEEPLABV3

          共 7075字,需瀏覽 15分鐘

           ·

          2021-06-21 14:51

          介紹

          語(yǔ)義圖像分割是一項(xiàng)計(jì)算機(jī)視覺任務(wù),它使用語(yǔ)義標(biāo)簽來(lái)標(biāo)記輸入圖像的特定區(qū)域。PyTorch 語(yǔ)義圖像分割DeepLabV3 模型可用于標(biāo)記具有20 個(gè)語(yǔ)義類的圖像區(qū)域,例如,自行車、公共汽車、汽車、狗和人。圖像分割模型在自動(dòng)駕駛和場(chǎng)景理解等應(yīng)用中非常有用。

          在本教程中,我們將提供有關(guān)如何在 iOS 上準(zhǔn)備和運(yùn)行 PyTorch DeepLabV3 模型的分步指南,帶您從開始擁有一個(gè)您可能想要在 iOS 上使用的模型到最終擁有一個(gè)完整的模型。使用該模型的 iOS 應(yīng)用程序。我們還將介紹有關(guān)如何檢查下一個(gè)最喜歡的預(yù)訓(xùn)練 PyTorch 模型是否可以在 iOS 上運(yùn)行以及如何避免陷阱的實(shí)用和一般技巧。

          筆記

          在學(xué)習(xí)本教程之前,您應(yīng)該查看適用于 iOS 的 PyTorch Mobile,快速嘗試一下PyTorch iOS HelloWorld示例應(yīng)用程序。本教程將超越圖像分類模型,通常是部署在移動(dòng)設(shè)備上的第一種模型。本教程的完整代碼存儲(chǔ)庫(kù)可在此處獲得。

          學(xué)習(xí)目標(biāo)

          在本教程中,您將學(xué)習(xí)如何:

          1. 為 iOS 部署轉(zhuǎn)換 DeepLabV3 模型。

          2. 在 Python 中獲取示例輸入圖像的模型輸出,并將其與 iOS 應(yīng)用程序的輸出進(jìn)行比較。

          3. 構(gòu)建一個(gè)新的 iOS 應(yīng)用程序或重用一個(gè) iOS 示例應(yīng)用程序來(lái)加載轉(zhuǎn)換后的模型。

          4. 將輸入準(zhǔn)備為模型期望的格式并處理模型輸出。

          5. 完成 UI、重構(gòu)、構(gòu)建和運(yùn)行應(yīng)用程序以查看圖像分割的實(shí)際效果。

          先決條件

          • PyTorch 1.6 或 1.7

          • 火炬視覺 0.7 或 0.8

          • Xcode 11 或 12

          腳步

          1.轉(zhuǎn)換DeepLabV3模型用于iOS部署

          在 iOS 上部署模型的第一步是將模型轉(zhuǎn)換為TorchScript格式。

          筆記

          目前并非所有 PyTorch 模型都可以轉(zhuǎn)換為 TorchScript,因?yàn)槟P投x可能使用 TorchScript 中沒有的語(yǔ)言功能,TorchScript 是 Python 的一個(gè)子集。有關(guān)更多詳細(xì)信息,請(qǐng)參閱腳本和優(yōu)化配方

          只需運(yùn)行下面的腳本即可生成腳本模型deeplabv3_scripted.pt

          import torch

          # use deeplabv3_resnet50 instead of deeplabv3_resnet101 to reduce the model size
          model = torch.hub.load('pytorch/vision:v0.8.0', 'deeplabv3_resnet50', pretrained=True)
          model.eval()

          scriptedm = torch.jit.script(model)
          torch.jit.save(scriptedm, "deeplabv3_scripted.pt")

          生成的deeplabv3_scripted.pt模型文件的大小應(yīng)該在 168MB 左右。理想情況下,在將模型部署到 iOS 應(yīng)用程序之前,還應(yīng)該對(duì)模型進(jìn)行量化以顯著減小尺寸并加快推理速度。要對(duì)量化有一個(gè)大致的了解,請(qǐng)參閱量化配方和那里的資源鏈接。我們將在以后的教程或秘籍中詳細(xì)介紹如何將稱為訓(xùn)練后靜態(tài)量化的量化工作流正確應(yīng)用于DeepLabV3 模型。

          2.在Python中獲取模型的示例輸入和輸出

          現(xiàn)在我們有了一個(gè)腳本化的 PyTorch 模型,讓我們用一些示例輸入進(jìn)行測(cè)試,以確保模型在 iOS 上正常工作。首先,讓我們編寫一個(gè) Python 腳本,使用該模型進(jìn)行推理并檢查輸入和輸出。對(duì)于 DeepLabV3 模型的這個(gè)示例,我們可以重用步驟 1 和DeepLabV3 模型中心站點(diǎn)中的代碼。將以下代碼片段添加到上面的代碼中:

          from PIL import Image
          from torchvision import transforms
          input_image = Image.open("deeplab.jpg")
          preprocess = transforms.Compose([
          transforms.ToTensor(),
          transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
          ])

          input_tensor = preprocess(input_image)
          input_batch = input_tensor.unsqueeze(0)
          with torch.no_grad():
          output = model(input_batch)['out'][0]

          print(input_batch.shape)
          print(output.shape)

          這里下載deeplab.jpg并運(yùn)行上面的腳本以查看模型的輸入和輸出的形狀:

          torch.Size([1, 3, 400, 400])
          torch.Size([21, 400, 400])

          因此,如果您向iOS 上的模型提供大小為 400x400的相同圖像輸入deeplab.jpg,則模型的輸出應(yīng)具有 [21, 400, 400] 大小。您還應(yīng)該至少打印出輸入和輸出的實(shí)際數(shù)據(jù)的開始部分,以便在下面的第 4 步中用于與模型在 iOS 應(yīng)用程序中運(yùn)行時(shí)的實(shí)際輸入和輸出進(jìn)行比較。

          3. 構(gòu)建一個(gè)新的 iOS 應(yīng)用程序或重用示例應(yīng)用程序并加載模型

          首先,按照iOS 模型準(zhǔn)備教程的第 3 步,在啟用 PyTorch Mobile 的 Xcode 項(xiàng)目中使用我們的模型。由于本教程中使用的 DeepLabV3 模型和 PyTorch HelloWorld iOS 示例中使用的 MobileNet v2 模型都是計(jì)算機(jī)視覺模型,因此您可以選擇以HelloWorld 示例 repo作為模板來(lái)重用加載模型和處理數(shù)據(jù)的代碼輸入和輸出。

          現(xiàn)在讓我們將步驟 2 中使用deeplabv3_scripted.ptdeeplab.jpg添加到 Xcode 項(xiàng)目中,并將ViewController.swift修改為類似:

          class ViewController: UIViewController {
          var image = UIImage(named: "deeplab.jpg")!

          override func viewDidLoad() {
          super.viewDidLoad()
          }

          private lazy var module: TorchModule = {
          if let filePath = Bundle.main.path(forResource: "deeplabv3_scripted",
          ofType: "pt"),
          let module = TorchModule(fileAtPath: filePath) {
          return module
          } else {
          fatalError("Can't load the model file!")
          }
          }()
          }

          然后在行返回模塊處設(shè)置斷點(diǎn)并構(gòu)建并運(yùn)行應(yīng)用程序。應(yīng)用程序應(yīng)該在斷點(diǎn)處停止,這意味著步驟 1 中的腳本模型已成功加載到 iOS 上。

          4. 處理模型輸入和輸出以進(jìn)行模型推理

          在上一步中加載模型后,讓我們驗(yàn)證它是否適用于預(yù)期的輸入并可以生成預(yù)期的輸出。由于 DeepLabV3 模型的模型輸入是圖像,與 HelloWorld 示例中的 MobileNet v2 相同,我們將重用HelloWorld 中TorchModule.mm文件中的部分代碼進(jìn)行輸入處理。更換predictImage的方法實(shí)現(xiàn)TorchModule.mm用下面的代碼:

          - (unsigned char*)predictImage:(void*)imageBuffer {
          // 1. the example deeplab.jpg size is size 400x400 and there are 21 semantic classes
          const int WIDTH = 400;
          const int HEIGHT = 400;
          const int CLASSNUM = 21;

          at::Tensor tensor = torch::from_blob(imageBuffer, {1, 3, WIDTH, HEIGHT}, at::kFloat);
          torch::autograd::AutoGradMode guard(false);
          at::AutoNonVariableTypeMode non_var_type_mode(true);

          // 2. convert the input tensor to an NSMutableArray for debugging
          float* floatInput = tensor.data_ptr<float>();
          if (!floatInput) {
          return nil;
          }
          NSMutableArray* inputs = [[NSMutableArray alloc] init];
          for (int i = 0; i < 3 * WIDTH * HEIGHT; i++) {
          [inputs addObject:@(floatInput[i])];
          }

          // 3. the output of the model is a dictionary of string and tensor, as
          // specified at https://pytorch.org/hub/pytorch_vision_deeplabv3_resnet101
          auto outputDict = _impl.forward({tensor}).toGenericDict();

          // 4. convert the output to another NSMutableArray for easy debugging
          auto outputTensor = outputDict.at("out").toTensor();
          float* floatBuffer = outputTensor.data_ptr<float>();
          if (!floatBuffer) {
          return nil;
          }
          NSMutableArray* results = [[NSMutableArray alloc] init];
          for (int i = 0; i < CLASSNUM * WIDTH * HEIGHT; i++) {
          [results addObject:@(floatBuffer[i])];
          }

          return nil;
          }

          筆記

          模型輸出是 DeepLabV3 模型的字典,因此我們使用toGenericDict來(lái)正確提取結(jié)果。對(duì)于其他模型,模型輸出也可能是單個(gè)張量或張量元組等。

          通過上面顯示的代碼更改,您可以在填充輸入結(jié)果的兩個(gè) for 循環(huán)之后設(shè)置斷點(diǎn),并將它們與您在步驟 2 中看到的模型輸入和輸出數(shù)據(jù)進(jìn)行比較,以查看它們是否匹配。對(duì)于在 iOS 和 Python 上運(yùn)行的模型的相同輸入,您應(yīng)該獲得相同的輸出。

          到目前為止,我們所做的只是確認(rèn)我們感興趣的模型可以像在 Python 中一樣在我們的 iOS 應(yīng)用程序中編寫腳本并正確運(yùn)行。到目前為止,我們?cè)?iOS 應(yīng)用程序中使用模型的步驟消耗了大部分(如果不是大部分)應(yīng)用程序開發(fā)時(shí)間,類似于數(shù)據(jù)預(yù)處理是典型機(jī)器學(xué)習(xí)項(xiàng)目中最繁重的提升。

          5. 完成 UI、重構(gòu)、構(gòu)建和運(yùn)行應(yīng)用程序

          現(xiàn)在我們已準(zhǔn)備好完成應(yīng)用程序和 UI,以將處理后的結(jié)果作為新圖像實(shí)際查看。輸出處理代碼應(yīng)該是這樣的,添加到TorchModule.mm中Step 4代碼片段的最后——記得先去掉return nil這一行;暫時(shí)放在那里以使代碼構(gòu)建和運(yùn)行:

          // see the 20 semantic classes link in Introduction
          const int DOG = 12;
          const int PERSON = 15;
          const int SHEEP = 17;

          NSMutableData* data = [NSMutableData dataWithLength:
          sizeof(unsigned char) * 3 * WIDTH * HEIGHT];
          unsigned char* buffer = (unsigned char*)[data mutableBytes];
          // go through each element in the output of size [WIDTH, HEIGHT] and
          // set different color for different classnum
          for (int j = 0; j < WIDTH; j++) {
          for (int k = 0; k < HEIGHT; k++) {
          // maxi: the index of the 21 CLASSNUM with the max probability
          int maxi = 0, maxj = 0, maxk = 0;
          float maxnum = -100000.0;
          for (int i = 0; i < CLASSNUM; i++) {
          if ([results[i * (WIDTH * HEIGHT) + j * WIDTH + k] floatValue] > maxnum) {
          maxnum = [results[i * (WIDTH * HEIGHT) + j * WIDTH + k] floatValue];
          maxi = i; maxj = j; maxk = k;
          }
          }
          int n = 3 * (maxj * width + maxk);
          // color coding for person (red), dog (green), sheep (blue)
          // black color for background and other classes
          buffer[n] = 0; buffer[n+1] = 0; buffer[n+2] = 0;
          if (maxi == PERSON) buffer[n] = 255;
          else if (maxi == DOG) buffer[n+1] = 255;
          else if (maxi == SHEEP) buffer[n+2] = 255;
          }
          }
          return buffer;

          這里的實(shí)現(xiàn)基于對(duì)DeepLabV3模型的理解,該模型為寬*高的輸入圖像輸出大小為[21, width, height]的張量。width*height 輸出數(shù)組中的每個(gè)元素都是一個(gè)介于 0 到 20 之間的值(對(duì)于介紹中描述的總共 21 個(gè)語(yǔ)義標(biāo)簽),該值用于設(shè)置特定顏色。這里分割的顏色編碼是基于概率最高的類,你可以擴(kuò)展你自己數(shù)據(jù)集中所有類的顏色編碼。

          輸出處理后,還需要調(diào)用一個(gè)輔助函數(shù)來(lái)轉(zhuǎn)換RGB緩沖到一個(gè)UIImage的實(shí)例上顯示的UIImageView。您可以參考代碼倉(cāng)庫(kù)UIImageHelper.mm定義的示例代碼convertRGBBufferToUIImage

          此應(yīng)用的 UI 也與 HelloWorld 的 UI 類似,只是您不需要UITextView來(lái)顯示圖像分類結(jié)果。您還可以添加兩個(gè)按鈕SegmentRestart如代碼庫(kù)中所示運(yùn)行模型推理并在顯示分割結(jié)果后顯示原始圖像。

          我們可以運(yùn)行應(yīng)用程序之前的最后一步是將所有部分連接在一起。修改ViewController.swift文件以使用在repo中重構(gòu)并更改為segmentImage 的 predictImage和您構(gòu)建的輔助函數(shù),如ViewController.swift中的 repo 中的示例代碼所示。將按鈕連接到動(dòng)作,你應(yīng)該很高興。

          現(xiàn)在,當(dāng)您在 iOS 模擬器或?qū)嶋H iOS 設(shè)備上運(yùn)行該應(yīng)用程序時(shí),您將看到以下屏幕:

           


          瀏覽 67
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  真人操逼 | 黄色影院在线免费观看 | 婷婷综合伊人 | 精品久久久久久久久久久久久久 | 哪灬翁公你的鸣巴好大好爽视频 |