一起学习用Verilog在FPGA上实现CNN----(七)全连接层设计

这篇具有很好参考价值的文章主要介绍了一起学习用Verilog在FPGA上实现CNN----(七)全连接层设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 全连接层设计

1.1 Layer

进行线性计算的单元layer,原理图如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

1.2 processingElement

Layer中的线性计算单元processingElement,原理图如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能
processingElement模块展开原理图,如图所示,包含一个乘法器和一个加法器,对输入进行累乘和累加

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

1.3 weightMemory

全连接层的权重存储于weightMemory单元,原理图如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2 代码实现

2.1 weightMemory

2.1.1 设计输入

创建weightMemory文件,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

双击打开,输入代码:

module weightMemory(clk,address,weights);

parameter DATA_WIDTH = 32;
parameter INPUT_NODES = 100;
parameter OUTPUT_NODES = 32;
parameter file = "E:/FPGA_Learn/FPGA/Day1211/Weight/weightsdense_1_IEEE.txt";

localparam TOTAL_WEIGHT_SIZE = INPUT_NODES * OUTPUT_NODES;

input clk;
input [7:0] address;
output reg [DATA_WIDTH*OUTPUT_NODES-1:0] weights;

reg [DATA_WIDTH-1:0] memory [0:TOTAL_WEIGHT_SIZE-1];

integer i;

always @ (posedge clk) begin	
	if (address > INPUT_NODES-1 || address < 0) begin
		weights = 0;
	end else begin
		for (i = 0; i < OUTPUT_NODES; i = i + 1) begin
			weights[(OUTPUT_NODES-1-i)*DATA_WIDTH+:DATA_WIDTH] = memory[(address*OUTPUT_NODES)+i];
		end
	end
end

initial begin
	$readmemh(file,memory);
end

endmodule

如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2.1.2 分析与综合

将weightMemory设置为顶层:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

关闭上次分析文件:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

对设计进行分析,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

分析后的设计,Vivado自动生成原理图,如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

原理图如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

对设计进行综合,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

综合完成,关闭即可

2.1.3 功能仿真

创建仿真激励文件,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

双击打开,输入激励代码:

module tb_weightMemroy();

reg clk;
reg [6:0] address;
wire [32*32-1:0] weights;

localparam PERIOD = 100;

always
	#(PERIOD/2) clk = ~clk;

initial begin
	#0
	clk = 1'b0;
	address = 0;

	#PERIOD
	address = 1;

	#PERIOD 
	address = 2;

	#PERIOD
	address = 32;

	#PERIOD
	$stop;
end

weightMemory UUT
(
	.clk(clk),
	.address(address),
	.weights(weights)
);

endmodule

如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能
将tb_weightMemory设置为顶层:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

开始进行仿真,操作如下:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

仿真波形,如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

仿真结束,关闭仿真:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2.2 processingElement

2.2.1 设计输入

创建processingElement文件,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

双击打开,输入代码:

module processingElement(clk,reset,floatA,floatB,result);

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

如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2.2.2 分析与综合

将processingElement设置为顶层:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

对设计进行分析,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

分析后的设计,Vivado自动生成原理图,如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

对设计进行综合,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

综合完成,关闭即可:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2.2.3 功能仿真

创建仿真激励文件,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

双击打开,输入激励代码:

module tb_processingElement();

reg clk,reset;
reg [31:0] floatA, floatB;
wire [31:0] result;

localparam PERIOD = 100;

always
	#(PERIOD/2) clk = ~clk;

initial begin
	#0
	clk = 1'b0;
	reset = 1;
	// A = 2 , B = 3
	floatA = 32'b01000000000000000000000000000000;
	floatB = 32'b01000000010000000000000000000000;

	#(PERIOD/4)
	reset = 0;

	// A = 1 , B = 5
	#(3*PERIOD/4)
	floatA = 32'b00111111100000000000000000000000;
	floatB = 32'b01000000101000000000000000000000;

	#(3*PERIOD/2)
	reset = 1;

	#(PERIOD)
	$stop;	
