主頁 >  其他 > 七萬字詳解paddle-openVINO【CPU】-從環境配置-模型部署全流程

七萬字詳解paddle-openVINO【CPU】-從環境配置-模型部署全流程

2022-01-28 08:24:33 其他

七萬字詳解paddle-openVINO【CPU】-從環境配置-模型部署全流程

在這篇文章你將會接觸到:paddle-openvino框架、兩者在Linux、windows多種配置方式、使用LabelMe對paddle資料的標注轉換與劃分、影像分類/目標檢測/實體分割/語意分割的資料格式、模型訓練、訓練引數調整、模型保存、模型壓縮(裁剪量化)與模型匯出(ONNX2),
你將會接觸到6個實戰專案:paddle(人像分割- RGB遙感影像分割-多通道遙感影像分割-地塊變化檢測)和paddle with openvino(paddleyolo、paddleyolo3、paddleOCR )

期間參考了百余篇官方技術檔案、借鑒了intel的優秀工程師張晶、許鈺雯、彭家麗、賈志剛、莊建、楊亦誠、raymondlo、吳卓等八位工程師,百度飛槳工程師大佬畢然、孫高峰、周湘陽、劉威威的一些資料以及大量的paddle官方開源文獻

為什么要選擇paddle+openVINO?

Paddlepaddle是國內百度推出的一款深度學習框架,Openvino是英特爾基于X86架構的芯片提出的一種部署方案,

飛槳主要解決的問題是AI開發者對于算力資源的巨大需求問題,飛槳提供了在線的云平臺,你可以使用他們的算卡設備進行模型的訓練與評估,

而openVINO解決對于主機上沒有顯卡或者算力不足的AI開發者的問題,

兩個部分的聯合,大大降低了AI開發者對于算力資源需求的門檻,從而實作較低成本的AI應用開發,使用飛槳訓練的模型不能夠直接部署到openVINO上,而是要經過兩個轉化,飛槳的模型匯出ONNX模型,然后再將這個模型轉換成為IR模型,才可以實作在openVINO上的部署,

會和TF、pytorch、caffe沖突嗎?

這個部分不僅僅沒有沖突,而且還有助于去理解這三個框架,飛槳的框架他的那很多語法都是和三者非常相似的,并且比較簡單,容易上手,可以幫助你去在飛槳上理解一些在演算法上比較復雜的架構,第二個是這三者也是可以在openVINO上部署的

三張圖講清openVINO-飛槳

這三張是來源于做Hackathon培訓時三位intel工程師彭家麗、楊亦誠、raymondlo的資料,三張圖就可以很好地把這個流程講清晰,

1、openVINO部署流程

請添加圖片描述

現在這個模型主要由構建、優化、部署工具去實作增量學習,基于我們開發者需要的資料對模型進行重新訓練,可以實作我們對精度上和工業效率上的要求,既可以利用現有的open model zoo幫助我們的開發者,還可以基于主流的TF、pytorch、PP進行模型轉化,

modeloptimizer和inference engine
在模型的優化階段我們我們用到了兩大核心組件,modeloptimizer和inference engine,前者主要是起到一個對第三方模型的一個轉移和優化的作用,把它轉化成為OPENVINO所支持的IR(intermediate representation.bin .xml)模型中間運算式,inference engine會讀取這些IR模型運算式,并把它搭載到相應的硬體中,對它進行一個底層的優化,以及算子的合并和模型簡化,部署是屬于第三個階段,在構建,

post-training optimization tool &deep learning workbench
比如post-training optimization tool主要是針對模型的一些特定的場景,做一些模型的量化和剪裁的作業,deep learning workbench是主要是可以基于一個可視化的web介面調節模型的一些精度,以及它的每個類的一個輸入輸出結果進行一個調優,

deep learning streaming
此之外呢,也集成了大量的第三方的一些工具,比如說deep learning streaming這樣一個工具,幫助開發者去對decode和encode做串流的處理,openCL加速模型的前后處理以及一些優化加速和相對應的開發,

還有一些成品腳本是可以去對比應用模型的一個精度和性能的測驗,以及相關性能的優化,

model server
那最后模型部署,是以服務器的形式部署在model server上的,只要通過request介面的形式去進行的調取這個模型的輸出結果就能準確的獲取到一個輸出,(這個只是提一下,推薦大家使用百度的公有云服務器即可)

development manager
針對一些特定的這個邊緣計算的場景,也提供了development manager,通過這個工具開發者就可以去針對工業領域的部署包進行一個剪裁,因為有的場景下,我們的開發者可能只需要cpu,不需要其他一些底層原廠的一些庫,那我們可以把在部署的時候把這些庫給它剔除掉,實作整個部署包的一個最小化,

最后整個軟體也是支持在X86架構所有的硬體產品的部署,
請添加圖片描述

2、paddlepaddle+OpenVINO

飛槳和openVINO兩者之間的嵌套,其實就如上面的流程一樣的,構建程序中我們使用paddle模型,然后將我們的飛槳模型通過轉換器轉換成IR模型,或者可以直接將一部分的飛槳模型部署到硬體上,從而實作了整個流程部署與開發,
請添加圖片描述

openVINO軟體架構

請添加圖片描述

前端

openVINO軟體架構可以分成這個前端和后端兩個部分,那與之相對應的代碼就是我們這個read_network函式介面和load_network這兩個函式介面,那前端主要功能就是通過我們這個這個read_network介面去讀取第三方模型并對其做一個決議,然后通過我們的一些通用的、優化的方式,對模型的一些layer進行一些優化.這些優化都是通用的,比如說基于比如說針對某些layer的比較稀疏的一些圖進行一個圖層融合,或者說把一些系統中的算子推理程序中可能不需要的,我們會把這個沒有用的算子給他進行剔除,然后把轉化好的模型轉化成我們的CNNnetwork,也就是前端的功能,

那前端這個代碼部分現在有主要有三個這樣的構建方法,
首先可以基于我們的如下圖左側的這樣一個引數介面,去自己手動去定一個模型的拓撲結構以及相應的引數,并把它轉化成CNNnetwork的形式,

其次也通過modeloptimizer去轉化一個第三方的模型,形成IR的模型中間運算式,并通過IR模型的進行一個讀取和決議,直接去轉化成這個CNNnetwork,

第三個也是最有挑戰性的,通過paddle reader 組件直接把飛槳模型進行讀取和加載,通過paddle converter這個組建一對一的映射到相對應算子中,實作對前端的支持,最后直接將paddle加載入CNNnetwork網路,

后端

通過load_network這個函式介面去指定模型要跑在哪一個硬體平臺上,load_network這個函式介面會去加載剛才已經優化過的CNNnetwork,并把它去推到指定的硬體平臺上去進行一個前端的推理,那在這個程序中會針對不同的硬體平臺做一些定制化的優化,比如說我們會通過這個記憶體重排或者是一些并行推理,去實作一些深度優化,保證在指定平臺上能達到一個最好的推理效能,通過這個介面也可以進行一些定制化的優化設定,比如說我們可以在這個介面上是指定在多個硬體平臺上去運行,這樣子可以實作對多資料流的支持,同時也可以實作異構推理這樣一個模式,可以會同時去生成多個推理請求,然后把這些推理情況平均分配到不同的計算單元中,給多個任務進行同時的這樣一個推理,提高整個網路的吞吐量,
請添加圖片描述

這其中的困難主要有三部分

1、第一部分是不同環境的配置,現在主要是是WINDOWS系統和Linux系統的配置,蘋果系統也可以用,
2、第二部分是對飛槳訓練模型的掌握和匯出與轉化,
3、第三部分是如何將匯出的模型進行轉換成IR模型并部署到openVINO上,

(PS:如果對于應用已經熟練掌握后,可以嘗試去做下不同模型的算子轉化,這是非常底層的也是非常訓練人基本功底的一個挑戰,比如說PP-OPENVINO算子的轉化等)

全流程的難點和重點就是這三個部分組成的,那我們就一次來解決這三個問題,

Paddlepaddle-PaddleX-openVINO安裝與環境調配

先來簡單介紹一下飛槳的架構組成吧,這個參考百度官方出品的“深度學習零基礎時間”一書中一圖,講得十分清晰,對于不同的領域的學者都能夠找到對應的體系,但是這里要說的是最核心的兩個部分,一個是paddle,一個是paddleX,前者是最核心的框架,通過這個核心框架來使用其他的框架,而paddleX是開發的全流程工具,用來開發自己的AI模型,

請添加圖片描述

PaddleX介紹

這里參考百度飛槳的官方技術檔案點擊深入了解

PaddleX可視化客戶端基于PaddleX開發的可視化深度學習模型訓練套件,目前支持訓練視覺領域的影像分類、目標檢測、實體分割和語意分割四大任務,同時支持模型裁剪、模型量化兩種方式壓縮模型,

PaddleX中的所有模型訓練都可以總結為以下3個步驟
定義:程序、資料集和模型,就可以得到一個AI 模型
請添加圖片描述

下面簡單用代碼展示一個開發的流程,但是這里不建議朋友們進行嘗試,因為此時朋友的電腦中還沒有安裝paddlepaddle,但是可以幫助大家理解這個程序,

以蔬菜分類為例子演示PaddleX開發全流程

  1. 安裝PaddleX

安裝相關問題我們會在接下來詳細講述,

pip install paddlex -i https://mirror.baidu.com/pypi/simple
  1. 準備蔬菜分類資料集
wget https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz
tar xzvf vegetables_cls.tar.gz
  1. 定義訓練/驗證影像處理流程transforms

因為訓練時加入了資料增強操作,因此在訓練和驗證程序中,模型的資料處理流程需要分別進行定義,如下所示,代碼在train_transforms中加入了RandomCrop和RandomHorizontalFlip兩種資料增強方式, 更多方法可以參考官方的資料增強檔案,

from paddlex.cls import transforms
train_transforms = transforms.Compose([
    transforms.RandomCrop(crop_size=224),
    transforms.RandomHorizontalFlip(),
    transforms.Normalize()
])
eval_transforms = transforms.Compose([
    transforms.ResizeByShort(short_size=256),
    transforms.CenterCrop(crop_size=224),
    transforms.Normalize()
])
  1. 定義dataset加載影像分類資料集

定義資料集,pdx.datasets.ImageNet表示讀取ImageNet格式的分類資料集

train_dataset = pdx.datasets.ImageNet(
    data_dir='vegetables_cls',
    file_list='vegetables_cls/train_list.txt',
    label_list='vegetables_cls/labels.txt',
    transforms=train_transforms,
    shuffle=True)
eval_dataset = pdx.datasets.ImageNet(
    data_dir='vegetables_cls',
    file_list='vegetables_cls/val_list.txt',
    label_list='vegetables_cls/labels.txt',
    transforms=eval_transforms)
    
  1. 使用MobileNetV3_small_ssld模型開始訓練

這里使用百度基于蒸餾方法得到的MobileNetV3預訓練模型,模型結構與MobileNetV3一致,但精度更高,PaddleX內置了20多種分類模型

num_classes = len(train_dataset.labels)
model = pdx.cls.MobileNetV3_small_ssld(num_classes=num_classes)

model.train(num_epochs=20,
            train_dataset=train_dataset,
            train_batch_size=32,
            eval_dataset=eval_dataset,
            lr_decay_epochs=[4, 6, 8],
            save_dir='output/mobilenetv3_small_ssld',
            use_vdl=True)

  1. 訓練程序使用VisualDL查看訓練指標變化

訓練程序中,模型在訓練集和驗證集上的指標均會以標準輸出流形式輸出到命令終端,當用戶設定use_vdl=True時,也會使用VisualDL格式將指標打點到save_dir目錄下的vdl_log檔案夾,在終端運行如下命令啟動visualdl并查看可視化的指標變化情況,

visualdl --logdir output/mobilenetv3_small_ssld --port 8001
服務啟動后,通過瀏覽器打開https://0.0.0.0:8001或https://localhost:8001即可,

  1. 加載訓練保存的模型預測

模型在訓練程序中,會每間隔一定輪數保存一次模型,在驗證集上評估效果最好的一輪會保存在save_dir目錄下的best_model檔案夾,通過如下方式可加載模型,進行預測,

import paddlex as pdx
model = pdx.load_model('output/mobilenetv3_small_ssld/best_model')
result = model.predict('vegetables_cls/bocai/100.jpg')
print("Predict Result: ", result)

預測結果輸出如下,

Predict Result: Predict Result: [{'score': 0.9999393, 'category': 'bocai', 'category_id': 0}]

那么到現在,你就已經完成了一次AI模型的開發了,即使是再復雜的工業工程,都是這三個步驟的細化,

