人工智能技術(shù)及應(yīng)用 課件 ch5-攝像頭模糊檢測(cè)_第1頁
人工智能技術(shù)及應(yīng)用 課件 ch5-攝像頭模糊檢測(cè)_第2頁
人工智能技術(shù)及應(yīng)用 課件 ch5-攝像頭模糊檢測(cè)_第3頁
人工智能技術(shù)及應(yīng)用 課件 ch5-攝像頭模糊檢測(cè)_第4頁
人工智能技術(shù)及應(yīng)用 課件 ch5-攝像頭模糊檢測(cè)_第5頁
已閱讀5頁,還剩38頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

5攝像頭模糊檢測(cè)SMART+FUTUREChapter05本章目錄數(shù)據(jù)采集與標(biāo)注01模型訓(xùn)練02模型量化03項(xiàng)目源碼分析部署與測(cè)試04本章總體介紹本章主要介紹了關(guān)于本實(shí)驗(yàn)的數(shù)據(jù)集采集與標(biāo)注,其中包括素材預(yù)處理,劃分,形成多個(gè)數(shù)據(jù)集。采用深度學(xué)習(xí)框架PyTorch進(jìn)行模型訓(xùn)練,通過Aim可視化進(jìn)行管理。模型量化包括onnx及的模型轉(zhuǎn)換,推理及驗(yàn)證,并對(duì)兩種模型進(jìn)行了對(duì)比。然后對(duì)項(xiàng)目的源碼進(jìn)行剖析,介紹不同組件的作用及具體的代碼,方便讀者根據(jù)自己的需要增加其他組件。最后進(jìn)行項(xiàng)目部署和測(cè)試。整體流程圖如圖所示,通過流程圖可以有個(gè)整體的解決思路。本章總體介紹在進(jìn)行攝像頭模糊檢測(cè)具體場(chǎng)景應(yīng)用時(shí),首先應(yīng)考慮分類方法問題,尤其是線性回歸方法是否適用的問題;在計(jì)算損失函數(shù)時(shí),需要對(duì)預(yù)測(cè)值遠(yuǎn)遠(yuǎn)偏離真實(shí)值的對(duì)象進(jìn)行懲罰,懲罰宜適度,需要在過擬合(懲罰力度過大)和欠擬合(懲罰力度不夠)之間達(dá)到平衡。一般來講,攝像頭模糊檢測(cè)場(chǎng)景應(yīng)用時(shí)并不推薦聚類方法,這是因?yàn)榫垲惙椒m然不需要訓(xùn)練集,但是其準(zhǔn)確率較低。由此可見,運(yùn)用有監(jiān)督的圖片分類方法產(chǎn)生離散的結(jié)果,是攝像頭模糊檢測(cè)應(yīng)用場(chǎng)景的優(yōu)選。那么需要解決的問題就變成了:1)訓(xùn)練一個(gè)自己的分類器(后面也叫分類模型);2)驗(yàn)證并選擇最優(yōu)的分類模型;3)預(yù)測(cè)樣本是屬于哪一類,此時(shí)輸出變量通常取有限個(gè)離散值,即需要的類別數(shù)。注意:多分類問題也是可以轉(zhuǎn)化為二分類問題的:具體就是將某類標(biāo)記為正類,其余類標(biāo)記為負(fù)類。5.1數(shù)據(jù)集采集與標(biāo)注5.1.1素材采集對(duì)于人類肉眼來講,識(shí)別攝像頭是否模糊、是否遮擋、是否正常是特別容易的,首先肉眼平時(shí)就能大量接觸這類圖像,我們對(duì)其特征有著十分深刻的認(rèn)識(shí),因此遇到這類問題的第一印象是這個(gè)場(chǎng)景非常容易識(shí)別的,但是對(duì)于計(jì)算機(jī)視覺算法來講就不是一回事了。下面是可能會(huì)出現(xiàn)的問題及對(duì)應(yīng)的解決辦法:1)攝像頭的硬件參數(shù)可能影響最終的成像效果,直接影響著分類器(分類模型)的結(jié)果,因此要選定一款攝像頭,從訓(xùn)練到測(cè)試部署都得用該攝像頭及該攝像頭錄制的素材。2)在像素層面上,光照的影響不能不考慮,尤其是夜間無燈光的情況下,極容易與遮擋混淆。因此最好選取能夠補(bǔ)光的攝像頭拍攝的素材進(jìn)行訓(xùn)練。3)素材量很重要的,模糊、遮擋、正常的素材都需要足夠,且覆蓋常用場(chǎng)景,做到各類樣本量均衡。4)不同場(chǎng)景也會(huì)影響最終的識(shí)別效果,例如雨天雨水導(dǎo)致的模糊及各種燈光直射導(dǎo)致的光斑都能認(rèn)為是模糊,但實(shí)際場(chǎng)景中一旦兩者結(jié)合極容易識(shí)別成遮擋,這是無法避免的,只能在數(shù)據(jù)集預(yù)標(biāo)注時(shí)統(tǒng)一標(biāo)準(zhǔn)。5)尺度問題,送入分類器(分類模型)的圖片可能存在部分遮擋的情況,若在原圖中截取一部分和整張圖上resize后再送入網(wǎng)絡(luò)的判別結(jié)果可能存在差異。同時(shí)送入模型的圖片size不能過小,不然提取到的特征不足以區(qū)分各類別。5.1數(shù)據(jù)集采集與標(biāo)注

