如何防止 NumPy 的标准偏差在极端体积计算期间抛出错误?

How to prevent NumPy's standard deviation from throwing errors during extreme-volume computations?

免责声明:这可能是一个很难回答的问题,但我将不胜感激任何见解、想法或建议。如果这个问题已经在别处得到解答而我只是没能找到它,请告诉我。此外,我对一般的算法工程有些陌生,特别是使用 Python/NumPy 来实现和评估非平凡的算法原型,并在我进行时将其全部挑选出来。我可能遗漏了一些使用 NumPy 进行科学计算的基础知识。

致版主:如果有更好的论坛,请随意移动此主题。我不确定这是否完全符合计算科学论坛的条件,因为它可能归结为 implementation/coding 问题。

注意:如果您想了解问题和上下文,阅读所有内容

我正在使用 NumPy 的 std() 函数计算算法实现中的标准偏差,该算法基于最小跨度树松散地查找图中节点的最佳组合。选择函数包含对 std() 的调用。这是该算法的早期单线程原型;该算法最初是为多线程设计的(可能会用 C 或 C++ 实现,因此此处不相关)。

边权重取决于先前选择的节点的属性,因此在算法检查可用节点时计算。该图可能包含数千个节点。在这个阶段搜索是详尽无遗的,可能需要数十万次计算。

此外,算法的评估是自动进行的,并且可能 运行 数百次连续试验,具体取决于用户输入。在搜索较小的图(例如 100 个节点)时,我没有看到错误(如下)突然出现,但是将图的大小缩放到接近 1000 可以保证它们出现。

相关代码可以简化为大致如下:

# graph.available = [{'id': (int), 'dims': {'dim1': (int), ...}}, ...]
# accumulatedDistr = {'dim1': (int), ...}
# Note: dicts as nodes, etc used here for readability
edges = []
for node in graph.available:
    intersection = my.intersect(node['distr'], accumulatedDistr) # Returns list
    edgeW = numpy.std(intersection)
    edges.append((node['id'], edgeW))
# Perform comparisons, select and combine into accumulatedDistr

分布保证包含非负、非零整数值,并且从 my.intersect() 返回的列表同样保证永远不会为空。

当我运行进行一系列试验时,我偶尔会在终端中看到以下消息:

C:\Program Files\Python36\lib\site-packages\numpy\core\_methods.py:135: RuntimeWarning: Degrees of freedom <= 0 for slice
  keepdims=keepdims)
C:\Program Files\Python36\lib\site-packages\numpy\core\_methods.py:105: RuntimeWarning: invalid value encountered in true_divide
  arrmean, rcount, out=arrmean, casting='unsafe', subok=False)
C:\Program Files\Python36\lib\site-packages\numpy\core\_methods.py:127: RuntimeWarning: invalid value encountered in double_scalars
  ret = ret.dtype.type(ret / rcount)

它们通常只在一组试验中出现几次,所以很可能每隔几百万次计算一次。然而,一个错误的计算可以(至少!)巧妙地改变整个试验的结果,所以我仍然希望尽可能避免这种情况。我假设一定有一些内部状态在累积错误,但我发现很少有关于如何解决该问题的建议。这让我非常担心,因为错误的累积会对以下计算的 所有 产生怀疑,如果确实如此的话。

我想我可能需要寻找一个专有库(例如,Python 英特尔内核数学库的包装器)以保证那种极端体积(请原谅滥用术语)的计算稳定性我想。但首先:有没有办法阻止它们(NumPy)?另外,以防万一:问题是否像我担心的那样严重?

我已经确认这确实是我自己代码中的一个错误,尽管从未在测试中发现它。诚然,根据证据,我将不得不 运行 几百万次左右的连续随机输入测试。回想起来,作为代码关键部分的一般做法,这可能不是一个坏主意,尽管它需要花费大量时间。最好尽早发现它,而不是在围绕受影响的代码构建了整个库之后。吸取教训。

感谢 BrenBarn 让我走上正轨!过去我 运行 跨过开源库 确实 有罕见的、难以解决的错误。我很欣慰 NumPy 不是其中之一。至少这次不是。不过,我认为仍有空间抱怨含糊、无用的错误消息。我想欢迎使用 NumPy。

因此,回答我自己的问题:NumPy 不是问题所在。 np.std() 非常 稳定。希望我在这里的经历能帮助其他人排除不是导致他们的代码崩溃的原因。