七萬字詳解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開發全流程
- 安裝PaddleX
安裝相關問題我們會在接下來詳細講述,
pip install paddlex -i https://mirror.baidu.com/pypi/simple
- 準備蔬菜分類資料集
wget https://bj.bcebos.com/paddlex/datasets/vegetables_cls.tar.gz
tar xzvf vegetables_cls.tar.gz
- 定義訓練/驗證影像處理流程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()
])
- 定義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)
- 使用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)
- 訓練程序使用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即可,
- 加載訓練保存的模型預測
模型在訓練程序中,會每間隔一定輪數保存一次模型,在驗證集上評估效果最好的一輪會保存在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可用于標注目標檢測、實體分割、語意分割資料集,是一款開源的標注工具,
- 安裝Anaconda
推薦使用Anaconda安裝python依賴,有經驗的開發者可以跳過此步驟,安裝Anaconda的方式可以參考檔案,
在安裝Anaconda,并創建環境之后,再進行接下來的步驟
- 安裝LabelMe
進入Python環境后,執行如下命令即可
conda activate my_paddlex
conda install pyqt
pip install labelme
- 啟動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”進行洗掉, 
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”進行洗掉, 
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