需要訓(xùn)練的素材來源可以有多個(gè)不同的渠道,可以在internet上尋找公開數(shù)據(jù)集下載、在計(jì)算機(jī)的屏幕上截取、從視頻文件中捕捉(使用ffmpeg逐幀截?。⒗檬謾C(jī)或攝像機(jī)數(shù)碼相機(jī)等便攜設(shè)備。

但由于該項(xiàng)目需要部署在特定的設(shè)備上,且主要是通過攝像頭進(jìn)行識(shí)別,因此我們需要用指定的攝像頭獲取對(duì)應(yīng)的素材進(jìn)行訓(xùn)練,可以將錄制的視頻導(dǎo)出并使用ffmpeg軟件將視頻文件截取成一張張圖片,圖片的格式分為矢量圖和位圖,一般都是截取為JPEG壓縮的位圖。采集步驟: 1)選取攝像頭,視項(xiàng)目而定。 2)選取錄制地點(diǎn),視項(xiàng)目部署地點(diǎn)而定。 3)設(shè)備通電,各連接線連接完成。 4)針對(duì)白天黑夜不同光照條件下,多次嘗試可能存在的情形。 5)導(dǎo)出視頻,運(yùn)用ffmpeg按幀截取視頻并保存。導(dǎo)出的素材如圖所示,其中左上圖為模糊類素材、右上圖和左下圖為遮擋類素材,右下為正常類圖片:5.1數(shù)據(jù)集采集與標(biāo)注5.1.2素材預(yù)處理分類問題的歸類方法如下:1)確定好標(biāo)準(zhǔn),每一類有明顯的參照標(biāo)準(zhǔn),不同類間有明確的分解標(biāo)準(zhǔn)。例如本項(xiàng)目中遮擋即一半以上認(rèn)為是遮擋,畫面看不清背景的設(shè)置為模糊,當(dāng)因?yàn)檎趽醵床磺灞尘暗目蓞⒄?)自行決定如何處理。2)對(duì)于模棱兩可的數(shù)據(jù),設(shè)置統(tǒng)一處理方法,可以棄用,也可以統(tǒng)一標(biāo)注。例如本項(xiàng)目就可直接棄用。將歸類好的素材進(jìn)行One-hot編碼,One-hot編碼又叫一位有效編碼,主要是采用N位狀態(tài)寄存器來對(duì)N個(gè)狀態(tài)進(jìn)行編碼,每個(gè)狀態(tài)都由他獨(dú)立的寄存器位,并且在任意時(shí)候只有一位有效。因?yàn)樵擁?xiàng)目中模糊、遮擋、正常這三個(gè)特征值并不連續(xù),而是離散的、無序的,因此我們規(guī)定分類的三個(gè)變量經(jīng)過編碼后為:模糊->0遮擋->1正常->2將分類變量作為二進(jìn)制向量表示的好處在于:1)將離散的屬性映射到歐式空間上的某個(gè)點(diǎn),解決分類器難以處理屬性數(shù)據(jù)的問題。2)一定程度上擴(kuò)充特征,計(jì)算特征距離時(shí)更合理。注意:onehot編碼前提是必須各類別互相獨(dú)立。5.1數(shù)據(jù)集采集與標(biāo)注5.1.3素材劃分確認(rèn)好編碼方式后即需要?jiǎng)?chuàng)建dataset文件夾,文件夾的目錄結(jié)構(gòu)如下:.├──0├──1└──2“0”文件夾代表模糊素材存放文件夾,“1”文件夾代表遮擋素材存放文件夾,2文件夾代表正常素材存放文件夾。素材量需要均衡,素材量少的類別的素材盡量不低于素材量多的類別的素材的1/3,如果不能符合要求盡量通過特定場(chǎng)景進(jìn)行多次采集。編碼后的數(shù)據(jù)集需要分為下面三個(gè)部分:1)訓(xùn)練集(Trainingset):是用于模型訓(xùn)練的數(shù)據(jù)樣本,一般設(shè)置訓(xùn)練集的數(shù)量為整個(gè)數(shù)據(jù)集數(shù)量的70%。2)驗(yàn)證集(Validationset):是模型在擬合訓(xùn)練集過程中單獨(dú)留出的樣本集,它包含在訓(xùn)練集內(nèi),作用是幫助微調(diào)模型的超參數(shù)及初步評(píng)估模型的分類能力,一般設(shè)置驗(yàn)證集的數(shù)量為整個(gè)數(shù)據(jù)集數(shù)量的10%。3)測(cè)試集(Testset):是用來最終評(píng)估模型的泛化能力。注意測(cè)試集不得作為調(diào)參等算法相關(guān)選擇的依據(jù),一般設(shè)置測(cè)試集的數(shù)量為整個(gè)數(shù)據(jù)集數(shù)量的20%。5.1數(shù)據(jù)集采集與標(biāo)注5.1.4小結(jié)經(jīng)過上面的步驟可以得到采集好并且歸類好的素材,此時(shí)前期的素材準(zhǔn)備就已經(jīng)完成,其中文件夾的名稱即為對(duì)應(yīng)的類別,這邊需要注意的是不同類別間的素材量需要在同一個(gè)數(shù)量級(jí)上,以免出現(xiàn)類間不均衡現(xiàn)象。同時(shí)需要保證同一類之前場(chǎng)景盡量不同,保證樣本的多樣性。5.2模型訓(xùn)練模糊檢測(cè)訓(xùn)練模塊主要采用深度學(xué)習(xí)框架PyTorch進(jìn)行訓(xùn)練,版本為2.0.1。PyTorch環(huán)境的搭建第三章已有教程,不再贅述。此處可以將依賴包寫入requirements.txt中,然后使用pipinstall-rrequirements.txt自動(dòng)安裝,也可以加-i指定安裝源,國內(nèi)有如豆瓣源、阿里源、清華源等可以加速安裝,但前提是該數(shù)據(jù)源需要有該版本的安裝包。模型搭建部分第三章已有教程,不再贅述。如圖所示是給模塊版本號(hào),供讀者參考。5.2模型訓(xùn)練5.2.1數(shù)據(jù)載入首先我們需要將圖片轉(zhuǎn)化成模型的輸入數(shù)據(jù),即torch對(duì)應(yīng)的Dataset對(duì)象,實(shí)現(xiàn)這個(gè)步驟有以下兩種辦法:

