Python 的错误"num"还是"np.sum"?



我正在研究以下代码片段来计算两个图像的相似性:

import cv2, sys                                                                          [5/981]
import numpy as np
def compute_hisgram(path):
hog = cv2.HOGDescriptor()
im = cv2.imread(path)
img_gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
h = hog.compute(im)
return h
def histogram_intersection(h1, h2):
# minima = np.minimum(h1, h2)
# intersection = np.true_divide(np.sum(minima), np.sum(h2))
#return intersection
return cv2.compareHist(h1, h2, cv2.HISTCMP_INTERSECT)

h1 = compute_hisgram(sys.argv[1])
h2 = compute_hisgram(sys.argv[2])
h12 = histogram_intersection(h1, h2)

# to normalize, we need to divide by the original image.
print (h12/np.sum(h2))

而当以两张图像作为输入执行上述代码时,它会输出一个接近 1.0 的值,这似乎很正常。

python3 t.py image1.png image2.png
0.9932124283243112

然而,令我非常惊讶的是,当最后一条语句以以下方式编写时:

print (h12/sum(h2))

输出不同,是一个大于 1 的数字!而且代码比以前慢得多。

python3 t.py image1.png image2.png
[1.1126189]

是 Pythonsum函数的错误吗?还是我在这里错过了什么?谢谢。

======== 更新

这是print (h2)的输出:

[[0.0924307 ]
[0.05680538]
[0.07150667]
...
[0.10983132]
[0.17328948]
[0.0688285 ]]

h12

4517725.058263534

这些函数以不同的方式进行求和。 例:

a = np.full((9000,), 1/9000)
sum(a)
# 0.9999999999998027
np.sum(a)
# 0.9999999999999999
math.fsum(a)
# 1.0

所以 np.sum() 给出的结果比 sum() 更准确。

有关一些解释,请参见 fsum:

math.fsum(可迭代)

返回可迭代对象中值的准确浮点总和。通过跟踪多个中间部分避免精度损失 算法的准确性取决于 IEEE-754 算术保证和舍入模式为半偶的典型情况。在一些 非 Windows 版本,底层 C 库使用扩展精度 加法,偶尔可能使中间和加法双倍,导致 它以最不重要的一点关闭。

有关进一步讨论和两种替代方法,请参阅 ASPN 说明书配方以实现准确的浮点求和。


您可能还想看看 accupy.有一些关于不同求和方法准确性的非常翔实的图表。

下面是一个非常病理的例子(从这里开始),显然准确的结果正好是20000:

a = [1, 1e100, 1, -1e100] * 10000
math.fsum(a), np.sum(a), sum(a)
# (20000.0, 0.0, 0.0)

最新更新