基于FPGA的卷積層并行加速方案
作者 / 肖昱 姚天堯 顧嘉盼 張延軍 北京理工大學(xué) 信息與電子學(xué)院(北京 100081)
本文引用地址:http://butianyuan.cn/article/201802/375426.htm*第一屆(2016-2017)全國(guó)大學(xué)生集成電路創(chuàng)新創(chuàng)業(yè)大賽全國(guó)總決賽FPGA設(shè)計(jì)方向獲獎(jiǎng)作品
卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks)是一種主要應(yīng)用于圖像處理領(lǐng)域的人工智能算法。尤其是在計(jì)算機(jī)視覺(jué)領(lǐng)域,CNN在包括識(shí)別(recognition)、檢測(cè)(detection)、分割(segmentation)等很多任務(wù)中占主流地位。
卷積神經(jīng)網(wǎng)絡(luò)的基本元素:卷積層(convolutional layer)、池化層(pooling)、激活函數(shù)(activation)、全連接層(fully-connected layer)。卷積神經(jīng)網(wǎng)絡(luò)(例如LeNet[3])對(duì)于神經(jīng)網(wǎng)絡(luò)(Neural Networks)最大的創(chuàng)新在于卷積層。卷積層在整幅圖像上使用相對(duì)很小的卷積核(convolutional kernel)進(jìn)行特征檢測(cè),實(shí)現(xiàn)了將原始圖像直接輸入神經(jīng)網(wǎng)絡(luò)而不會(huì)引發(fā)維數(shù)災(zāi)難??朔酥盎谑止ぬ卣骱头诸?lèi)器的系統(tǒng)需要分別訓(xùn)練的缺點(diǎn),使得圖像分類(lèi)任務(wù)實(shí)現(xiàn)了端到端(end-to-end)。
想要將卷積神經(jīng)網(wǎng)絡(luò)投入實(shí)際應(yīng)用,例如在移動(dòng)端利用服務(wù)器訓(xùn)練好的卷積核參數(shù)進(jìn)行實(shí)時(shí)的物體或者人臉識(shí)別,需要對(duì)CNN進(jìn)行許多改進(jìn)。其中,卷積層運(yùn)算需要消耗大量計(jì)算資源,使用串行計(jì)算方式速度不快。因此,提高CNN卷積層的計(jì)算速度是CNN進(jìn)行實(shí)際應(yīng)用時(shí)需要解決的一個(gè)重要問(wèn)題。
1設(shè)計(jì)標(biāo)準(zhǔn)與約束
1.1設(shè)計(jì)問(wèn)題
“將上述算法在硬件平臺(tái)上實(shí)現(xiàn)并優(yōu)化,主要考慮總線帶寬,內(nèi)部緩存,Pipeline設(shè)計(jì),計(jì)算單元等因素,給出不同緩存下,總線帶寬計(jì)算公式和典型案例下的數(shù)據(jù)。”
由賽題分析,本設(shè)計(jì)方案主要分為兩部分:實(shí)現(xiàn)方案、優(yōu)化方案。實(shí)現(xiàn)方案涉及系統(tǒng)架構(gòu)的設(shè)計(jì)、計(jì)算單元的設(shè)計(jì)等;優(yōu)化方案涉及總線帶寬和片上緩存在不同情況下的設(shè)計(jì)等。
1.2設(shè)計(jì)標(biāo)準(zhǔn)
競(jìng)賽題目中提到的標(biāo)準(zhǔn):
1)運(yùn)算速率:100GMAC,每秒100G次乘加運(yùn)算;
2)輸入圖像數(shù)量:1024 channel,1024個(gè)輸入feature map
3)卷積核數(shù)量:1024,1024個(gè)輸出feature map
4)輸入輸出圖像分辨率:150*150
我們對(duì)細(xì)節(jié)進(jìn)行的假設(shè):
1)數(shù)據(jù)寬度:8位,像素點(diǎn)取值范圍(0~255)
2)卷積核尺寸:3*3
1.3約束條件
本設(shè)計(jì)方案基于Altera公司的Stratix IV EP4SGX230KF40C2,其有兩項(xiàng)硬件資源約束:
1)硬件乘法器;
2)片上RAM;
本設(shè)計(jì)方案在設(shè)計(jì)時(shí)對(duì)不同DDR在不同數(shù)據(jù)總線帶寬下給出相應(yīng)的緩存方案,在實(shí)現(xiàn)中使用DDR2 SRAM。實(shí)現(xiàn)中的DDR2數(shù)據(jù)總線帶寬通過(guò)實(shí)驗(yàn)測(cè)出,其他類(lèi)型的DDR數(shù)據(jù)帶寬通過(guò)查閱資料進(jìn)行估算。圖一列出了Micron公司不同DDR在FPGA平臺(tái)上的參數(shù),我們將根據(jù)這些數(shù)據(jù)進(jìn)行隨后的計(jì)算。
圖0 不同DDR SRAM參數(shù)(Micron)
2設(shè)計(jì)總體架構(gòu)
2.1硬件架構(gòu)
我們會(huì)使用如下圖中的總體架構(gòu):數(shù)據(jù)開(kāi)始存放在DDR中;由DDR讀寫(xiě)IP核將數(shù)據(jù)從DDR中讀出;數(shù)據(jù)由DDR讀寫(xiě)IP通過(guò)FIFO進(jìn)行跨時(shí)鐘域操作送給片上RAM緩存;再將數(shù)據(jù)由RAM中讀出送給并行計(jì)算單元陣列進(jìn)行卷積運(yùn)算,得到運(yùn)算結(jié)果;運(yùn)算結(jié)果暫存在片上RAM中;再?gòu)腞AM中將運(yùn)算結(jié)果讀出,通過(guò)FIFO送給DDR讀寫(xiě)IP寫(xiě)回DDR中。
圖1 系統(tǒng)架構(gòu)設(shè)計(jì)
在設(shè)計(jì)的過(guò)程中,我們將在計(jì)算單元和緩存中采取兩種不同層次的數(shù)據(jù)復(fù)用策略,以降低系統(tǒng)對(duì)于帶寬資源的需求。
2.2優(yōu)化問(wèn)題的數(shù)學(xué)模型
我們認(rèn)為,對(duì)卷積運(yùn)算進(jìn)行加速的關(guān)鍵在于:在充分利用讀寫(xiě)帶寬的前提下,通過(guò)使用片上緩存和并行策略,盡量提高系統(tǒng)的并行度以達(dá)到設(shè)計(jì)標(biāo)準(zhǔn)。
顯然地,系統(tǒng)對(duì)于DDR的讀寫(xiě)速度將遠(yuǎn)慢于并行運(yùn)算的速度,所以最大化地利用讀寫(xiě)帶寬將是不可避免的。根據(jù)查詢(xún)到的資料,以任何現(xiàn)有內(nèi)存設(shè)備的讀寫(xiě)速度,都是不能支持100GMAC的串行卷積運(yùn)算的。因此,并行地進(jìn)行卷積運(yùn)算也將是不可避免的。此時(shí),帶寬資源還有可能不足,可以使用片上RAM緩存對(duì)已讀取的數(shù)據(jù)進(jìn)行復(fù)用以進(jìn)一步減小對(duì)于帶寬的需求。
總而言之,我們希望最大化地利用帶寬資源,并使用并行設(shè)計(jì)和RAM緩存使系統(tǒng)達(dá)到100GMAC的設(shè)計(jì)標(biāo)準(zhǔn)。
考慮到片上RAM成本較高,目前的FPGA普遍不具備很大的片上RAM容量,所以在設(shè)計(jì)中我們希望使用盡可能少的片上RAM資源。由此,可以用數(shù)學(xué)語(yǔ)言描述本次設(shè)計(jì)中的優(yōu)化問(wèn)題:
(定義復(fù)用率X:若一次讀取的一個(gè)輸入圖像與若干數(shù)量的卷積核進(jìn)行卷積運(yùn)算,則此卷積核的數(shù)量占全部卷積核數(shù)量的比例為X。)
從以上問(wèn)題中可以分析得出,RAM資源需求是復(fù)用率X的線性函數(shù);運(yùn)算速率與X無(wú)關(guān);數(shù)據(jù)速率是X的反比例函數(shù)。因此本優(yōu)化問(wèn)題是關(guān)于變量X的非線性?xún)?yōu)化問(wèn)題。
3設(shè)計(jì)細(xì)節(jié)分析
3.1計(jì)算單元設(shè)計(jì):串行輸入,并行計(jì)算
3.1.1計(jì)算單元設(shè)計(jì)的目標(biāo):數(shù)據(jù)復(fù)用
在卷積運(yùn)算的計(jì)算單元中,我們希望對(duì)數(shù)據(jù)進(jìn)行復(fù)用,
并行計(jì)算的可能性根植于卷積層的設(shè)計(jì)中。在全連接的神經(jīng)網(wǎng)絡(luò)的每一層中,每一個(gè)輸入和每一個(gè)輸出之間都有一個(gè)權(quán)重(w),每一個(gè)輸出都與全部輸入的信息相關(guān);而在卷積神經(jīng)網(wǎng)絡(luò)中,存在著卷積核的共用(shared-weight),這使得每個(gè)輸出圖像都包含著一個(gè)卷積核對(duì)于所有輸入圖像中特征提取的信息。具體而言,每個(gè)卷積核會(huì)對(duì)所有輸入圖像的各個(gè)區(qū)域進(jìn)行運(yùn)算處理。于是這種卷積核在卷積計(jì)算過(guò)程中的重復(fù)使用,為并行計(jì)算提供了可能。如果我們能夠由這種重復(fù)使用的性質(zhì),盡量減少對(duì)于卷積核數(shù)據(jù)的讀取次數(shù),那么卷積運(yùn)算的時(shí)間將大大減少。
輸入圖像在每一個(gè)點(diǎn)上的數(shù)據(jù)參與卷積運(yùn)算的次數(shù)(乘法)是卷積核的尺寸(3×3),不僅卷積核的數(shù)據(jù)在串行計(jì)算的過(guò)程中被反復(fù)讀取,輸入圖像的數(shù)據(jù)也在被反復(fù)讀取。在串行計(jì)算中,卷積計(jì)算的滑動(dòng)窗口(sliding window)在讀取端,每一個(gè)點(diǎn)都被反復(fù)讀取了相應(yīng)的次數(shù)。我們希望把通過(guò)設(shè)置一些寄存器,將滑動(dòng)窗從數(shù)據(jù)的讀取端移動(dòng)到計(jì)算端,實(shí)現(xiàn)對(duì)輸入圖像的每一個(gè)點(diǎn)進(jìn)行一次數(shù)據(jù)讀取就完成其在滑動(dòng)窗中所需進(jìn)行的所有乘法運(yùn)算(9次)。也就是說(shuō),我們希望能夠串行得從內(nèi)存中讀取數(shù)據(jù),每一個(gè)點(diǎn)僅進(jìn)行一次讀取就足以完成其在卷積運(yùn)算的滑動(dòng)窗中所要進(jìn)行的9次乘法。
3.1.2計(jì)算單元的設(shè)計(jì)
現(xiàn)在,我們暫且假設(shè)從內(nèi)存中讀取來(lái)的數(shù)據(jù)是均勻的流(每個(gè)時(shí)鐘周期讀取一個(gè)像素點(diǎn)的數(shù)據(jù));我們也暫且假設(shè)卷積核是不更換的,也就是指僅有一個(gè)卷積核的情形。本節(jié)中,我們對(duì)于數(shù)據(jù)是均勻的流以及只有一個(gè)卷積核的情況,設(shè)計(jì)一個(gè)高效的并行計(jì)算單元。
在計(jì)算端設(shè)置一些緩存以實(shí)現(xiàn)卷積核數(shù)據(jù)和輸入圖像數(shù)據(jù)的復(fù)用是通過(guò)圖2和圖3中的設(shè)計(jì)實(shí)現(xiàn)的。
圖2 計(jì)算單元(processing element)的設(shè)計(jì)
圖3 計(jì)算子(processing unit)的設(shè)計(jì)
3.1.3計(jì)算單元的工作原理
卷積核的值直接被保存在計(jì)算子的寄存器中,而輸入圖像從由SRAM構(gòu)成的移存器一端輸入(同時(shí)送給第三行的寄存器)。由SRAM移存輸出的圖像數(shù)據(jù)也分別送向第一行和第二行的寄存器。每行的計(jì)算子的寄存器之間也被設(shè)計(jì)為移存關(guān)系,數(shù)據(jù)由第三列送向第二列,再送向第一列。
在這種設(shè)計(jì)下,每一次計(jì)算單元在一個(gè)時(shí)鐘周期可以完成9次乘加運(yùn)算。由此,可以根據(jù)設(shè)計(jì)標(biāo)準(zhǔn),在合理的時(shí)鐘頻率下得到系統(tǒng)所需要達(dá)到的并行度。經(jīng)過(guò)綜合考慮,并行度n為64時(shí)可以保證時(shí)鐘周期的合理且達(dá)到100GMAC的運(yùn)算速率??梢郧蟮盟璧臅r(shí)鐘周期:
3.2優(yōu)化緩存和帶寬
3.2.1使用緩存實(shí)現(xiàn)進(jìn)一步數(shù)據(jù)復(fù)用
在100GMAC的計(jì)算速度下,通過(guò)簡(jiǎn)單的計(jì)算可以得知,如果不對(duì)已讀取的輸入圖像數(shù)據(jù)與多個(gè)卷積核進(jìn)行運(yùn)算,則不可滿(mǎn)足帶寬資源的需求。根據(jù)公式②和圖像和卷積核的尺寸以及運(yùn)算速率得出這種情況下系統(tǒng)所需的最小數(shù)據(jù)速率:
以上這個(gè)大約11G的帶寬需求是難以滿(mǎn)足的。因此,必須降低系統(tǒng)對(duì)于帶寬的需求,片上RAM提供了一種合理的途徑。
通過(guò)RAM降低帶寬需求的想法如下:卷積核的尺寸遠(yuǎn)小于輸入圖像的尺寸,將大量的卷積核數(shù)據(jù)儲(chǔ)存在片上的代價(jià)并不大。如果在讀取完一個(gè)輸入圖像后,將其與若干個(gè)不同的卷積核進(jìn)行運(yùn)算,相當(dāng)于將同樣的數(shù)據(jù)復(fù)用了若干次,使得DDR讀寫(xiě)IP有更多時(shí)間進(jìn)行下一幅輸入圖像數(shù)據(jù)的讀取。這樣就降低了系統(tǒng)對(duì)于帶寬的要求。需要注意的是,同一幅輸入圖像與不同的卷積核進(jìn)行運(yùn)算的結(jié)果需要分別儲(chǔ)存在片上,這就造成了對(duì)于片上RAM的需求。
3.2.2不同復(fù)用率下的緩存和帶寬需求
正如之前所述,如何在帶寬資源需求和片上RAM資源需求之間取舍是本次設(shè)計(jì)的重點(diǎn)。
下面根據(jù)查詢(xún)到的數(shù)據(jù)大致計(jì)算不同的復(fù)用策略下所需的最小片上RAM容量。
表1 不同復(fù)用率下的緩存和帶寬需求
(*第一列表示不同的并行策略,X表示每次讀入一幅輸入圖像,與其進(jìn)行卷積運(yùn)算的卷積核數(shù)量占全部卷積核數(shù)量(1024)的比例;第二列表示不同并行策略下所需的最小片上RAM空間;第三列表示不同策略下的最小數(shù)據(jù)讀取速率)
3.2.3不同數(shù)據(jù)帶寬下的最小緩存需求
下面根據(jù)DDR產(chǎn)品(以Micron公司為例)的用戶(hù)說(shuō)明中的數(shù)據(jù)對(duì)于四種DDR在不同運(yùn)行設(shè)置下的數(shù)據(jù)帶寬進(jìn)行計(jì)算,并估計(jì)最大復(fù)用率時(shí)所需的片上RAM容量:
表2 不同DDR的最低緩存需求
(*各列交替表示不同類(lèi)型的DDR的讀寫(xiě)速度和相應(yīng)的最小片上RAM容量;各行表示各類(lèi)DDR在不同工作狀態(tài)下的不同情況:Long Max(16位寬數(shù)據(jù)總線,最大數(shù)據(jù)速率),Long Avr(16位寬數(shù)據(jù)總線,平均數(shù)據(jù)速率),Short Max(8位數(shù)據(jù)總線,最大數(shù)據(jù)速率),Short Avr(8位寬數(shù)據(jù)總線,平均數(shù)據(jù)速率))
4實(shí)現(xiàn)結(jié)構(gòu)
4.1 DDR2的接口設(shè)計(jì)和測(cè)試
“我是誰(shuí)?我從哪里來(lái)?我要到哪里去?”這是哲學(xué)三大終極問(wèn)題。對(duì)于數(shù)字系統(tǒng)架構(gòu)設(shè)計(jì),亦是如此:我們不能僅僅關(guān)注數(shù)據(jù)的固有性質(zhì)和系統(tǒng)的運(yùn)算方式,更不能忽視數(shù)據(jù)的讀寫(xiě)速度和系統(tǒng)的存儲(chǔ)結(jié)構(gòu)。
在本系統(tǒng)中,輸入圖像、卷積核和運(yùn)算結(jié)果都存儲(chǔ)在DDR中,而且輸入圖像的規(guī)模和數(shù)據(jù)帶寬是比較大的,因此DDR的傳輸速率勢(shì)必會(huì)對(duì)整個(gè)系統(tǒng)的效率產(chǎn)生非常大的影響。所以設(shè)計(jì)DDR接口與系統(tǒng)總線并測(cè)試其傳輸速率是非常有必要的。
在Altera FPGA中,使用Avalon總線接口可以簡(jiǎn)單高效的組件系統(tǒng),Avalon總線接口適用于高速數(shù)據(jù)流,讀寫(xiě)寄存器,存儲(chǔ)器,以及控制片外設(shè)備。這些標(biāo)準(zhǔn)接口在Qsys中有效地設(shè)計(jì)到組件中,其架構(gòu)示意圖如圖4所示。
圖4 Avalon總線示意圖
在此圖中,NIOS II處理器使用Avalon-MM接口存取片內(nèi)組件的控制寄存器和狀態(tài)寄存器。分散集中DMA使用Avalon-ST接口發(fā)送和接收數(shù)據(jù)。四個(gè)組件包括利用軟件運(yùn)行在NIOS II處理器上的中斷接口服務(wù)程序。PLL通過(guò)Avalon clock sink接口接受一個(gè)時(shí)鐘,并提供兩個(gè)時(shí)鐘源。兩個(gè)組件包括Avalon-TC接口存取片外存儲(chǔ)器。最后,DDR控制器使用Avalon conduit接口存取外部DDR3存儲(chǔ)器。
DDR-SDRAM存儲(chǔ)體采用突發(fā)傳輸模式[2]。在此模式下,把多個(gè)傳遞作為一個(gè)單元執(zhí)行,不是獨(dú)立地處理每個(gè)字。突發(fā)可提高從器件端口在一個(gè)時(shí)間處理多個(gè)字時(shí)達(dá)到較大效率的能力。突發(fā)中的純粹作用是為了突發(fā)的持續(xù)而鎖定仲裁。支持讀寫(xiě)突發(fā)的Avalon-MM接口,必須都支持讀寫(xiě)突發(fā)。其讀寫(xiě)時(shí)序規(guī)則如圖5和圖6所示。
圖5 Avalon Burst模式 讀時(shí)序
時(shí)序圖中的序號(hào),表示隨后的變化:
1. 在CLK上升沿之后,主器件斷言address(A0),burstcount,和read。從器件斷言waitrequest,引起除beginbursttransfer之外的所有輸入直到另一個(gè)時(shí)鐘周期保持不變。
2. 在CLK上升沿從器件捕獲A0和burstcount。在下一個(gè)周期可啟動(dòng)新的傳遞。
3. 主器件B驅(qū)動(dòng)address(A1),burstcount和read。從器件斷言waitrequest,引起除beginbursttransfer之外的所有輸入保持不變。此時(shí),從器件最早從第一個(gè)讀請(qǐng)求返回讀數(shù)據(jù)。
4. 從器件傳送有效的readdata和斷言readdatavalid,給主器件A傳遞數(shù)據(jù)的第一個(gè)字。
5. 給主器件A的第二個(gè)字已經(jīng)傳遞。從器件解除readdatavalid暫停讀突發(fā)。從器件端口可保持解除readdatavalid任意時(shí)鐘周期數(shù)。
6. 給主器件B的第一個(gè)字已經(jīng)返回。
圖6 Avalon Burst模式 寫(xiě)時(shí)序
時(shí)序圖中的序號(hào),表示隨后的變化:
1. 主器件斷言address,burstcount,write,并驅(qū)動(dòng)writedata的第一個(gè)單元。從器件立即斷言waitrequest,表示其沒(méi)有準(zhǔn)備好進(jìn)行傳遞。
2. waitrequest為低電平。從器件捕獲addr1,burstcount和writedata的第一個(gè)單元。在傳遞隨后的周期,address和burstcount都被忽略。
3. 在CLK時(shí)鐘上升沿從器件捕獲數(shù)據(jù)的第二個(gè)單元。
4. 突發(fā)被暫停直到write被解除。
5. 在CLK時(shí)鐘上升沿從器件捕獲數(shù)據(jù)的第三個(gè)單元。
6. 從器件斷言waitrequest。在響應(yīng)中,所有輸出直到另一個(gè)時(shí)鐘周期都保持不變。
7. 在CLK時(shí)鐘上升沿從器件捕獲數(shù)據(jù)的最后一個(gè)單元。從器件寫(xiě)突發(fā)結(jié)束。
按照以上規(guī)范設(shè)計(jì)DDR2接口[3],仿真結(jié)果如圖7所示。
圖7 DDR讀取的ModelSim-Altera仿真波形
在圖7中,可以看到讀取6個(gè)Bank的64位數(shù)據(jù)需要16個(gè)時(shí)鐘周期的時(shí)間,因此可以計(jì)算DDR的讀取速率為
4.2系統(tǒng)實(shí)現(xiàn)設(shè)計(jì)結(jié)構(gòu)圖
圖7 系統(tǒng)實(shí)現(xiàn)設(shè)計(jì)結(jié)構(gòu)
(*IP READ/IP WRITE分別為讀端和寫(xiě)端控制DDR IP的狀態(tài)機(jī),均通過(guò)AVALON標(biāo)準(zhǔn)總線與DDR IP相連;FIFO用于跨時(shí)鐘域傳輸數(shù)據(jù),DDR接口部分與卷積運(yùn)算部分使用不同的時(shí)鐘。)
5實(shí)驗(yàn)
5.1 MATLAB算法驗(yàn)證
我們實(shí)現(xiàn)對(duì)于卷積算法進(jìn)行了MATLAB驗(yàn)證,并使用隨機(jī)生成的卷積核對(duì)灰度圖像進(jìn)行了卷積運(yùn)算,結(jié)果如圖5所示。
圖8 卷積算法的MATLAB驗(yàn)證
5.2計(jì)算單元設(shè)計(jì)的MATLAB驗(yàn)證
為了證實(shí)卷積計(jì)算單元設(shè)計(jì)的可行性,我們?cè)贛ATLAB上編寫(xiě)了計(jì)算單元的代碼,并使用MNIST數(shù)據(jù)集中的圖片和隨機(jī)生成的卷積核進(jìn)行了實(shí)驗(yàn)。實(shí)驗(yàn)結(jié)果如圖6所示。
圖9 計(jì)算單元設(shè)計(jì)的MATLAB驗(yàn)證
參考文獻(xiàn):
[1]中星微電子集團(tuán):深度學(xué)習(xí)——卷積神經(jīng)網(wǎng)絡(luò)(CNN)優(yōu)化
[2]Chen Zhang, Peng Li, Guangyu Sun, Yijin Guan, Bingjun Xiao, Jason Cong. Optimizing FPGA-based Accelerator Design for Deep Convolutional Neural Networks.
[3] Y. Lecun, L. Bottou, Y. Bengio, and P. Haffner. Gradient-based learning applied to document recognition. Processing of the IEEE, 86(11):2278-2324, 1998.
[4] Xilinx/Micron: Micron DRAM Memory Support for Xilinx Platforms
附錄
附錄A:卷積算法MATLAB驗(yàn)證代碼:
%small scale test for convolutional unit
%fixed size: 224*300, image: 'bbtest.jpg', fixed number of channels: in:3, out:3
%read image
im = imread('bbtest.jpg');
im_input = permute(im, [3, 1, 2]); %exchanging dimension
%initialize kernel
kernels = rand(3, 3, 3, 3) .* 0.005 %kernel size: 3*3, range: 1~0.005
%initialize output figure
output_fm = zeros(3, 300, 224);
%image processing
R = 300, C = 224, M = 3, N = 3, S = 1; %size of input image and input, output channels
for row = 1:R-3
for col = 1:C-3
for to = 1:M
for ti = 1:N
for i = 1:3
for j = 1:3
output_fm(to, row, col) = output_fm(to, row, col)...
+ kernels(to, ti, i, j) * im_input(ti, S * row + i, S * col + j);
end
end
end
end
end
end
%show the images
output_fm;
output_show = permute(output_fm, [2, 3, 1]);
imshow(output_show);
附錄B:計(jì)算單元設(shè)計(jì)MATLAB驗(yàn)證代碼:
% testing the processing element
% time: 13:40; 3.16.2017
% initializing buffers
procwin = zeros(3, 3);
kernel = rand(3, 3) * 0.005;
buffer1 = zeros(25);
buffer2 = zeros(25);
R_pixel = zeros(1,784); % cauculating result for single pixels
% loading data
data = ones(784);
im = imread('test.jpg');
data = reshape(im,1,784);
% initializing data
procwin(1, :) = data(1: 3);
buffer1 = data(4: 28);
procwin(2, :) = data(29: 31);
buffer2 = data(32: 56);
procwin(3, :) = data(57: 59);
%cauculating
for i = 60:784
% cauculating pixel level result
for m = 1:3
for n = 1:3
R_pixel(i-59) = R_pixel(i-59) + procwin(m,n) * kernel(m,n);
end
end
% moving data in processing window
reg2 = procwin(2, 1); % preserve for moving into ram
reg3 = procwin(3, 1); % preserve for moving inro ram
for j = 1:2
procwin(:, j) = procwin(:, j+1);
end
procwin(1, 3) = buffer1(1);
procwin(2, 3) = buffer2(1);
procwin(3, 3) = data(i);
% moving data in ram
for j = 1:24
buffer1(j) = buffer2(j+1);
buffer2(j) = buffer2(j+1);
end
buffer1(25) = reg2;
buffer2(25) = reg3;
end
im_output = reshape(R_pixel,28,28);
imshow(im_output);
評(píng)論