人工智能技術(shù)及應(yīng)用 課件 張文安 ch7-車道線檢測實(shí)踐;ch8-人臉檢測實(shí)踐_第1頁
人工智能技術(shù)及應(yīng)用 課件 張文安 ch7-車道線檢測實(shí)踐;ch8-人臉檢測實(shí)踐_第2頁
人工智能技術(shù)及應(yīng)用 課件 張文安 ch7-車道線檢測實(shí)踐;ch8-人臉檢測實(shí)踐_第3頁
人工智能技術(shù)及應(yīng)用 課件 張文安 ch7-車道線檢測實(shí)踐;ch8-人臉檢測實(shí)踐_第4頁
人工智能技術(shù)及應(yīng)用 課件 張文安 ch7-車道線檢測實(shí)踐;ch8-人臉檢測實(shí)踐_第5頁
已閱讀5頁,還剩60頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

7車道線檢測實(shí)踐LANELINEINSPECTIONPRACTICEChapter07本章目錄數(shù)據(jù)采集與標(biāo)注01環(huán)境部署02模型訓(xùn)練03模型的量化04項(xiàng)目部署與落地05本章總體介紹車道線檢測是輔助駕駛中必不可少的一項(xiàng),它的主要目標(biāo)是通過計(jì)算機(jī)視覺和圖像處理技術(shù),從道路圖像中精確提取出車道線的位置和形狀信息。這些提取到的車道線信息可以用于車道保持、車道偏離預(yù)警、自動(dòng)駕駛路徑規(guī)劃等應(yīng)用。通過實(shí)現(xiàn)準(zhǔn)確的車道線檢測系統(tǒng),可以提高駕駛安全性,減少交通事故的發(fā)生,并為駕駛員提供更好的駕駛體驗(yàn)。基于視覺的車道線檢測方法可以分為:傳統(tǒng)圖像方法和深度學(xué)習(xí)方法兩類。其中傳統(tǒng)的圖像檢測方法可以通過邊緣檢測、濾波或是顏色空間的車道線檢測等方式得到車道線區(qū)域,再結(jié)合相關(guān)圖像檢測算法實(shí)現(xiàn)車道線檢測。但面對(duì)環(huán)境明顯變化的場景并不能很好的檢測,工作量大且魯棒性差。而深度學(xué)習(xí)的方法有較好的魯棒性,且準(zhǔn)確率更高。它大致有基于分類和目標(biāo)檢測的方法和基于端到端圖像分割的方法等相關(guān)車道線檢測方法。而本書的車道線檢測采用的是UNet的語義分割網(wǎng)絡(luò)。本章總體介紹車道線檢測算法的流程如下圖所示。主要思路是:通過素材采集獲取訓(xùn)練要用的原始數(shù)據(jù),再經(jīng)過標(biāo)注與生成標(biāo)簽圖兩個(gè)步驟將原始數(shù)據(jù)轉(zhuǎn)化為可以被學(xué)習(xí)訓(xùn)練的素材,然后通過模型訓(xùn)練得到相應(yīng)模型,最后經(jīng)過模型量化、轉(zhuǎn)換和部署等步驟將模型優(yōu)化并轉(zhuǎn)化成可被嵌入式平臺(tái)運(yùn)行的程序。車道線項(xiàng)目流程圖7.1數(shù)據(jù)集采集與標(biāo)注素材的獲取一般有兩種途徑,一種是自己利用相關(guān)設(shè)備如行車記錄儀獲取,另一種是通過下載公開的數(shù)據(jù)集獲取。車道線檢測相關(guān)的數(shù)據(jù)集有TuSimple、CULane、CurveLanes、BDD100k等。素材標(biāo)注使用Labelme工具,本項(xiàng)目提供的例程的“數(shù)據(jù)集”文件夾內(nèi)已經(jīng)提供原圖與對(duì)應(yīng)標(biāo)注文件,車道線識(shí)別項(xiàng)目對(duì)于車道線的標(biāo)注有以下幾點(diǎn)要求:需要標(biāo)注的內(nèi)容為圖片中人眼可以識(shí)別的車道線,包括實(shí)線、虛線、白線和黃線。對(duì)于雙線的車道線,兩條分開標(biāo)注。對(duì)于虛線中間沒有車道線的部分進(jìn)行補(bǔ)足。對(duì)于沒有車道線的圖片,直接跳過,不做處理。7.1數(shù)據(jù)集采集與標(biāo)注下圖是按以上要求所給出的標(biāo)注示例。車道線項(xiàng)目流程圖相較于分類和目標(biāo)檢測,語義分割的素材多了一步從標(biāo)簽文件到分割圖的轉(zhuǎn)換。因?yàn)檎Z義分割是像素級(jí)別的推理,每個(gè)像素點(diǎn)都有其對(duì)應(yīng)的標(biāo)簽,因此在訓(xùn)練中,它的標(biāo)簽就是和它等大的一張分割圖。7.2環(huán)境部署深度學(xué)習(xí)的框架除了PyTorch外還有TensorFlow框架,本項(xiàng)目在TensorFlow框架下訓(xùn)練,所以在進(jìn)行本章之前需要進(jìn)行TensorFlow環(huán)境的搭建,其環(huán)境總體搭建步驟如下:(1)在Ubuntu系統(tǒng)(WSL2、虛擬機(jī)或多系統(tǒng))下搭建TensorFlow環(huán)境的docker(2)在docker環(huán)境內(nèi)安裝本項(xiàng)目的相關(guān)庫當(dāng)然,若有需求也可以在創(chuàng)建一個(gè)docker容器后,在其內(nèi)部建立conda的虛擬環(huán)境,然后安裝本項(xiàng)目需要的TensorFlow環(huán)境與相關(guān)庫。7.2環(huán)境部署7.2.1docker環(huán)境部署針對(duì)不同的顯卡,需要搭建不同的環(huán)境。本項(xiàng)目以30系顯卡為例進(jìn)行環(huán)境搭建介紹,30系顯卡需要CUDA11.1,可以使用NVIDIA提供的docker鏡像—NVIDIA-TensorFlow。如果沒有安裝過NVIDIA-docker,首先要進(jìn)行NVIDIA-docker的安裝,它是使用上述鏡像的前提,如下是安裝步驟:$distribution=$(./etc/os-release;echo$ID$VERSION_ID)$curl-s-Lhttps://nvidia.github.io/nvidia-docker/gpgkey|sudoapt-keyadd-$curl-s-Lhttps://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list|sudotee/etc/apt/sources.list.d/nvidia-docker.list$sudoapt-getupdate$sudoapt-getinstall-ynvidia-docker27.2環(huán)境部署7.2.1docker環(huán)境部署接著進(jìn)行NVIDIA-TensorFlow的docker環(huán)境部署#拉取鏡像nvidia-dockerpullnvcr.io/nvidia/tensorflow:20.10-tf1-py3#創(chuàng)建容器nvidia-dockerrun-d-it-p10022:22-p10500:5000-v/home:/home--namenvidia_tensorflownvcr.io/nvidia/tensorflow:20.10-tf1-py3#-p代表了端口的映射-p宿主機(jī)端口:容器端口這里預(yù)留了22可以用于ssh登錄5000后面會(huì)用到#進(jìn)入容器nvidia-dockerexec-itnvidia_tensorflow/bin/bash安裝TensorFlowwheel的索引pipinstallnvidia-index用官方提供的命令安裝依賴的包pipinstallnvidia-tensorflow[horovod]7.2環(huán)境部署7.2.1docker環(huán)境部署下載完成后進(jìn)入對(duì)應(yīng)的目錄,因?yàn)檫@些依賴包安裝存在一定順序,所以按以下順序執(zhí)行指令。若覺得一條一條執(zhí)行繁瑣,可以建一個(gè)后綴名為.sh的shell腳本文件,將下列指令復(fù)制進(jìn)文件后執(zhí)行sh文件名.sh指令提高效率。pipinstallgoogle_pasta-0.2.0-py3-none-any.whlpipinstallnvidia_cublas-4-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_cuda_cupti-11.1.69-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_cuda_nvcc-11.1.74-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_cuda_cupti-11.1.69-cp36-cp36m-linux_x86_64.whlnvidia_cuda_nvcc-11.1.74-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_cuda_nvrtc-11.1.74-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_cuda_runtime-11.1.74-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_cudnn-8.0.70-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_cufft-4-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_curand-4-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_cusolver-4-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_cusparse-75-cp36-cp36m-linux_x86_64.whl7.2環(huán)境部署7.2.1docker環(huán)境部署pipinstallnvidia_dali_cuda110-0.26.0-1608709-py3-none-manylinux2014_x86_64.whlpipinstallnvidia_dali_nvtf_plugin-0.26.0+nv20.10-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_nccl-2.7.8-cp36-cp36m-linux_x86_64.whlpipinstallnvidia_tensorboard-1.15.0+nv20.10-py3-none-any.whlpipinstallnvidia_tensorrt--cp36-none-linux_x86_64.whlpipinstallnvidia_tensorflow-1.15.4+nv20.10-cp36-cp36m-linux_x86_64.whlpipinstalltensorflow_estimator-1.15.1-py2.py3-none-any.whlpipinstallnvidia_horovod-0.20.0+nv20.10-cp36-cp36m-linux_x86_64.whl此外本項(xiàng)目還需要用到以下幾個(gè)Python包,讀者可以使用以下命令安裝或者直接使用項(xiàng)目中的requirements.txt導(dǎo)入。pipinstallscipy==1.1.0-i/simplepipinstallscikit-learn-i/simplepipinstalltqdm-i/simple7.2環(huán)境部署7.2.2安裝TensorFlowObjectDetectionAPITensorFlowObjectDetectionAPI是一個(gè)基于TensorFlow構(gòu)建的開源框架,用于目標(biāo)檢測任務(wù)。它提供了豐富的目標(biāo)檢測模型,其中包括了一些經(jīng)典的模型架構(gòu),如FasterR-CNN、SSD、Mask-RCNN等,具體可見TensorFlow的GitHub的model倉庫。7.3模型訓(xùn)練項(xiàng)目文件夾為project,項(xiàng)目目錄如圖。“部署代碼”文件夾包含的是模型部署的代碼,“權(quán)重轉(zhuǎn)換與量化”包含的是模型量化轉(zhuǎn)換的相關(guān)代碼,本節(jié)介紹“訓(xùn)練代碼”和“數(shù)據(jù)集”文件夾部分,實(shí)現(xiàn)數(shù)據(jù)集制作與模型訓(xùn)練與保存。標(biāo)簽轉(zhuǎn)換程序、數(shù)據(jù)集制作程序和模型及訓(xùn)練程序這三部分對(duì)應(yīng)在“訓(xùn)練代碼”文件夾下,分別對(duì)應(yīng)的是ldw_draw.py、make_dataset.py和剩下其他程序,目錄結(jié)構(gòu)如圖所示。models內(nèi)存有模型程序,builders內(nèi)存有模型接口程序,utils是相關(guān)的輔助函數(shù)集合,train.py是模型訓(xùn)練程序,ckpt2pb.py是將訓(xùn)練完成后的ckpt文件轉(zhuǎn)換為pb文件的程序,eval.py是評(píng)估程序用訓(xùn)練過程中保存的pb文件進(jìn)行推理。項(xiàng)目目錄結(jié)構(gòu)traincode目錄結(jié)構(gòu)7.3模型訓(xùn)練7.3.1模型設(shè)計(jì)思想本項(xiàng)目使用UNet的語義分割網(wǎng)絡(luò),從圖中可以看到,其形狀類似字母“U”所以被稱為UNet。參考論文《U-Net:ConvolutionalNetworksforBiomedicalImageSegmentation》,起初UNet被用于醫(yī)學(xué)領(lǐng)域,而后UNet憑借著突出的效果被廣泛應(yīng)用。UNet本質(zhì)上是一個(gè)編碼器和解碼器的結(jié)構(gòu),左邊是特征提取,右邊是采樣恢復(fù)原始分辨率,中間采用跳層鏈接的方式將位置信息和語義信息融合。UNet網(wǎng)絡(luò)結(jié)構(gòu)7.3模型訓(xùn)練7.3.2標(biāo)簽轉(zhuǎn)換7.1節(jié)中標(biāo)注完的素材僅僅是多了一個(gè)標(biāo)簽文件,保存了所標(biāo)注的那些多邊形的類別和位置。而實(shí)際在訓(xùn)練中用到的是像素級(jí)別的標(biāo)簽,也就是對(duì)于原圖上每個(gè)像素點(diǎn),都會(huì)有一個(gè)對(duì)應(yīng)了類別的標(biāo)簽,這個(gè)時(shí)候就需要利用標(biāo)注文件來生成分割用的標(biāo)簽圖。本項(xiàng)目提供的標(biāo)簽轉(zhuǎn)換程序?yàn)閘dw_draw.py。詳見代碼清單7-1。將對(duì)應(yīng)腳本—ldw_draw.sh中的Path參數(shù)配置成讀者自己電腦上的標(biāo)注圖片的所在目錄,執(zhí)行腳本,結(jié)果如下。image中存放原始圖片;json中存放標(biāo)注文件;roadmap中存放分割標(biāo)簽圖片,轉(zhuǎn)換后的目錄結(jié)構(gòu)和圖片經(jīng)過轉(zhuǎn)換后的結(jié)果如圖所示。轉(zhuǎn)換后的目錄結(jié)構(gòu)轉(zhuǎn)換前后對(duì)比,原圖(左),轉(zhuǎn)換后圖(右)7.3模型訓(xùn)練7.3.3數(shù)據(jù)集制作在project下的“數(shù)據(jù)集”目錄中放置數(shù)據(jù)集,在“數(shù)據(jù)集”下再建一層子目錄,用于數(shù)據(jù)集分類。這里就以type1、type2為例,將轉(zhuǎn)化完成后的素材文件夾放入子文件夾中。對(duì)于本項(xiàng)目提供的例程,需要將“數(shù)據(jù)集”文件夾內(nèi)data文件夾放入“訓(xùn)練代碼”文件夾內(nèi)make_dataset.py所在目錄下,或者讀者可以修改make_dataset.py的相關(guān)路徑。詳見代碼清單7-2。將腳本—make_datase.sh中的dataset參數(shù)配置成data下的子目錄,樣例數(shù)據(jù)集中有兩個(gè)子目錄type1、type2,存有上一小節(jié)所轉(zhuǎn)換的相關(guān)素材。input_height和input_width根據(jù)實(shí)際情況配置,所演示的項(xiàng)目中是256*128。修改make_datase.sh中的type1、type2后分別執(zhí)行。完成后其目錄結(jié)構(gòu)如圖所示,新增兩個(gè)文件夾。數(shù)據(jù)集制作后的目錄結(jié)構(gòu)7.3模型訓(xùn)練7.3.3數(shù)據(jù)集制作新增文件夾的目錄結(jié)構(gòu)如圖所示,test:測試集圖片;test_label:測試機(jī)標(biāo)簽;train:訓(xùn)練集圖片;train_label:訓(xùn)練集標(biāo)簽;val:驗(yàn)證集圖片;val_label:驗(yàn)證集標(biāo)簽。同時(shí),處理完的素材文件夾會(huì)被移動(dòng)到data/done下面,以便于未來多次制作數(shù)據(jù)集時(shí)不會(huì)重復(fù)操作。新增文件夾的目錄結(jié)構(gòu)7.3模型訓(xùn)練7.3.4網(wǎng)絡(luò)搭建在“訓(xùn)練代碼”文件夾下models目錄中放置需要搭建的模型文件,這里就以上面提到的UNet為例。本項(xiàng)目提供的例程在models下有一個(gè)UNet.py程序。詳見代碼清單7-3。在traincode下builders目錄,本項(xiàng)目提供一個(gè)model_builder.py程序作為創(chuàng)建模型總的接口,用于不同類型模型的選擇和搭建。importsys,osimporttensorflowastfimportsubprocess#存放模型的目錄sys.path.append("models")#載入模型的搭建函數(shù)frommodels.UNetimportbuild_unet#自定義模型名稱SUPPORTED_MODELS=["UNet"]#統(tǒng)一的模型搭建接口defbuild_model(model_name,net_input,num_classes,is_training=False):print("Preparingthemodel...") ifmodel_namenotinSUPPORTED_MODELS: raiseValueError("Themodelyouselectedisnotsupported.Thefollowingmodelsarecurrentlysupported:{0}".format(SUPPORTED_MODELS)) network=None #根據(jù)模型名稱調(diào)用對(duì)應(yīng)的模型搭建函數(shù)

