我有一个带有几百万个条目的大型向量F,它在采用规范时会产生这种不一致的行为。
np.linalg.norm(F,2.000001)=3225.96..
np.linalg.norm(F,2)=inf
np.linalg.norm(F,1.999999)=3226.01..
np.linalg.norm(F,1)=inf
---------
np.linalg.norm(F)=inf
np.linalg.norm(F/12)=inf
np.linalg.norm(F/13)=246.25
---------
np.sum(F*F)=inf
np.sum(F*F/169)=60639
np.sum(F*F/144)=inf
---------
np.all(np.isfinite(F))=True
np.max(np.abs(F))=11
---------
F.dtype=dtype('float16')
除了某种hacky解决方案之外,有没有人知道发生了什么?
答案 0 :(得分:3)
正如评论中所述,您的问题是float16
太小而无法代表中间结果 - 其最大值为65504.更简单的测试用例是:
np.linalg.norm(np.float16([1000]))
为避免溢出,您可以除以最大值,然后重新乘以:
def safe_norm(x):
xmax = np.max(x)
return np.linalg.norm(x / xmax) * xmax
可能存在np.linalg.norm
默认情况下应该为float16执行此操作的论据
答案 1 :(得分:0)
Numpy似乎还没有修复。所以,为了完整性,我的另一个(非常明显的)解决方案是计算规范:
def calcNorm(vector):
if (vector.dtype == np.float16):
vector = vector.astype(np.float32)
return np.linalg.norm(vector)
或者,正如我需要的那样,在规范化向量的用例中:
def normalize(vector):
prevType = vector.dtype
if (vector.dtype == np.float16):
vector = vector.astype(np.float32)
norm = np.linalg.norm(vector)
if (norm != 0 and np.isfinite(norm)):
vector /= norm
return vector.astype(prevType)