likes
comments
collection
share

FPGA - lenet - avgpooling+FC

作者站长头像
站长
· 阅读数 51

池化后图像大小 (W-F)/S +1 w为图像宽,F为卷积核尺度。 S为步长

28x28x6 - 经过2x2,步长为2的平均池化。 14x14

步长S就等于池化核的尺寸。 平均池化后尺寸为输入尺寸 除以池化核的尺寸。

Average pool Multi Layer

执行多个通道的image的平均池化,并行度为1,循环复用AvgPoolSingle完成所有通道的平均池化。

FPGA - lenet - avgpooling+FC

FPGA - lenet - avgpooling+FC

Avarage pool Single Layer

平均池化,取均值。全并行化同时进行所有窗口的计算。

执行单个通道的image的平均池化,这里为全并行化。每个窗口都有一个AvgU。

这里为组合逻辑电路

FPGA - lenet - avgpooling+FC

Averaging Unit

求输入的四个均值,

逻辑:先求和,再将和乘以0.25得到四个输入的均值

组合逻辑电路,插入寄存器形成pipeline

FPGA - lenet - avgpooling+FC

三个加法器,一个乘法器

FC

集成的全连接层,包含两个全连接层,Tanh激活函数层以及Softmax层

Weight存储全连接层的权重。

Layer 进行线性运算

Tanh 激活非线性

SoftMax 多分类

FPGA - lenet - avgpooling+FC

FPGA - lenet - avgpooling+FC

PE:

FPGA - lenet - avgpooling+FC

FPGA - lenet - avgpooling+FC

一个乘法器,一个加法器。 累乘之后累加


parameter DATA_WIDTH = 32;

input clk, reset;
input [DATA_WIDTH-1:0] floatA, floatB;
output reg [DATA_WIDTH-1:0] result;

wire [DATA_WIDTH-1:0] multResult;
wire [DATA_WIDTH-1:0] addResult;

floatMult FM (floatA,floatB,multResult);
//和上次结果进行累加。
floatAdd FADD (multResult,result,addResult);

always @ (posedge clk or posedge reset) begin
	if (reset == 1'b1) begin
		result = 0;
	end else begin
                //重新赋值
		result = addResult;
	end
end

endmodule

FC:

module integrationFC (clk,reset,iFCinput,CNNoutput);

parameter DATA_WIDTH = 32;
parameter IntIn = 120;    //输入节点数目
parameter FC_1_out = 84;  // 第一个全连接层输出节点个数
parameter FC_2_out = 10;

input clk, reset;
input [IntIn*DATA_WIDTH-1:0] iFCinput;
output [FC_2_out*DATA_WIDTH-1:0] CNNoutput;

wire [FC_1_out*DATA_WIDTH-1:0] fc1Out;
wire [FC_1_out*DATA_WIDTH-1:0] fc1OutTanh;

wire [FC_2_out*DATA_WIDTH-1:0] fc2Out;
wire [FC_2_out*DATA_WIDTH-1:0] fc2OutSMax;

wire [DATA_WIDTH*FC_1_out-1:0] wFC1;
wire [DATA_WIDTH*FC_2_out-1:0] wFC2;

reg FC1reset;
reg FC2reset;
reg TanhReset;
wire TanhFlag;
reg SMaxEnable;
wire DoneFlag;

integer counter;
reg [7:0] address1;
reg [7:0] address2;

weightMemory 
#(.INPUT_NODES(IntIn),
  .OUTPUT_NODES(FC_1_out),
  .file("C:/Users/ahmed/Desktop/Logic Design 2 Project/Parameters With No Seperators/weightsdense_1_IEEE.txt"))
  W1(
    .clk(clk),
    .address(address1),
    .weights(wFC1)
    );
    
weightMemory 
#(.INPUT_NODES(FC_1_out),
  .OUTPUT_NODES(FC_2_out),
  .file("C:/Users/ahmed/Desktop/Logic Design 2 Project/Parameters With No Seperators/weightsdense_2_IEEE.txt"))
  W2(
    .clk(clk),
    .address(address2),
    .weights(wFC2)
    );  
    