ifmodel_name=="UNet": network=build_unet(net_input,num_classes,is_training=is_training) else: raiseValueError("Error:themodel%disnotavailable.Trycheckingwhichmodelsareavailableusingthecommandpythonmain.py--help") returnnetwork7.3模型訓(xùn)練7.3.5模型訓(xùn)練訓(xùn)練的代碼由相關(guān)數(shù)據(jù)的讀取、訓(xùn)練參數(shù)設(shè)置、數(shù)據(jù)增強(qiáng)、訓(xùn)練信息顯示及保存、繼續(xù)訓(xùn)練等相關(guān)部分構(gòu)成。在訓(xùn)練開始前,需要對(duì)訓(xùn)練進(jìn)行一些相關(guān)參數(shù)的設(shè)置,其中一些參數(shù)的設(shè)置將會(huì)影響訓(xùn)練模型的效果。相關(guān)參數(shù)有:num_epochs:總訓(xùn)練輪數(shù);epoch_start_i:開始輪數(shù),配合繼續(xù)訓(xùn)練使用,程序會(huì)自動(dòng)加載epoch_start_i-1的權(quán)重;validation_step:間隔多少輪驗(yàn)證一次模型;continue_training:是否繼續(xù)訓(xùn)練;dataset:數(shù)據(jù)集,可配置列表;imgprocess:載入圖片操作,裁剪或者縮放;input_height:網(wǎng)絡(luò)輸入的高;input_width:網(wǎng)絡(luò)輸入的寬;batch_size:每個(gè)批次圖片數(shù)量;num_val_images:每次驗(yàn)證取多少張驗(yàn)證集中的圖片;h_flip:數(shù)據(jù)增強(qiáng)是否進(jìn)行水平翻轉(zhuǎn);v_flip:數(shù)據(jù)增強(qiáng)是否進(jìn)行垂直翻轉(zhuǎn);brightness:數(shù)據(jù)增強(qiáng)是否隨機(jī)亮度;color:數(shù)據(jù)增強(qiáng)是否隨機(jī)添加顏色;rotation:數(shù)據(jù)增強(qiáng)隨機(jī)旋轉(zhuǎn)角度;model:訓(xùn)練的模型;savedir:保存的路徑;7.3模型訓(xùn)練7.3.5模型訓(xùn)練數(shù)據(jù)增強(qiáng)是一種在深度學(xué)習(xí)中廣泛使用的技術(shù),用于擴(kuò)充訓(xùn)練數(shù)據(jù)集,以提高模型的泛化能力和魯棒性。數(shù)據(jù)增強(qiáng)通過對(duì)原始訓(xùn)練數(shù)據(jù)應(yīng)用一系列隨機(jī)變換或變形操作,生成額外的訓(xùn)練樣本,從而增加數(shù)據(jù)的多樣性。數(shù)據(jù)增強(qiáng)部分,程序根據(jù)讀者傳入的訓(xùn)練參數(shù),再載入每個(gè)批次的圖片時(shí)會(huì)對(duì)圖片進(jìn)行隨機(jī)數(shù)據(jù)增強(qiáng)的操作。詳見代碼清單7-4。損失函數(shù),也稱為目標(biāo)函數(shù)或代價(jià)函數(shù),是深度學(xué)習(xí)模型中的一個(gè)關(guān)鍵組成部分。損失函數(shù)用于度量模型的預(yù)測輸出與真實(shí)標(biāo)簽之間的差異或錯(cuò)誤程度,通過最小化該差異來優(yōu)化模型的參數(shù)。本項(xiàng)目損失函數(shù)部分采用的是focal_loss,其主要側(cè)重于根據(jù)樣本的難易程度給樣本對(duì)應(yīng)的損失增加權(quán)重。deffocal_loss(prediction_tensor,target_tensor,weights=None,alpha=0.25,gamma=2):