1)使用torchvision的ImageFolder函數(shù);

2)繼承Dataset寫一個(gè)自己的載入數(shù)據(jù)函數(shù);這兩個(gè)方法都包含圖片預(yù)處理過程,即:更多的transforms的一系列增強(qiáng)選項(xiàng)詳見增強(qiáng)方法的詳細(xì)介紹見3.5.1章節(jié)。雖然上文已經(jīng)介紹了如何編寫Python腳本來劃分?jǐn)?shù)據(jù)集,但是實(shí)際使用中也可以省略此操作,我們以沒有劃分的數(shù)據(jù)集為例,自己編寫一個(gè)載入的函數(shù)。classImageFolder(Dataset):#初始化,繼承參數(shù)def__init__(self,root,transform=None,target_transform=None,loader=default_loader):#TODO#1.Initializefilepathorlistoffilenames.#找到root的文件和索引classes,class_to_idx=find_classes(root)#保存路徑下圖片文件路徑和索引至imgsimgs=make_dataset(root,class_to_idx)iflen(imgs)==0:raise(RuntimeError("Found0imagesinsubfoldersof:"+root+"\n""Supportedimageextensionsare:"+",".join(IMG_EXTENSIONS)))

5.2模型訓(xùn)練

self.root=rootself.imgs=imgsself.classes=classesself.class_to_idx=class_to_idxself.transform=transformself.target_transform=target_transformself.loader=loader

