Scipy Linalg 确定性/非确定性代码



我使用以下代码从scipy运行此 SVD 求解器:

import numpy as np
from scipy.sparse.linalg import svds
features = np.arange(9,dtype=np.float64).reshape((3,3))
for i in range(10):
_,_,V = svds(features,2)
print i,np.mean(V)

我希望打印的平均值每次都相同,但是它会发生变化,并且似乎循环浏览一些最喜欢的值。我很高兴接受这种行为,这是低级优化/随机播种的结果。

我不太明白的是为什么每次运行该脚本时它都会以相同的顺序输出相同的值。对我来说,这似乎是半确定性和半非确定性的。

这个问题正在影响一些更复杂的处理,很高兴理解它,这样我至少可以做一些黑客的解决方法。

在没有测试自己的情况下(现在在平板电脑上没有 Python shell),我相信这是由于与近似特征求解器库 ARPACK 使用的初始化起点相关的一些奇怪行为,这就是svds最终调用的。

如果你从svds开始按照Python代码进行操作,v0(有问题的起点)只在_ArpackParams中处理,其中它设置为零,如果v0 is Noneinfo参数设置为0;否则,v0将保留为其值,info1。然后我们进入Fortran 的领域,调用(如果矩阵加倍)函数dsaupd,我没有完全检查,但我假设最终在请求随机起点时调用cgetv0。此函数似乎在第一次调用时将 LAPACK RNG 种子初始化为 1357。

因此,如果你不对ARPACK进行任何其他调用(或者可能是其他LAPACK的东西,不确定它们是如何相互作用的),你每次都使用相同的种子启动RNG,因此每次都得到相同的初始化点;因此,假设这是算法中唯一的随机性来源,你每次都会得到相同的答案序列。

你可以解决这个问题,比如说,在代码开始时随机调用一个小矩阵上的eigs

最新更新