end

processingElement PE 
(
	.clk(clk),
	.reset(reset),
	.floatA(floatA),
	.floatB(floatB),
	.result(result)
);

endmodule

如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能
将tb_processingElement设置为顶层:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

开始进行仿真,操作如下:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

仿真波形,如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

仿真结束,关闭仿真:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2.3 Layer

2.3.1 设计输入

创建Layer文件,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

输入文件名:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能
确定创建:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

双击打开,输入代码:

module layer(clk,reset,input_fc,weights,output_fc);

parameter DATA_WIDTH = 32;
parameter INPUT_NODES = 100;
parameter OUTPUT_NODES = 32;

input clk, reset;
input [DATA_WIDTH*INPUT_NODES-1:0] input_fc;
input [DATA_WIDTH*OUTPUT_NODES-1:0] weights;
output [DATA_WIDTH*OUTPUT_NODES-1:0] output_fc;

reg [DATA_WIDTH-1:0] selectedInput;
integer j;

genvar i;

generate
	for (i = 0; i < OUTPUT_NODES; i = i + 1) begin
		processingElement PE 
		(
			.clk(clk),
			.reset(reset),
			.floatA(selectedInput),
			.floatB(weights[DATA_WIDTH*i+:DATA_WIDTH]),
			.result(output_fc[DATA_WIDTH*i+:DATA_WIDTH])
		);
	end
endgenerate