layer
#(.INPUT_NODES(IntIn),
  .OUTPUT_NODES(FC_1_out))
 FC1(
    .clk(clk),
    .reset(FC1reset),
    .input_fc(iFCinput),
    .weights(wFC1),
    .output_fc(fc1Out)
    );

layer
#(.INPUT_NODES(FC_1_out),
  .OUTPUT_NODES(FC_2_out))
 FC2(
    .clk(clk),
    .reset(FC2reset),
    .input_fc(fc1OutTanh),
    .weights(wFC2),
    .output_fc(fc2Out)
    );
    
UsingTheTanh
#(.nofinputs(FC_1_out))
Tanh1(
      .x(fc1Out),
      .clk(clk),
      .Output(fc1OutTanh),
      .resetExternal(TanhReset),
      .FinishedTanh(TanhFlag)
      );

softmax SMax(
      .inputs(fc2Out),
      .clk(clk),
      .enable(SMaxEnable),
      .outputs(CNNoutput),
      .ackSoft(DoneFlag)
      );

always @(posedge clk or posedge reset) begin
  if (reset == 1'b1) begin
    FC1reset = 1'b1;
    FC2reset = 1'b1;
    TanhReset = 1'b1;
    SMaxEnable = 1'b0;
    counter = 0;
    address1 = -1;
    address2 = -1;
  end
  else begin
      counter = counter + 1;      // 工作时钟周期
    if (counter > 0 && counter < IntIn + 10) begin // 启动FC1,进行第一层全连接层计算
       FC1reset = 1'b0;
    end
    else if (counter > IntIn + 10 && counter < IntIn + 12 + FC_1_out*6) begin   //启动Tanh
       TanhReset = 1'b0;
       address2 = -3;
    end
    else if (counter > IntIn + 12 + FC_1_out*6 && counter < IntIn + 12 + FC_1_out*6 + FC_1_out + 10) begin  //启动FC2
       FC2reset = 1'b0;
    end
    else if (counter > IntIn + 12 + FC_1_out*6 + FC_1_out + 10) begin//启动softmax
       SMaxEnable = 1'b1;
    end
    if (address1 != 8'hfe) begin
      address1 = address1 + 1;
    end
    else
      address1 = 8'hfe;
    address2 = address2 + 1;
  end
end

endmodule  

全连接层的输入是一维数组,多维数组需先进行Flatten进行一维化处理,然后连接全连接层。全连接层的每一个结点都与上一层的所有结点相连,用来把前边提取到的特征综合起来。由于其全相连的特性,一般全连接层的参数也是最多的。

权值参数 = 输入一维数组大小*全连接层输出结点数

偏置参数b=全连接层输出结点数

输入有5044个神经元结点,输出有500个结点,则一共需要5044*500=400000个权值参数W和500个偏置参数b

网络层分析

输入32x32图像

C1 第一次卷积:5x5x6,no padding,stride=1

(32-5)/1 +1 = 28

得到28x28x6 feature map

S2平均池化: 2x2,stride = 2

(28-2)/2 +1 即28/2 = 14

得到14x14x6的feature map

C3第二次卷积: 5x5x16

得到10x10x16的feature map

S4平均池化: 2x2,stride = 2

得到5x5x16的feature map

C5第三次卷积:卷积核为5x5x120

得到5-5 +1 = 1

得到1x1x120的feature map

F6 全连接层: 有84个输出节点

权值参数 120x84 偏置参数 84

得到1x84的输出

F7全连接层: 有10个输出节点,因为为10类

权值参数 84x10 偏置参数 10

得到1x10的输出

最后接一个softmax激活函数,进行归一化,得到每一类的概率。得出对该图片的类别判断。

转载自:https://juejin.cn/post/7124877735817691143
评论
请登录