sigmoid_p=tf.nn.sigmoid(prediction_tensor)#創(chuàng)建一個(gè)將所有元素設(shè)置為0的張量

zeros=array_ops.zeros_like(sigmoid_p,dtype=sigmoid_p.dtype)#正樣本損失(車道線)

pos_p_sub=array_ops.where(target_tensor>zeros,target_tensor-sigmoid_p,zeros)#負(fù)樣本損失(背景)

neg_p_sub=array_ops.where(target_tensor>zeros,zeros,sigmoid_p)#-ylog(p^)-(1-y)log(1-p^)

per_entry_cross_ent=-alpha*(pos_p_sub**gamma)*tf.log(tf.clip_by_value(sigmoid_p,1e-8,1.0))-(1-alpha)*(neg_p_sub**gamma)*tf.log(tf.clip_by_value(1.0-sigmoid_p,1e-8,1.0))returntf.reduce_mean(per_entry_cross_ent)7.3模型訓(xùn)練7.3.5模型訓(xùn)練載入每個(gè)批次的圖片,語義分割的標(biāo)簽是一張圖,所以在送入網(wǎng)絡(luò)之前要對(duì)rgb對(duì)應(yīng)的標(biāo)簽做一次轉(zhuǎn)化,再進(jìn)行獨(dú)熱編碼(one-hot)。defone_hot_it(label,label_values):semantic_map=[]#label_values從csv文件中載入forcolourinlabel_values:equality=np.equal(label,colour)class_map=np.all(equality,axis=-1)semantic_map.append(class_map)semantic_map=np.stack(semantic_map,axis=-1)returnsemantic_map評(píng)估指標(biāo)部分,打印了整體分?jǐn)?shù)、各類別分?jǐn)?shù)、F1、IOU。defevaluate_segmentation(pred,label,num_classes,score_averaging="weighted"):flat_pred=pred.flatten()flat_label=label.flatten()#計(jì)算全局的分?jǐn)?shù)