剛才我們提到,想要使用paddle X用戶的電腦中就必須有paddlepaddle的環境(paddlepaddle-gpu或paddlepaddle(版本大于或等于1.8.1),那么接下來我來講解一下不同環境下paddle的安裝,

1、安裝paddle paddle

首先每個用戶的電腦環境都不一定相同,所以百度官方提供了如下頁面的指導,打開下面的鏈接,選擇你所屬于的電腦環境,就可以獲得相關安裝指引,一般在十多分鐘后就可以安裝完成,
這里就以官方的指引為主了,

https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/install/pip/macos-pip.html
請添加圖片描述

2.win/Mac/linux/anaconda/pip/pycocotools

安裝paddleX

pip安裝

下面是Windows安裝命令

pip install paddlex -i https://mirror.baidu.com/pypi/simple

Anaconda安裝

Anaconda是一個開源的Python發行版本,其包含了conda、Python等180多個科學包及其依賴項,使用Anaconda可以通過創建多個獨立的Python環境,避免用戶的Python環境安裝太多不同版本依賴導致沖突,
代碼安裝

git clone https://github.com/PaddlePaddle/PaddleX.git
cd PaddleX
git checkout release/1.3
python setup.py install

pycocotools安裝問題

PaddleX依賴pycocotools包,如安裝pycocotools失敗,可參照如下方式安裝pycocotools

Windows系統

Windows安裝時可能會提示Microsoft Visual C++ 14.0 is required,從而導致安裝出錯,這個是時候需要下載VC build tools安裝再執行如下pip命令
下載鏈接
https://go.microsoft.com/fwlink/?LinkId=691126

注意:安裝完后,需要重新打開新的終端命令視窗

pip install cython
pip install git+https://gitee.com/jiangjiajun/philferriere-cocoapi.git#subdirectory=PythonAPI

Linux/Mac系統

Linux/Mac系統下,直接使用pip安裝如下兩個依賴即可

pip install cython  
pip install pycocotools
Next  Previous

3、openVINO安裝與相關環境適配

如果是使用window作業系統的伙伴遇到困難可以參考之前寫的一篇博客,里面有每步的截圖,
博客鏈接

但是這里因為要和飛槳適配,所以下載的版本有一些特定的要求,這里推薦使用OpenVINO 2020.4與2021.1版本

注意:
由于PaddleX分割模型使用了ReSize-11 Op,OpenVINO 2021.1版本開始支持支持Resize-11 ,CPU下請務必下載OpenVINO 2021.1+版本
由于VPU在OpenVINO 2021.1版本下轉換的分類模型會出現Range layer不支持的情況,VPU下請務必下載OpenVINO 2020.4版本

可以看下各大軟硬設備對openVINO的支持
請添加圖片描述

Windows安裝openVINO

我們先來說下一些要裝的環境
有什么問題如果看完后還是不懂,可以看下官方技術檔案
https://docs.openvino.ai/latest/openvino_docs_install_guides_installing_openvino_windows.html

前置條件
Visual Studio 2019
OpenVINO 2020.4或者2021.1+
CMake 3.0+
python3.6+

還是再提醒一嘴:CPU下使用OpenVINO 2021.1+版本;VPU下請使用OpenVINO 2020.4版本

安裝步驟

1、安裝外部軟體依賴項
2、安裝OpenVINOTM工具包的英特爾?發行版
3、配置環境
4、配置模型優化器

第1步:安裝外部軟體依賴項

1、Microsoft Visual Studio* 2019 with MSBuild
https://visualstudio.microsoft.com/vs/older-downloads/#visual-studio-2019-and-other-products
2、CMake 3.14 or higher 64-bit
https://cmake.org/download/
3、Python - 64-bit
https://www.python.org/downloads/windows/

請添加圖片描述

第2步:安裝OpenVINOTM工具包核心組件的英特爾?發行版

1、從適用于Windows的OpenVINOTM工具包的英特爾?分發下載OpenVINOTM工具包包檔案的英特爾?分發,從下拉選單中選擇適用于Windows的OpenVINOTM工具包的英特爾?發行版,

2、轉到“Downloads”檔案夾,雙擊中
w_openvino_toolkit_p_.exe,打開一個視窗,允許您選擇安裝目錄和組件,

在這里插入圖片描述

3、按照螢屏上的說明操作,注意以下資訊,以防您必須完成其他步驟:

在這里插入圖片描述

4、默認情況下,Intel?Distribution of OpenVINO?安裝到以下目錄,在檔案的其他地方稱為<INSTALL_DIR>: C:\Program Files (x86)\Intel\ openvino_,為了簡單起見,還創建了一個最新安裝的快捷方式:C:\Program Files (x86)\Intel\ openvino_2021,

5、可選:可以選擇自定義來更改安裝目錄或要安裝的組件,
在這里插入圖片描述

單擊“完成”以關閉安裝向導,

單擊“完成”以關閉安裝向導后,將打開一個新的瀏覽器視窗,其中包含您正在閱讀的檔案(以防您沒有安裝),然后跳轉到包含后續安裝步驟的部分,
核心組件現已安裝,繼續下一節以安裝其他依賴項,

第3步:配置環境

請添加圖片描述

必須更新多個環境變數,然后才能編譯和運行OpenVINOTM應用程式,打開命令提示符,然后運行setupvars.bat批處理檔案以臨時設定環境變數:

C:\程式檔案 (x86)\Intel\openvino_2021\bin\setupvars.bat

注意:不建議運行配置命令的Windows PowerShell,改用命令提示符(cmd),這里我試過了,只能用終端,不是建議,

建議:關閉命令提示視窗時,OpenVINO工具包環境變數將被洗掉,作為一個選項,您可以手動永久設定環境變數,

第4步:配置模型優化器

Model Optimizer是基于Python的命令列工具,用于從流行的深度學習框架(如Caffe、TensorFlow*、Apache MXNet*、ONNX和Kaldi)匯入訓練有素的模型,

模型優化器是OpenVINO工具包英特爾發行的關鍵組件,對模型執行推斷(ONNX和nGraph模型除外)需要通過模型優化器運行模型,當通過模型優化器轉換預訓練的模型時,輸出是網路的中間表示(IR),中間表示是一對描述整個模型的檔案:

.xml:描述網路拓撲
.bin:包含權重和偏置二進制資料

1、在搜索視窗框中輸入cmd打開命令提示符,然后按Enter鍵,在打開的視窗中輸入命令:請添加圖片描述

2、轉到模型優化器先決條件目錄,

cd C:\Program Files (x86)\Intel\openvino_2021\deployment_tools\model_optimizer\install_prerequisites

3、運行此批處理檔案以配置Caffe、TensorFlow 2.x、MXNet、Kaldi*和ONNX的模型優化器:

install_prerequisites.bat

注意:安裝完OpenVINO后需要手動添加OpenVINO目錄到系統環境變數,否則在運行程式時會出現找不到dll的情況,以安裝OpenVINO時不改變OpenVINO安裝目錄情況下為示例,
流程如下

我的電腦->屬性->高級系統設定->環境變數

在系統變數中找到Path(如沒有,自行創建),并雙擊編輯
新建,分別將OpenVINO以下路徑填入并保存:

C:\Program File (x86)\IntelSWTools\openvino\inference_engine\bin\intel64\Release

C:\Program File (x86)\IntelSWTools\openvino\inference_engine\external\tbb\bin

C:\Program File (x86)\IntelSWTools\openvino\deployment_tools\ngraph\lib

請確保系統已經安裝好上述基本軟體,并配置好相應環境,下面所有示例以作業目錄為 D:\projects演示,

window- paddle- openVINO勾連

這里使用c++下預測部署的方法

Step1: 下載PaddleX預測代碼

打開win的終端,在在D盤下載預測代碼

d:
mkdir projects
cd projects
git clone https://github.com/PaddlePaddle/PaddleX.git
cd PaddleX
git checkout release/1.3

說明:其中C++預測代碼在PaddleX\deploy\openvino 目錄,該目錄不依賴任何PaddleX下其他目錄,

Step2 軟體依賴

提供了依賴軟體預編譯庫:

gflas
opencv

下載完opencv后需要配置環境變數,如下流程所示- 我的電腦->屬性->高級系統設定->環境變數 - 在系統變數中找到Path(如沒有,自行創建),并雙擊編輯 - 新建,將opencv路徑填入并保存,如D:\projects\opencv\build\x64\vc14\bin

Step3: 使用Visual Studio 2019直接編譯CMake

打開Visual Studio 2019 Community,點擊繼續但無需代碼
點擊: 檔案->打開->CMake 選擇C++預測代碼所在路徑(例如D:\projects\PaddleX\deploy\openvino),并打開CMakeList.txt
點擊:專案->CMake設定
點擊瀏覽,分別設定編譯選項指定OpenVINO、Gflags、NGRAPH、OPENCV的路徑

請添加圖片描述

設定完成后, 點擊保存并生成CMake快取以加載變數, 5. 點擊生成->全部生成

Step4: 預測

上述Visual Studio 2019編譯產出的可執行檔案在out\build\x64-Release目錄下,打開cmd,并切換到該目錄:

D:
cd D:\projects\PaddleX\deploy\openvino\out\build\x64-Release

編譯成功后,圖片預測demo的入口程式為detector.exe,classifier.exe,segmenter.exe,用戶可根據自己的模型型別選擇,其主要命令引數說明如下:
請添加圖片描述

測驗:
在CPU下做單張圖片的分類任務預測測驗圖片 /path/to/test_img.jpeg
直接在終端輸入下行代碼看看預測是否能成功

./classifier.exe --model_dir=/path/to/openvino_model --image=/path/to/test_img.jpeg --cfg_file=/path/to/PadlleX_model.yml

如果成功的話,恭喜你你已經可以在window系統下使用兩者了,

Linux安裝openVINO

如果看完后還是有一些不懂的地方,可以直接看下官方的技術檔案,
https://docs.openvino.ai/latest/openvino_docs_install_guides_installing_openvino_linux.html

接下來說下Linux的安裝步驟,相對來說比windows會簡單:
1、安裝OpenVINOTM工具包的英特爾?發行版
2、安裝外部軟體依賴項
3、配置環境
4、配置模型優化器

第1步:安裝OpenVINOTM工具包核心組件的英特爾?發行版

從適用于Linux的OpenVINOTM工具包的英特爾?分發*OpenVINOTM工具包下載包檔案的英特爾?分發,從下拉選單中選擇適用于Linux軟體包的OpenVINOTM工具包的英特爾?發行版,

1、打開命令提示終端視窗,使用鍵盤快捷鍵:Ctrl+Alt+T
2、將目錄更改為您下載Linux*軟體包檔案的OpenVINO工具包的英特爾分發,
3、如果您將軟體包檔案下載到當前用戶的Downloads目錄:

cd ~/下載/

默認情況下,該檔案保存為l_openvino_toolkit_p_.tgz,例如l_openvino_toolkit_p_2021.4.689.tgz,

4、解壓.tgz檔案:

tar -xvzf l_openvino_toolkit_p_<version>.tgz

5、轉到l_openvino_toolkit_p_目錄:

cd l_openvino_toolkit_p_<版本>

6、選擇安裝選項,并將相關腳本作為根運行,以使用圖形用戶界面(GUI)安裝向導或命令列指令(CLI),GUI提供截圖,CLI不提供截圖,下面的資訊也適用于CLI,對安裝很有幫助,可以看到相同的選擇和任務,

選項1:GUI安裝向導:

sudo ./install_GUI.sh

選項2:命令列說明:

Sudo ./install.sh

選項3:命令列靜音說明:

sudo sed -i's/decline/accept/g' silent.cfg
sudo ./install.sh -s silent.cfg

7、注意以下資訊,以防必須完成其他步驟,看看有沒有缺環境:
在這里插入圖片描述
對于根或管理員:/opt/intel/openvino_/
對于普通用戶:/home//intel/openvino_/
為了簡單起見,還創建了最新安裝的符號鏈接:/opt/intel/openvino_2021/或/home//intel/openvino_2021/

8、“完成”螢屏表示核心組件已安裝:
在這里插入圖片描述

單擊“完成”關閉安裝向導后,將使用此檔案打開一個新的瀏覽器視窗,它跳轉到包含后續安裝步驟的部分,

默認情況下,OpenVINOTM的英特爾?發行版安裝在以下目錄中:

第2步:安裝外部軟體依賴項

如果將OpenVINOTM的英特爾?發行版安裝到非默認目錄,請將/opt/intel替換為安裝軟體的目錄,
這些依賴項是以下條件所必需的:

英特爾優化的OpenCV庫構建
深度學習推理引擎
深度學習模型優化器工具

1、轉到install_dependencies目錄:

cd /opt/intel/openvino_2021/install_dependencies

2、運行腳本下載和安裝外部軟體依賴項:

sudo -E ./install_openvino_dependencies.sh

安裝依賴項后,繼續下一節設定環境變數,

第3步:配置環境

必須更新多個環境變數,然后才能編譯和運行OpenVINOTM應用程式,使用vi(如下)或首選編輯器設定以下持久環境變數:

1、在/home/中打開.bashrc檔案:

vi ~/.bashrc

2、按i鍵切換到插入模式,

3、將以下行添加到檔案末尾:

來源/opt/intel/openvino_2021/bin/setupvars.sh

4、保存并關閉檔案:按Esc鍵并鍵入:wq,

5、要驗證更改,請打開一個新的終端,您將看到[setupvars.sh] OpenVINO環境已初始化,

來源/opt/intel/openvino_2021/bin/setupvars.sh

設定了環境變數,接下來,將配置模型優化器,

第4步:配置模型優化器

由于CentOS不正式支持TensorFlow框架,因此無法在該作業系統上配置和運行TensorFlow的模型優化器,
*
Model Optimizer是基于Python的命令列工具,用于從流行的深度學習框架(如Caffe、TensorFlow
、Apache MXNet
、ONNX和Kaldi)匯入訓練有素的模型,

模型優化器是OpenVINO工具包英特爾發行的關鍵組件,對模型執行推斷(ONNX和nGraph模型除外)需要通過模型優化器運行模型,當通過模型優化器運行預訓練模型時,輸出是網路的中間表示(IR),中間表示是一對描述整個模型的檔案:

.xml:描述網路拓撲
.bin:包含權重和偏置二進制資料

1、轉到模型優化器先決條件目錄:

cd /opt/intel/openvino_2021/deployment_tools/model_optimizer/install_prerequisites

2、運行腳本為Caffe、TensorFlow 2.x、MXNet、Kaldi和ONNX配置模型優化器:

sudo ./install_prerequisites.sh

如果已經安裝好paddle和openVINO后,并配置好相應環境,下面所有示例以作業目錄 /root/projects/演示,

預測部署測驗

檔案提供了c++下預測部署的方法,如果需要在python下預測部署請參考python預測部署

Step1 下載PaddleX預測代碼

mkdir -p /root/projects
cd /root/projects
git clone https://github.com/PaddlePaddle/PaddleX.git
cd PaddleX
git checkout release/1.3

說明:其中C++預測代碼在PaddleX/deploy/openvino 目錄,該目錄不依賴任何PaddleX下其他目錄,

Step2 軟體依賴

Step3中的編譯腳本會一鍵安裝第三方依賴軟體的預編譯包,用戶不需要單獨下載或編譯這些依賴軟體,

Step3: 編譯

編譯cmake的命令在scripts/build.sh中,若在樹莓派(Raspbian OS)上編譯請修改ARCH引數x86為armv7,若自行編譯第三方依賴軟體請根據Step1中編譯軟體的實際情況修改主要引數,其主要內容說明如下:

#openvino預編譯庫的路徑
OPENVINO_DIR=$INTEL_OPENVINO_DIR/inference_engine
#gflags預編譯庫的路徑
GFLAGS_DIR=$(pwd)/deps/gflags
#ngraph lib預編譯庫的路徑
NGRAPH_LIB=$INTEL_OPENVINO_DIR/deployment_tools/ngraph/lib
#opencv預編譯庫的路徑
OPENCV_DIR=$(pwd)/deps/opencv/
#cpu架構(x86或armv7)
ARCH=x86

執行build腳本:

sh ./scripts/build.sh

Step4: 預測

可以跑一下下面這個例子
linux系統在CPU下做單張圖片的分類任務預測測驗圖片 /path/to/test_img.jpeg

./build/classifier --model_dir=/path/to/openvino_model --image=/path/to/test_img.jpeg --cfg_file=/path/to/PadlleX_model.yml

編譯成功后,分類任務的預測可執行程式為classifier,檢測任務的預測可執行程式為detector,分割任務的預測可執行程式為segmenter,其主要命令引數說明如下:
請添加圖片描述

開始訓練

將代碼保存到本地后運行(代碼下載鏈接位于上面的表格中),代碼會自動下載訓練資料并開始訓練,如保存為deeplabv3p_mobilenetv2_x0.25.py,執行如下命令即可開始訓練:

python deeplabv3p_mobilenetv2_x0.25.py

OpenVINO部署常見問題

轉模型程序中出現”ModuleNotFoundError: No module named ‘mo’”

原因:該問題主要是因為在安裝OpenVINO之后未初始化OpenVINO環境解決方案:找到OpenVINO初始化環境腳本,運行后即可以解決此問題

Linux系統初始化OpenVINO環境

1)root用戶安裝,以OpenVINO 2021.1版本為例,運行如下命令即可初始化

