【发布时间】:2017-01-27 16:47:55
【问题描述】:
如果我有 N 个独立的优化问题,一般来说,独立解决每个问题或合并问题会更快吗?假设种子合理,牛顿法对于给定的精度 p 具有时间复杂度 log(p) *(计算导数比率的时间)。如果多元 Newton Raphson 时间复杂度不随维数缩放,那么给定 p 的复杂度仍将取决于梯度/粗麻布计算和线性求解器。我主要是为了代码效率而问:我想用每个子集正则化或全局正则化来拟合数据子集的似然函数。如果两者的成本相似,我可以实现一个牛顿优化器,它可以将各种正则化惩罚作为函数参数,在适当的时候在稀疏求解器和密集求解器之间切换。
下面,稀疏求解器通过循环击败了个人,但我想知道这是否只是 python 循环开销(使用 Cython 会得到更好的循环结果吗)?从矩阵堆栈到块对角线的转换成本很高,但与我的实现无关;我在每次迭代中填充预先存在的梯度/粗麻布数组,因此计算时间应该相同。当我将np.linalg.solve 与bigA 的密集矩阵一起使用时,我的IDE 冻结了,这引发了另一个问题,我可能需要找到一种更有效的方法来解决全局正则化导致的密集问题。
import timeit
setup = '''
import numpy as np; import scipy as sp
import scipy.sparse; import scipy.sparse.linalg
A = np.random.random((1000,10,10))
b = np.random.random((1000,10))
bigA = sp.sparse.block_diag(A, format = "csr")
bigb = b.flatten()
'''
expr1 = 'for i in range(1000): np.linalg.solve(A[i,...], b[i,...])'
expr2 = 'sp.sparse.linalg.spsolve(bigA, bigb)'
timeit.timeit(expr1, setup, number = 100)
# 1.2879039069994178
timeit.timeit(expr2, setup, number = 100)
# 0.45410968599753687
# with setup
imports = '''
import numpy as np
import scipy as sp
import scipy.sparse
import scipy.sparse.linalg
'''
setup1 = '''
A = np.random.random((1000,10,10))
b = np.random.random((1000,10))
for i in range(1000):
np.linalg.solve(A[i,...], b[i,...])
'''
setup2 = '''
A = np.random.random((1000,10,10))
b = np.random.random((1000,10))
bigA = sp.sparse.block_diag(A, format = "csr")
bigb = b.flatten()
sp.sparse.linalg.spsolve(bigA, bigb)
'''
timeit.timeit(setup1, imports, number = 100)
# 1.355804075999913
timeit.timeit(setup2, imports, number = 100)
# 24.209087412000372
sol1 = np.empty(1e4)
u = 0
for i in range(1000):
sol1[u:u+10] = np.linalg.solve(A[i,...], b[i,...])
u += 10
sol2 = sp.sparse.linalg.spsolve(bigA, bigb)
np.sum((sol1 - sol2)**2)
# 2.49782849627e-14
【问题讨论】:
标签: python performance optimization linear-algebra