always @ (posedge clk or posedge reset) begin
	if (reset == 1'b1) begin
		selectedInput = 0;
		j = INPUT_NODES - 1;
	end else if (j < 0) begin
		selectedInput = 0;
	end else begin
		selectedInput = input_fc[DATA_WIDTH*j+:DATA_WIDTH];
		j = j - 1;
	end
end

endmodule

如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2.3.2 分析与综合

将Layer设置为顶层:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能
关闭上次的分析文件:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

对设计进行分析,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

分析后的设计,Vivado自动生成原理图,如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

原理图如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

对设计进行综合,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

综合完成,关闭即可:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2.3.3 功能仿真

创建仿真激励文件,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

双击打开,输入激励代码:

module tb_layer();
reg clk, reset;
reg [32*100-1:0] input_fc;
wire [32*32-1:0] weights;
wire [32*32-1:0] output_fc;

reg [7:0] address;

localparam PERIOD = 100;

always
	#(PERIOD/2) clk = ~clk;

always @ (posedge clk or posedge reset) begin
	if (reset == 1'b1) begin
		address = 0;
	end else begin
		address = address + 1;
	end
end

weightMemory WM 
(
	.clk(clk),
	.address(address),
	.weights(weights)
);

initial begin
	#0
	clk = 1'b0;
	reset = 1'b1;
	input_fc = 3200'b00111110110101101010010110110100001111110011010001110101011100000011111100101101101110010110001000111110101011101000010101010100001111110110000001111111101110100011111011000011010010010111101000111111011111001000101111111100001111110111001000101111111000000011111101011010001000111010111000111111011101000000011111101110001111100010111111011001011101100011111100000010101100110000001000111110101010010111100101011010001111101100110010000101101000000011111101111011101001111111110000111110011010111101000111101110001111110110011010000011110100100011111101101111110100011101110000111110101011011010100101100100001111100001000110100001000100100011111100010001101100110010100000111111001011100010000101100100001111110111100011001101111010100011111010100100100001010011110000111111010011010100111110011100001111110010101001000011010101100011111101111100000000000000000000111110101010001011100101010110001111110100110001101111100111000011111000001100010010010011010000111111000110110111111100111000001111011001010011100001001010100011111100001100000001110001010000111111000000111101100100000010001111110110111100001011111000000011111100111000110101110110101000111111001011110010100101011110001111110110111101110111111000100011111101101001101000011100101000111111010110110100010110111110001111110011000111010101010111100011111101001000000100011001000000111110110001001110100110000000001111101111011010111101111101000011111011110100011110011111011000111101110110011001000110111100001111101110000100001101101111100011110110101010011000010101101000111111010100001000110110100000001111101011010011101101011100000011111101100000101000011011111000111110101110111001010110000000001111110100010100110011100011100011111010010001011000010001110000111101010111101000000110110000001111110101100010001101101100000011111100001101101010010010001000111111000000111001100100001010001111110110010011011011110011100011111101101111001100111101101000111111010111111011100110111110001111110001000111101011001000000011111010110001110010010111000000111111001100001010001101100010001111101010011010010001010000100011111101011110000100111100001000111101101000101100000101000110001111110110000011111011110010100011111101010010101000111010110000111111000001010101101100000010001111110010101100000101010100100011111100000001111101010000011000111111001000010011100101000010001111101100011100001101100001000011110110111001100100010111100000111110111101111001110111110100001110110111000000000001110110100011111010000110000011010000001000111111010010010011011110001110001111110000111010110101000111000011111101111101111010111111101000111111000110011001101100101100001111011000101110000001000101000011111001010010100010011001100000111110110100011001010110101010001111110011100101111011011101000011111000110011010110010111100000111111000110111101100100110100001111110000011101111011000001100011111101011111000000111100000000111111001110111111111101111010001111101100001101100101100010000011111100000100011111010000101000111100001100111000000100110110001111110110110010100011110101100011111001011000011110011100010000111110000100101010000100110000001111110101100001110101101101000011110111101101011100011111001000111101011101111110000111101110;

	#PERIOD
	reset = 1'b0;
	

	#(102*PERIOD)
	$stop;
end

layer UUT
(
	.clk(clk),
	.reset(reset),
	.input_fc(input_fc),
	.weights(weights),
	.output_fc(output_fc)
);
endmodule

如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

将tb_layer设置为顶层:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

开始进行仿真,操作如下:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

仿真波形,如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

仿真结束,关闭仿真:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2.4 integrationFC

2.4.1 设计输入

打开integrationFC文件,输入代码:

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 SMaxEnable;
wire DoneFlag;

reg [7:0] address1;

weightMemory 
#(.INPUT_NODES(IntIn),
  .OUTPUT_NODES(FC_1_out),
  .file("E:/FPGA_Learn/FPGA/Day1211/Weight/weightsdense_1_IEEE.txt"))
  W1(
    .clk(clk),
    .address(address1),
    .weights(wFC1)
    );
    
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)
    );    
softmax SMax(
      .inputs(fc2Out),
      .clk(clk),
      .enable(SMaxEnable),
      .outputs(CNNoutput),
      .ackSoft(DoneFlag)
      );
      
endmodule

如图所示:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

2.4.2 分析与综合

将integrationFC设置为顶层:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

关闭上次的分析文件:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

对设计进行分析,操作如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

分析后的设计,Vivado自动生成原理图,如图:

fpga上实现cnn,笔记,一起学ZYNQ,fpga开发,cnn,ZYNQ,神经网络,人工智能

希望本文对大家有帮助,上文若有不妥之处,欢迎指正

分享决定高度,学习拉开差距文章来源地址https://www.toymoban.com/news/detail-778853.html