source /opt/intel/openvino_2021/bin/setupvars.sh

2)非root用戶安裝,以OpenVINO 2021.1版本、用戶名為paddlex為例,運行如下命令即可初始化

source /home/paddlex/intel/openvino_2021/bin/setupvar.sh

Window系統初始化OpenVINO環境

以OpenVINO 2021.1版本為例,執行如下命令即可初始化OpenVINO環境

cd C:\Program Files (x86)\Intel\openvino_2021\bin\
setupvars.bat

paddlepaddle的訓練

資料準備(資料標注、轉換、劃分)

使用Labelme標注
官網鏈接:
https://paddlex.readthedocs.io/zh_CN/release-1.3/data/annotation/labelme.html

LabelMe的安裝和啟動

LabelMe的安裝和啟動

LabelMe可用于標注目標檢測、實體分割、語意分割資料集,是一款開源的標注工具,

  1. 安裝Anaconda

推薦使用Anaconda安裝python依賴,有經驗的開發者可以跳過此步驟,安裝Anaconda的方式可以參考檔案,

在安裝Anaconda,并創建環境之后,再進行接下來的步驟

  1. 安裝LabelMe

進入Python環境后,執行如下命令即可

conda activate my_paddlex
conda install pyqt
pip install labelme
  1. 啟動LabelMe

進入安裝了LabelMe的Python環境,執行如下命令即可啟動LabelMe

conda activate my_paddlex
labelme

影像分類

影像分類標注是一項最基礎,最簡單的標注任務,用戶只需將屬于同一類的圖片放在同一個檔案夾下即可,例如下所示目錄結構,

MyDataset/ # 影像分類資料集根目錄
|--dog/ # 當前檔案夾所有圖片屬于dog類別
|  |--d1.jpg
|  |--d2.jpg
|  |--...
|  |--...
|
|--...
|
|--snake/ # 當前檔案夾所有圖片屬于snake類別
|  |--s1.jpg
|  |--s2.jpg
|  |--...
|  |--...

資料劃分
在模型進行訓練時,我們需要劃分訓練集,驗證集和測驗集,因此需要對如上資料進行劃分,直接使用paddlex命令即可將資料集隨機劃分成70%訓練集,20%驗證集和10%測驗集

paddlex --split_dataset --format ImageNet --dataset_dir MyDataset --val_value 0.2 --test_value 0.1

劃分好的資料集會額外生成labels.txt, train_list.txt, val_list.txt, test_list.txt四個檔案,之后可直接進行訓練,

目標檢測

目標檢測資料的標注推薦使用LabelMe標注工具,如先前并無安裝,那么LabelMe的安裝可參考LabelMe安裝和啟動
官網鏈接:
https://paddlex.readthedocs.io/zh_CN/release-1.3/data/annotation/labelme.html

注意:LabelMe不要在如下的路徑以及檔案名中出現中文字符!

準備作業
1、將收集的影像存放于JPEGImages檔案夾下,例如存盤在D:\MyDataset\JPEGImages
2、創建與影像檔案夾相對應的檔案夾Annotations,用于存盤標注的json檔案,如D:MyDataset\Annotations
3、打開LabelMe,點擊”Open Dir“按鈕,選擇需要標注的影像所在的檔案夾打開,則”File List“對話框中會顯示所有影像所對應的絕對路徑,接著便可以開始遍歷每張影像,進行標注作業

目標框標注
1、打開矩形框標注工具(右鍵選單->Create Rectangle),具體如下圖所示
在這里插入圖片描述
2、使用拖拉的方式對目標物體進行標識,并在彈出的對話框中寫明對應label(當label已存在時點擊即可, 此處請注意label勿使用中文),具體如下圖所示,當框標注錯誤時,可點擊左側的“Edit Polygons”再點擊標注框,通過拖拉進行修改,也可再點擊“Delete Polygon”進行洗掉,
在這里插入圖片描述
3、點擊右側”Save“,將標注結果保存到中創建的檔案夾Annotations目錄中
格式轉換

LabelMe標注后的資料還需要進行轉換為PascalVOC或MSCOCO格式,才可以用于目標檢測任務的訓練,創建D:\dataset_voc目錄,在python環境中安裝paddlex后,使用如下命令即可

paddlex --data_conversion --source labelme --to PascalVOC \
        --pics D:\MyDataset\JPEGImages \
        --annotations D:\MyDataset\Annotations \
        --save_dir D:\dataset_voc

資料集劃分

轉換完資料后,為了進行訓練,還需要將資料劃分為訓練集、驗證集和測驗集,同樣在安裝paddlex后,使用如下命令即可將資料劃分為70%訓練集,20%驗證集和10%的測驗集

paddlex --split_dataset --format VOC --dataset_dir D:\MyDataset --val_value 0.2 --test_value 0.1

執行上面命令列,會在D:\MyDataset下生成labels.txt, train_list.txt, val_list.txt和test_list.txt,分別存盤類別資訊,訓練樣本串列,驗證樣本串列,測驗樣本串列

實體分割

準備作業

1、將收集的影像存放于JPEGImages檔案夾下,例如存盤在D:\MyDataset\JPEGImages
2、創建與影像檔案夾相對應的檔案夾Annotations,用于存盤標注的json檔案,如D:MyDataset\Annotations
3、打開LabelMe,點擊”Open Dir“按鈕,選擇需要標注的影像所在的檔案夾打開,則”File List“對話框中會顯示所有影像所對應的絕對路徑,接著便可以開始遍歷每張影像,進行標注作業

目標邊緣標注

1、打開多邊形標注工具(右鍵選單->Create Polygon)以打點的方式圈出目標的輪廓,并在彈出的對話框中寫明對應label(當label已存在時點擊即可,此處請注意label勿使用中文),具體如下提所示,當框標注錯誤時,可點擊左側的“Edit Polygons”再點擊標注框,通過拖拉進行修改,也可再點擊“Delete Polygon”進行洗掉, ../../_images/detection2.png

2、點擊右側”Save“,將標注結果保存到中創建的檔案夾Annotations目錄中

格式轉換
LabelMe標注后的資料還需要進行轉換為MSCOCO格式,才可以用于實體分割任務的訓練,創建保存目錄D:\dataset_seg,在python環境中安裝paddlex后,使用如下命令即可

paddlex --data_conversion --source labelme --to MSCOCO \
        --pics D:\MyDataset\JPEGImages \
        --annotations D:\MyDataset\Annotations \
        --save_dir D:\dataset_coco

資料集劃分
轉換完資料后,為了進行訓練,還需要將資料劃分為訓練集、驗證集和測驗集,同樣在安裝paddlex后,使用如下命令即可將資料劃分為70%訓練集,20%驗證集和10%的測驗集

paddlex --split_dataset --format COCO --dataset_dir D:\MyDataset --val_value 0.2 --test_value 0.1

執行上面命令列,會在D:\MyDataset下生成train.json, val.json, test.json,分別存盤訓練樣本資訊,驗證樣本資訊,測驗樣本資訊

語意分割

準備作業

1、將收集的影像存放于JPEGImages檔案夾下,例如存盤在D:\MyDataset\JPEGImages
2、創建與影像檔案夾相對應的檔案夾Annotations,用于存盤標注的json檔案,如D:MyDataset\Annotations
3、打開LabelMe,點擊”Open Dir“按鈕,選擇需要標注的影像所在的檔案夾打開,則”File List“對話框中會顯示所有影像所對應的絕對路徑,接著便可以開始遍歷每張影像,進行標注作業

目標邊緣標注
1、打開多邊形標注工具(右鍵選單->Create Polygon)以打點的方式圈出目標的輪廓,并在彈出的對話框中寫明對應label(當label已存在時點擊即可,此處請注意label勿使用中文),具體如下提所示,當框標注錯誤時,可點擊左側的“Edit Polygons”再點擊標注框,通過拖拉進行修改,也可再點擊“Delete Polygon”進行洗掉, ../../_images/detection2.png

2、點擊右側”Save“,將標注結果保存到中創建的檔案夾Annotations目錄中

格式轉換
LabelMe標注后的資料還需要進行轉換為SEG格式,才可以用于語意分割任務的訓練,創建保存目錄D:\dataset_seg,在python環境中安裝paddlex后,使用如下命令即可

paddlex --data_conversion --source labelme --to SEG \
        --pics D:\MyDataset\JPEGImages \
        --annotations D:\MyDataset\Annotations \
        --save_dir D:\dataset_seg

資料集劃分
轉換完資料后,為了進行訓練,還需要將資料劃分為訓練集、驗證集和測驗集,同樣在安裝paddlex后,使用如下命令即可將資料劃分為70%訓練集,20%驗證集和10%的測驗集

paddlex --split_dataset --format SEG --dataset_dir D:\MyDataset --val_value 0.2 --test_value 0.1

執行上面命令列,會在D:\MyDataset下生成train_list.txt, val_list.txt, test_list.txt,分別存盤訓練樣本資訊,驗證樣本資訊,測驗樣本資訊

資料格式

影像分類ImageNet

資料檔案夾結構

在PaddleX中,影像分類支持ImageNet資料集格式,資料集目錄data_dir下包含多個檔案夾,每個檔案夾中的影像均屬于同一個類別,檔案夾的命名即為類別名(注意路徑中不要包括中文,空格), 如下為示例結構

MyDataset/ # 影像分類資料集根目錄
|--dog/ # 當前檔案夾所有圖片屬于dog類別
|  |--d1.jpg
|  |--d2.jpg
|  |--...
|  |--...
|
|--...
|
|--snake/ # 當前檔案夾所有圖片屬于snake類別
|  |--s1.jpg
|  |--s2.jpg
|  |--...
|  |--...

劃分訓練集驗證集
為了用于訓練,我們需要在MyDataset目錄下準備train_list.txt, val_list.txt和labels.txt三個檔案,分別用于表示訓練集串列,驗證集串列和類別標簽串列,點擊下載影像分類示例資料集

注:也可使用PaddleX自帶工具,對資料集進行隨機劃分,在資料集按照上面格式組織后,使用如下命令即可快速完成資料集隨機劃分,其中val_value表示驗證集的比例,test_value表示測驗集的比例(可以為0),剩余的比例用于訓練集,

paddlex --split_dataset --format ImageNet --dataset_dir MyDataset --val_value 0.2 --test_value 0.1
labels.txt

labels.txt用于列出所有類別,類別對應行號表示模型訓練程序中類別的id(行號從0開始計數),例如labels.txt為以下內容

dog
cat
snake

即表示該分類資料集中共有3個類別,分別為dog,cat和snake,在模型訓練中dog對應的類別id為0, cat對應1,以此類推

train_list.txt

train_list.txt列出用于訓練時的圖片集合,與其對應的類別id,示例如下

dog/d1.jpg 0
dog/d2.jpg 0
cat/c1.jpg 1
... ...
snake/s1.jpg 2

其中第一列為相對對MyDataset的相對路徑,第二列為圖片對應類別的類別id

val_list.txt

val_list列出用于驗證時的圖片集成,與其對應的類別id,格式與train_list.txt一致

PaddleX資料集加載

示例代碼如下,

import paddlex as pdx
from paddlex.cls import transforms
train_transforms = transforms.Compose([
    transforms.RandomCrop(crop_size=224), transforms.RandomHorizontalFlip(),
    transforms.Normalize()
])
eval_transforms = transforms.Compose([
    transforms.ResizeByShort(short_size=256),
    transforms.CenterCrop(crop_size=224), transforms.Normalize()
])
train_dataset = pdx.datasets.ImageNet(
                    data_dir='./MyDataset',
                    file_list='./MyDataset/train_list.txt',
                    label_list='./MyDataset/labels.txt',
                    transforms=train_transforms)
eval_dataset = pdx.datasets.ImageNet(
                    data_dir='./MyDataset',
                    file_list='./MyDataset/eval_list.txt',
                    label_list='./MyDataset/labels.txt',
                    transforms=eval_transforms)
Next  Previous

目標檢測PascalVOC

資料集檔案夾結構

在PaddleX中,目標檢測支持PascalVOC資料集格式,建議用戶將資料集按照如下方式進行組織,原圖均放在同一目錄,如JPEGImages,標注的同名xml檔案均放在同一目錄,如Annotations,示例如下