global_accuracy=compute_global_accuracy(flat_pred,flat_label)#計(jì)算每個(gè)類別的分?jǐn)?shù)

class_accuracies=compute_class_accuracies(flat_pred,flat_label,num_classes)#計(jì)算精確率

prec=precision_score(flat_pred,flat_label,average=score_averaging)#計(jì)算召回率

rec=recall_score(flat_pred,flat_label,average=score_averaging)#計(jì)算F1f1=f1_score(flat_pred,flat_label,average=score_averaging)#計(jì)算IOUiou=compute_mean_iou(flat_pred,flat_label)returnglobal_accuracy,class_accuracies,prec,rec,f1,iou7.3模型訓(xùn)練7.3.5模型訓(xùn)練執(zhí)行文件夾內(nèi)的train.sh腳本后進(jìn)行訓(xùn)練,其訓(xùn)練部分過程如圖所示。訓(xùn)練過程7.3模型訓(xùn)練7.3.5模型訓(xùn)練訓(xùn)練結(jié)束后將多出一個(gè)checkpoints文件夾,如圖所示。訓(xùn)練后文件夾結(jié)構(gòu)checkpoints文件夾中包含了訓(xùn)練過程中的一些保存信息,如圖所示。訓(xùn)練信息保存文件夾結(jié)構(gòu)其中每個(gè)文件夾內(nèi)保存了對(duì)應(yīng)epoch的訓(xùn)練信息,訓(xùn)練是以ckpt的形式保存模型的,包含三個(gè)文件:(1).mate文件保存了當(dāng)前圖結(jié)構(gòu)(2).data文件保存了當(dāng)前參數(shù)名和值(3).index文件保存了輔助索引信息7.3模型訓(xùn)練7.3.5模型訓(xùn)練這里需要把ckpt固化成pb模型文件,真正部署的時(shí)候,一般不會(huì)提供ckpt的模型,而是固化成pb模型。程序見ckpt2pb.py,如圖所示,其中frozen_graph.pb文件就是后續(xù)小節(jié)“模型轉(zhuǎn)換”所需要的模型保存文件。在評(píng)估階段會(huì)用到數(shù)據(jù)集中的test部分,由于目錄結(jié)構(gòu)類似,所以這一部分的代碼其實(shí)就是train中驗(yàn)證部分給單獨(dú)提取出來,用訓(xùn)練過程中保存的pb文件進(jìn)行推理,代碼詳見eval.py,運(yùn)行腳本后會(huì)從train目錄的checkpoint文件中找到model_checkpoint_path權(quán)重進(jìn)行評(píng)估。run_once參數(shù)的作用在于是否定時(shí)對(duì)權(quán)重進(jìn)行評(píng)估,eval操作是可以和train同時(shí)進(jìn)行的,因?yàn)閠rain會(huì)定期保存權(quán)重,對(duì)應(yīng)的checkpoint中model_checkpoint_path權(quán)重隨之變化,所以可以實(shí)時(shí)對(duì)權(quán)重進(jìn)行評(píng)估,如圖所示。保存節(jié)點(diǎn)文件夾結(jié)構(gòu)評(píng)估結(jié)果7.4模型的量化7.4.1RKNN量化上面的所有步驟完成后,其實(shí)如果項(xiàng)目是用在PC端的,那么這個(gè)權(quán)重已經(jīng)可以落地了,但是本章節(jié)的最終目標(biāo)是將它在AIBOX中運(yùn)行,所以,針對(duì)AIBOX的環(huán)境,需要對(duì)模型文件進(jìn)行量化。模型量化所需要用到的RKNN-toolkit的container環(huán)境詳見前面章節(jié)。本書提供的此部分代碼在“權(quán)重轉(zhuǎn)換與量化”文件夾下,結(jié)構(gòu)如圖所示。這部分的作用是將模型轉(zhuǎn)化成RV1808芯片可用的類型,從而實(shí)現(xiàn)后續(xù)的部署。其中l(wèi)dw.py是將pb文件轉(zhuǎn)換為RKNN文件的程序,resize_ldw.py是調(diào)整素材的程序,test.py用于生成后的RKNN模型的推理。ret.png是執(zhí)行推理后的結(jié)果,它表示所轉(zhuǎn)化的RKNN模型文件可以實(shí)現(xiàn)車道線的檢測,并能看出其檢測效果。RKNN模型轉(zhuǎn)換文件夾結(jié)構(gòu)7.4模型的量化7.4.1RKNN量化其中有一個(gè)注意點(diǎn),就是圖片輸入的順序。車道線檢測的模型,用于輸入網(wǎng)絡(luò)訓(xùn)練的圖片其通道次序?yàn)锽GR,按照訓(xùn)練和部署需要統(tǒng)一的標(biāo)準(zhǔn),部署在AIBOX上送入網(wǎng)絡(luò)推理的圖片通道次序也應(yīng)該是BGR。RKNN的量化過程中,程序會(huì)讀取一個(gè)列表中的圖像送入網(wǎng)絡(luò)量化,內(nèi)部讀取圖片的方式是按照RGB來的,和OpenCV是相反的。所以如果要用BGR的圖片進(jìn)行量化,在準(zhǔn)備數(shù)據(jù)集的時(shí)候,如果用OpenCV打開,就要做一步操作,就是BGR2RGB。雖然參數(shù)上是BGR到RGB的轉(zhuǎn)化,但本質(zhì)上是通道變更,當(dāng)OpenCV將圖片按照RGB的格式保存以后,其他默認(rèn)以RGB載入圖片的包將圖片加載后,實(shí)際得到的就是BGR。首先準(zhǔn)備好一批素材用于量化,素材需要盡可能覆蓋所有可能出現(xiàn)的場景,將它們的尺寸調(diào)整為網(wǎng)絡(luò)輸入的大小,并生成文件列表,程序見代碼清單7-5。然后運(yùn)行l(wèi)dw.py程序?qū)b模型轉(zhuǎn)換為RKNN模型,程序見代碼清單。7.4模型的量化7.4.1RKNN量化量化部分重點(diǎn)要講的是推理的部分,在PC上推理出正確的結(jié)果,那么在部署的時(shí)候只需要把對(duì)應(yīng)的Python代碼翻譯成C++即可。PC推理的代碼在test.py中,核心代碼片段如下。print('-->Runningmodel')outputs=rknn.inference(inputs=[img])print('done')

nout=len(outputs)foriinrange(np.array(outputs).shape[2]):l1=outputs[0][0][i][0]l2=outputs[0][0][i][1]ifl1>l2:#這里可以參考訓(xùn)練工程中的輸出節(jié)點(diǎn)來理解

#logit=tf.reshape(network,(-1,args.input_height*args.input_width,num_classes),name='logits')

#當(dāng)通道0的數(shù)值大時(shí)則該像素格推理為背景,填充0,黑色