def__getitem__(self,index):"""Args:index(int):IndexReturns:tuple:(image,target)wheretargetisclass_indexofthetargetclass.

"""#TODO#1.Readonedatafromfile(e.g.usingnumpy.fromfile,PIL.Image.open).#2.Preprocessthedata(e.g.torchvision.Transform).#3.Returnadatapair(e.g.imageandlabel).#這里需要注意的是,第一步:readonedata,是一個(gè)datapath,target=self.imgs[index]#這里返回的是圖片路徑,而需要的是圖片格式img=self.loader(path)#將圖片路徑加載成所需圖片格式ifself.transformisnotNone:img=self.transform(img)ifself.target_transformisnotNone:target=self.target_transform(target)returnimg,targetdef__len__(self):#returnthetotalsizeofyourdataset.returnlen(self.imgs)5.2模型訓(xùn)練然后將所需要的幾個(gè)其它函數(shù)補(bǔ)齊,這些都可以通過torchvision庫查找到,若你的torchvision并不支持imagefolder載入,下面這些代碼將幫助你更快的實(shí)現(xiàn)。具體見代碼清單5-3,這里僅展示部分代碼#判斷是不是圖片文件defis_image_file(filename):#只要文件以IMG_EXTENSIONS結(jié)尾,就是圖片#注意any的使用returnany(filename.endswith(extension)forextensioninIMG_EXTENSIONS)

#結(jié)果:classes:['0','1','2','3','4','5','6','7','8','9']#classes_to_idx:{'1':1,'0':0,'3':3,'2':2,'5':5,'4':4,'7':7,'6':6,'9':9,'8':8}deffind_classes(dir):'''

返回dir下的類別名,classes:所有的類別,class_to_idx:將文件中str的類別名轉(zhuǎn)化為int類別classes為目錄下所有文件夾名字的集合#os.listdir:以列表的形式顯示當(dāng)前目錄下的所有文件名和目錄名,但不會(huì)區(qū)分文件和目錄。#os.path.isdir:判定對(duì)象是否是目錄,是則返回True,否則返回False#os.path.join:連接目錄和文件名classes=[dfordinos.listdir(dir)ifos.path.isdir(os.path.join(dir,d))]#sort:排序classes.sort()#將文件名中得到的類別轉(zhuǎn)化為數(shù)字class_to_idx['3']=3class_to_idx={classes[i]:iforiinrange(len(classes))}returnclasses,class_to_idx#class_to_idx:{'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}#如果文件是圖片文件,則保留它的路徑,和索引至images(path,class_to_idx)5.2模型訓(xùn)練然后調(diào)用剛創(chuàng)建的ImageFolder

orig_set=ImageFolder(root='xxxxx/xxxxxxxxxx',transform=tran)#yourdataset將數(shù)據(jù)集劃分為訓(xùn)練集、驗(yàn)證集、測(cè)試集n=len(orig_set)#所有數(shù)據(jù)集數(shù)量n_test=int(0.2*n)#取20%作為測(cè)試集test_dataset=torch.utils.data.Subset(orig_set,range(n_test))train_dataset=torch.utils.data.Subset(orig_set,range(n_test,n))#劃分

最后將數(shù)據(jù)載入train_loader=torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,

num_workers=0,shuffle=True)test_loader=torch.utils.data.DataLoader(dataset=test_dataset,

batch_size=batch_size,num_workers=0,

shuffle=False)5.2模型訓(xùn)練通過上面的torch.utils.data.DataLoader載入數(shù)據(jù),可以自動(dòng)將數(shù)據(jù)分成多個(gè)batch,順序是否打亂由shuffle決定。同時(shí)該函數(shù)提供多個(gè)線程處理數(shù)據(jù)集,即num_workers=x,x是一個(gè)int類型的整數(shù),是加載數(shù)據(jù)(batch)的線程數(shù)目。當(dāng)加載一個(gè)batch的時(shí)間小于數(shù)據(jù)訓(xùn)練的時(shí)間時(shí),GPU每次訓(xùn)練完可以直接取到下一個(gè)batch的數(shù)據(jù),無需額外的等待,因此并不需要多余的worker,即使增加worker也不會(huì)影響訓(xùn)練速度;當(dāng)加載一個(gè)batch的時(shí)間大于數(shù)據(jù)訓(xùn)練的時(shí)間時(shí),GPU每次訓(xùn)練完都需要等待下一個(gè)batch的數(shù)據(jù),因此此時(shí)需要增加worker來加快模型訓(xùn)練。5.2模型訓(xùn)練5.2.2訓(xùn)練策略