MyDataset/ # 目標檢測資料集根目錄
|--JPEGImages/ # 原圖檔案所在目錄
|  |--1.jpg
|  |--2.jpg
|  |--...
|  |--...
|
|--Annotations/ # 標注檔案所在目錄
|  |--1.xml
|  |--2.xml
|  |--...
|  |--...

劃分訓練集驗證集

為了用于訓練,我們需要在MyDataset目錄下準備train_list.txt, val_list.txt和labels.txt三個檔案,分別用于表示訓練集串列,驗證集串列和類別標簽串列,點擊下載目標檢測示例資料集

注:也可使用PaddleX自帶工具,對資料集進行隨機劃分,在資料集按照上面格式組織后,使用如下命令即可快速完成資料集隨機劃分,其中val_value表示驗證集的比例,test_value表示測驗集的比例(可以為0),剩余的比例用于訓練集,

paddlex --split_dataset --format VOC --dataset_dir MyDataset --val_value 0.2 --test_value 0.1
labels.txt

labels.txt用于列出所有類別,類別對應行號表示模型訓練程序中類別的id(行號從0開始計數),例如labels.txt為以下內容

dog
cat
snake

表示該檢測資料集中共有3個目標類別,分別為dog,cat和snake,在模型訓練中dog對應的類別id為0, cat對應1,以此類推

train_list.txt

train_list.txt列出用于訓練時的圖片集合,與其對應的標注檔案,示例如下

JPEGImages/1.jpg Annotations/1.xml
JPEGImages/2.jpg Annotations/2.xml
... ...

其中第一列為原圖相對MyDataset的相對路徑,第二列為標注檔案相對MyDataset的相對路徑

val_list.txt

val_list列出用于驗證時的圖片集成,與其對應的標注檔案,格式與val_list.txt一致

PaddleX資料集加載

示例代碼如下,

import paddlex as pdx
from paddlex.det import transforms

train_transforms = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.Normalize(),
    transforms.ResizeByShort(short_size=800, max_size=1333),
    transforms.Padding(coarsest_stride=32)
])

eval_transforms = transforms.Compose([
    transforms.Normalize(),
    transforms.ResizeByShort(short_size=800, max_size=1333),
    transforms.Padding(coarsest_stride=32),
])

train_dataset = pdx.datasets.VOCDetection(
                        data_dir='./MyDataset',
                        file_list='./MyDataset/train_list.txt',
                        label_list='./MyDataset/labels.txt',
                        transforms=train_transforms)
eval_dataset = pdx.datasets.VOCDetection(
                        data_dir='./MyDataset',
                        file_list='./MyDataset/val_list.txt',
                        label_list='MyDataset/labels.txt',
                        transforms=eval_transforms)
Next  Previous

實體分割MSCOCO

資料集檔案夾結構

在PaddleX中,實體分割支持MSCOCO資料集格式(MSCOCO格式同樣也可以用于目標檢測),建議用戶將資料集按照如下方式進行組織,原圖均放在同一目錄,如JPEGImages,標注檔案(如annotations.json)放在與JPEGImages所在目錄同級目錄下,示例結構如下

MyDataset/ # 實體分割資料集根目錄
|--JPEGImages/ # 原圖檔案所在目錄
|  |--1.jpg
|  |--2.jpg
|  |--...
|  |--...
|
|--annotations.json # 標注檔案所在目錄

劃分訓練集驗證集

在PaddleX中,為了區分訓練集和驗證集,在MyDataset同級目錄,使用不同的json表示資料的劃分,例如train.json和val.json,點擊下載實體分割示例資料集,

注:也可使用PaddleX自帶工具,對資料集進行隨機劃分,在資料集按照上面格式組織后,使用如下命令即可快速完成資料集隨機劃分,其中val_value表示驗證集的比例,test_value表示測驗集的比例(可以為0),剩余的比例用于訓練集,

paddlex --split_dataset --format COCO --dataset_dir MyDataset --val_value 0.2 --test_value 0.1

MSCOCO資料的標注檔案采用json格式,用戶可使用Labelme, 精靈標注助手或EasyData等標注工具進行標注,參見資料標注工具

PaddleX加載資料集

示例代碼如下,

import paddlex as pdx
from paddlex.det import transforms

train_transforms = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.Normalize(),
    transforms.ResizeByShort(short_size=800, max_size=1333),
    transforms.Padding(coarsest_stride=32)
])

eval_transforms = transforms.Compose([
    transforms.Normalize(),
    transforms.ResizeByShort(short_size=800, max_size=1333),
    transforms.Padding(coarsest_stride=32),
])

train_dataset = pdx.dataset.CocoDetection(
                    data_dir='./MyDataset/JPEGImages',
                    ann_file='./MyDataset/train.json',
                    transforms=train_transforms)
eval_dataset = pdx.dataset.CocoDetection(
                    data_dir='./MyDataset/JPEGImages',
                    ann_file='./MyDataset/val.json',
                    transforms=eval_transforms)
Next  Previous

語意分割Seg

資料集檔案夾結構

在PaddleX中,標注檔案為png檔案,建議用戶將資料集按照如下方式進行組織,原圖均放在同一目錄,如JPEGImages,標注的同名png檔案均放在同一目錄,如Annotations,示例如下

MyDataset/ # 語意分割資料集根目錄
|--JPEGImages/ # 原圖檔案所在目錄
|  |--1.jpg
|  |--2.jpg
|  |--...
|  |--...
|
|--Annotations/ # 標注檔案所在目錄
|  |--1.png
|  |--2.png
|  |--...
|  |--...

語意分割的標注影像,如1.png,為單通道影像,像素標注類別需要從0開始遞增(一般0表示background背景), 例如0, 1, 2, 3表示4種類別,標注類別最多255個類別(其中像素值255不參與訓練和評估),

劃分訓練集驗證集

為了用于訓練,我們需要在MyDataset目錄下準備train_list.txt, val_list.txt和labels.txt三個檔案,分別用于表示訓練集串列,驗證集串列和類別標簽串列,點擊下載語意分割示例資料集

注:也可使用PaddleX自帶工具,對資料集進行隨機劃分,在資料集按照上面格式組織后,使用如下命令即可快速完成資料集隨機劃分,其中val_value表示驗證集的比例,test_value表示測驗集的比例(可以為0),剩余的比例用于訓練集,

paddlex --split_dataset --format Seg --dataset_dir MyDataset --val_value 0.2 --test_value 0.1
labels.txt

labels.txt用于列出所有類別,類別對應行號表示模型訓練程序中類別的id(行號從0開始計數),例如labels.txt為以下內容

background
human
car

表示該檢測資料集中共有3個分割類別,分別為background,human和car,在模型訓練中background對應的類別id為0, human對應1,以此類推,如不知具體類別標簽,可直接在labels.txt逐行寫0,1,2…序列即可,

train_list.txt

train_list.txt列出用于訓練時的圖片集合,與其對應的標注檔案,示例如下

JPEGImages/1.jpg Annotations/1.png
JPEGImages/2.jpg Annotations/2.png
... ...

其中第一列為原圖相對MyDataset的相對路徑,第二列為標注檔案相對MyDataset的相對路徑

val_list.txt

val_list列出用于驗證時的圖片集成,與其對應的標注檔案,格式與val_list.txt一致

PaddleX資料集加載

示例代碼如下,

import paddlex as pdx
from paddlex.seg import transforms

train_transforms = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.ResizeRangeScaling(),
    transforms.RandomPaddingCrop(crop_size=512),
    transforms.Normalize()
])

eval_transforms = transforms.Compose([
    transforms.ResizeByLong(long_size=512),
    transforms.Padding(target_size=512),
    transforms.Normalize()
])

train_dataset = pdx.datasets.SegDataset(
                        data_dir='./MyDataset',
                        file_list='./MyDataset/train_list.txt',
                        label_list='./MyDataset/labels.txt',
                        transforms=train_transforms)
eval_dataset = pdx.datasets.SegDataset(
                        data_dir='./MyDataset',
                        file_list='./MyDataset/val_list.txt',
                        label_list='MyDataset/labels.txt',
                        transforms=eval_transforms)

地塊檢測ChangeDet

資料集檔案夾結構

在PaddleX中,標注檔案為png檔案,建議用戶將資料集按照如下方式進行組織,同一地塊不同時期的地貌原圖均放在同一目錄,如JPEGImages,標注的同名png檔案均放在同一目錄,如Annotations,示例如下

MyDataset/ # 語意分割資料集根目錄
|--JPEGImages/ # 原圖檔案所在目錄,包含同一物體前期和后期的圖片
|  |--1_1.jpg
|  |--1_2.jpg
|  |--2_1.jpg
|  |--2_2.jpg
|  |--...
|  |--...
|
|--Annotations/ # 標注檔案所在目錄
|  |--1.png
|  |--2.png
|  |--...
|  |--...

同一地塊不同時期的地貌原圖,如1_1.jpg和1_2.jpg,可以是RGB彩色影像、灰度圖、或tiff格式的多通道影像,語意分割的標注影像,如1.png,為單通道影像,像素標注類別需要從0開始遞增(一般0表示background背景), 例如0, 1, 2, 3表示4種類別,標注類別最多255個類別(其中像素值255不參與訓練和評估),

劃分訓練集驗證集

為了用于訓練,我們需要在MyDataset目錄下準備train_list.txt, val_list.txt和labels.txt三個檔案,分別用于表示訓練集串列,驗證集串列和類別標簽串列,

labels.txt

labels.txt用于列出所有類別,類別對應行號表示模型訓練程序中類別的id(行號從0開始計數),例如labels.txt為以下內容

unchanged
changed

表示該檢測資料集中共有2個分割類別,分別為unchanged和changed,在模型訓練中unchanged對應的類別id為0, changed對應1,以此類推,如不知具體類別標簽,可直接在labels.txt逐行寫0,1,2…序列即可,

train_list.txt

train_list.txt列出用于訓練時的圖片集合,與其對應的標注檔案,示例如下

JPEGImages/1_1.jpg JPEGImages/1_2.jpg Annotations/1.png
JPEGImages/2_1.jpg JPEGImages/2_2.jpg Annotations/2.png
... ...

其中第一列和第二列為原圖相對MyDataset的相對路徑,對應同一地塊不同時期的地貌影像,第三列為標注檔案相對MyDataset的相對路徑

val_list.txt

val_list列出用于驗證時的圖片集成,與其對應的標注檔案,格式與val_list.txt一致

paddle模型訓練與引數調整

模型訓練

影像分類

PaddleX共提供了20+的影像分類模型,可滿足開發者不同場景的需求下的使用,

-Top1精度: 模型在ImageNet資料集上的測驗精度
-預測速度:單張圖片的預測用時(不包括預處理和后處理)
-“-”表示指標暫未更新
請添加圖片描述

開始訓練

將代碼保存到本地后運行(代碼下載鏈接位于上面的表格),代碼會自動下載訓練資料并開始訓練,如保存為mobilenetv3_small_ssld.py,執行如下命令即可開始訓練:

python mobilenetv3_small_ssld.py

目標檢測

PaddleX目前提供了FasterRCNN和YOLOv3兩種檢測結構,多種backbone模型,可滿足開發者不同場景和性能的需求,

-Box MMAP: 模型在COCO資料集上的測驗精度
-預測速度:單張圖片的預測用時(不包括預處理和后處理)
-“-”表示指標暫未更新

請添加圖片描述

開始訓練

將代碼保存到本地后運行(代碼下載鏈接位于上面的表格),代碼會自動下載訓練資料并開始訓練,如保存為yolov3_mobilenetv1.py,執行如下命令即可開始訓練:

python yolov3_mobilenetv1.py

實體分割

PaddleX目前提供了MaskRCNN實體分割模型結構,多種backbone模型,可滿足開發者不同場景和性能的需求,

-Box MMAP/Seg MMAP: 模型在COCO資料集上的測驗精度
-預測速度:單張圖片的預測用時(不包括預處理和后處理)
-“-”表示指標暫未更新
請添加圖片描述

開始訓練

將代碼保存到本地后運行(代碼下載鏈接位于上面表格中),代碼會自動下載訓練資料并開始訓練,如保存為mask_rcnn_r50_fpn.py,執行如下命令即可開始訓練:

python mask_rcnn_r50_fpn.py

語意分割

PaddleX目前提供了DeepLabv3p、UNet、HRNet和FastSCNN四種語意分割結構,多種backbone模型,可滿足開發者不同場景和性能的需求,

-mIoU: 模型在CityScape資料集上的測驗精度
-預測速度:單張圖片的預測用時(不包括預處理和后處理)
-“-”表示指標暫未更新

請添加圖片描述
開始訓練

將代碼保存到本地后運行(代碼下載鏈接位于上面的表格中),代碼會自動下載訓練資料并開始訓練,如保存為deeplabv3p_mobilenetv2_x0.25.py,執行如下命令即可開始訓練:

python deeplabv3p_mobilenetv2_x0.25.py

加載模型預測

影像分類

加載模型預測

PaddleX可以使用paddlex.load_model介面加載模型(包括訓練程序中保存的模型,匯出的部署模型,量化模型以及裁剪的模型)進行預測,同時PaddleX中也內置了一系列的可視化工具函式,幫助用戶方便地檢查模型的效果,

注意:使用paddlex.load_model介面加載僅用于模型預測,如需要在此模型基礎上繼續訓練,可以將該模型作為預訓練模型進行訓練,具體做法是在訓練代碼中,將train函式中的pretrain_weights引數指定為預訓練模型路徑,

影像分類

點擊下載如下示例代碼中的模型

import paddlex as pdx
test_jpg = 'mobilenetv3_small_ssld_imagenet/test.jpg'
model = pdx.load_model('mobilenetv3_small_ssld_imagenet')
result = model.predict(test_jpg)
print("Predict Result: ", result)

結果輸出如下:

Predict Result: [{'category_id': 549, 'category': 'envelope', 'score': 0.29062933}]

測驗圖片如下:
在這里插入圖片描述

目標檢測

