海思NNIE開發(二):FasterRCNN在海思NNIE平臺上的執行流程(一)

海思NNIE開發系列文章:

 

海思NNIE開發(一):海思Hi3559AV100/Hi3519AV100 NNIE深度學習模塊開發與調試記錄

海思NNIE開發(二):FasterRCNN在海思NNIE平臺上的執行流程(一)

海思NNIE開發(三):FasterRCNN在海思NNIE平臺上的執行流程(二)

海思NNIE開發(四):NNIE模塊讀入JPEG圖片或視頻

海思NNIE開發(五):基於Hi3559AV100的FasterRCNN、RFCN、SSD、Yolov2、Yolov3性能綜合測評

-----------------------------------------------------------------------------------------------------------------------------------

前文:

本博客將以系列文章講解FasterRCNN等深度學習網絡模型在海思NNIE平臺上的執行原理。本篇將講解NNIE平臺上幾個存儲模型網絡參數的幾個結構體,以及NNIE分段執行的概念。

正文:

以SAMPLE_SVP_NNIE_FasterRcnn這個sample爲例解析海思NNIE模型網絡參數。

首先來看以下函數:

s32Ret = SAMPLE_COMM_SVP_NNIE_LoadModel(pcModelName,&s_stFasterRcnnModel);

該函數用於從wk文件中解析出模型的網絡參數。我們來看s_stFasterRcnnModel這個參數,它是一個結構體,如下:

typedef struct hiSAMPLE_SVP_NNIE_MODEL_S
{
    SVP_NNIE_MODEL_S    stModel;
    SVP_MEM_INFO_S      stModelBuf;//store Model file
}SAMPLE_SVP_NNIE_MODEL_S;

stModel存儲解析出來的模型網絡參數,我們來看SVP_NNIE_MODEL_S這個結構體:

/*NNIE model*/
typedef struct hiSVP_NNIE_MODEL_S
{
    SVP_NNIE_RUN_MODE_E     enRunMode;/*枚舉類型,網絡模型運行模式*/

    HI_U32                  u32TmpBufSize; /*輔助內存大小temp buffer size*/
    HI_U32                  u32NetSegNum;/*網絡模型中 NNIE 執行的網絡分段數,取值[1,8]*/
    SVP_NNIE_SEG_S          astSeg[SVP_NNIE_MAX_NET_SEG_NUM]/*網絡在 NNIE 引擎上執行的段信息*/;
    SVP_NNIE_ROIPOOL_INFO_S astRoiInfo[SVP_NNIE_MAX_ROI_LAYER_NUM]; /*網絡模型中 RoiPooling 以及 PsRoiPooling 的信息數組ROIPooling info*/

    SVP_MEM_INFO_S          stBase/*網絡其他信息*/;
}SVP_NNIE_MODEL_S;

在Sample_nnie_main這個sample中加入打印語句,輸出如下:

enRunModel:爲枚舉類型,表示網絡模型的運行模式,有SVP_NNIE_RUN_MODE_CHIP(只能在Chip上運行),以及SVP_NNIE_RUN_MODE_FUNC_SIM(只能用於PC端功能仿真)兩個枚舉值。通過以上打印可以看到FasterRCNN網絡模型只能在Chip上運行。

u32TempBufSize:爲輔助內存大小,以上打印爲21094400.

u32NetSegNum:爲網絡模型中NNIE執行的網絡分段數,取值爲1~8。這裏的分段是指模型執行中可能會分成多段,一些段在NNIE上執行,一些段在CPU或DSP上執行。如下圖所示:

這個u32NetSegNum就是指有多少段是在NNIE上執行的,如果一個網絡模型全部都是在NNIE上執行,那麼這個u32NetSegNum就是1。通過以上打印可知FasterRCNN網絡的NNIE執行分爲兩段。

astSeg[SVP_NNIE_MAX_NET_SEG_NUM]:這個參數是一個結構體數組,SVP_NNIE_MAX_NET_SEG_NUM在hi_nnie.h中定義爲8,這個數組表示每一段NNIE網絡的各段的具體信息,具體信息有哪些,我們來看SVP_NNIE_SEG_S這個結構體:

/*Segment information*/
typedef struct hiSVP_NNIE_SEG_S
{
    SVP_NNIE_NET_TYPE_E enNetType; /*網絡段的類型*/
    HI_U16              u16SrcNum; /*網絡段的輸入節點數*/
    HI_U16              u16DstNum;/*網絡段的輸出節點數*/
    HI_U16              u16RoiPoolNum;/*絡段中包含的 RoiPooling 以及 PSRoiPooling layer 數*/
    HI_U16              u16MaxStep;/*RNN/LSTM 網絡中序列的最大“幀數”*/

    HI_U32              u32InstOffset;
    HI_U32              u32InstLen;

    SVP_NNIE_NODE_S     astSrcNode[SVP_NNIE_MAX_INPUT_NUM]; /*網絡段的第 i 個輸入節點信息, SVP_NNIE_MAX_INPUT_NUM爲16*/
    SVP_NNIE_NODE_S     astDstNode[SVP_NNIE_MAX_OUTPUT_NUM];/*網絡段的第 i 個輸出節點信息, SVP_NNIE_MAX_OUTPUT_NUM爲16*/
    HI_U32              au32RoiIdx[SVP_NNIE_MAX_ROI_LAYER_NUM_OF_SEG]; /*網絡段的第 i 個 RoiPooling 或者 PsRoiPooling 在SVP_NNIE_MODEL_S 中 SVP_NNIE_ROIPOOL_INFO_S 數組的下標,SVP_NNIE_MAX_ROI_LAYER_NUM_OF_SEG爲2*/
}SVP_NNIE_SEG_S;

enNetType:這個參數枚舉類型,如下:

typedef enum hiSVP_NNIE_NET_TYPE_E
{
    SVP_NNIE_NET_TYPE_CNN  = 0x0, /* Non-ROI input cnn net,普通的CNN\DNN網絡類型 */
    SVP_NNIE_NET_TYPE_ROI  = 0x1, /* With ROI input cnn net,有RPN層輸出框信息的網絡類型*/
    SVP_NNIE_NET_TYPE_RECURRENT = 0x2, /* RNN or LSTM net */

    SVP_NNIE_NET_TYPE_BUTT
}SVP_NNIE_NET_TYPE_E;

包含4種類型:SVP_NNIE_NET_TYPE_CNN表示普通的的CNN網絡, SVP_NNIE_NET_TYPE_ROI有RPN層輸出框信息的網絡類型,這裏其實就是指Faster RCNN的NNIE模型中的Proposal層,這個層包含RPN輸出框信息,且由CPU來執行。SVP_NNIE_NET_TYPE_RECURRENT則表示RNN循環神經網絡或者LSTM長短期記憶網絡。

u16SrcNum:表示這個段的輸入節點數,即這個段網絡有多少個輸入,也是後面的astSrcNode數組的元素的有效個數

u16DstNum:表示這個段的輸出節點數,即這個段網絡有多少個輸出,也是後面的astDstNode數組的元素的有效個數

astSrcNode與astDstNode:表示這個段的輸入和輸出節點的具體信息,其類型爲SVP_NNIE_NODE_S,如下:

/*Node information*/
typedef struct hiSVP_NNIE_NODE_S
{
    SVP_BLOB_TYPE_E  enType;/*節點的類型*/
    union
    {
        struct
        {
            HI_U32 u32Width; /*節點內存形狀的寬*/
            HI_U32 u32Height;/*節點內存形狀的高*/
            HI_U32 u32Chn;/*節點內存形狀的通道數*/
        }stWhc;
        HI_U32 u32Dim;/*節點內存的向量維度*/
    }unShape;
    HI_U32 u32NodeId;/*節點在網絡中的 Id*/
	HI_CHAR szName[SVP_NNIE_NODE_NAME_LEN];/*Report layer bottom name or data layer bottom name*/
}SVP_NNIE_NODE_S;

enType是枚舉類型,其類型SVP_BLOB_TYPE_E如下:

/*Blob type*/
typedef enum hiSVP_BLOB_TYPE_E
{
    SVP_BLOB_TYPE_S32       =  0x0,/*Blob 數據元素爲 S32 類型*/
    SVP_BLOB_TYPE_U8        =  0x1,/*Blob 數據元素爲 U8 類型*/
    /*channel = 3*/
    SVP_BLOB_TYPE_YVU420SP  =  0x2,/*Blob 數據內存排布爲 YVU420SP*/
    /*channel = 3*/
    SVP_BLOB_TYPE_YVU422SP  =  0x3,/*Blob 數據內存排布爲 YVU422SP*/
    SVP_BLOB_TYPE_VEC_S32   =  0x4,/*Blob 中存儲向量,每個元素爲 S32 類型*/
    SVP_BLOB_TYPE_SEQ_S32   =  0x5,/*Blob 中存儲序列,數據元素爲 S32 類型*/
    SVP_BLOB_TYPE_BUTT
}SVP_BLOB_TYPE_E;

通過打印輸出SVP_NNIE_MODEL_S結構體中的astSeg,即打印兩段NNIE網絡信息的輸入輸出節點信息,如下:

從打印的 信息,我們首先看段與節點的類型,這個對於以後的分析有用,因爲後面的一些初始化操作會根據不同的類型有不同的操作,如下表:

段類型/段類型值 輸入/輸出 節點名 節點類型/節點類型值

第1段

SVP_NNIE_NET_TYPE_CNN/0 輸入 data SVP_BLOB_TYPE_S32/0
輸出 conv5 SVP_BLOB_TYPE_S32/0
rpn_cls_score SVP_BLOB_TYPE_S32/0
rpn_bbox_pred SVP_BLOB_TYPE_S32/0
rpn_cls_prob_reshape SVP_BLOB_TYPE_S32/0

第2段

SVP_NNIE_NET_TYPE_ROI/1 輸入 conv5 SVP_BLOB_TYPE_S32/0
輸出 bbox_pred SVP_BLOB_TYPE_VEC_S32/4
cls_prob SVP_BLOB_TYPE_VEC_S32/4

將以上打印與下面網絡圖結合,這裏的節點名szName,個人的理解是,如果作爲輸入節點,則顯示的是該層的bottom的名字,如果作爲輸出節點,則顯示top的名字。第1段有1個輸入節點,即data層的輸入。輸出節點的數量打印顯示是4個輸出,而下面的網絡圖中只有3個輸出,即conv5, rpn_bbox_pred, rpn_cls_prob_reshape,打印顯示多了一個rpn_cls_score。在RuyiStudio的網絡圖裏rpn_cls_score是在第一段的中間,並非作爲輸出,爲什麼會把它當輸出呢?玄機就在網絡描述文件.prototxt裏面,我們來看rpn_cls_score這一層,如下:

layer {
  name: "rpn_cls_score"
  type: "Convolution"
  bottom: "rpn/output"
  top: "rpn_cls_score_report"
  convolution_param {
    num_output: 18   # 2(bg/fg) * 9(anchors)
    kernel_size: 1 pad: 0 stride: 1
    weight_filler { type: "gaussian" std: 0.01 }
    bias_filler { type: "constant" value: 0 }
  }
}

這一層的top輸出是rpn_cls_score_report,即rpn_cls_score加了後綴_report。我們打開《HiSVP開發指南》的3.2.7章節,如下:

可以看到,中間層的top加上_report後當作該段的一個輸出,因此從打印那裏可以看到這一段有rpn_cls_score作爲輸出。

 

第2段有1個輸入節點,conv5,這裏顯示的u32NodeId爲0,那麼這個u32NodeId應該是指該節點在該段中的序號。這個段的輸出節點bbox_pred, cls_prob,顯示序號爲7和9。

這裏還有個疑問,不知道這個u32NodeId序號是怎麼排的,例如第1段的輸出節點conv5,序號爲8,但從下圖來看,應該是7(relu層應該跟conv5同一個序號)。但是rpn_cls_prob_reshape的序號怎麼是19,rpn_bbox_pred的序號爲13也對不上。

 

注:以上網絡使用的是以下FasterRCNN網絡

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章