網(wǎng)絡(luò)初始化共有3個(gè)方法:·默認(rèn)初始化,創(chuàng)建網(wǎng)絡(luò)實(shí)例的時(shí)候會(huì)默認(rèn)初始化;·Finetune初始化,一般用于遷移學(xué)習(xí)。·自定義初始化,可以看一個(gè)例子。

fromtorch.nnimportinitdefweigth_init(net):forminnet.modules():

#isinstance()是Python中的一個(gè)內(nèi)建函數(shù)。是用來判斷一個(gè)對(duì)象的變量類型。

#初始化卷積層ifisinstance(m,nn.Conv2d):init.xavier_uniform_(m.weight.data)init.constant_(m.bias.data,0)

#初始化歸一化層elifisinstance(m,nn.BatchNorm2d):init.constant_(m.weight.data,1)init.constant_(m.bias.data,0)

#初始化全連接層elifisinstance(m,nn.Linear):init.normal_(m.weight.data,std=1e-3)init.constant_(m.bias.data,0)#實(shí)例化一個(gè)網(wǎng)絡(luò)model=_MyNet(num_classes)#初始化1model.apply(weigth_init)#初始化2#weigth_init(model)

5.2模型訓(xùn)練一般選擇何種初始化有以下幾個(gè)原則:·自己的數(shù)據(jù)量比較少,但是和finetune的網(wǎng)絡(luò)數(shù)據(jù)相似度很高,這個(gè)時(shí)候就需要選擇finetune初始化,修改最后面的幾層即可。·自己的數(shù)據(jù)量少,相似度也低,那么只需要保留淺層卷積的權(quán)重,然后重新訓(xùn)練,具體保留層數(shù)視情況而定。·自己的數(shù)據(jù)量很大,相似度也很高,這是最理想的情況,只需要微調(diào)就可以了,一般只需要修改學(xué)習(xí)率即可,一般這種情況下主干網(wǎng)絡(luò)的學(xué)習(xí)率并不需要很大,學(xué)習(xí)率可以每層單獨(dú)設(shè)置,視情況而定?!ぷ约旱臄?shù)據(jù)量很大,相似度很低,這個(gè)時(shí)候直接用默認(rèn)初始化或者自定義初始化即可。5.2模型訓(xùn)練5.2.3模型保存可分為完整保存和僅保存權(quán)重,僅保存權(quán)重的好處在于速度快,占空間小,缺點(diǎn)是每次都需要定義模型結(jié)構(gòu)。#完整保存模型torch.save(model,'1.pt')#載入模型#model_dict=torch.load('1.pt')#僅保存模型權(quán)重torch.save(model.state_dict(),'1.pt')#載入模型權(quán)重#model_dict=model.load_state_dict(torch.load('1.pt'))5.2模型訓(xùn)練5.2.4可視化大部分項(xiàng)目使用tensorboard可視化,本項(xiàng)目簡(jiǎn)單介紹下如何使用Aim可視化。Aim可以在幾分鐘內(nèi)記錄、搜索和比較100項(xiàng)實(shí)驗(yàn),相較TensorBoard或MLFlow而言速度更快,這對(duì)于實(shí)驗(yàn)管理的新手而言非常方便,其交互界面如圖所示。5.2模型訓(xùn)練如圖所示,在訓(xùn)練腳本所在文件目錄下輸入Aimup,再將顯示的網(wǎng)址在瀏覽器打開即可,得到如圖所示界面。5.2模型訓(xùn)練5.2.5小結(jié)通過制定上面訓(xùn)練策略,就可以開始訓(xùn)練步驟。進(jìn)入對(duì)應(yīng)的Python環(huán)境,在train.py文件的目錄下運(yùn)行:pythontrain.py然后通過aim界面的準(zhǔn)確率和loss變化微調(diào)參數(shù)即可,一般來說訓(xùn)練過程中的Loss開始會(huì)有極速下降的過程,在這之后會(huì)進(jìn)入到斜坡緩慢下降,最后減小學(xué)習(xí)率會(huì)再次得到一個(gè)快速下降的過程。初始學(xué)習(xí)率、訓(xùn)練的Epoch數(shù)、減小學(xué)習(xí)率都需要通過實(shí)驗(yàn)得到,這些主要是觀察訓(xùn)練Loss曲線、模型在訓(xùn)練集和測(cè)試集上面的準(zhǔn)確率變化曲線,考慮到數(shù)據(jù)集的大小、數(shù)據(jù)特征的分布、素材的特征是否明顯等因素,然后靠經(jīng)驗(yàn)和手感來調(diào)整。5.3模型量化5.3.1onnx轉(zhuǎn)換本節(jié)介紹如何將上文中保存的模型轉(zhuǎn)換成onnx以及如何使用onnx模型進(jìn)行推理。1)如何將模型轉(zhuǎn)化為onnximportosimporttorchfromtorch.autogradimportVariableimportnet#導(dǎo)出onnx模型的文件名onnx_path="model.onnx"defconvert():#定義網(wǎng)絡(luò)結(jié)構(gòu)model=_MyNet(num_classes)#模型切換到測(cè)試模式model.eval()#載入權(quán)重model.load_state_dict(torch.load(r'1.pth'),False)#注意矩陣的尺寸與訓(xùn)練尺寸一致torch.onnx.export(model,Variable(torch.randn(1,3,224,224)),onnx_path,export_params=True,verbose=True)if__name__=='__main__':convert()5.3模型量化5.3.1onnx轉(zhuǎn)換2)如何使用onnx進(jìn)行推理具體代碼見代碼清單5-7,這里僅展示部分代碼。#類別數(shù)labels=['0','1','2']定義一個(gè)onnx類classONNXModel():def__init__(self,onnx_path): """:paramonnx_path:"""self.onnx_session=onnxruntime.InferenceSession(onnx_path)