點擊下載如下示例代碼中模型

import paddlex as pdx
test_jpg = 'yolov3_mobilenetv1_coco/test.jpg'
model = pdx.load_model('yolov3_mobilenetv1_coco')

#predict介面并未過濾低置信度識別結果,用戶根據需求按score值進行過濾
result = model.predict(test_jpg)

#可視化結果存盤在./visualized_test.jpg, 見下圖
pdx.det.visualize(test_jpg, result, threshold=0.3, save_dir='./')

在這里插入圖片描述

實體分割

實體分割

點擊下載如下示例代碼中模型

import paddlex as pdx
test_jpg = 'mask_r50_fpn_coco/test.jpg'
model = pdx.load_model('mask_r50_fpn_coco')

# predict介面并未過濾低置信度識別結果,用戶根據需求按score值進行過濾
result = model.predict(test_jpg)

# 可視化結果存盤在./visualized_test.jpg, 見下圖
pdx.det.visualize(test_jpg, result, threshold=0.5, save_dir='./')

在這里插入圖片描述

語意分割

語意分割

點擊下載如下示例代碼中模型

import paddlex as pdx
test_jpg = './deeplabv3p_mobilenetv2_voc/test.jpg'
model = pdx.load_model('./deeplabv3p_mobilenetv2_voc')
result = model.predict(test_jpg)
# 可視化結果存盤在./visualized_test.jpg,見下圖右(左圖為原圖)
pdx.seg.visualize(test_jpg, result, weight=0.0, save_dir='./')

在上述示例代碼中,通過呼叫paddlex.seg.visualize可以對語意分割的預測結果進行可視化,可視化的結果保存在save_dir下,見下圖,其中weight引數用于調整預測結果和原圖結果融合展現時的權重,0.0時只展示預測結果mask的可視化,1.0時只展示原圖可視化,

訓練引數調整

PaddleX所有訓練介面中,內置的引數均為根據單GPU卡相應batch_size下的較優引數,用戶在自己的資料上訓練模型,涉及到引數調整時,如無太多引數調優經驗,則可參考如下方式

1.num_epochs的調整

num_epochs是模型訓練迭代的總輪數(模型對訓練集全部樣本過一遍即為一個epoch),用戶可以設定較大的數值,根據模型迭代程序在驗證集上的指標表現,來判斷模型是否收斂,進而提前終止訓練,此外也可以使用train介面中的early_stop策略,模型在訓練程序會自動判斷模型是否收斂自動中止,

2.batch_size和learning_rate

Batch Size指模型在訓練程序中,前向計算一次(即為一個step)所用到的樣本數量
如若使用多卡訓練, batch_size會均分到各張卡上(因此需要讓batch size整除卡數)
Batch Size跟機器的顯存/記憶體高度相關,batch_size越高,所消耗的顯存/記憶體就越高
PaddleX在各個train介面中均配置了默認的batch size(默認針對單GPU卡),如若訓練時提示GPU顯存不足,則相應調低BatchSize,如若GPU顯存高或使用多張GPU卡時,可相應調高BatchSize,
如若用戶調整batch size,則也注意需要對應調整其它引數,特別是train介面中默認的learning_rate值,如在YOLOv3模型中,默認train_batch_size為8,learning_rate為0.000125,當用戶將模型在2卡機器上訓練時,可以將train_batch_size調整為16, 那么同時learning_rate也可以對應調整為0.000125 * 2 = 0.00025
3.warmup_steps和warmup_start_lr

在訓練模型時,一般都會使用預訓練模型,例如檢測模型在訓練時使用backbone在ImageNet資料集上的預訓練權重,但由于在自行訓練時,自己的資料與ImageNet資料集存在較大的差異,可能會一開始由于梯度過大使得訓練出現問題,這種情況下可以在剛開始訓練時,讓學習率以一個較小的值,慢慢增長到設定的學習率,warmup_steps和warmup_start_lr就是起到這個作用,模型開始訓練時,學習率會從warmup_start_lr開始,在warmup_steps個batch資料迭代后線性增長到設定的學習率,

例如YOLOv3的train介面,默認train_batch_size為8,learning_rate為0.000125, warmup_steps為1000, warmup_start_lr為0.0;在此引數配置下表示,模型在啟動訓練后,在前1000個step(每個step使用一個batch的資料,即8個樣本)內,學習率會從0.0開始線性增長到設定的0.000125,
4.lr_decay_epochs和lr_decay_gamma

lr_decay_epochs用于讓學習率在模型訓練后期逐步衰減,它一般是一個list,如[6, 8, 10],表示學習率在第6個epoch時衰減一次,第8個epoch時再衰減一次,第10個epoch時再衰減一次,每次學習率衰減為之前的學習率*lr_decay_gamma,

例如YOLOv3的train介面,默認num_epochs為270,learning_rate為0.000125, lr_decay_epochs為[213, 240],lr_decay_gamma為0.1;在此引數配置下表示,模型在啟動訓練后,在前213個epoch中,訓練時使用的學習率為0.000125,在第213至240個epoch之間,訓練使用的學習率為0.000125x0.1=0.0000125,在240個epoch之后,使用的學習率為0.000125x0.1x0.1=0.00000125
5.引數設定時的約束

根據上述幾個引數,可以了解到學習率的變化分為WarmUp熱身階段和Decay衰減階段,

Wamup熱身階段:隨著訓練迭代,學習率從較低的值逐漸線性增長至設定的值,以step為單位
Decay衰減階段:隨著訓練迭代,學習率逐步衰減,如每次衰減為之前的0.1, 以epoch為單位
step與epoch的關系:1個epoch由多個step組成,例如訓練樣本有800張影像,train_batch_size為8, 那么每個epoch都要完整用這800張圖片訓一次模型,而每個epoch總共包含800//8即100個step
在PaddleX中,約束warmup必須在Decay之前結束,因此各引數設定需要滿足下面條件

warmup_steps <= lr_decay_epochs[0] * num_steps_each_epoch

其中num_steps_each_epoch計算方式如下,

num_steps_each_eposh = num_samples_in_train_dataset // train_batch_size

因此,如若你在啟動訓練時,被提示warmup_steps should be less than…時,即表示需要根據上述公式調整你的引數啦,可以調整lr_decay_epochs或者是warmup_steps,

6.如何使用多GPU卡進行訓練

在import paddlex前配置環境變數,代碼如下

import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0' # 使用0號GPU卡進行訓練
# 注意paddle或paddlex都需要在設定環境變數后再import
import paddlex as pdx
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '' # 不使用GPU,使用CPU進行訓練
import paddlex as pdx
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '0,1,3' # 同時使用第0、1、3號GPU卡進行訓練
import paddlex as pdx


模型保存

訓練程序保存
PaddleX在模型訓練程序中,根據train函式介面中的save_interval_epoch引數設定,每間隔相應輪數保存一次模型,模型目錄中包含了model.pdparams, model.yml等檔案,
在訓練程序中保存的模型,可用于作為pretrain_weights繼續訓練模型,也可使用paddlex.load_model介面加載測驗模型的預測和評估等,

部署模型匯出
在前面提到的訓練中保存的模型,如若要用于部署(部署可參閱PaddleX檔案中的模型多端部署章節),需匯出為部署的模型格式,部署的模型目錄中包含__model__,params__和model.yml三個檔案,
模型部署在Python層面,可以使用基于高性能預測庫的python介面paddlex.deploy.Predictor,也可使用paddlex.load_model介面,
【總結】如若模型目錄中包含model.pdparams,那說明模型是訓練程序中保存的,部署時需要進行匯出;部署的模型目錄中需包含__model
,__params__和model.yml三個檔案,

模型部署檔案說明
model:保存了模型的網路結構資訊
params: 保存了模型網路中的引數權重
model.yml:在PaddleX中,將模型的預處理,后處理,以及類別相關資訊均存盤在此檔案中

模型匯出為ONNX模型
PaddleX作為開放開源的套件,其中的大部分模型均支持匯出為ONNX協議,滿足開發者多樣性的需求,
需要注意的是ONNX存在多個OpSet版本,下表為PaddleX各模型支持匯出的ONNX協議版本,
請添加圖片描述

模型壓縮優化

模型裁剪

模型裁剪可以更好地滿足在端側、移動端上部署場景下的性能需求,可以有效得降低模型的體積,以及計算量,加速預測性能,PaddleX集成了PaddleSlim的基于敏感度的通道裁剪演算法,用戶可以在PaddleX的訓練代碼里輕松使用起來,

在本檔案中展示了分類模型的裁剪程序,檔案中代碼以及更多其它模型的的裁剪代碼可在Github中的tutorials/slim/prune目錄獲取,

使用方法

模型裁剪相對比我們普通訓練一個模型,步驟會多出兩步

1.采用正常的方式訓練一個模型
2.對模型的引數進行敏感度分析
3.根據第2步得到的敏感度資訊,對模型進行裁剪,并以第1步訓練好的模型作為預訓練權重,繼續進行訓練
具體我們以影像分類模型MobileNetV2為例,本示例中所有代碼均可在Github的[tutorials/slim/prune/image_classification]中獲得,

第一步 正常訓練模型

此步驟中采用正常的代碼進行模型訓練,在獲取本示例代碼后,直接執行如下命令即可

python mobilenetv2_train.py

在訓練完成后,我們以output/mobilenetv2/best_model保存的模型,繼續接下來的步驟

第二步 引數敏感度分析

此步驟中,我們需要加載第一步訓練保存的模型,并通過不斷地遍歷引數,分析各引數裁剪后在驗證資料集上的精度損失,以此判斷各引數的敏感度,敏感度分析的代碼很簡單, 用戶可直接查看params_analysis.py,在命令列終端執行如下命令開始引數分析,

python params_analysis.py

在此步驟中,我們會得到保存的mobilenetv2.sensi.data檔案,這個檔案保存了模型中每個引數的敏感度,在后續的裁剪訓練中,會根據此檔案中保存的資訊,對各個引數進行裁剪,同時,我們也可以對這個檔案進行可視化分析,判斷eval_metric_loss的大小設定與模型被裁剪比例的關系,(eval_metric_loss的說明見第三步)

模型裁剪比例可視化分析代碼見slim_visualize.py,執行如下命令即可

python slim_visualize.py

可視化結果如下,該圖表明,當我們將eval_metric_loss設為0.05時,模型將被裁剪掉65%;將eval_metric_loss設為0.10,模型將被裁剪掉68.0%,因此在實際使用時,我們可以根據自己的需求,去設定eval_metric_loss控制裁剪比例,

第三步 模型裁剪訓練

在前兩步,我們得到了正常訓練保存的模型output/mobilenetv2/best_model和基于該保存模型得到的引數敏感度資訊檔案mobilenetv2.sensi.data,接下來則是進行模型裁剪訓練,模型裁剪訓練的代碼第第一步基本一致,唯一區別在最后的train函式中,我們修改了pretrain_weights,save_dir,sensitivities_file和eval_metric_loss四個引數,如下所示

model.train(
	num_epoch=10,
	train_dataset=train_dataset,
	train_batch_size=32,
	eval_dataset=eval_dataset,
	lr_decay_epochs=[4,6,8],
	learning_rate=0.025,
	pretrain_weights='output/mobilenetv2/best_model',
	save_dir='output/mobilenetv2_prune',
	sensitivities_file='./mobilenetv2.sensi.data',
	eval_metric_loss=0.05,
	use_vdl=True)

具體代碼見tutorials/slim/prune/image_classification/mobilenetv2_prune_train.py,執行如下命令即可

python mobilenetv2_prune_train.py
其中修改的4個引數函式如下

1、pretrain_weights: 預訓練權重,在裁剪訓練中,將其指定為第一步正常訓練得到的模型路徑
2、save_dir: 裁剪訓練程序中,模型保存的新路徑
3、sensitivities_file: 第二步中分析得到的各引數敏感度資訊檔案
4、請添加圖片描述
eval_metric_loss: 可用于控制模型最終被裁剪的比例,見第二步中的可視化說明
裁剪效果

在本示例的資料集上,經過裁剪訓練后,模型的效果對比如下,其中預測速度不包括影像的預處理和結果的后處理,從表中可以看到,對于本示例中的簡單資料集,模型裁剪掉68%后,模型準確度沒有降低,在CPU的單張圖片預測用時減少了37%

模型量化

模型量化將模型的計算從浮點型轉為整型,從而加速模型的預測計算速度,在移動端/邊緣端設備上降低模型的體積,

注:量化后的模型,通過PaddleLite轉換為PaddleLite部署的模型格式后,模型體積將會大幅壓縮,如若量化后的模型仍是以服務端本地部署格式(檔案包括__model__和__params__),那么模型的檔案大小是無法呈現引數變化情況的,

使用方法

PaddleX中已經將量化功能作為模型匯出的一個API,代碼使用方式如下,本示例代碼和模型資料均可通過GitHub專案上代碼tutorials/slim/quant/image_classification獲取得到

import paddlex as pdx
model = pdx.load_model('mobilenetv2_vegetables')
# 加載資料集用于量化
dataset = pdx.datasets.ImageNet(
                data_dir='vegetables_cls',
                file_list='vegetables_cls/train_list.txt',
                label_list='vegetables_cls/labels.txt',
                transforms=model.test_transforms)

# 開始量化
pdx.slim.export_quant_model(model, dataset,
			  batch_size=4,
			  batch_num=5,
	                  save_dir='./quant_mobilenet',
	                  cache_dir='./tmp')
	                  

在獲取本示例代碼后,執行如下命令即可完成量化和PaddleLite的模型匯出

# 將mobilenetv2模型量化保存
python mobilenetv2_quant.py
# 將量化后的模型匯出為PaddleLite部署格式
python paddlelite_export.py

量化效果

在本示例中,我們可以看到模型量化后的服務端部署模型格式server_mobilenet和quant_mobilenet兩個目錄中,模型引數大小并無變化, 但在使用PaddleLite匯出后,mobilenetv2.nb和mobilenetv2_quant.nb大小分別為8.8M, 2.7M,壓縮至原來的31%,

部署模型匯出

