0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

結(jié)合卷積層來創(chuàng)建一個完整的推理函數(shù)

OpenFPGA ? 來源:OpenFPGA ? 2023-03-13 09:22 ? 次閱讀

到上一篇為止,我們已經(jīng)完成了卷積層、全連接層、池化層、激活函數(shù)ReLU的所有C的編程實(shí)現(xiàn)。在本文中,我們將結(jié)合這些層來創(chuàng)建一個完整的推理函數(shù)。

模型實(shí)現(xiàn)

下面是在第 2 篇文章中創(chuàng)建的推理模型的圖表。

8eefb56e-c01c-11ed-bfe3-dac502259ad0.png

首先輸入一張1x28x28的圖片,然后兩次通過Conv2d -> ReLU -> MaxPool2d提取特征,最后轉(zhuǎn)為linear,> ReLU -> Linear為10階向量值。

用C寫的時候,只需按如下依次逐層處理即可。

voidconv2d(constfloat*x,constfloat*weight,constfloat*bias,int32_twidth,int32_theight,
int32_tin_channels,int32_tout_channels,int32_tksize,float*y){
for(int32_toch=0;och=height||pw=width){
continue;
}

int64_tpix_idx=(ich*height+ph)*width+pw;
int64_tweight_idx=((och*in_channels+ich)*ksize+kh)*ksize+kw;

sum+=x[pix_idx]*weight[weight_idx];
}
}
}

//addbias
sum+=bias[och];

y[(och*height+h)*width+w]=sum;
}
}
}
}

函數(shù)內(nèi)部的緩沖區(qū) (x1-x8) 用于連接各層之間的特征數(shù)據(jù)。

在HLS中,在哪里定義這個buffer很重要,如果像這次一樣把它放在函數(shù)中,就可以指定使用FPGA中的RAM(或寄存器)。

另一方面,如果將此緩沖區(qū)作為函數(shù)的參數(shù)提供,則可以將數(shù)據(jù)連接到外部 DRAM。這個區(qū)域需要根據(jù)應(yīng)用來設(shè)計,但是這次內(nèi)部SRAM已經(jīng)夠用了,所以定義在函數(shù)內(nèi)部。

如果像以前一樣編寫接口規(guī)范,將如下所示:

輸入

x: 輸入圖像。shape=(1, 28, 28)

weight0:第一個卷積層的權(quán)重。shape=(4, 1, 3, 3)

bias0:第一個卷積層的偏差。shape=(4)

weight1:第二個卷積層的權(quán)重。shape=(8, 4, 3, 3)

bias1:第二個卷積層的偏差。shape=(8)

weight2:第一個全連接層的權(quán)重。shape=(32, 8 * 7 * 7)

bias2:第一個全連接層的偏差。shape=(32)

weight3:第二個全連接層的權(quán)重。shape=(10, 32)

bias3:第二個全連接層的偏差。shape=(10)

輸出

y:輸出向量。shape=(10)

界面設(shè)置

在目前創(chuàng)建的函數(shù)中,我們還沒有具體定義創(chuàng)建電路的接口。未指定接口時,HLS 會為簡單 SRAM 生成一個接口。

該接口不能用于訪問DRAM等訪問時間不確定的接口,不方便在真機(jī)上操作。為此,我們告訴HLS使用一種稱為AMBA AXI4接口協(xié)議(以下簡稱AXI)的協(xié)議,該協(xié)議主要用于Xilinx FPGA上IP之間的接口。

簡單介紹一下AXI,AXI是ARM公司提供的一種接口標(biāo)準(zhǔn)。

Xilinx IP主要使用以下三種協(xié)議。

AXI4:高速內(nèi)存訪問協(xié)議(主要用途:訪問DRAM、PCIe等)

AXI4-Lite:AXI4的一個子集,一種用于低速內(nèi)存訪問的協(xié)議(主要用途:IP寄存器控制)

AXI4-Stream:僅用于單向數(shù)據(jù)傳輸?shù)膮f(xié)議,無地址(主要用途:流數(shù)據(jù)處理)