self.input_name=self.get_input_name(self.onnx_session)self.output_name=self.get_output_name(self.onnx_session)defget_output_name(self,onnx_session): """output_name=onnx_session.get_outputs()[0].name:paramonnx_session::return:"""

5.3模型量化Onnx模型性能驗(yàn)證

我們從圖可以看出,訓(xùn)練集的準(zhǔn)確率比測(cè)試集的準(zhǔn)確率要低一些。通常而言,訓(xùn)練集準(zhǔn)確率和測(cè)試集準(zhǔn)確率并不直接掛鉤。本項(xiàng)目的原因主要有以下幾點(diǎn):

·訓(xùn)練集和測(cè)試集的分布無法保證相同;

·因?yàn)橛袛?shù)據(jù)增強(qiáng)的存在,預(yù)處理會(huì)導(dǎo)致訓(xùn)練集的分布產(chǎn)生不同程度變化;

·數(shù)據(jù)集太小,切分后分布無法保證一致;·訓(xùn)練集的準(zhǔn)確率是每個(gè)batch之后產(chǎn)生的,驗(yàn)證集是每個(gè)epoch后產(chǎn)生的,有滯后性。5.3模型量化5.3.2RKNN模型轉(zhuǎn)換以RK1808為例,本項(xiàng)目使用PyTorch2.0.1進(jìn)行訓(xùn)練,對(duì)應(yīng)的rknntoolkit的版本是1.6.0,這個(gè)時(shí)候我們需要打開瑞星微官方文檔,查看當(dāng)前版本RKNN支持的op操作。/rockchip-linux/rknn-toolkit/blob/v1.6.0/doc/RKNN_OP_Support_V1.6.0.md如果有不支持的op的情況,那么模型轉(zhuǎn)化將會(huì)有問題,此時(shí)可以自己寫算子替換對(duì)應(yīng)的op,但對(duì)個(gè)人能力有一定要求。這邊推薦最快捷方便的還是更換對(duì)應(yīng)的op,以適配對(duì)應(yīng)的模型。當(dāng)查詢op均支持后,動(dòng)手開始量化。rknntoolkit的鏡像地址為:/s/3eTG3VsY#sharelink/path=%2F,密碼為:rknn,可以下載對(duì)應(yīng)2.0.1的rknntoolkit鏡像。5.3模型量化首先我們需要準(zhǔn)備rk量化的圖片,保存在images文件夾下,這些素材需要未經(jīng)過訓(xùn)練。然后需要檢查源碼內(nèi)訓(xùn)練素材的通道順序,這時(shí)我們需要回頭查看訓(xùn)練代碼,得到圖像通道順序是RGB。#打開文件withopen(path,'rb')asf:withImage.open(f)asimg:#convert:用于圖像不同模式圖像之間的轉(zhuǎn)換,這里轉(zhuǎn)換為‘RGB’returnimg.convert('RGB')最后需要保證rknn.config內(nèi)設(shè)置的通道順序與訓(xùn)練素材的通道順序保持一致。[012]表示順序保持一致,即保持RGB不變,運(yùn)行量化代碼,得到如圖的結(jié)果。5.3模型量化RKNN模型驗(yàn)證本小節(jié)主要對(duì)轉(zhuǎn)化后的RKNN進(jìn)行二次驗(yàn)證即測(cè)試RKNN模型推理是否合理,測(cè)試時(shí)需要將上一個(gè)腳本中的rknn.build中的預(yù)編譯pre_compile設(shè)置為false,即不采用預(yù)編譯。預(yù)編譯可以起到加速的作用,測(cè)試的時(shí)候不可開啟預(yù)編譯,只有當(dāng)正式部署時(shí)才設(shè)置為True。說到底量化就是將浮點(diǎn)存儲(chǔ)(運(yùn)算)轉(zhuǎn)換為整型存儲(chǔ)(運(yùn)算)的一種模型壓縮技術(shù)。兩者模型區(qū)別與權(quán)重對(duì)比如兩圖所示,對(duì)比一下onnx量化為RKNN模型前后的差異以及第一層權(quán)重的差異,可以看出量化是將onnx中的Conv和BatchNormalization層融合為CONV2D層,且權(quán)重有浮點(diǎn)數(shù)變成了整型數(shù)。5.3模型量化5.3.3小結(jié)本節(jié)主要通過對(duì)onnx和RKNN模型測(cè)試,驗(yàn)證模型是否符合要求,以及驗(yàn)證模型量化過程中的其他原因?qū)е履P娃D(zhuǎn)化前后效果的差異,這一步測(cè)試通過后即可進(jìn)行下一步操作。5.4項(xiàng)目源碼分析部署與測(cè)試5.4.1工程目錄結(jié)構(gòu)ctest|--sdk_rk1808相關(guān)sdk|--src源碼 |--ctest主模塊程序 |--assets模型文件 |--ctest_proc.cpp主模塊源文件 |--ctest_proc.h

