防止矩阵乘法溢出? (麻木的)
Prevent Overflow in Matrix Multiplication? (Numpy)
我正在处理一些基于整数的高维数据,出于内存原因,我们必须对所有内容都使用 int8。我 运行 遇到的问题是我需要用这个 int8 数据做矩阵乘法,但如果结果高于 127,我只需要 return 127 而不是溢出是什么.
例如:
import numpy as np
a = np.random.choice([0,1], size=[128,2000]).astype(np.int8)
b = np.random.randint(0,128, size=[2000,2000]).astype(np.int8)
c = np.matmul(a, b)
# c returns values between -128 and 127, instead of the desired 0 to 127
澄清一下,我不只是在寻找额外的 space 无符号整数 - b 中的值有时可能是负数。 (为了进一步说明我的观点,我只是将 b 全部设为正面。)
是否有算法或 Numpy 技巧可以让我限制这些操作而不是让它们溢出?我仔细阅读了 Numpy 文档并询问了我在 CS 部门的一些朋友,但我还没有找到任何线索。
最后,我知道我可以在 C 中用位旋转来完成其中的一些,但是我们项目的其余部分不可避免地在 Python 中,几乎没有扩展的机会(并且给定 Python ,如果可能的话,我更愿意使用 Numpy 进行矩阵乘法。
谢谢大家!
也许这样的事情对你有用。这是逐行执行操作,因此您一次只需要在 int32 数据类型中保存一行。这是@user2357112 描述的分块方法。
def matmul(a, b):
"""chunked matmul which converts datatypes and filters values too large to 127"""
c = np.empty((a.shape[0], b.shape[1]), dtype = np.int8) # output
for i in range(a.shape[0]): # iterate over rows in a
aa = a[i].astype(np.int32) # convert one row to extended datatype
cc = aa @ b # broadcasting means cc is the dtype of aa
cc[cc > 127] = 127 # set all future overflows to 127
c[i] = cc.astype(np.int8) # convert dtype back
return c
c = matmul(a, b) # your computation of interest
这会慢很多,但可能不会使您的内存过载。
如果这不起作用,您可以根据需要使用 np.load
和 mmap_mode
关键字将 a
和 b
的行和列加载到内存中,如前所述。然后您可以执行计算 row @ col
以在所需数据范围内开发单个元素 c[i,j]
。
我正在处理一些基于整数的高维数据,出于内存原因,我们必须对所有内容都使用 int8。我 运行 遇到的问题是我需要用这个 int8 数据做矩阵乘法,但如果结果高于 127,我只需要 return 127 而不是溢出是什么.
例如:
import numpy as np
a = np.random.choice([0,1], size=[128,2000]).astype(np.int8)
b = np.random.randint(0,128, size=[2000,2000]).astype(np.int8)
c = np.matmul(a, b)
# c returns values between -128 and 127, instead of the desired 0 to 127
澄清一下,我不只是在寻找额外的 space 无符号整数 - b 中的值有时可能是负数。 (为了进一步说明我的观点,我只是将 b 全部设为正面。)
是否有算法或 Numpy 技巧可以让我限制这些操作而不是让它们溢出?我仔细阅读了 Numpy 文档并询问了我在 CS 部门的一些朋友,但我还没有找到任何线索。
最后,我知道我可以在 C 中用位旋转来完成其中的一些,但是我们项目的其余部分不可避免地在 Python 中,几乎没有扩展的机会(并且给定 Python ,如果可能的话,我更愿意使用 Numpy 进行矩阵乘法。
谢谢大家!
也许这样的事情对你有用。这是逐行执行操作,因此您一次只需要在 int32 数据类型中保存一行。这是@user2357112 描述的分块方法。
def matmul(a, b):
"""chunked matmul which converts datatypes and filters values too large to 127"""
c = np.empty((a.shape[0], b.shape[1]), dtype = np.int8) # output
for i in range(a.shape[0]): # iterate over rows in a
aa = a[i].astype(np.int32) # convert one row to extended datatype
cc = aa @ b # broadcasting means cc is the dtype of aa
cc[cc > 127] = 127 # set all future overflows to 127
c[i] = cc.astype(np.int8) # convert dtype back
return c
c = matmul(a, b) # your computation of interest
这会慢很多,但可能不会使您的内存过载。
如果这不起作用,您可以根据需要使用 np.load
和 mmap_mode
关键字将 a
和 b
的行和列加载到内存中,如前所述row @ col
以在所需数据范围内开发单个元素 c[i,j]
。