私はのソリューションをスピードアップしようとしていますシンプルな凸状の問題を抱えています。私はシータとRTがNx1のある高速最適化
のargmin(シータ)を解くいます。
私はcvxpy
import numpy as np
from scipy.optimize import minimize
import cvxpy
np.random.seed(123)
T = 50
N = 5
R = np.random.uniform(-1, 1, size=(T, N))
cvtheta = cvxpy.Variable(N)
fn = -sum([cvxpy.log(1 + cvtheta.T * rt) for rt in R])
prob = cvxpy.Problem(cvxpy.Minimize(fn))
prob.solve()
prob.status
#'optimal'
prob.value
# -5.658335088091929
cvtheta.value
# matrix([[-0.82105079],
# [-0.35475695],
# [-0.41984643],
# [ 0.66117397],
# [ 0.46065358]])
しかし、これはあまりにも遅くなるので、私はscipy
さんfmin_cg
で勾配ベースの方法をしようとしていますR
大きなためで簡単にこの問題を解決することができます。
goalfun
です関数値とグラデーションを返すフレンドリ関数。
def goalfun(theta, *args):
R = args[0]
N = R.shape[1]
common = (1 + np.sum(theta * R, axis=1))**-1
if np.any(common < 0):
return 1e2, 1e2 * np.ones(N)
fun = np.sum(np.log(common))
thetaprime = np.tile(theta, (N, 1)).T
np.fill_diagonal(thetaprime, np.ones(N))
grad = np.sum(np.dot(R, thetaprime) * common[:, None], axis=0)
return fun, grad
:
goalfun(np.squeeze(np.asarray(cvtheta.value)), R)
# (-5.6583350819293603,
# array([ -9.12423065e-09, -3.36854633e-09, -1.00983679e-08,
# -1.49619901e-08, -1.22987872e-08]))
しかし、これだけでゴミをもたらし、関係なく、method
の、反復回数などを解く(x0
が実質的である場合Optimization terminated successfully
を生み出す唯一のものがあります最適シータ)
x0 = np.random.rand(R.shape[1])
minimize(fun=goalfun, x0=x0, args=R, jac=True, method='CG')
# fun: 3.3690101669818775
# jac: array([-11.07449021, -14.04017873, -13.38560561, -5.60375334, -2.89210078])
# message: 'Desired error not necessarily achieved due to precision loss.'
# nfev: 25
# nit: 1
# njev: 13
# status: 2
# success: False
# x: array([ 0.00892177, 0.24404118, 0.51627475, 0.21119326, -0.00831957])
すなわちに等しいですcvxpy
が扱いやすい、このように見えない無害な問題は、非凸型ソルバにとって完全に病理的であることが分かります。この問題は本当に厄介ですか、何か不足していますか?これをスピードアップするための代替手段は何ですか?
あなたはソルバー[SCS](httpsをしようとしました:// githubのを。com/cvxgrp/scs)(cvxpy内)、おそらく '' 'use_indirect = True''モードでしょうか? – sascha
いいえ、私はソルバーオプションを設定していません。上記の例のように、実行したものはすべてデフォルトのオプションを仮定しています。 – luffe
確かに、デフォルトでは良いECOSが使用されます。 SCSは時には**少し速く(ADMMベースの方法)している間に**多くの**高速です。 2つのモードがあります.1つは切り捨てられたnewtonメソッドのようなものです。 (ソースからコンパイルされたSCSは、デフォルトのものよりもはるかに速くなります;マルチスレッド化)。 GPUサポートさえあります。 **アップデート**生態系:90秒; 5000x500の場合はscs = 3秒(MTを使用したソースインストール、use_indirect = True)。 – sascha