到了这里,关于一起学习用Verilog在FPGA上实现CNN----(七)全连接层设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【探索AI】十八 深度学习之第3周:卷积神经网络(CNN)(二)-常见的卷积层、池化层与全连接层

    卷积神经网络(Convolutional Neural Network,CNN)是一种深度学习算法,特别适用于处理图像相关的任务。CNN通过模拟人脑视觉皮层的层次化结构,实现了对图像的高效特征提取和分类。下面将详细介绍CNN的基本原理和结构,包括卷积层、池化层和全连接层的作用和位置。 卷积层

    2024年04月16日
    浏览(45)
  • 神经网络:全连接层

    在计算机视觉中,全连接层(也称为密集连接层或线性层)是一种常用的神经网络层,用于将输入数据与模型的参数进行线性组合,并产生输出结果。 作用: 全连接层在神经网络中起到特征映射和非线性变换的作用。它通过将输入数据与权重矩阵进行线性组合,并通过激活

    2024年02月10日
    浏览(38)
  • 对全连接层的理解

    全连接层 Fully Connected Layer 一般位于整个 卷积神经网络的最后 ,负责将卷积输出的 二维特征图转化成一维的一个向量 ,由此实现了端到端的学习过程(即:输入一张图像或一段语音,输出一个向量或信息)。 全连接层的每一个结点都与上一层的所有结点相连因而称之为全连

    2024年02月13日
    浏览(36)
  • 深度学习--全连接层、高阶应用、GPU加速

    MSE均方差 Cross Entropy Loss:交叉熵损失 Entropy 熵: 1948年,香农将统计物理中熵的概念,引申到信道通信的过程中,从而开创了信息论这门学科,把信息中排除了冗余后的平均信息量称为“信息熵”。香农定义的“熵”又被称为香农熵或信息熵,即 其中标记概率空间中所有可能

    2023年04月22日
    浏览(36)
  • 【深度学习_TensorFlow】感知机、全连接层、神经网络

    感知机、全连接层、神经网络是什么意思? 感知机: 是最简单的神经网络结构,可以对线性可分的数据进行分类。 全连接层: 是神经网络中的一种层结构,每个神经元与上一层的所有神经元相连接,实现全连接。 神经网络: 是由大量神经元组成的网络结构,通过层与层之间

    2024年02月14日
    浏览(41)
  • 卷积神经网络中的卷积层、池化层、全连接层、softmax

    卷积层的作用是提取输入图片中的信息,这些信息被称为图像特征,这些特征是由图像中的每个像素通过组合或者独立的方式所体现,比如图片的纹理特征,颜色特征。 卷积操作类似于数学中的卷积,但是更加简单,计算机和我们看到的图像不一样,计算机看到的图像其实就

    2024年02月09日
    浏览(43)
  • 7.3 详解NiN模型--首次使用多层感知机(1x1卷积核)替换掉全连接层的模型

    多层感知机 :由一个输入层,一个或多个隐藏层和一个输出层组成。(至少有一个隐藏层,即至少3层) 全连接层 :是MLP的一种特殊情况,每个节点都与前一层的所有节点连接,全连接层可以解决线性可分问题,无法学习到非线性特征。(只有输入和输出层) NiN与过去模型

    2024年02月13日
    浏览(54)
  • CNN的硚口实现: 由Verilog编写并在FPGA上合成

    目录 前言 一、环境设置 二、CNN的硬件设计思路 三、使用Verilog实现CNN

    2024年02月13日
    浏览(47)
  • 【人工智能与深度学习】当输入层维度为1024,输出层维度为100时,为什么全连接层参数量为1024*100+100

    在神经网络中,全连接层(也称为稠密层或线性层)的参数量计算通常包括权重(weights)和偏置(biases)。对于一个全连接层,如果输入层维度(即输入特征的数量)为1024,输出层维度(即输出特征的数量)为100,那么参数的计算方式如下: 权重 :每个输入特征都与每个输

    2024年01月17日
    浏览(84)
  • 基于FPGA的电子时钟设计与实现 (在EDA开发板上实现电子时钟功能)

    开发板: 此款开发板使用的是 ALTERA 公司的 Cyclone IV 系列 FPGA,型号为 EP4CE6F17C8, 256 个引脚的 FBGA 封装。  题目:在EDA开发板上实现电子时钟功能 要求:实现电子时钟程序编写,实现在7段数码管显示时、分、秒,使用4x4矩阵按键模拟调节时钟指令输入按键,并实现整点报时

    2024年02月04日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包