這次我們將使用 AXI4 訪問輸入/輸出數(shù)據(jù),使用 AXI4-Lite 控制 IP。

具有接口定義的推理函數(shù)如下所示:

voidinference_top(constfloatx[kMaxSize],
constfloatweight0[kMaxSize],constfloatbias0[kMaxSize],
constfloatweight1[kMaxSize],constfloatbias1[kMaxSize],
constfloatweight2[kMaxSize],constfloatbias2[kMaxSize],
constfloatweight3[kMaxSize],constfloatbias3[kMaxSize],
floaty[kMaxSize]){
#pragmaHLSinterfacem_axiport=xoffset=slavebundle=gmem0
#pragmaHLSinterfacem_axiport=weight0offset=slavebundle=gmem1
#pragmaHLSinterfacem_axiport=weight1offset=slavebundle=gmem2
#pragmaHLSinterfacem_axiport=weight2offset=slavebundle=gmem3
#pragmaHLSinterfacem_axiport=weight3offset=slavebundle=gmem4
#pragmaHLSinterfacem_axiport=bias0offset=slavebundle=gmem5
#pragmaHLSinterfacem_axiport=bias1offset=slavebundle=gmem6
#pragmaHLSinterfacem_axiport=bias2offset=slavebundle=gmem7
#pragmaHLSinterfacem_axiport=bias3offset=slavebundle=gmem8
#pragmaHLSinterfacem_axiport=yoffset=slavebundle=gmem9
#pragmaHLSinterfaces_axiliteport=xbundle=control
#pragmaHLSinterfaces_axiliteport=weight0bundle=control
#pragmaHLSinterfaces_axiliteport=weight1bundle=control
#pragmaHLSinterfaces_axiliteport=weight2bundle=control
#pragmaHLSinterfaces_axiliteport=weight3bundle=control
#pragmaHLSinterfaces_axiliteport=bias0bundle=control
#pragmaHLSinterfaces_axiliteport=bias1bundle=control
#pragmaHLSinterfaces_axiliteport=bias2bundle=control
#pragmaHLSinterfaces_axiliteport=bias3bundle=control
#pragmaHLSinterfaces_axiliteport=ybundle=control
#pragmaHLSinterfaces_axiliteport=returnbundle=control
dnnk::inference(x,
weight0,bias0,
weight1,bias1,
weight2,bias2,
weight3,bias3,
y);
}

dnnk::inference函數(shù)就是前面提到的推理函數(shù),這個函數(shù)將dnnk::inference“包起來”了。

和上一篇文章一樣,top函數(shù)的接口是一個數(shù)組,而不是一個指針。在仿真 HLS 時,此符號對于指定仿真器保留的內(nèi)存緩沖區(qū)的大小是必需的,但它并不是很重要。

第 30-50 行 #pragma HLS interfaceport=<參數(shù)名稱>bundle=<要分配的接口名稱> 使用語法為每個函數(shù)參數(shù)指定接口協(xié)議,使用的協(xié)議有兩個,m_axi和s_axilite,其中m_/s_部分表示請求是發(fā)送還是接收(AXI術(shù)語中的master/slave),后面的部分就是前面提到的協(xié)議部分增加。

在此函數(shù)中,每個數(shù)據(jù)端口都成為 AXI4 主端口并主動從 DRAM (L30-39) 中獲取數(shù)據(jù)。此時主機(jī)CPU等訪問的存儲器地址可以通過AXI4-Lite從端口(L40-49)進(jìn)行設(shè)置。

最后,用于開始處理的控制寄存器和用于檢查處理完成的狀態(tài)寄存器port=return鏈接到 AXI4-Lite 從端口 (L50)。

綜合/結(jié)果確認(rèn)

界面

將這個電路作為IP輸出,放到Vivado的IP Integrator中,如下圖。每個端口的名稱對應(yīng)于上面的interface pragma bundle位置。

8f0edcc8-c01c-11ed-bfe3-dac502259ad0.png