在服務端部署模型時需要將訓練程序中保存的模型匯出為inference格式模型,匯出的inference格式模型包括__model__、__params__和model.yml三個檔案,分別表示模型的網路結構、模型權重和模型的組態檔(包括資料預處理引數等),

檢查你的模型檔案夾,如果里面是model.pdparams, model.pdmodel和model.yml3個檔案時,那么就需要按照下面流程進行模型匯出
在安裝完PaddleX后,在命令列終端使用如下命令將模型匯出,可直接下載小度熊分揀模型來測驗本檔案的流程xiaoduxiong_epoch_12.tar.gz,

paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./inference_model

請添加圖片描述

使用TensorRT預測時,需固定模型的輸入大小,通過–fixed_input_shape來制定輸入大小[w,h],

注意:

1、分類模型的固定輸入大小請保持與訓練時的輸入大小一致;
2、檢測模型模型中YOLO系列請保存w與h一致,且為32的倍數大小;3、RCNN類無此限制,按需設定即可指定[w,h]時,w和h中間逗號隔開,不允許存在空格等其他字符,
4、需要注意的,w,h設得越大,模型在預測程序中所需要的耗時和記憶體/顯存占用越高;設得太小,會影響模型精度

paddlex --export_inference --model_dir=./xiaoduxiong_epoch_12 --save_dir=./inference_model --fixed_input_shape=[640,960]

飛槳實體演示

人像分割模型

本教程基于PaddleX核心分割模型實作人像分割,開放預訓練模型和測驗資料、支持視頻流人像分割、提供模型Fine-tune到Paddle Lite移動端及Nvidia Jeston嵌入式設備部署的全流程應用指南,

預訓練模型和測驗資料

預訓練模型

本案例開放了兩個在大規模人像資料集上訓練好的模型,以滿足服務器端場景和移動端場景的需求,使用這些模型可以快速體驗視頻流人像分割,也可以部署到移動端或嵌入式設備進行實時人像分割,也可以用于完成模型Fine-tuning,

請添加圖片描述
1、Checkpoint Parameter為模型權重,用于Fine-tuning場景,包含__params__模型引數和model.yaml基礎的模型配置資訊,
2、Inference Model和Quant Inference Model為預測部署模型,包含__model__計算圖結構、__params__模型引數和model.yaml基礎的模型配置資訊,
其中Inference Model適用于服務端的CPU和GPU預測部署,Qunat 3、3、Inference Model為量化版本,適用于通過Paddle Lite進行移動端等端側設備部署,

關于預測鋸齒問題

在訓練完模型后,可能會遇到預測出來結果存在『鋸齒』的問題,這個可能存在的原因是由于模型在預測程序中,經歷了原圖縮放再放大的程序,如下流程所示,

原圖輸入 -> 預處理transforms將影像縮放至目標大小 -> Paddle模型預測 -> 預測結果放大至原圖大小

對于這種原因導致的問題,可以手動修改模型中的model.yml檔案,將預處理中的目標大小調整到更高優化此問題,如在本檔案中提供的人像分割server端模型中model.yml檔案內容,修改target_size至1024*1024(這樣也會帶來模型預測所需的資源更多,預測速度更慢)

Model: DeepLabv3p
Transforms:
- Resize:
    interp: LINEAR
    target_size:
    - 512
    - 512

修改為

Model: DeepLabv3p
Transforms:
- Resize:
    interp: LINEAR
    target_size:
    - 1024
    - 1024

預訓練模型的存盤大小和推理時長如下所示,其中移動端模型的運行環境為cpu:驍龍855,記憶體:6GB,圖片大小:192*192
請添加圖片描述

執行以下腳本下載全部的預訓練模型:

~下載PaddleX原始碼:

git clone https://github.com/PaddlePaddle/PaddleX
cd PaddleX
git checkout release/1.3

~下載預訓練模型的代碼位于PaddleX/examples/human_segmentation,進入該目錄:

cd PaddleX/examples/human_segmentation

~執行下載

python pretrain_weights/download_pretrain_weights.py

測驗資料

supervise.ly發布了人像分割資料集Supervisely Persons, 本案例從中隨機抽取一小部分資料并轉化成PaddleX可直接加載的資料格式,運行以下代碼可下載該資料、以及手機前置攝像頭拍攝的人像測驗視頻video_test.mp4.

下載測驗資料的代碼位于PaddleX/xamples/human_segmentation,進入該目錄并執行下載:

python data/download_data.py

快速體驗視頻流人像分割

前置依賴

PaddlePaddle >= 1.8.0
Python >= 3.5
PaddleX >= 1.0.0
安裝的相關問題參考PaddleX安裝

下載PaddleX原始碼:

git clone https://github.com/PaddlePaddle/PaddleX
cd PaddleX
git checkout release/1.3

視頻流人像分割和背景替換的執行檔案均位于PaddleX/examples/human_segmentation,進入該目錄:

cd PaddleX/examples/human_segmentation

光流跟蹤輔助的視頻流人像分割

本案例將DIS(Dense Inverse Search-basedmethod)光流跟蹤演算法的預測結果與PaddleX的分割結果進行融合,以此改善視頻流人像分割的效果,運行以下代碼進行體驗,以下代碼位于PaddleX/xamples/human_segmentation:

通過電腦攝像頭進行實時分割處理

python video_infer.py --model_dir pretrain_weights/humanseg_mobile_inference

對離線人像視頻進行分割處理

python video_infer.py --model_dir pretrain_weights/humanseg_mobile_inference --video_path data/video_test.mp4

視頻分割結果如下所示:
請添加圖片描述

人像背景替換

本案例還實作了人像背景替換功能,根據所選背景對人像的背景畫面進行替換,背景可以是一張圖片,也可以是一段視頻,人像背景替換的代碼位于PaddleX/xamples/human_segmentation,進入該目錄并執行:

通過電腦攝像頭進行實時背景替換處理, 通過’–background_video_path’傳入背景視頻

python bg_replace.py --model_dir pretrain_weights/humanseg_mobile_inference --background_image_path data/background.jpg

對人像視頻進行背景替換處理, 通過’–background_video_path’傳入背景視頻

python bg_replace.py --model_dir pretrain_weights/humanseg_mobile_inference --video_path data/video_test.mp4 --background_image_path data/background.jpg

對單張影像進行背景替換

python bg_replace.py --model_dir pretrain_weights/humanseg_mobile_inference --image_path data/human_image.jpg --background_image_path data/background.jpg

背景替換結果如下:

請添加圖片描述
注意:

視頻分割處理時間需要幾分鐘,請耐心等待,
提供的模型適用于手機攝像頭豎屏拍攝場景,寬屏效果會略差一些,

模型Fine-tune

前置依賴

PaddlePaddle >= 1.8.0
Python >= 3.5
PaddleX >= 1.0.0
安裝的相關問題參考PaddleX安裝

下載PaddleX原始碼:

git clone https://github.com/PaddlePaddle/PaddleX
cd PaddleX
git checkout release/1.3

人像分割訓練、評估、預測、模型匯出、離線量化的執行檔案均位于PaddleX/examples/human_segmentation,進入該目錄:

cd PaddleX/examples/human_segmentation

模型訓練

使用下述命令進行基于預訓練模型的模型訓練,請確保選用的模型結構model_type與模型引數pretrain_weights匹配,如果不需要本案例提供的測驗資料,可更換資料、選擇合適的模型并調整訓練引數,

# 指定GPU卡號(以0號卡為例)
export CUDA_VISIBLE_DEVICES=0
# 若不使用GPU,則將CUDA_VISIBLE_DEVICES指定為空
# export CUDA_VISIBLE_DEVICES=
python train.py --model_type HumanSegMobile \
--save_dir output/ \
--data_dir data/mini_supervisely \
--train_list data/mini_supervisely/train.txt \
--val_list data/mini_supervisely/val.txt \
--pretrain_weights pretrain_weights/humanseg_mobile_params \
--batch_size 8 \
--learning_rate 0.001 \
--num_epochs 10 \
--image_shape 192 192

其中引數含義如下:

–model_type: 模型型別,可選項為:HumanSegServer和HumanSegMobile
–save_dir: 模型保存路徑
–data_dir: 資料集路徑
–train_list: 訓練集串列路徑
–val_list: 驗證集串列路徑
–pretrain_weights: 預訓練模型路徑
–batch_size: 批大小
–learning_rate: 初始學習率
–num_epochs: 訓練輪數
–image_shape: 網路輸入影像大小(w, h)
更多命令列幫助可運行下述命令進行查看:

python train.py --help

注意:可以通過更換–model_type變數與對應的–pretrain_weights使用不同的模型快速嘗試,

評估

使用下述命令對模型在驗證集上的精度進行評估:

python eval.py --model_dir output/best_model \
--data_dir data/mini_supervisely \
--val_list data/mini_supervisely/val.txt \
--image_shape 192 192

其中引數含義如下:

–model_dir: 模型路徑
–data_dir: 資料集路徑
–val_list: 驗證集串列路徑
–image_shape: 網路輸入影像大小(w, h)

預測

使用下述命令對測驗集進行預測,預測可視化結果默認保存在./output/result/檔案夾中,

python infer.py --model_dir output/best_model \
--data_dir data/mini_supervisely \
--test_list data/mini_supervisely/test.txt \
--save_dir output/result \
--image_shape 192 192

其中引數含義如下:

–model_dir: 模型路徑
–data_dir: 資料集路徑
–test_list: 測驗集串列路徑
–image_shape: 網路輸入影像大小(w, h)

模型匯出

在服務端部署的模型需要首先將模型匯出為inference格式模型,匯出的模型將包括__model__、__params__和model.yml三個文名,分別為模型的網路結構,模型權重和模型的組態檔(包括資料預處理引數等等),在安裝完PaddleX后,在命令列終端使用如下命令完成模型匯出:

paddlex --export_inference --model_dir output/best_model \
--save_dir output/export

其中引數含義如下:

–model_dir: 模型路徑
–save_dir: 匯出模型保存路徑

RGB遙感影像分割

本案例基于PaddleX實作遙感影像分割,提供滑動視窗預測方式,以避免在直接對大尺寸圖片進行預測時顯存不足的發生,此外,滑動視窗之間的重疊程度可配置,以此消除最終預測結果中各視窗拼接處的裂痕感,

前置依賴

Paddle paddle >= 1.8.4
Python >= 3.5
PaddleX >= 1.1.4
安裝的相關問題參考PaddleX安裝

下載PaddleX原始碼:

git clone https://github.com/PaddlePaddle/PaddleX
cd PaddleX
git checkout release/1.3

該案例所有腳本均位于PaddleX/examples/remote_sensing/,進入該目錄:

cd PaddleX/examples/remote_sensing/

資料準備

本案例使用2015 CCF大資料比賽提供的高清遙感影像,包含5張帶標注的RGB影像,影像尺寸最大有7969?×?7939、最小有4011?×?2470,該資料集共標注了5類物體,分別是背景(標記為0)、植被(標記為1)、道路(標記為2)、建筑(標記為3)、水體(標記為4),

本案例將前4張圖片劃分入訓練集,第5張圖片作為驗證集,為增加訓練時的批量大小,以滑動視窗為(1024,1024)、步長為(512, 512)對前4張圖片進行切分,加上原本的4張大尺寸圖片,訓練集一共有688張圖片,在訓練程序中直接對大圖片進行驗證會導致顯存不足,為避免此類問題的出現,針對驗證集以滑動視窗為(769, 769)、步長為(769,769)對第5張圖片進行切分,得到40張子圖片,

運行以下腳本,下載原始資料集,并完成資料集的切分:

python prepare_data.py

模型訓練

分割模型選擇Backbone為MobileNetv3_large_ssld的Deeplabv3模型,該模型兼備高性能高精度的優點,運行以下腳本,進行模型訓練:

python train.py

也可以跳過模型訓練步驟,直接下載預訓練模型進行后續的模型預測和評估:

wget https://bj.bcebos.com/paddlex/examples/remote_sensing/models/ccf_remote_model.tar.gz
tar -xvf ccf_remote_model.tar.gz

模型預測

直接對大尺寸圖片進行預測會導致顯存不足,為避免此類問題的出現,本案例提供了滑動視窗預測介面,支持有重疊和無重疊兩種方式,

無重疊的滑動視窗預測
在輸入圖片上以固定大小的視窗滑動,分別對每個視窗下的影像進行預測,最后將各視窗的預測結果拼接成輸入圖片的預測結果,由于每個視窗邊緣部分的預測效果會比中間部分的差,因此每個視窗拼接處可能會有明顯的裂痕感,

該預測方式的API介面詳見overlap_tile_predict,使用時需要把引數pad_size設定為[0, 0],

有重疊的滑動視窗預測
在Unet論文中,作者提出一種有重疊的滑動視窗預測策略(Overlap-tile strategy)來消除拼接處的裂痕感,對各滑動視窗預測時,會向四周擴展一定的面積,對擴展后的視窗進行預測,例如下圖中的藍色部磁區域,到拼接時只取各視窗中間部分的預測結果,例如下圖中的黃色部磁區域,位于輸入影像邊緣處的視窗,其擴展面積下的像素則通過將邊緣部分像素鏡像填補得到,

請添加圖片描述

相比無重疊的滑動視窗預測,有重疊的滑動視窗預測策略將本案例的模型精度miou從80.58%提升至81.52%,并且將預測可視化結果中裂痕感顯著消除,可見下圖中兩種預測方式的效果對比,

請添加圖片描述

運行以下腳本使用有重疊的滑動視窗進行預測:

python predict.py

模型評估

在訓練程序中,每隔10個迭代輪數會評估一次模型在驗證集的精度,由于已事先將原始大尺寸圖片切分成小塊,此時相當于使用無重疊的大圖切小圖預測方式,最優模型精度miou為80.58%,運行以下腳本,將采用有重疊的大圖切小圖的預測方式,重新評估原始大尺寸圖片的模型精度,此時miou為81.52%,

python eval.py

多通道遙感影像分割

