FC2カウンター FPGAの部屋 2019年07月04日

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。


FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。



前回は、KERAS_conv1d_small_nfilt5 ネットワークをビルドして、C コードの合成結果を観察した。今回は、KERAS_conv1d_small_nfilt5 のネットワーク構造を調べていこう。

KERAS_conv1d_small_nfilt5.cpp を引用する。

//    rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks
//    Copyright (C) 2017 EJ Kreinar
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    GNU General Public License for more details.
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#include <iostream>

#include "KERAS_conv1d_small_nfilt5.h"

//hls-fpga-machine-learning insert weights
#include "weights/w2.h"
#include "weights/b2.h"
#include "weights/w4.h"
#include "weights/b4.h"
#include "weights/w6.h"
#include "weights/b6.h"
#include "weights/w8.h"
#include "weights/b8.h"
#include "weights/w10.h"
#include "weights/b10.h"

void KERAS_conv1d_small_nfilt5(
    input_t input_1[N_INPUT_1_1*N_INPUT_2_1],
    result_t layer11_out[N_LAYER_10],
    unsigned short &const_size_in_1,
    unsigned short &const_size_out_1
) {

    //hls-fpga-machine-learning insert IO
    #pragma HLS ARRAY_RESHAPE variable=input_1 complete dim=0 
    #pragma HLS ARRAY_RESHAPE variable=layer11_out complete dim=0 
    #pragma HLS INTERFACE ap_vld port=input_1,layer11_out 
    #pragma HLS PIPELINE 

    const_size_in_1 = N_INPUT_1_1*N_INPUT_2_1;
    const_size_out_1 = N_LAYER_10;

    // ****************************************
    // ****************************************

    //hls-fpga-machine-learning insert layers

    layer2_t layer2_out[Y_OUTPUTS_2*N_FILT_2];
    #pragma HLS ARRAY_PARTITION variable=layer2_out complete dim=0
    nnet::conv_1d<input_t, layer2_t, config2>(input_1, layer2_out, w2, b2);

    layer3_t layer3_out[Y_OUTPUTS_2*N_FILT_2];
    #pragma HLS ARRAY_PARTITION variable=layer3_out complete dim=0
    nnet::relu<layer2_t, layer3_t, relu_config3>(layer2_out, layer3_out);

    layer4_t layer4_out[Y_OUTPUTS_4*N_FILT_4];
    #pragma HLS ARRAY_PARTITION variable=layer4_out complete dim=0
    nnet::conv_1d<layer3_t, layer4_t, config4>(layer3_out, layer4_out, w4, b4);

    layer5_t layer5_out[Y_OUTPUTS_4*N_FILT_4];
    #pragma HLS ARRAY_PARTITION variable=layer5_out complete dim=0
    nnet::relu<layer4_t, layer5_t, relu_config5>(layer4_out, layer5_out);

    layer6_t layer6_out[Y_OUTPUTS_6*N_FILT_6];
    #pragma HLS ARRAY_PARTITION variable=layer6_out complete dim=0
    nnet::conv_1d<layer5_t, layer6_t, config6>(layer5_out, layer6_out, w6, b6);

    layer7_t layer7_out[Y_OUTPUTS_6*N_FILT_6];
    #pragma HLS ARRAY_PARTITION variable=layer7_out complete dim=0
    nnet::relu<layer6_t, layer7_t, relu_config7>(layer6_out, layer7_out);

    layer8_t layer8_out[N_LAYER_8];
    #pragma HLS ARRAY_PARTITION variable=layer8_out complete dim=0
    nnet::dense<layer7_t, layer8_t, config8>(layer7_out, layer8_out, w8, b8);

    layer9_t layer9_out[N_LAYER_8];
    #pragma HLS ARRAY_PARTITION variable=layer9_out complete dim=0
    nnet::relu<layer8_t, layer9_t, relu_config9>(layer8_out, layer9_out);

    layer10_t layer10_out[N_LAYER_10];
    #pragma HLS ARRAY_PARTITION variable=layer10_out complete dim=0
    nnet::dense<layer9_t, layer10_t, config10>(layer9_out, layer10_out, w10, b10);

    nnet::softmax<layer10_t, result_t, softmax_config11>(layer10_out, layer11_out);


KERAS_conv1d_small_nfilt5.cpp と parameters.h から推定した層構成を示す。ただしすべての層の変数の型は ap_fixed<16,6> となっている。

入力層 40 入力
conv_1d 入力数 40 出力数 30
relu 入力数 30 出力数 30
conv_1d 入力数 30 出力数 20
relu 入力数 20 出力数 20
conv_1d 入力数 20 出力数 10
relu 入力数 10 出力数 10
dense 入力数 10 出力数 5
relu 入力数 5 出力数 5
dense 入力数 5 出力数 5
softmax 入力数 5 出力数 5

IP の入力と出力のフォーマットだが、 KERAS_conv1d_small_nfilt5.cpp で dim=0 で ARRAY_RESHAPE ディレクティブが書かれている。
よって、入力の input_1 が ap_fixed<16,6> が 40 個なので、640 ビット幅となり、
出力の layer9_out が ap_fixed<16,6> が 5 個なので、 80 ビット幅となっている。
KERAS_conv1d_small_nfilt5.vhd の entity 部分を引用する。

entity KERAS_conv1d_small_nfilt5 is
port (
    ap_clk : IN STD_LOGIC;
    ap_rst : IN STD_LOGIC;
    ap_start : IN STD_LOGIC;
    ap_done : OUT STD_LOGIC;
    ap_idle : OUT STD_LOGIC;
    ap_ready : OUT STD_LOGIC;
    input_1_V_ap_vld : IN STD_LOGIC;
    input_1_V : IN STD_LOGIC_VECTOR (639 downto 0);
    layer11_out_V : OUT STD_LOGIC_VECTOR (79 downto 0);
    layer11_out_V_ap_vld : OUT STD_LOGIC;
    const_size_in_1 : OUT STD_LOGIC_VECTOR (15 downto 0);
    const_size_in_1_ap_vld : OUT STD_LOGIC;
    const_size_out_1 : OUT STD_LOGIC_VECTOR (15 downto 0);
    const_size_out_1_ap_vld : OUT STD_LOGIC );

2つの hls4ml のexample ネットワークを見てきたが、小さいネットワークだった。自分で構築したニューラルネットワークを次にはやってみたい。
  1. 2019年07月04日 04:56 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0