熟悉 Vivado 開發(fā)的都知道,剩下要做的就是適當(dāng)?shù)剡B接端口,將能夠創(chuàng)建能夠進(jìn)行推理處理的 FPGA 圖像。

綜合

綜合時的表現(xiàn)如下:執(zhí)行時間最短 1.775 ms,最長 7.132 ms。

8f287d68-c01c-11ed-bfe3-dac502259ad0.png

在這里,我想知道為什么輸入圖像大小是固定的,但執(zhí)行時間不固定,這是因?yàn)榈谌恼轮袆?chuàng)建的卷積函數(shù)continue包括補(bǔ)零處理。

由于這個補(bǔ)零過程只在屏幕邊緣進(jìn)行,實(shí)際執(zhí)行時間幾乎是最大時間7.132 ms。

for(int32_tkw=0;kw=height||pw=width){
continue;
}

int64_tpix_idx=(ich*height+ph)*width+pw;
int64_tweight_idx=((och*in_channels+ich)*ksize+kh)*ksize+kw;

sum+=x[pix_idx]*weight[weight_idx];
}

在這里為了可讀性,用continue中止,但是在FPGA上,與在這里中斷循環(huán)的處理相比,使用已經(jīng)安裝的乘法加法器進(jìn)行0加法運(yùn)算的成本更少。

資源使用

FPGA的資源利用率如下所示:總體使用量是微不足道的,因?yàn)闆]有增加并行化和流水線等資源的加速。

8f415f86-c01c-11ed-bfe3-dac502259ad0.png






審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • DRAM
    +關(guān)注

    關(guān)注

    40

    文章

    2292

    瀏覽量

    183132
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5271

    瀏覽量

    119655
  • SRAM芯片
    +關(guān)注

    關(guān)注

    0

    文章

    65

    瀏覽量

    12033
  • HLS
    HLS
    +關(guān)注

    關(guān)注

    1

    文章

    128

    瀏覽量

    23968

原文標(biāo)題:總結(jié)

