实现softmax的步骤

背景知识

Softmax 函数通常用于多分类问题中,将模型的输出(通常是未归一化的分数或对数几率)转换为概率分布。它的作用是让每个类别的输出值在 [0,1][0, 1][0,1] 范围内,并且所有类别的输出值之和为 1。

假设输入是一个形状为 n×kn \times kn×k 的矩阵 XXX,其中 nnn 是样本数量,kkk 是类别数量。Softmax 的目标是对每个样本的 kkk 个类别进行归一化处理。


具体步骤

步骤 1:对每个项求幂(使用 exp)
  • 输入矩阵 XXX 中的每个元素 xijx_{ij}xij 都会被计算为 exije^{x_{ij}}exij
  • 求幂的作用是将任意实数值映射到正数范围(因为指数函数 ex>0e^x > 0ex>0 对于所有 xxx 成立),并且保持相对大小关系不变。
  • 这一步的结果是一个新的矩阵 exp(X)\text{exp}(X)exp(X),形状仍然是 n×kn \times kn×k

示例:

如果输入矩阵 XXX 为:

X=[1234] X = \begin{bmatrix} 1 & 2 \\ 3 & 4 \end{bmatrix} X=[1324]

那么经过第一步后:
exp(X)=[e1e2e3e4]=[2.7187.38920.08654.598] \text{exp}(X) = \begin{bmatrix} e^1 & e^2 \\ e^3 & e^4 \end{bmatrix} =\begin{bmatrix} 2.718 & 7.389 \\ 20.086 & 54.598 \end{bmatrix} exp(X)=[e1e3e2e4]=[2.71820.0867.38954.598]


步骤 2:对每一行求和,得到规范化常数
  • 在这一步中,我们需要计算每个样本(即每行)的规范化常数。具体来说,对于第 iii 行,规范化常数为该行所有元素的和:
    normi=∑j=1kexij \text{norm}_i = \sum_{j=1}^k e^{x_{ij}} normi=j=1kexij
  • 结果是一个形状为 n×1n \times 1n×1 的向量,表示每个样本的规范化常数。

示例:

对于上一步中的矩阵 exp(X)\text{exp}(X)exp(X)
exp(X)=[2.7187.38920.08654.598] \text{exp}(X) = \begin{bmatrix} 2.718 & 7.389 \\ 20.086 & 54.598 \end{bmatrix} exp(X)=[2.71820.0867.38954.598]
每一行的和为:
norm1=2.718+7.389=10.107 \text{norm}_1 = 2.718 + 7.389 = 10.107 norm1=2.718+7.389=10.107
norm2=20.086+54.598=74.684 \text{norm}_2 = 20.086 + 54.598 = 74.684 norm2=20.086+54.598=74.684
因此,规范化常数向量为:
norm=[10.10774.684] \text{norm} = \begin{bmatrix} 10.107 \\ 74.684 \end{bmatrix} norm=[10.10774.684]


步骤 3:将每一行除以其规范化常数
  • 最后一步是将 exp(X)\text{exp}(X)exp(X) 中的每个元素除以其对应的规范化常数,确保每行的概率和为 1。
  • 对于第 iii 行第 jjj 列的元素,计算公式为:
    softmaxij=exijnormi \text{softmax}_{ij} = \frac{e^{x_{ij}}}{\text{norm}_i} softmaxij=normiexij
  • 结果是一个形状为 n×kn \times kn×k 的矩阵,表示每个样本的类别概率分布。

示例:

对于 exp(X)\text{exp}(X)exp(X)norm\text{norm}norm
exp(X)=[2.7187.38920.08654.598],norm=[10.10774.684] \text{exp}(X) = \begin{bmatrix} 2.718 & 7.389 \\ 20.086 & 54.598 \end{bmatrix}, \quad \text{norm} = \begin{bmatrix} 10.107 \\ 74.684 \end{bmatrix} exp(X)=[2.71820.0867.38954.598],norm=[10.10774.684]
逐行归一化后:

softmax(X)=[2.71810.1077.38910.10720.08674.68454.59874.684]=[0.2690.7310.2690.731] \text{softmax}(X) = \begin{bmatrix} \frac{2.718}{10.107} & \frac{7.389}{10.107} \\ \frac{20.086}{74.684} & \frac{54.598}{74.684} \end{bmatrix} =\begin{bmatrix} 0.269 & 0.731 \\ 0.269 & 0.731 \end{bmatrix} softmax(X)=[10.1072.71874.68420.08610.1077.38974.68454.598]=[0.2690.2690.7310.731]


### FPGA 上实现 Softmax 函数 Softmax 函数通常用于多分类问题中的最后一层,将网络输出转换成概率分布。在FPGA上实现此功能时,考虑到硬件资源的有效利用以及计算效率,建议采取以下方法: #### 方法概述 1. **指数运算** 需要在FPGA内部完成对每个输入数据的e次幂操作。由于直接实现自然底数e的指数函数较为复杂,在实际应用中往往通过查找表(LUT)来近似该过程[^2]。 2. **求和阶段** 计算所有经过指数变换后的数值之和∑exp(x_i),这一步骤可以直接使用累加器电路完成。对于大规模并行处理的情况,则可考虑树形结构以减少延迟时间。 3. **除法操作** 将每一个exp(x_i)的结果分别除以上述得到的整体总和Σexp(x_j),从而获得最终的概率值p_i=exp(x_i)/Σexp(x_j)[^1]。鉴于FPGA内部分割单元数量有限,推荐采用迭代式或流水线架构下的倒数生成器配合乘法代替传统意义上的显式分母去除分子的方式。 4. **量化策略** 考虑到定点运算能够显著降低逻辑单元占用率,因此在整个流程里应当尽可能维持较低位宽的数据表示形式(比如16-bit),仅当必要时才提升至更高精度[^3]。 #### 示例代码 (Verilog) 下面给出一段简化版的Verilog描述作为参考: ```verilog module softmax #(parameter WIDTH = 16, N = 8)( input wire clk, input wire rst_n, input wire signed [WIDTH-1:0] data_in[N-1:0], output reg signed [WIDTH*2-1:0] result_out[N-1:0] ); // ...省略中间定义... always @(posedge clk or negedge rst_n) begin : exp_calculation if (!rst_n) // Reset logic here... else for(int i = 0; i < N ;i++)begin temp_exp[i] <= LUT[data_in[i]]; // 使用预存好的LUT进行快速查表 end end assign sum_all = {N{sum}} & {{(WIDTH*N)-$clog2(N){1'b0}},temp_sum}; genvar j; generate for(j = 0;j<N;j=j+1)begin : div_and_store_results always@(posedge clk or negedge rst_n)begin if(!rst_n) // Reset condition... else result_out[j]<= temp_exp[j]*reciprocal(sum_all); // 这里的乘法实际上是在执行除法 end end endgenerate endmodule ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值