当前位置:   article > 正文

基于FPGA的神经网络的预测过程的实现_fpga搭建神经网络

fpga搭建神经网络
       前言:

本文的目的是在一个神经网络已经通过python或者MATLAB训练好的神经网络模型,将训练好的模型的权重和偏置文件以TXT文件格式导出,然后通过python程序将txt文件转化为coe文件,(coe文件是为了将其写入rom,网络中的权重和偏置通过读取ROM即可,后续需要修改输入其他特征值,只需要修改input的rom里面的coe文件即可)。

设计思想

        其中sigmoid函数是本次实验最大的难点,因为sigmoid函数的值是在0-1之间的小数,其值越大,说明该模型的输出是该结果的几率越大。但是verilog硬件描述语言,其计算结果只有0或1两种情况,所以要想直接通过verilog语言计算出sigmoid函数的值是比较复杂的,本次使用的方法为查找表法,通过外部其他语言计算出sigmoid函数的值,然后将其放入查找表,后续当需要使用sigmoid函数时,直接输出结果。但是这个需要不断地往里面加值,每更新一次输入,那么就往sigmoid模块里面的查找表添加上该输入的sigmoid值。

        由于FPGA的计算是基于数字逻辑和二进制运算,小数计算只能通过  固定点数(即带有定点小数位的整数表示)来模拟某些浮点数计算。这需要使用额外的逻辑来实现浮点数的运算、舍入和特殊值处理。

        但是本文选择一个简便的方法,选择将输入,权重 分别保留两位小数(可自己选择位数,保留越多精度越高,反之精度越低),然后分别将其乘以100,将数据全都变成带符号整数,然后将其进行乘加运算。将偏置保留4位小数并乘以10000,得到的结果除以10000然后进行sigmoid计算,后续无论添加多少层,都可以以此方法来进行计算。以下为搭建神经网络的步骤:

step1: 处理数据,将保存好的权重文件转化为coe文件,然后添加一个ROM,并将coe文件加载进             ROM里面;

  1. module input_rom_ctr(
  2. input sys_clk, //50MHz时钟
  3. input rst_n, //复位,低电平有效
  4. input [5:0] data_deep,
  5. output reg [31:0] rom_data_r , //ROM读出数据
  6. output reg viald,
  7. output reg [6:0] rom_addr_rr //ROM输入地址
  8. );
  9. reg [6:0] rom_addr;
  10. //产生ROM地址读取数据
  11. always @ (posedge sys_clk or negedge rst_n)
  12. begin
  13. if(!rst_n)begin
  14. rom_addr <= 7'd0;
  15. viald <= 1'b1;
  16. end
  17. else if(rom_addr_rr >= (data_deep -1'd1))begin
  18. viald <= 1'b0;
  19. end
  20. else if(rom_addr >= (data_deep - 1'd1))begin
  21. rom_addr <= 7'd0;
  22. end
  23. else begin
  24. rom_addr <= rom_addr+1'b1;
  25. viald <= viald;
  26. end
  27. end
  28. reg [6:0]rom_addr_r;
  29. always @(posedge sys_clk or negedge rst_n) begin
  30. if(!rst_n)begin
  31. rom_addr_r <= 7'd0;
  32. rom_addr_rr <= 7'd0;
  33. end
  34. else begin
  35. rom_addr_r <= rom_addr;
  36. rom_addr_rr <= rom_addr_r;
  37. end
  38. end
  39. wire [31:0] rom_data;
  40. always @(posedge sys_clk or negedge rst_n)begin
  41. if(!rst_n)begin
  42. rom_data_r <= 32'd0;
  43. end
  44. else begin
  45. rom_data_r <= #2 rom_data;
  46. end
  47. end
  48. //实例化ROM
  49. input_rom rom_ip_inst
  50. (
  51. .clka (sys_clk ), //inoput clka
  52. .addra (rom_addr), //input [4:0] addra
  53. .douta (rom_data) //output [7:0] douta
  54. );
  55. endmodule

step2:将ROM里的数据读取出来,如果数据较少就直接使用二维数组保存数据,较多的话可以添             加一个RAM,然后通过调用RAM里面的变量搭建第一层神经网络(暂不添加sigmoid)。

  1. input_rom_ctr input_rom( //取输入层的数据存入ram
  2. .sys_clk (clk), //50MHz时钟
  3. .rst_n (rst_n), //复位,低电平有效
  4. .data_deep(5),
  5. .rom_data_r (rom_data1), //ROM读出数据
  6. .viald (en_wr1),
  7. .rom_addr_rr (input_index)
  8. );
  9. always @(posedge clk)begin
  10. if(en_wr1) begin
  11. input_layer[input_index] <= rom_data1; //从rom里面读出数据,并将其写入ram/寄存器里面,后面的神经网络直接调用寄存器操作
  12. end
  13. else begin
  14. input_data <= input_layer[input_index];//从ram里面读出来的数据,加载地址就得到相应的数据。
  15. end
  16. end

Step3:通过仿真得到第一层神经网络每个神经元的乘加结果,并加上偏置后,通过外部计算得到            sigmoid值后将其添加到sigmoid模块的lut查找模块中,如此反复,最后就可以得到一个神经            网络框架。(sigmoid函数的结果也要乘以100,作为下一层的输入),最后得到的输入层             的每个神经元的结果就代表其识别结果的概率。

  1. module sigmoid (
  2. input wire signed [31:0] input_value, // 输入32位有符号整数
  3. output reg signed [31:0] sigmoid_output // 输出32位有符号整数
  4. );
  5. always @(*) begin //可以看做是一个查找表,将上一层的输入进入sigmoid函数来进行查找值,然后将得到的值乘以100用于保留两位小数,精度要求高的就多乘一点
  6. case (input_value)
  7. -2673 : sigmoid_output = 43; //上一层输入3490,是原本输入乘以100,保留两位小数乘以权重乘以100,即改结果是原本结果的10000倍,所以进sigmoid函数的应该是0.349
  8. 17232 : sigmoid_output = 85; //建议以后有更多值后继续添加,查找表越丰满,后续能使用的输入就越多。
  9. 36380 : sigmoid_output = 97;
  10. 124358 : sigmoid_output = 100;
  11. -47650 : sigmoid_output = 1;
  12. -5781 : sigmoid_output = 36;
  13. 3657 : sigmoid_output = 59;
  14. -23082 : sigmoid_output = 9;
  15. ///上面是第一层隐层的结果,下面是输出层的结果。
  16. 4816 : sigmoid_output = 62;
  17. -3390 : sigmoid_output = 42;
  18. 20652 : sigmoid_output = 89;
  19. -4386 : sigmoid_output = 39;
  20. -2004 : sigmoid_output = 45;
  21. -623 : sigmoid_output = 48;
  22. default: sigmoid_output = 0;
  23. endcase
  24. end
  25. endmodule

仿真结果

 最后的output_layer就是输出的最后结果。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/473788
推荐阅读
相关标签
  

闽ICP备14008679号