【问题标题】:Matrix multiplication in Fixed Point for 16 bits16 位定点矩阵乘法
【发布时间】:2020-11-28 10:51:43
【问题描述】:

我需要在神经网络的不同层之间执行矩阵乘法。即:W0, W1, W2, ... Wn 是神经网络的权重,输入为data。结果矩阵是:

Out1 = data * W0
Out2 = Out1 * W1
Out3 = Out2 * W2
.
.
.
OutN = Out(N-1) * Wn

我知道权重矩阵中的绝对最大值,并且我知道输入数据范围值是从 0 到 1(输入是标准化的)。矩阵乘法是 16 位的定点乘法。权重被缩放到最佳格式点。例如:如果W0 中的绝对最大值为 2.5,我知道整数部分的最小位数为 2,小数部分的位数为 14。因为数据输入范围为 [0,1 ] 我也知道整数和小数位是 1.15。

我的问题是:如何知道结果矩阵中整数部分的最小位数以避免溢出?无论如何研究和推断矩阵乘法中的最大值?我知道矩阵的 determinantnorm,但是,我认为问题在于矩阵行和列中的连续负值或正值。例如,如果我有这个行向量和这个列向量,结果是 8 位定点:

A = [1, 2, 3, 4, 5, 6, -7, -8]
B = [1, 2, 3, 4, 5, 6, 7, 8]
A * B = (1*1) + (2*2) + (3*3) + (4*4) + (5*5) + (6*6) + (7*-7) + (8*8) = 90 - 49 + -68

当和累加器小于 64 时,会发生溢出,最终结果包含在 [-64,63] 之间。

另一个例子:如果我有这个行向量和这个列向量,结果是8位定点:

A = [1, -2, 3, -4, 5, -6, 7, -8]
B = [1, 2, 3, 4, 5, 6, 7, 8]
A * B = (1*1) - (2*2) + (3*3) - (4*4) + (5*5) - (6*6) + (7*7) - (8*8) = -36

任何时刻的和累加器超过8位的最大范围。

总结一下:我正在寻找一种方法来分析权重矩阵以避免总和累加器中的溢出。我进行矩阵乘法的方式是(仅当矩阵 A 和 B 已缩放为 1.15 格式时的示例):

A1 --> 1.15 bits
B1 --> 1.15 bits
A2 --> 1.15 bits
B2 --> 1.15 bits
mult_1 = (A1 * B1) >> 2^15; // Right shift to alineate the operands
mult_2 = (A2 * B2) >> 2^15; // Right shift to alineate the operands
sum_acc = mult_1 + mult_2;  // Sum accumulator

【问题讨论】:

  • 嗨@spektre 当矩阵尺寸很大时会发生什么:从[数百×数百]到[数千×数千]?也许我不明白你说:“你最终会得到 (2*(n-1)).15”。谢谢。
  • 好的,如果日志函数被应用到最大整数位上,它是可以在FPGA中实现的。我还将寻找论文或类似的东西来找到推断矩阵乘法大小的方法。谢谢@Spektre !!
  • 好的,我完成了答案的编辑...现在应该是正确的,因为所有示例现在都匹配。

标签: math matrix matrix-multiplication fixed-point


【解决方案1】:

让我们以%3.13 定点格式的n=100 维点积(它是任何矩阵乘法或卷积的一部分)为例。

  1. 整数位

    %4.13 中的最大值略低于 2^4,因此我们可以考虑:15.999999

    现在n 维点积具有n 乘法和n-1 加法。

    15.999999*15.999999 + 15.999999*15.999999 + .... + 15.999999*15.999999
    

    每次乘法都会对整数位求和

    15.999999*15.999999 = 255.999999 -> ceil(log2(255)) = 8 = 2*(4)-> %8.13
    

    现在这个值加了 99 次,所以它与:

    255.999999*99 = 25343.999999 -> ceil(log2(25343)) = 15 = ceil(8+log2(99)) -> %15.13
    

    所以如果n 是维数,i 是结果需要的整数位数:

    i' = ceil((i*2)+log2(n-1)) 
    

    整数位...所以:

    %1.? -> 99*( 1.999999^2) =   395.99 -> % 9.?
    %2.? -> 99*( 3.999999^2) =  1583.99 -> %11.?
    %3.? -> 99*( 7.999999^2) =  6335.99 -> %13.?
    %4.? -> 99*(15.999999^2) = 25343.99 -> %15.?
    
    i(1) = ceil((1*2)+log2(99)) = ceil(2+6.626) = 9
    i(2) = ceil((2*2)+log2(99)) = ceil(4+6.626) = 11
    i(3) = ceil((3*2)+log2(99)) = ceil(6+6.626) = 13
    i(4) = ceil((4*2)+log2(99)) = ceil(8+6.626) = 15
    
  2. 小数位

    好的,让我们看看乘法会发生什么:

    0.1b^2 = 0.01b        -> %?.1 -> %?.2
    0.01b^2 = 0.0001b     -> %?.2 -> %?.4
    0.001b^2 = 0.000001b  -> %?.3 -> %?.6
    

    所以f' = 2*f 其中f 是小数位数。添加不会改变位宽:

    0.1b*2 = 1.0b         -> %?.1 -> %?.1
    0.01b*2 = 0.1b        -> %?.2 -> %?.2
    0.001b*2 = 0.01b      -> %?.3 -> %?.3
    

    因为结果不会小于操作数。因此,当将小数部分应用于点积时,我们将拥有:

    i' = ceil((i*2)+log2(n-1)) 
    f' = 2*f 
    

【讨论】:

  • 最后一个问题:假设我有这个矩阵维度:A_dims = [4096, 512], B_dims = [512, 4096] 并且这个固定点格式:format_A = [4, 12], format_B = [1, 15]。因为矩阵乘法中涉及的最大操作数是 Columns(A) * Rows(B),所以 n 和 i 的值将是: n = A_dims[1] i = format_A[0] * format_B[ 0],整数结果位数将是: integer_bits = ceil(((i+1)*2)+log2(n-1)) 小数部分的位数将始终是两个操作数之间的最大值小数部分,对吧?
  • @DiegoRuiz 小数部分通常被截断......但是,如果你不想失去精度,那么加法不会改变它,但乘法会再次对操作数的小数位求和......你想要类似的例子,就像我对整数部分所做的那样?
  • 不需要再举一个例子,我明白你的意思。到目前为止,你帮了我很多。谢谢!
  • @DiegoRuiz heh 同时我还是做到了:) 你的评论中的ceil(((i+1)*2)+log2(n-1)) 也不正确,应该是ceil((i*2)+log2(n-1))
猜你喜欢
  • 2015-05-10
  • 1970-01-01
  • 2018-04-11
  • 2017-03-11
  • 2013-12-23
  • 2014-09-19
  • 1970-01-01
相关资源
最近更新 更多