文章出處:【微信號:Open_FPGA,微信公眾號:OpenFPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    函數(shù)計算序列線性卷積結(jié)果

    定義函數(shù)文件,功能是采用重疊相加法完成無限長序列與有限長序列的線性卷積,然后用該函數(shù)文件計算序列x[k]=2k+1,0≤k≤18與序列h
    發(fā)表于 11-29 13:36

    CNN之卷積

    相乘再求和)的操作就是所謂的『卷積』操作,也是卷積神經(jīng)網(wǎng)絡(luò)的名字來源。非嚴(yán)格意義上來講,下圖中紅框框起來的部分便可以理解為濾波器,即帶著
    發(fā)表于 10-17 10:15

    卷積神經(jīng)網(wǎng)絡(luò)卷積的處理過程

    。本文就以卷積神經(jīng)網(wǎng)絡(luò)為例談?wù)勗趺?b class='flag-5'>來進(jìn)步優(yōu)化卷積神經(jīng)網(wǎng)絡(luò)使用的memory。文章(卷積神經(jīng)
    發(fā)表于 12-23 06:16

    【飛凌RK3568開發(fā)板試用體驗(yàn)】RKNN模型推理測試

    MobileNet是Google團(tuán)隊2017年提出深度學(xué)習(xí)模型,專注于移動端或者嵌入式設(shè)備中的輕量級CNN網(wǎng)絡(luò)。模型推理卷積操作占用了大部分的時間,因此MobileNet V1使
    發(fā)表于 12-08 19:06

    如何在PyTorch上學(xué)習(xí)和創(chuàng)建網(wǎng)絡(luò)模型呢?

    的網(wǎng)絡(luò)模型是卷積神經(jīng)網(wǎng)絡(luò),該網(wǎng)絡(luò)由以下三和激活函數(shù)的組合組成。全連接
    發(fā)表于 02-21 15:22

    卷積的C++實(shí)現(xiàn)詳細(xì)介紹

    。第一個三級循環(huán)確定輸出圖像上的位置,隨后的三級循環(huán)對該位置執(zhí)行卷積操作。零填充在第 24-26 行完成。由于實(shí)際創(chuàng)建零填充輸入圖像是低效的,所以零填充是通過在訪問圖像外部時不參與乘積之和
    發(fā)表于 02-24 15:41

    一層卷積能做啥?一層卷積可以做超分嗎?

      Abstract  經(jīng)典的圖像縮放(比如bicubic)可以視作卷積+上采樣濾波器
    發(fā)表于 03-06 14:05

    結(jié)合卷積與全連接創(chuàng)建完整推理函數(shù)

    連接的偏差。shape=(10)  輸出  y:輸出向量。shape=(10)  界面設(shè)置  在目前創(chuàng)建函數(shù)中,我們還沒有具體定義創(chuàng)建電路的接口。未指定接口時,HLS 會為簡單 S
    發(fā)表于 03-17 16:19

    C語言入門教程-創(chuàng)建函數(shù)

    創(chuàng)建函數(shù)庫 上述程序中的rand和bubble_sort函數(shù)很實(shí)用,很可能在您寫其他程序時也能派上用場。為了能更方便地重復(fù)使用,您可以
    發(fā)表于 07-29 11:18 ?3110次閱讀

    種改進(jìn)的殘差網(wǎng)絡(luò)結(jié)構(gòu)以減少卷積參數(shù)

    網(wǎng)絡(luò)結(jié)構(gòu),以降低殘差塊數(shù)量與卷積核數(shù)量減少卷積參數(shù)。同時,在原始損失函數(shù)中加入類間相似懲罰項
    發(fā)表于 03-23 14:48 ?8次下載
    <b class='flag-5'>一</b>種改進(jìn)的殘差網(wǎng)絡(luò)結(jié)構(gòu)以減少<b class='flag-5'>卷積</b><b class='flag-5'>層</b>參數(shù)

    如何去理解CNN卷積與池化計算?

    概述 深度學(xué)習(xí)中CNN網(wǎng)絡(luò)是核心,對CNN網(wǎng)絡(luò)來說卷積與池化的計算至關(guān)重要,不同的步長、填充方式、卷積核大小、
    的頭像 發(fā)表于 04-06 15:13 ?2682次閱讀
    如何去理解CNN<b class='flag-5'>卷積</b><b class='flag-5'>層</b>與池化<b class='flag-5'>層</b>計算?

    卷積神經(jīng)網(wǎng)絡(luò)層級結(jié)構(gòu) 卷積神經(jīng)網(wǎng)絡(luò)的卷積講解

    像分類、目標(biāo)檢測、人臉識別等。卷積神經(jīng)網(wǎng)絡(luò)的核心是卷積和池化,它們構(gòu)成了網(wǎng)絡(luò)的主干,實(shí)現(xiàn)了對圖像特征的提取和抽象。 、
    的頭像 發(fā)表于 08-21 16:49 ?7097次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)共有幾層 卷積神經(jīng)網(wǎng)絡(luò)模型三

    卷積神經(jīng)網(wǎng)絡(luò)共有幾層 卷積神經(jīng)網(wǎng)絡(luò)模型三? 卷積神經(jīng)網(wǎng)絡(luò) (Convolutional Neural Networks,CNNs) 是
    的頭像 發(fā)表于 08-21 17:11 ?6760次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)每一層的作用

    (Input Layer) 輸入卷積神經(jīng)網(wǎng)絡(luò)的第一層,負(fù)責(zé)接收輸入數(shù)據(jù)。在圖像識別任務(wù)中,輸入通常接收
    的頭像 發(fā)表于 07-02 15:28 ?808次閱讀

    卷積神經(jīng)網(wǎng)絡(luò)激活函數(shù)的作用

    卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks, CNNs)是深度學(xué)習(xí)中種重要的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),廣泛應(yīng)用于圖像識別、語音識別、自然語言處理等領(lǐng)域。在卷積神經(jīng)網(wǎng)絡(luò)中,激活
    的頭像 發(fā)表于 07-03 09:18 ?522次閱讀