遙感影像分割是影像分割領域中的重要應用場景,廣泛應用于土地測繪、環境監測、城市建設等領域,遙感影像分割的目標多種多樣,有諸如積雪、農作物、道路、建筑、水源等地物目標,也有例如云層的空中目標,

本案例基于PaddleX實作多通道遙感影像分割,涵蓋資料分析、模型訓練、模型預測等流程,旨在幫助用戶利用深度學習技術解決多通道遙感影像分割問題,

前置依賴

Paddle paddle >= 1.8.4
Python >= 3.5
PaddleX >= 1.1.4
安裝的相關問題參考PaddleX安裝

另外還需安裝gdal, 使用pip安裝gdal可能出錯,推薦使用conda進行安裝:

conda install gdal
下載PaddleX原始碼:

git clone https://github.com/PaddlePaddle/PaddleX
cd PaddleX
git checkout release/1.3

該案例所有腳本均位于PaddleX/examples/channel_remote_sensing/,進入該目錄:

cd PaddleX/examples/channel_remote_sensing/  

資料準備

遙感影像的格式多種多樣,不同傳感器產生的資料格式也可能不同,PaddleX現已兼容以下4種格式圖片讀取:

tif
png
img
npy
標注圖要求必須為單通道的png格式影像,像素值即為對應的類別,像素標注類別需要從0開始遞增,例如0,1,2,3表示有4種類別,255用于指定不參與訓練和評估的像素,標注類別最多為256類,

本案例使用L8 SPARCS公開資料集進行云雪分割,該資料集包含80張衛星影像,涵蓋10個波段,原始標注圖片包含7個類別,分別是cloud, cloud shadow, shadow over water, snow/ice, water, land和flooded,由于flooded和shadow over water2個類別占比僅為1.8%和0.24%,我們將其進行合并,flooded歸為land,shadow over water歸為shadow,合并后標注包含5個類別,

數值、類別、顏色對應表:

請添加圖片描述

請添加圖片描述

執行以下命令下載并解壓經過類別合并后的資料集:

mkdir dataset && cd dataset
wget https://paddleseg.bj.bcebos.com/dataset/remote_sensing_seg.zip
unzip remote_sensing_seg.zip
cd ..

其中data目錄存放遙感影像,data_vis目錄存放彩色合成預覽圖,mask目錄存放標注圖,

資料分析

遙感影像往往由許多波段組成,不同波段資料分布可能大相徑庭,例如可見光波段和熱紅外波段分布十分不同,為了更深入了解資料的分布來優化模型訓練效果,需要對資料進行分析,

參考檔案資料分析對訓練集進行統計分析,確定影像像素值的截斷范圍,并統計截斷后的均值和方差,

模型訓練

本案例選擇UNet語意分割模型完成云雪分割,運行以下步驟完成模型訓練,模型的最優精度miou為78.38%,

設定GPU卡號
export CUDA_VISIBLE_DEVICES=0
運行以下腳本開始訓練
python train.py --data_dir dataset/remote_sensing_seg \
--train_file_list dataset/remote_sensing_seg/train.txt \
--eval_file_list dataset/remote_sensing_seg/val.txt \
--label_list dataset/remote_sensing_seg/labels.txt \
--save_dir saved_model/remote_sensing_unet \
--num_classes 5 \
--channel 10 \
--lr 0.01 \
--clip_min_value 7172 6561 5777 5103 4291 4000 4000 4232 6934 7199 \
--clip_max_value 50000 50000 50000 50000 50000 40000 30000 18000 40000 36000 \
--mean 0.15163569 0.15142828 0.15574491 0.1716084  0.2799778  0.27652043 0.28195933 0.07853807 0.56333154 0.5477584 \
--std  0.09301891 0.09818967 0.09831126 0.1057784  0.10842132 0.11062996 0.12791838 0.02637859 0.0675052  0.06168227 \
--num_epochs 500 \
--train_batch_size 3

也可以跳過模型訓練步驟,下載預訓練模型直接進行模型預測:

wget https://bj.bcebos.com/paddlex/examples/multi-channel_remote_sensing/models/l8sparcs_remote_model.tar.gz
tar -xvf l8sparcs_remote_model.tar.gz

模型預測

運行以下腳本,對遙感影像進行預測并可視化預測結果,相應地也將對應的標注檔案進行可視化,以比較預測效果,

export CUDA_VISIBLE_DEVICES=0
python predict.py

可視化效果如下所示:
請添加圖片描述

數值、類別、顏色對應表:

請添加圖片描述

地塊變化檢測

本案例基于PaddleX實作地塊變化檢測,將同一地塊的前期與后期兩張圖片進行拼接,而后輸入給語意分割網路進行變化區域的預測,在訓練階段,使用隨機縮放尺寸、旋轉、裁剪、顏色空間擾動、水平翻轉、豎直翻轉多種資料增強策略,在驗證和預測階段,使用滑動視窗預測方式,以避免在直接對大尺寸圖片進行預測時顯存不足的發生,

前置依賴

Paddle paddle >= 1.8.4
Python >= 3.5
PaddleX >= 1.2.2
安裝的相關問題參考PaddleX安裝

下載PaddleX原始碼:

git clone https://github.com/PaddlePaddle/PaddleX
cd PaddleX
git checkout release/1.3

該案例所有腳本均位于PaddleX/examples/change_detection/,進入該目錄:

cd PaddleX/examples/change_detection/

資料準備

本案例使用Daifeng Peng等人開放的Google Dataset, 該資料集涵蓋了廣州部磁區域于2006年至2019年期間的房屋建筑物的變化情況,用于分析城市化行程,一共有20對高清圖片,圖片有紅、綠、藍三個波段,空間解析度為0.55m,圖片大小有1006x1168至4936x5224不等,

由于Google Dataset僅標注了房屋建筑物是否發生變化,因此本案例是二分類變化檢測任務,可根據實際需求修改類別數量即可拓展為多分類變化檢測,

本案例將15張圖片劃分入訓練集,5張圖片劃分入驗證集,由于圖片尺寸過大,直接訓練會發生顯存不足的問題,因此以滑動視窗為(1024,1024)、步長為(512, 512)對訓練圖片進行切分,切分后的訓練集一共有743張圖片,以滑動視窗為(769, 769)、步長為(769,769)對驗證圖片進行切分,得到108張子圖片,用于訓練程序中的驗證,

運行以下腳本,下載原始資料集,并完成資料集的切分:

python prepare_data.py

切分后的資料示意如下:

請添加圖片描述

注意:

tiff格式的圖片PaddleX統一使用gdal庫讀取,gdal安裝可參考gdal檔案,若資料是tiff格式的三通道RGB影像,如果不想安裝gdal,需自行轉成jpeg、bmp、png格式圖片,
label檔案需為單通道的png格式圖片,且標注從0開始計數,標注255表示該類別不參與計算,例如本案例中,0表示unchanged類,1表示changed類,

模型訓練

由于資料量較小,分割模型選擇較好兼顧淺層細節資訊和深層語意資訊的UNet模型,運行以下腳本,進行模型訓練:

python train.py

本案例使用0,1,2,3號GPU卡完成訓練,可根據實際顯存大小更改訓練腳本中的GPU卡數量和train_batch_size的設定值,按train_batch_size的調整比例相應地調整學習率learning_rate,例如train_batch_size由16減少至8時,learning_rate則由0.1減少至0.05,此外,不同資料集上能獲得最優精度所對應learning_rate可能有所不同,可以嘗試調整,

也可以跳過模型訓練步驟,直接下載預訓練模型進行后續的模型評估和預測:

wget https://bj.bcebos.com/paddlex/examples/change_detection/models/google_change_det_model.tar.gz
tar -xvf google_change_det_model.tar.gz

模型評估

在訓練程序中,每隔10個迭代輪數會評估一次模型在驗證集的精度,由于已事先將原始大尺寸圖片切分成小塊,相當于使用無重疊的滑動視窗預測方式,最優模型精度:

請添加圖片描述

category分別對應unchanged和changed兩類,

運行以下腳本,將采用有重疊的滑動視窗預測方式,重新評估原始大尺寸圖片的模型精度,此時模型精度為:

請添加圖片描述

python eval.py

滑動視窗預測介面說明詳見API說明,已有的使用場景可參考RGB遙感分割案例,可根據實際顯存大小修改評估腳本中tile_size,pad_size和batch_size,

模型預測

執行以下腳本,使用有重疊的滑動預測視窗對驗證集進行預測,可根據實際顯存大小修改評估腳本中tile_size,pad_size和batch_size,

python predict.py

預測可視化結果如下圖所示:
請添加圖片描述

OpenVINO模型轉換

將Paddle模型轉換為OpenVINO的Inference Engine

1、環境依賴

Paddle2ONNX 0.4
ONNX 1.6.0+
PaddleX 1.3+
OpenVINO 2020.4+

說明:PaddleX安裝請參考PaddleX , OpenVINO安裝請參考OpenVINO,ONNX請安裝1.6.0以上版本否則會出現轉模型錯誤, Paddle2ONNX請安裝0.4版本,
注意:安裝OpenVINO時請務必安裝官網教程初始化OpenVINO運行環境,并安裝相關依賴,否則會出現”No module named mo”等問題

請確保系統已經安裝好上述基本軟體,下面所有示例以作業目錄 /root/projects/演示,

2、匯出inference模型

paddle模型轉openvino之前需要先把paddle模型匯出為inference格式模型,匯出的模型將包括__model__、__params__和model.yml三個檔案名,匯出命令如下

paddlex --export_inference --model_dir=/path/to/paddle_model --save_dir=./inference_model --fixed_input_shape=[w,h]

注意:需要轉OpenVINO模型時,匯出inference模型請務必指定–fixed_input_shape引數來固定模型的輸入大小,且模型的輸入大小需要與訓練時一致, PaddleX客戶端在發布模型時沒有固定輸入大小,因此對于可視化客戶端,請找到任務所在目錄,從里面的output檔案夾找到best_model模型目錄,將此目錄使用如上命令進行固定shape匯出即可,

3、匯出OpenVINO模型

mkdir -p /root/projects
cd /root/projects
git clone https://github.com/PaddlePaddle/PaddleX.git
cd PaddleX
git checkout release/1.3
cd deploy/openvino/python

python converter.py --model_dir /path/to/inference_model --save_dir /path/to/openvino_model --fixed_input_shape [w,h]

轉換成功后會在save_dir下出現后綴名為.xml、.bin、.mapping三個檔案轉換引數說明如下:

請添加圖片描述

paddle- openVINO部署實體

openvino-yolo

物件檢測示例代碼

這個演示是如何在OpenVINO上運行PaddlePaddle YoloV3檢測演算法,
首先如果你想對這些有一個更深入的理解,可以看下下面三個鏈接,

YOLOV3Model Configuration(模型配置):
https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.1/configs/yolov3

PPYOLO Annotation Data(資料):
https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.2/docs/tutorials/config_annotation/ppyolo_r50vd_dcn_1x_coco_annotation.md

PPYOLO Model Configuration:
https://github.com/PaddlePaddle/PaddleDetection/tree/release/2.1/configs/ppyolo

import os, sys, os.path
import numpy as np
import cv2
from openvino.inference_engine import IENetwork, IECore, ExecutableNetwork
from IPython import display
from PIL import Image, ImageDraw
import urllib, shutil, json
import yaml
from yaml.loader import SafeLoader

下載和匯出百度型號- YOLOV3和PPYOLO

這個需要一些時間,要確保按照官網中read me中的安裝說明將PaddleDetection GitHub安裝在openvino-paddlepaddle-demo目錄中,
下面是官網的鏈接
Reference on Baidu Model Exporting: https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.1/deploy/EXPORT_MODEL.md

#Get the YOLOV3
PADDLE_DET_PATH="../../PaddleDetection"
YML_CONFIG="configs/yolov3/yolov3_darknet53_270e_coco.yml"
PRETRAINED="yolov3_darknet53_270e_coco.pdparams"
OUTPUT_DIR="models"
if(not os.path.isfile("models/yolov3_darknet53_270e_coco/model.pdmodel")):
    print("Download and Export Model... This may take a while...")
    ! python $PADDLE_DET_PATH/tools/export_model.py -c $PADDLE_DET_PATH/$YML_CONFIG -o use_gpu=false weights=https://paddledet.bj.bcebos.com/models/$PRETRAINED  "TestReader.inputs_def.image_shape=[3,608,608]" --output_dir=$OUTPUT_DIR
else:
    print("Model is already downloaded")

結果顯示模型已經下載了
Model is already downloaded

#Get the PPYOLO (experimental)
PADDLE_DET_PATH="../../PaddleDetection"
YML_CONFIG="configs/ppyolo/ppyolo_r50vd_dcn_1x_coco.yml"
PRETRAINED="ppyolo_r50vd_dcn_1x_coco.pdparams"
OUTPUT_DIR="models"
if(not os.path.isfile("models/ppyolo_r50vd_dcn_1x_coco/model.pdmodel")):
    print("Download and Export Model... This may take a while...")
    ! python $PADDLE_DET_PATH/tools/export_model.py -c $PADDLE_DET_PATH/$YML_CONFIG -o use_gpu=false weights=https://paddledet.bj.bcebos.com/models/$PRETRAINED  "TestReader.inputs_def.image_shape=[3,608,608]" --output_dir=$OUTPUT_DIR
else:
    print("Model is already downloaded")

Model is already downloaded

#Helper functions
def image_preprocess(input_image, size):
    img = cv2.resize(input_image, (size,size))
    img = np.transpose(img, [2,0,1]) / 255
    img = np.expand_dims(img, 0)
    ##NormalizeImage: {mean: [0.485, 0.456, 0.406], std: [0.229, 0.224, 0.225], is_scale: True}
    img_mean = np.array([0.485, 0.456,0.406]).reshape((3,1,1))
    img_std = np.array([0.229, 0.224, 0.225]).reshape((3,1,1))
    img -= img_mean
    img /= img_std
    return img.astype(np.float32)
