首页 > 解决方案 > 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

标签: pythondebugging

解决方案


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

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)

推荐阅读