主模塊對(duì)應(yīng)的頭文件 |--detector.cpp推理模塊源文件 |--detector.h推理對(duì)應(yīng)的頭文件 |--CmakeLists.txt |--test測(cè)試程序 |--main.cpp測(cè)試程序入口 |--test_draw.hpp結(jié)果繪圖相關(guān) |--CmakeLists.txt|--build_emv.cmake編譯環(huán)境配置,供CMakeLists調(diào)用|--CMakeLists.txt用于生成makefile,各源碼模塊中也有對(duì)應(yīng)文件,逐級(jí)調(diào)用|--readme.md編譯參考命令本項(xiàng)目主要分為視頻源、測(cè)試程序、主模塊庫函數(shù)、繪圖四個(gè)部分組成,從視頻源獲取傳入的實(shí)時(shí)數(shù)據(jù),測(cè)試程序通過回調(diào)函數(shù)讀取實(shí)時(shí)數(shù)據(jù),主模塊庫函數(shù)通過回調(diào)函數(shù)讀取測(cè)試程序傳入的實(shí)時(shí)數(shù)據(jù)并將識(shí)別結(jié)果通過回調(diào)函數(shù)返回給測(cè)試模塊,測(cè)試程序再將回調(diào)來的推理結(jié)果提供給繪圖模塊,最終形成整套系統(tǒng)。5.4項(xiàng)目源碼分析部署與測(cè)試5.4.2源碼分析1)主模塊頭文件定義模型識(shí)別結(jié)果的枚舉enumTStatusTag{kBlur=0,///<模糊kCover=1,///<遮擋kClear=2,///<清晰};typedefenumTStatusTagTStatus;定義回調(diào)結(jié)果structTResultTag{intscene_status;///<模型識(shí)別結(jié)果,參見TStatusTagintscore;///<識(shí)別分?jǐn)?shù)};typedefstructTResultTagTResult;

定義初始化時(shí)需要設(shè)置的相關(guān)內(nèi)容structTInitialItemTag{

charconfig_file[128];///<配置文件路徑(標(biāo)準(zhǔn)的ini文件)

ac::ImageHeaderimage_header;///<圖像頭部數(shù)據(jù)};typedefstructTInitialItemTagTInitialItem;

定義回調(diào)typedefvoid(ac::Object::*Method)(TResultresult);5.4項(xiàng)目源碼分析部署與測(cè)試·定義調(diào)用其他對(duì)象的方法structTEventTag{

ac::Object*sender;///<對(duì)象指針

Methodmethod;///<該對(duì)象的public方法};typedefstructTEventTagTEvent;·無參構(gòu)造函數(shù)

TCtestProcInterface(){};·析構(gòu)函數(shù)

virtual~TCtestProcInterface()=0;·初始化模型

virtualintInit(constTInitialItem&item)=0;·反初始化

virtualvoidDeInit()=0;·更新最新畫面

virtualboolUpdate(constvoid*data,unsignedintsize)=0;·設(shè)置狀態(tài)事件

virtualboolSetChangedEvent(constTEvent&OnChanged)=0;·創(chuàng)建對(duì)象

TCtestProcInterface*CreateCtestProc();·銷毀創(chuàng)建的對(duì)象

voidDestroyCtestProc(TCtestProcInterface*obj);5.4項(xiàng)目源碼分析部署與測(cè)試5.4.2源碼分析2)主模塊模塊初始化,從傳入的配置文件ini中讀取模型文件的路徑,如果未傳入則會(huì)設(shè)置為默認(rèn)的路徑。同時(shí)模型推理的輸入尺寸可以從模型文件中讀取,后續(xù)更改模型輸入就無須更改源碼,只需要替換模型即可。具體代碼見代碼清單5-12,這里僅展示部分代碼。if(item.image_header.width>0anditem.image_header.height>0){///默認(rèn)值constchar*default_model="assets/ctest_model.rknn";std::stringmodel=default_model;///從傳入的配置文件中讀取模型ai::IniFileini;boolr=(item.config_file!=nullptr)andini.Load(item.config_file);......5.4項(xiàng)目源碼分析部署與測(cè)試反初始化,可以理解為當(dāng)上述初始化對(duì)象銷毀時(shí),需要對(duì)其屬性進(jìn)行釋放。如果不釋放,資源就浪費(fèi)了,反初始化方法可以釋放初始化對(duì)象,減少資源浪費(fèi)。這里需要注意的是:當(dāng)要反初始化時(shí)候,要把對(duì)象設(shè)置為null,不然反初始化方法不會(huì)被調(diào)用。voidTCtestProcImpl::DeInit(){if(valid_flag_==true)

{

///反初始化推理deletedetector_;detector_=nullptr;///反初始化RGAautop=rga_prev_;rga_prev_=nullptr;deletep;valid_flag_=false;}}5.4項(xiàng)目源碼分析部署與測(cè)試Update函數(shù),供外部調(diào)用,每次調(diào)用都會(huì)為主模塊提供最新幀,通過rga轉(zhuǎn)換后寫入緩沖區(qū),而且是不斷寫入。同時(shí)主模塊和外部調(diào)用是異步操作,中間靠單項(xiàng)緩沖區(qū)連接,因此每次主模塊調(diào)用的都會(huì)是最新的圖片,但具體是否丟幀或重復(fù)推理同一幀就得比較模型推理的速度和外部調(diào)用update函數(shù)速度。boolTCtestProcImpl::Update(constvoid*data,unsignedintsize){boolret=false;if(valid_flag_and(callback_.method!=nullptr)and(buffer_!=nullptr)and(notbuffer_->IsFull())and(data!=nullptr)and(size>0)){constauto&prev_pairs=rga_prev_->RgaBlit(reinterpret_cast<constuint8_t*>(data),size,true);///rga的轉(zhuǎn)換結(jié)果

......5.4項(xiàng)目源碼分析部署與測(cè)試5.4.2源碼分析3)推理模塊頭文件構(gòu)造函數(shù)TDetector(constchar*model_file);析構(gòu)函數(shù)virtual~TDetector();檢測(cè)函數(shù)intDetect(constac::Im

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(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)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論