def draw_box(img, results, label_text, scale_x, scale_y):
    for i in range(len(results)):
        #print(results[i])
        bbox = results[i, 2:]
        label_id = int(results[i, 0])
        score = results[i, 1]
        if(score>0.20):
            xmin, ymin, xmax, ymax = [int(bbox[0]*scale_x), int(bbox[1]*scale_y), 
                                      int(bbox[2]*scale_x), int(bbox[3]*scale_y)]
            cv2.rectangle(img,(xmin, ymin),(xmax, ymax),(0,255,0),3)
            font = cv2.FONT_HERSHEY_SIMPLEX
            label_text = label_list[label_id];
            cv2.rectangle(img, (xmin, ymin), (xmax, ymin-70), (0,255,0), -1)
            cv2.putText(img, "#"+label_text,(xmin,ymin-10), font, 1.2,(255,255,255), 2,cv2.LINE_AA)
            cv2.putText(img, str(score),(xmin,ymin-40), font, 0.8,(255,255,255), 2,cv2.LINE_AA)
    return img

設定模型

可以在兩個不同的模型之間切換-默認是PPYolo來對比兩個模型的性能

#PPYolo3
#pdmodel_path = "models/yolov3_darknet53_270e_coco"

#PPYolo (experimental)
pdmodel_path = "models/ppyolo_r50vd_dcn_1x_coco"

pdmodel_file = pdmodel_path + "/model.pdmodel"
pdmodel_config = pdmodel_path + "/infer_cfg.yml"
device = 'CPU'

#load the data from config, and setup the parameters
label_list=[]
with open(pdmodel_config) as f:
    data = yaml.load(f, Loader=SafeLoader)
label_list = data['label_list'];

將PaddlePaddle預訓練模型加載到OpenVINO推理引擎(IE)中

ie = IECore()
net = ie.read_network(pdmodel_file)

net.reshape({'image': [1, 3, 608, 608], 'im_shape': [
            1, 2], 'scale_factor': [1, 2]})

exec_net = ie.load_network(net, device)
assert isinstance(exec_net, ExecutableNetwork)

加載影像并運行推理步驟

input_image = cv2.imread("horse.jpg")
test_image = image_preprocess(input_image, 608)
test_im_shape = np.array([[608, 608]]).astype('float32')
test_scale_factor = np.array([[1, 2]]).astype('float32')
#print(test_image.shape)

inputs_dict = {'image': test_image, "im_shape": test_im_shape,
               "scale_factor": test_scale_factor}

output = exec_net.infer(inputs_dict)
result_ie = list(output.values())


result_image = cv2.imread("horse.jpg")
scale_x = result_image.shape[1]/608*2
scale_y = result_image.shape[0]/608
result_image = draw_box(result_image, result_ie[0], label_list, scale_x, scale_y)
_,ret_array = cv2.imencode('.jpg', result_image) 
i = display.Image(data=ret_array)            
display.display(i)

cv2.imwrite("yolo-output.png",result_image) 

在這里插入圖片描述

實時攝像頭演示

下面的示例顯示了在攝像頭上運行YoloV3,這個模型確實更復雜,因此可以提供更好的mAP,也考慮其他的模型,如mobilenet,如果你想權衡性能和準確性,

Source: https://github.com/PaddlePaddle/PaddleDetection

def YoloVideo(VideoIndex=0, scale=0.5):
    #PPYolo3
    pdmodel_path = "models/yolov3_darknet53_270e_coco"

    pdmodel_file = pdmodel_path + "/model.pdmodel"
    pdmodel_config = pdmodel_path + "/infer_cfg.yml"
    device = 'CPU'

    #load the data from config, and setup the parameters
    label_list=[]
    with open(pdmodel_config) as f:
        data = yaml.load(f, Loader=SafeLoader)
    label_list = data['label_list'];
    
    ie = IECore()
    net = ie.read_network(pdmodel_file)

    net.reshape({'image': [1, 3, 608, 608], 'im_shape': [
                1, 2], 'scale_factor': [1, 2]})

    exec_net = ie.load_network(net, device)
    assert isinstance(exec_net, ExecutableNetwork)
    
    try:
        cap = cv2.VideoCapture(VideoIndex)
    except:
        print("Cannot Open Device")
        del exec_net
    try:
        ret, frame = cap.read()
        
        while(ret==True):
            # Capture frame-by-frame
            ret, frame = cap.read()
            
            if not ret:
                # Release the Video Device if ret is false
                cap.release()
                # Message to be displayed after releasing the device
                print ("Released Video Resource")
                break
            #frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            half_frame = cv2.resize(frame, (0, 0), fx = scale, fy = scale)
             
            #Processing the Frame
            test_image = image_preprocess(half_frame, 608)
            test_im_shape = np.array([[608, 608]]).astype('float32')
            test_scale_factor = np.array([[1, 2]]).astype('float32')
            #print(test_image.shape)
            inputs_dict = {'image': test_image, "im_shape": test_im_shape,
                           "scale_factor": test_scale_factor}

            output = exec_net.infer(inputs_dict)
            result_ie = list(output.values())
            
            result_image = half_frame.copy()
            #result_image = cv2.resize(result_image, (int(608*1.0),int(608*1.0)))
            scale_x = result_image.shape[1]/608*2
            scale_y = result_image.shape[0]/608
            
            result_image = draw_box(result_image, result_ie[0], label_list, scale_x, scale_y)
            
            #convert to jpg for performance results
            _,ret_array = cv2.imencode('.jpg', result_image) 
            i = display.Image(data=ret_array)            
            
            display.display(i)
            display.clear_output(wait=True)
    except KeyboardInterrupt:
        # Release the Video Device
        cap.release()
        # Message to be displayed after releasing the device
        print("Released Video Resource from KeyboardInterrupt")
        del exec_net
    pass

運行Webcam Feed

請按下停止按鈕,以正確終止,

YoloVideo(1, 0.75)
Released Video Resource from KeyboardInterrupt

openvino-PaddleOCR

手寫識別古詩

這個演示出自博士吳卓(OpenVINO Edge AI軟體布道者- Intel)
的一個開源專案,演示了如何在OpenVINO上運行PaddleOCR (Lite)模型,我們現在可以直接從mobilenetv3模型讀取而不需要任何轉換,而不是將mobilenetv3模型匯出到ONNX,然后通過OpenVINO優化器創建中間表示(IR)格式,

如果有什么出錯的地方,可以參考這里

通過OpenVINO運行Paddle Detection

import os, os.path
import sys
import json
import urllib.request
import cv2
import numpy as np
import paddle
import math
import time

from openvino.inference_engine import IENetwork, IECore, ExecutableNetwork
from IPython import display
from PIL import Image, ImageDraw
import copy

import logging
import imghdr
from shapely.geometry import Polygon
import pyclipper

from pre_post_processing import *

加載圖片

def image_preprocess(input_image, size):
    img = cv2.resize(input_image, (size,size))
    img = np.transpose(img, [2,0,1]) / 255
    img = np.expand_dims(img, 0)
    ##NormalizeImage: {mean: [0.485, 0.456, 0.406], std: [0.229, 0.224, 0.225], is_scale: True}
    img_mean = np.array([0.485, 0.456,0.406]).reshape((3,1,1))
    img_std = np.array([0.229, 0.224, 0.225]).reshape((3,1,1))
    img -= img_mean
    img /= img_std
    return img.astype(np.float32)
# Test images provided include 1 handwritten Chinese image and 1 printed Chinese image
image_file = "handwritten_simplified_chinese_test.jpg"

ii = cv2.imread(image_file)
test_image = image_preprocess(ii,640)
Load the Network
model_dir = "./inference/ch_ppocr_mobile_v2.0_det_infer"
model_file_path = model_dir + "/inference.pdmodel"
params_file_path = model_dir + "/inference.pdiparams"
# initialize inference engine
ie = IECore()
# initialize inference engine
net = ie.read_network(model_file_path)

# pdmodel might be dynamic shape, this will reshape based on the input
input_key = list(net.input_info.items())[0][0] # 'inputs'
net.reshape({input_key: test_image.shape})

exec_net = ie.load_network(net, 'CPU') 
assert isinstance(exec_net, ExecutableNetwork)
#perform the inference step
det_start_time = time.time()
output = exec_net.infer({input_key: test_image})
det_stop_time = time.time()
result_ie = list(output.values())
det_infer_time = det_stop_time - det_start_time

對PaddleDetection的推理結果進行后處理

ori_im = ii.copy()
data = {'image': ii}

data_resize = DetResizeForTest(data)
data_norm = NormalizeImage(data_resize)
data_list = []
keep_keys =  ['image', 'shape']
for key in keep_keys:
    data_list.append(data[key])
img, shape_list = data_list

shape_list = np.expand_dims(shape_list, axis=0)
pred = result_ie[0]      
if isinstance(pred, paddle.Tensor):
    pred = pred.numpy()
pred = pred[:, 0, :, :]
segmentation = pred > 0.3

boxes_batch = []
for batch_index in range(pred.shape[0]):
    src_h, src_w, ratio_h, ratio_w = shape_list[batch_index]

    mask = segmentation[batch_index]
    boxes, scores = boxes_from_bitmap(pred[batch_index], mask,src_w, src_h)
    boxes_batch.append({'points': boxes})

post_result = boxes_batch
dt_boxes = post_result[0]['points']
dt_boxes = filter_tag_det_res(dt_boxes, ii.shape)

在openvino 上運行飛漿識別

# Processing detection results for Recognition

dt_boxes = sorted_boxes(dt_boxes)
img_crop_list = []

for bno in range(len(dt_boxes)):
    tmp_box = copy.deepcopy(dt_boxes[bno])
    img_crop = get_rotate_crop_image(ori_im, tmp_box)
    img_crop_list.append(img_crop)

預處理輸送給Paddle識別的影像

def resize_norm_img(img, max_wh_ratio):
        rec_image_shape = [3, 32, 320]
        imgC, imgH, imgW = rec_image_shape
        assert imgC == img.shape[2]
        character_type = "ch"
        if character_type == "ch":
            imgW = int((32 * max_wh_ratio))
        h, w = img.shape[:2]
        ratio = w / float(h)
        if math.ceil(imgH * ratio) > imgW:
            resized_w = imgW
        else:
            resized_w = int(math.ceil(imgH * ratio))
        resized_image = cv2.resize(img, (resized_w, imgH))
        resized_image = resized_image.astype('float32')
        resized_image = resized_image.transpose((2, 0, 1)) / 255
        resized_image -= 0.5
        resized_image /= 0.5
        padding_im = np.zeros((imgC, imgH, imgW), dtype=np.float32)
        padding_im[:, :, 0:resized_w] = resized_image
        return padding_im

Load the Network

model_dir = "./inference/ch_ppocr_mobile_v2.0_rec_infer"
model_file_path = model_dir + "/inference.pdmodel"
params_file_path = model_dir + "/inference.pdiparams"

ie = IECore()
net = ie.read_network(model_file_path)

開始識別古詩詞

img_num = len(img_crop_list)
# Calculate the aspect ratio of all text bars
width_list = []
for img in img_crop_list:
    width_list.append(img.shape[1] / float(img.shape[0]))
# Sorting can speed up the recognition process
indices = np.argsort(np.array(width_list))
rec_res = [['', 0.0]] * img_num
rec_batch_num = 6
batch_num = rec_batch_num
rec_processing_times = 0
for beg_img_no in range(0, img_num, batch_num):
    end_img_no = min(img_num, beg_img_no + batch_num)
    norm_img_batch = []
    max_wh_ratio = 0
    for ino in range(beg_img_no, end_img_no):
        h, w = img_crop_list[indices[ino]].shape[0:2]
        wh_ratio = w * 1.0 / h
        max_wh_ratio = max(max_wh_ratio, wh_ratio)
    for ino in range(beg_img_no, end_img_no):
        norm_img = resize_norm_img(img_crop_list[indices[ino]],max_wh_ratio)
        norm_img = norm_img[np.newaxis, :]
        norm_img_batch.append(norm_img)

    norm_img_batch = np.concatenate(norm_img_batch)
    norm_img_batch = norm_img_batch.copy()
    
    # pdmodel might be dynamic shape, this will reshape based on the input
    input_key = list(net.input_info.items())[0][0] # 'inputs'
    net.reshape({input_key: norm_img_batch.shape})

    #load the network on CPU
    start_time = time.time()
    exec_net = ie.load_network(net, 'CPU') 
    stop_time = time.time()
    assert isinstance(exec_net, ExecutableNetwork)
    
    rec_processing_times += stop_time - start_time

    for index in range(len(norm_img_batch)):
        output = exec_net.infer({input_key: norm_img_batch})
    result_ie = list(output.values())
    preds = result_ie[0]
    postprocess_op = build_post_process(postprocess_params)
    rec_result = postprocess_op(preds)
    for rno in range(len(rec_result)):
        rec_res[indices[beg_img_no + rno]] = rec_result[rno]

final_stop_time = time.time()
processing_time = final_stop_time - det_start_time
print("The total prediction and processing time is ", processing_time)

The total prediction and processing time is 0.3596353530883789

print("The total inference time for detection is ", det_infer_time)
print("The total inference time for recognition is ", rec_processing_times)

The total inference time for detection is 0.030055999755859375
The total inference time for recognition is 0.127180814743042

可視化檢測和識別結果

src_im = draw_text_det_res(dt_boxes, image_file)
img_name_pure = os.path.split(image_file)[-1]
img_path = "det_res_{}".format(img_name_pure)
cv2.imwrite(img_path, src_im)

#Visualization Paddle Detection results
_,ret_array = cv2.imencode('.jpg', src_im) 
i = display.Image(data=ret_array)            
display.display(i)

在這里插入圖片描述

#Visualization Paddle Recognition results, format
print(rec_res)

[(‘結廬在人境品無車馬喧’, 0.7947357), (‘問君何能爾心遠地自偏采前’, 0.78279454), (‘東鶴下您然見南山山氣日夕’, 0.8802729), (‘佳飛鳥相與還此中有真意欲’, 0.8675663), (‘辯已意言’, 0.38597608)]

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/421860.html

標籤:AI

上一篇:RTX3060安裝pytorch

下一篇:Streamx測驗Flinksql Bug

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more