#當(dāng)通道1的數(shù)值大時(shí)則該像素格推力為車道線,填充255,白色

img[i//img_w][i%img_w][0]=0

img[i//img_w][i%img_w][1]=0

img[i//img_w][i%img_w][2]=0else:

img[i//img_w][i%img_w][0]=255

img[i//img_w][i%img_w][1]=255

img[i//img_w][i%img_w][2]=255cv2.imwrite("ret.png",img)7.4模型的量化7.4.1RKNN量化結(jié)合代碼中注釋來解釋。推理后的輸出有4個(gè)維度,第一個(gè)維度是rk中輸出節(jié)點(diǎn),當(dāng)前項(xiàng)目只有一個(gè)輸出,所以這一維度是1;第二個(gè)維度是圖片的張數(shù),其實(shí)也就是batchsize,這里也是1,這兩個(gè)維度在本項(xiàng)目中沒有作用;第三個(gè)維度是在訓(xùn)練時(shí)將圖片的寬高兩個(gè)維度給轉(zhuǎn)化成了一維,還是可以按照h*w的排布來解析;第四個(gè)維度是通道,這里是對(duì)應(yīng)像素點(diǎn)上0通道的值和1通道的值,其實(shí)也就是對(duì)應(yīng)類別的分?jǐn)?shù)。在解析的過程中,只需要取分?jǐn)?shù)大的通道作為當(dāng)前像素格上的推理結(jié)果即可。下圖為推理過程及推理后的結(jié)果。推理過程推理結(jié)果原圖(左)推理后(右)7.4模型的量化7.4.2小結(jié)通過上述項(xiàng)目的量化過程可以看到,量化是整個(gè)過程中必不可少的一環(huán),因?yàn)榱炕诩铀偻评淼耐瑫r(shí),也是對(duì)硬件環(huán)境的一種適配。其實(shí)即便是落地在PC上的項(xiàng)目,原模型可以直接運(yùn)行的情況下,考慮到性能也會(huì)使用例如TensorRT等方式對(duì)模型進(jìn)行量化。在這個(gè)階段需要關(guān)心的只是送入網(wǎng)絡(luò)的圖片和網(wǎng)絡(luò)輸出的數(shù)據(jù)解析。為了讓模型在項(xiàng)目部署落地上有最佳的表現(xiàn),訓(xùn)練、量化、落地這三個(gè)階段所有的素材、網(wǎng)絡(luò)輸入輸出都必須有統(tǒng)一標(biāo)準(zhǔn)。7.5項(xiàng)目部署與落地經(jīng)過上述幾個(gè)環(huán)節(jié)得到RKNN文件后,我們就能將模型移植進(jìn)RV1808芯片的嵌入式板子中了,這部分就是嵌入式開發(fā)的工作。通過AIBOX的攝像頭得到輸入圖像,經(jīng)過前面得到的模型實(shí)現(xiàn)車道線檢測,將其繪制輸出到顯示屏上。其邏輯和上一節(jié)的推理過程類似。此部分代碼例程在“部署代碼”文件夾下,其結(jié)構(gòu)如圖所示。其中build用于camke與make生成文件的存放,build_emv.cmake用于編譯環(huán)境配置,供CMakeLists調(diào)用,CMakeLists.txt用于生成makefile,各源碼模塊中也有對(duì)應(yīng)文件,逐級(jí)調(diào)用。sdk_rk1808文件夾保存相關(guān)的sdk,src是源碼,其結(jié)構(gòu)如圖所示。在./src/stest/assets/rk1808下存放RKNN模型文件,在./src/test下是測試程序。部署代碼文件夾結(jié)構(gòu)src文件夾結(jié)構(gòu)7.5項(xiàng)目部署與落地7.5.1源碼解析本小節(jié)僅對(duì)關(guān)鍵函數(shù)進(jìn)行解析,其他可見源碼的注釋。主模塊,對(duì)rga進(jìn)行初始化。詳見代碼清單7-6。車道線檢測需要推理的僅僅是圖片的下半部分,在程序中rga初始化的部分,就要和訓(xùn)練時(shí)數(shù)據(jù)集處理步驟對(duì)應(yīng)起來,先裁剪下半部分,再縮放到網(wǎng)絡(luò)輸入的大小。子線程循環(huán)推理,詳見代碼清單。這部分代碼中,因?yàn)楸卷?xiàng)目僅介紹到模型推理的部分,單純從語義分割的結(jié)果上來看,到這一步回調(diào)給外部的就是一張和標(biāo)簽圖類似的圖片。實(shí)際車道線項(xiàng)目中會(huì)在推理結(jié)果的基礎(chǔ)上做進(jìn)一步的后處理,然后依據(jù)上層應(yīng)用的需求返回車道線。推理模塊,網(wǎng)絡(luò)輸出轉(zhuǎn)換為像素格類別。詳見代碼清單。這部分代碼就是PC上測試代碼的翻譯,函數(shù)中做了nhwc和nchw的兼容,這一部分信息RKNN在量化時(shí)已經(jīng)寫入了模型中。TensorFlow默認(rèn)是nhwc排布,所以本項(xiàng)目中值用到了判斷的第一個(gè)分支,感興趣的讀者可以嘗試用PyTorch搭建復(fù)現(xiàn)模型,然后同樣可以用這份代碼落地。7.5項(xiàng)目部署與落地7.5.2部署工程使用本書提供的例程,進(jìn)入“部署代碼”文件夾,進(jìn)入build中,執(zhí)行cmake命令。cmake-DTARGET_SDK=../sdk_rk1808..當(dāng)看到如下打印時(shí)則表明執(zhí)行成功。--Configuringdone--Generatingdone執(zhí)行編譯makeinstall如果沒有報(bào)錯(cuò)并且打印了一連串的--Installing:信息,則表示執(zhí)行成功。至此在build下會(huì)生成一個(gè)install的目錄,結(jié)構(gòu)如圖所示。其中assets是模型文件,從src/otest/assets中拷貝過來的;include是主模塊庫的頭文件,從src/otest中拷貝過來的;lib是主模塊的庫文件和相關(guān)聯(lián)的一些庫;test_test是生成的可執(zhí)行文件??蓤?zhí)行文件所在文件夾結(jié)構(gòu)7.5項(xiàng)目部署與落地7.5.2部署工程進(jìn)入到install文件夾下,將程序推入AIBOX。adbpushotest/home如果是通過網(wǎng)線連接,AIBOX也可以直接拖拽進(jìn)去。進(jìn)入到AIBOX中,進(jìn)入剛才推送程序的路徑,這里是/home/otest,對(duì)可執(zhí)行程序賦權(quán)限后執(zhí)行。chmod755test_test./test_test程序開始運(yùn)行,并打印出如圖所示的單張圖片的推理速度、當(dāng)前的推理幀率、視頻流幀率。處理信息打印7.5項(xiàng)目部署與落地7.5.2部署工程程序運(yùn)行結(jié)果如圖所示。終端識(shí)別結(jié)果(1)終端識(shí)別結(jié)果(2)課后習(xí)題1)什么是車道線檢測?2)車道線檢測有哪些方法?3)什么是數(shù)據(jù)增強(qiáng)?4)車道線檢測有哪些挑戰(zhàn)?5)如何克服這些挑戰(zhàn)?8人臉檢測實(shí)踐FACIALDETECTIONPRACTICEChapter02學(xué)習(xí)目標(biāo)數(shù)據(jù)集采集與標(biāo)注01模型訓(xùn)練 02模型量化03項(xiàng)目落地與部署048人臉檢測實(shí)踐本章介紹的是人臉檢測項(xiàng)目,顧名思義,就是通過目標(biāo)檢測方法獲取圖像中的人臉,本項(xiàng)目還包括同時(shí)獲取人臉的五個(gè)關(guān)鍵點(diǎn),包括兩只眼睛、鼻子和兩嘴角。單純的人臉檢測是人臉關(guān)鍵點(diǎn)檢測的前提,但由于本項(xiàng)目同時(shí)檢測人臉和關(guān)鍵點(diǎn),因此不需要再單獨(dú)實(shí)現(xiàn)人臉關(guān)鍵點(diǎn)檢測功能,這能大大提升程序的整體運(yùn)行速度。人臉檢測的主要應(yīng)用場景有智慧人臉考勤、刷臉閘機(jī)通行、門禁、人臉特效美顏、名人換臉等。

接下來介紹本項(xiàng)目人臉檢測的主要流程,如右圖所示,后續(xù)將詳細(xì)介紹流程每一節(jié)點(diǎn)。8.1數(shù)據(jù)集采集與標(biāo)注8.1.1素材采集本項(xiàng)目的素材來源主要有兩個(gè):1)公開數(shù)據(jù)集本項(xiàng)目使用WIDERFACE數(shù)據(jù)集,下載網(wǎng)址是http://shuoyang1213.me/WIDERFACE/。根據(jù)官網(wǎng)的介紹,WiderFace數(shù)據(jù)集最早是在2015年公開的(v1.0版本)。該數(shù)據(jù)集的圖片來源是WIDER數(shù)據(jù)集,從中挑選出了32,203圖片并進(jìn)行了人臉標(biāo)注,總共標(biāo)注了393,703個(gè)人臉數(shù)據(jù)。并且對(duì)于每張人臉都附帶有更加詳細(xì)的信息,包括expression(表情),illumination(光照),occlusion(遮擋),pose(姿態(tài))等,如圖所示,后面會(huì)進(jìn)一步介紹。8.1數(shù)據(jù)集采集與標(biāo)注8.1.1素材采集數(shù)據(jù)集文件結(jié)構(gòu)如右所示,包含人臉檢測和人臉關(guān)鍵點(diǎn)數(shù)據(jù)集,分別存放于WIDER_FACE_rect和WIDER_FACE_landmark文件夾。#人臉檢測數(shù)據(jù)集├──WIDER_FACE_landmark│├──annotations│ ├──0--Parade│ ├──0_Parade_marchingband_1_849.xml│├──images│ ├──0--Parade│ ├──0_Parade_marchingband_1_849.jpg#人臉關(guān)鍵點(diǎn)數(shù)據(jù)集├──WIDER_FACE_rect│├──annotations│ ├──0--Parade│ ├──0_Parade_marchingband_1_849.xml│├──images│ ├──0--Parade│ ├──0_Parade_marchingband_1_849.jpg8.1數(shù)據(jù)集采集與標(biāo)注8.1.1素材采集WIDER_FACE_rect文件夾包含61類人臉,共12880張jpg格式的圖片和xml格式的標(biāo)簽,分別存放于當(dāng)前目錄下的images和annotations文件夾中,xml標(biāo)簽文件包含了圖片所有人臉的坐標(biāo)。xml標(biāo)簽文件內(nèi)容如下所示:<?xmlversion="1.0"?><annotation> #標(biāo)簽對(duì)應(yīng)的圖像名稱<filename>1501925967889.jpg</filename>#圖像大小,包括寬、高和通道數(shù)<size><width>640</width><height>480</height><depth>3</depth></size>#人臉目標(biāo)<object><name>face</name><truncated>1</truncated><difficult>0</difficult> #人臉框左上角和右下角坐標(biāo)<bndbox><xmin>317</xmin><ymin>0</ymin><xmax>534</xmax><ymax>200</ymax></bndbox> #無人臉關(guān)鍵點(diǎn)<has_lm>0</has_lm></object></annotation>8.1數(shù)據(jù)集采集與標(biāo)注8.1.1素材采集WIDER_FACE_landmark文件夾包含了同樣類別的人臉,共12596張圖片和標(biāo)簽,同樣分別存放于當(dāng)前目錄下的images和annotations文件夾中,xml標(biāo)簽文件包含了圖片所有人臉關(guān)鍵點(diǎn)的坐標(biāo)。與WIDER_FACE_rect中相同人臉圖像對(duì)應(yīng)的人臉關(guān)鍵點(diǎn)標(biāo)簽文件內(nèi)容如下所示:<?xmlversion="1.0"?><annotation> #標(biāo)簽文件對(duì)應(yīng)的圖像,與上一標(biāo)簽圖像名稱相同,不同是標(biāo)簽包含的信息有區(qū)別<filename>1501925967889.jpg</filename>#圖像大小,包括寬、高和通道數(shù)<size><width>640</width><height>480</height><depth>3</depth></size>#人臉目標(biāo)

<object><name>face</name><truncated>1</truncated><difficult>0</difficult>#人臉框左上角和右下角坐標(biāo)<bndbox><xmin>317</xmin><ymin>0</ymin><xmax>534</xmax><ymax>200</ymax></bndbox> #人臉框?qū)?yīng)的人臉關(guān)鍵點(diǎn)坐標(biāo),包括兩只眼睛、鼻子和兩嘴角坐標(biāo)<lm><x1>389.362</x1><y1>38.352</y1><x2>478.723</x2><y2>36.879</y2><x3>451.773</x3><y3>85.816</y3><x4>405.674</x4><y4>137.589</y4><x5>482.27</x5><y5>133.333</y5></lm> #有人臉關(guān)鍵點(diǎn)<has_lm>1</has_lm></object></annotation>8.1數(shù)據(jù)集采集與標(biāo)注8.1.1素材采集2)自主采集由于不同攝像頭采集的圖像其特征存在差異,因此利用公開數(shù)據(jù)集訓(xùn)練得到的模型有時(shí)候不一定能在自己攝像頭獲取的圖像上推理成功,這時(shí)就需要使用自己攝像頭采集的數(shù)據(jù)集進(jìn)行訓(xùn)練,來減少訓(xùn)練圖像和推理圖像特征之間存在的差異,從而提升圖像推理成功率。自主采集首先需確定攝像頭類型,然后利用第3.2.4節(jié)介紹的方式進(jìn)行素材采集,此處不再贅述。通過自主采集獲得數(shù)據(jù)集之后,需要將數(shù)據(jù)集按WIDERFACE數(shù)據(jù)集結(jié)構(gòu)形式存放,有利于后續(xù)的數(shù)據(jù)集制作和數(shù)據(jù)集加載。8.1數(shù)據(jù)集采集與標(biāo)注8.1.2素材標(biāo)注公開數(shù)據(jù)集已包含訓(xùn)練所需的人臉框和關(guān)鍵點(diǎn)標(biāo)簽信息,因此無需再對(duì)其進(jìn)行標(biāo)注,現(xiàn)主要針對(duì)自主采集的素材進(jìn)行標(biāo)注。首先,根據(jù)項(xiàng)目的具體任務(wù)選擇合適的標(biāo)注軟件。本項(xiàng)目的任務(wù)是對(duì)圖像中的人臉及其5個(gè)關(guān)鍵點(diǎn)進(jìn)行檢測,也就是說標(biāo)注素材時(shí)既需要標(biāo)注人臉框,也需要標(biāo)注人臉關(guān)鍵點(diǎn),本項(xiàng)目選擇LabelImge和Sloth標(biāo)注軟件分別對(duì)人臉和關(guān)鍵點(diǎn)進(jìn)行標(biāo)注。其次,標(biāo)注之前,需要明確本項(xiàng)目的圖像標(biāo)注要求??山Y(jié)合項(xiàng)目的具體需求對(duì)自主采集的素材進(jìn)行標(biāo)注,標(biāo)注要求如下:1)標(biāo)注人臉框時(shí),人臉框需包含整個(gè)人臉輪廓,不包含耳朵和額頭往上的頭發(fā)部分;標(biāo)注人臉關(guān)鍵點(diǎn)時(shí),關(guān)鍵點(diǎn)應(yīng)在眼睛開合處的中心、鼻尖和嘴角如圖(a)所示。2)當(dāng)人臉是側(cè)臉,且看不見該人臉的眼睛、鼻子和嘴巴時(shí),不標(biāo)注人臉框及其關(guān)鍵點(diǎn),如圖(b)所示。3)當(dāng)人臉被遮擋,且看不見該人臉的眼睛、鼻子和嘴巴或者遮擋超過一半時(shí),不標(biāo)注人臉框及其關(guān)鍵點(diǎn),如圖(c)所示。4)因圖像較為模糊、曝光較強(qiáng)、光線較暗導(dǎo)致人臉特征不清晰時(shí),不標(biāo)注人臉及其關(guān)鍵點(diǎn),如圖(d)所示。8.2環(huán)境部署 本項(xiàng)目采用的深度學(xué)習(xí)框架是PyTorch,版本為2.0.1。假設(shè)已安裝PyTorch2.0.1虛擬環(huán)境,還需安裝的Python依賴包及其版本如下所示。PackageVersion-----------------------------------------albumentations1.0.3matplotlib3.3.4numpy1.19.2onnx1.9.0onnx-simplifier0.3.6onnxoptimizer0.2.6onnxruntime1.8.0opencv-pythonopencv-python-headless6Pillow8.2.0protobuf3.17.2scikit-image0.17.2scipy1.5.4tqdm4.62.28.2環(huán)境部署 建議將上述依賴包寫入requirements.txt中,然后使用pipinstall-rrequirements.txt自動(dòng)安裝。如果建議方法安裝較慢,也可使用pip單獨(dú)進(jìn)行安裝,命令最后加上國內(nèi)源,如下所示,即可加快安裝速度。pipinstallalbumentations=1.0.3-i/ubuntu/8.3模型訓(xùn)練8.3.1訓(xùn)練代碼準(zhǔn)備從/ShiqiYu/libfacedetection.train.git下載訓(xùn)練代碼。代碼包含兩部分,如下所示,一部分是數(shù)據(jù)集制作、iou損失計(jì)算、nms、預(yù)選框生成等模塊,一部分是網(wǎng)絡(luò)定義、訓(xùn)練、測試和ONNX模型轉(zhuǎn)換等相關(guān)腳本。├──src│├──data.py│├──eiou.py│├──multibox_loss.py│├──nms.py│├──prior_box.py│├──timer.py│└──utils.py└──tasks └──task1 ├──config.py ├──datasets.py ├──detect.py ├──exportcpp.py ├──exportonnx.py ├──test.py ├──train.py └──yufacedetectnet.py。8.3模型訓(xùn)練8.3.2模型設(shè)計(jì)思想本項(xiàng)目采用的模型YuFaceDetectNet是一個(gè)輕量級(jí)的SSD架構(gòu),該網(wǎng)絡(luò)實(shí)現(xiàn)了多個(gè)尺度特征預(yù)測,這大大提升了小目標(biāo)的檢測精度,同時(shí)該網(wǎng)絡(luò)還借鑒了RetinaFace回歸關(guān)鍵點(diǎn)的方法,可以在回歸人臉框的同時(shí)回歸該人臉的5個(gè)關(guān)鍵點(diǎn)。下面通過代碼實(shí)現(xiàn)的方式詳細(xì)介紹該網(wǎng)絡(luò)模型。首先,定位到項(xiàng)目中train.py中模型的入口,如下代碼所示:#從模型定義文件中導(dǎo)入模型類from

yufacedetectnet

import

YuFaceDetectNet#模型輸入img_dim

=

160#加載模型net

=

YuFaceDetectNet('train',

img_dim)然后,定位至yufacedetectnet.py中的YuFaceDetectNet類,見書本246頁代碼所示,從__init__、multibox和forward三個(gè)模塊可知,本項(xiàng)目采用的模型由特征提取網(wǎng)絡(luò)和SSD檢測頭組成,特征提取網(wǎng)絡(luò)采用類似VGG的直筒式結(jié)構(gòu),由多組卷積層以及最大池化層完成下采樣,每組卷積層由兩到三個(gè)卷積模塊組成[3*3+1*1]或[3*3+1*1+3*3]的組合,每個(gè)卷積模塊由卷積Conv2d、歸一化BatchNorm2d和激活函數(shù)ReLu構(gòu)成,即網(wǎng)絡(luò)代碼里的self.model1~self.model6。圖像經(jīng)過上述特征提取網(wǎng)絡(luò)得到四個(gè)特征層的特征,分別是self.model3、self.model4、self.model5、self.model6層的輸出,這四個(gè)層的特征通過SSD檢測頭最終輸出人臉框位置loc、置信度conf和iou。8.3模型訓(xùn)練8.3.2模型設(shè)計(jì)思想最后,定位到SSD模塊的預(yù)選框生成部分,即train.py中的PriorBox類實(shí)例和src/prior_box.py中的PriorBox類實(shí)現(xiàn)部分。由config.py中的cfg字典中的“min_sizes”可知,libfacedetection設(shè)置了四組錨框,分別是[[10,

16,

24],

[32,

48],

[64,

96],

[128,

192,

256]],共有3+2+2+3=9種不同尺寸的預(yù)選框。由src.py中的PriorBox類可知,每組錨框?qū)?yīng)不同的特征層,因此共需要四個(gè)特征層來生成預(yù)選框,分別是輸入圖像的1/8、1/16、1/32、1/64下的特征層。由上述條件,我們可獲取預(yù)選框生成公式如下:上述公式中,

為生成的預(yù)選框總數(shù)量,

分別表示每個(gè)特征層的寬高,即輸入圖像尺寸的1/8、1/16、1/32、1/64特征尺寸,

表示每個(gè)特征層上的每一個(gè)像素所對(duì)應(yīng)的預(yù)選框個(gè)數(shù),即該特征層對(duì)應(yīng)的一組錨框的尺寸。假如圖像輸入寬高為160和160,有上述公式可得,生成的預(yù)選框總計(jì)(160/8)*(160/8)*3+(160/16)*(160/16)*2+(160/32)*(160/32)*2+(160/64)*(160/64)*3=1200+200+50+45=1495個(gè)。8.3模型訓(xùn)練8.3.3數(shù)據(jù)集制作(1)數(shù)據(jù)集制作通過第8.1節(jié)素材采集和標(biāo)注,我們得到了一批原始數(shù)據(jù)集,現(xiàn)在需要將原始數(shù)據(jù)集制作成訓(xùn)練時(shí)數(shù)據(jù)集加載所需的文件img_list.txt,該文件每一行保存一張圖片路徑和對(duì)應(yīng)的xml標(biāo)簽文件路徑信息并以空格分開,注意文件名不能有空格,路徑信息由兩部分組成并以符號(hào)“_”連接,“_”之前為該圖片或標(biāo)簽所屬文件夾名,之后為該圖片或標(biāo)簽真實(shí)名稱,如下所示為根據(jù)WIDER_FACE_rect數(shù)據(jù)集制作成的

img_list.txt。0--Parade_0_Parade_marchingband_1_849.jpg0--Parade_0_Parade_marchingband_1_849.xml0--Parade_0_Parade_Parade_0_904.jpg0--Parade_0_Parade_Parade_0_904.xml0--Parade_0_Parade_marchingband_1_799.jpg0--Parade_0_Parade_marchingband_1_799.xml8.3模型訓(xùn)練8.3.3數(shù)據(jù)集制作以第一行為例,圖片路徑信息為0--Parade_0_Parade_marchingband_1_849.jpg,標(biāo)簽路徑信息為0--Parade_0_Parade_marchingband_1_849.xml,中間用空格分開,其中兩者路徑信息0--Parade_0_Parade_marchingband_1_849由兩部分組成并以符號(hào)“_”連接,其中0--Parade是該圖片和標(biāo)簽所屬的文件夾,0_Parade_marchingband_1_849.jpg為該文件夾下一張圖片的名稱,具體的圖片路徑為WIDER_FACE_rect/images/0--Parade/0_Parade_marchingband_1_849.jpg,標(biāo)簽路徑為WIDER_FACE_rect/annotations/0--Parade/0_Parade_marchingband_1_849.xml,該路徑將由后續(xù)數(shù)據(jù)集加載部分獲取?,F(xiàn)在,我們使用make_data_list.py中的如下代碼將數(shù)據(jù)集制作成img_list.txt,如果公開數(shù)據(jù)集中已生成該文件,可忽略此操作。8.3模型訓(xùn)練8.3.3數(shù)據(jù)集制作(2)數(shù)據(jù)集加載根據(jù)(1)獲取數(shù)據(jù)集文件img_list.txt后,在訓(xùn)練時(shí)需要對(duì)img_list.txt包含的所有圖片和標(biāo)簽進(jìn)行加載,即根據(jù)設(shè)置的數(shù)據(jù)集目錄和img_list.txt文件,對(duì)數(shù)據(jù)集進(jìn)行解析。解析模塊包括xml轉(zhuǎn)換、圖像增強(qiáng)、裁剪等。dataset_rect=FaceRectLMDataset(training_face_rect_dir,img_dim,rgb_mean)使用PyTorch數(shù)據(jù)加載模塊加載數(shù)據(jù),輸出是一個(gè)以批次(batchsize)為單位的字典。train_loader=torch.utilis.data.DataLoader(dataset=dataset,batch_size=batch_size,collate_fn=detection_collate,shuffle=True,num_workers=num_workers,pin_memory=False,drop_last=True,)讀入PyTorch數(shù)據(jù)加載結(jié)果,以batch為單位,將數(shù)據(jù)送入網(wǎng)絡(luò),得到網(wǎng)絡(luò)推理結(jié)果。foriter_idx,one_batch_datainenumerate(train_loader) images,targets=one_batch_data out=net(images)8.3模型訓(xùn)練8.3.4訓(xùn)練參數(shù)設(shè)置'--training_face_rect_dir''--training_face_landmark_dir''-b','--batch_size''--num_workers''--gpu_ids''--lr','--learning-rate''--momentum''--resume_net''--resume_epoch''-max','--max_epoch''--weight_decay''--gamma''--weight_filename_prefix''--lambda_bbox''--lambda_iouhead'1)優(yōu)化器和損失函數(shù)optimizer=optim.SGD(net.parameters(),lr=args.lr,momentum=momentum,weight_decay=weight_decay)criterion=MultiBoxLoss(num_classes,0.35,True,0,True,3,0.35,False,False)#lossofdifferentpartloss_l,loss_lm,loss_c,loss_iou=criterion(out,priors,targets)#backpropoptimizer.zero_grad()loss.backward()optimizer.step()8.3模型訓(xùn)練8.3.4訓(xùn)練2)訓(xùn)練在設(shè)置參數(shù)后,就可以訓(xùn)練了。訓(xùn)練腳本train.sh如下:pythontrain.py--gamma0.1--gpu_ids0,1,2可以在腳本中適當(dāng)增加定制參數(shù)。nohuptrain.sh&3)保存模型見train.py中的相關(guān)代碼。4)測試pythondetect.py-mweights/yunet_final.pth--

image_file=test.jpg測試所需源圖像如左圖所示,其推理結(jié)果如右圖所示。5)結(jié)果評(píng)估pythontest.py-mweights/yunet_final.pth8.4模型量化8.4.1ONNX轉(zhuǎn)換及測試

代碼清單8-3#第一步,從pth文件加載模型#第二步,使用torch的onnx模塊導(dǎo)出onnx模型weights=“weights/yunet_final.pth”file=weights.replace('.pt','.onnx')torch.onnx.export(model,img,file,verbose=False,opset_version=11,input_names=['images'],dynamic_axes={'images':{0:'batch',2:'height',3:'width'},'output':{0:'batch',2:'y',3:'x'}}ifopt.dynamicelseNone)#第三步,checkimportonnxmodel_onnx=onnx.load(f)onnx.checker.check_model(model_onnx)#第四步,簡化importonnxsimmodel_onnx,check=onnxsim.simplify(model_onnx,dynamic_input_shape=opt.dynamic,input_shapes={'images':list(img.shape)}ifopt.dynamicelseNone)onnx.save(model_onnx,file)8.4模型量化8.4.1ONNX轉(zhuǎn)換及測試

onnx轉(zhuǎn)rknn#第一步,創(chuàng)建rknn對(duì)象rknn=RKNN()#第二步,預(yù)處理配置rknn.config(channel_mean_value='0.00.00.01.0',reorder_channel='201',target_platform=target_platform_str)#第三步,加載onnx模型ret=rknn.load_onnx(model='weights/yunet_final.onnx')#第四步,構(gòu)建模型ret=rknn.build(do_quantization=True,dataset='./dataset300_192.txt',pre_compile=True)#第五步,輸出rknn模型ret=rknn.export_rknn('./face_det.rknn')#第六步,釋放資源rknn.release()最終生成的模型如下圖所示8.4模型量化8.4.2rknn轉(zhuǎn)換及測試importrknn#Setinputsimg=cv2.imread('./cat_224x224.jpg')img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)print('-->Initruntimeenvironment')ret=rknn.init_runtime()ifret!=0:print('Initruntimeenvironmentfailed')exit(ret)print('done')#Inferenceprint('-->Runningmodel')outputs=rknn.inference(inputs=[img])show_outputs(outputs)print('done')#perf-性能測試print('-->Beginevaluatemodelperformance')perf_results=rknn.eval_perf(inputs=[img])print('done')8.6項(xiàng)目落地8.6.1編譯環(huán)境

操作系統(tǒng)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論