次は、例えば、保存して、前のx
から再起動し、 が、私はあなたがより多くの状態を保存し、再起動します集めることができます勾配も。それを明確にすることはできますか?
も参照してください。basinhopping、 これはすばらしいGUIを持っています。pele-pythonです。
#!/usr/bin/env python
""" Funcgradmn: wrap f() and grad(), save all x[] f[] grad[] to plot or restart """
from __future__ import division
import numpy as np
__version__ = "2016-10-18 oct denis"
class Funcgradmon(object):
""" Funcgradmn: wrap f() and grad(), save all x[] f[] grad[] to plot or restart
Example: minimize, save, restart --
fg = Funcgradmon(func, gradfunc, verbose=1)
# fg(x): f(x), g(x) for minimize(jac=True)
# run 100 iter (if linesearch, 200-300 calls of fg()) --
options = dict(maxiter=100) # ...
min0 = minimize(fg, x0, jac=True, options=options)
fg.savez("0.npz", paramstr="...") # to plot or restart
# restart from x[50] --
# (won't repeat the previous path from 50
# unless you save and restore the whole state of the optimizer)
x0 = fg.restart(50)
# change params ...
min50 = minimize(fg, x0, jac=True, options=options)
"""
def __init__(self, func, gradfunc, verbose=1):
self.func = func
self.gradfunc = gradfunc
self.verbose = verbose
self.x, self.f, self.g = [], [], [] # growing lists
self.t = 0
def __call__(self, x):
""" f, g = func(x), gradfunc(x); save them; return f, g """
x = np.asarray_chkfinite(x) # always
f = self.func(x)
g = self.gradfunc(x)
g = np.asarray_chkfinite(g)
self.x.append(np.copy(x))
self.f.append(_copy(f))
self.g.append(np.copy(g))
if self.verbose:
print "%3d:" % self.t ,
fmt = "%-12g" if np.isscalar(f) else "%s\t"
print fmt % f ,
print "x: %s" % x , # with user's np.set_printoptions
print "\tgrad: %s" % g
# better df dx dg
# callback: plot
self.t += 1
return f, g
def restart(self, n):
""" x0 = fg.restart(n) returns x[n] to minimize(fg, x0)
"""
x0 = self.x[n] # minimize from here
del self.x[:n]
del self.f[:n]
del self.g[:n]
self.t = n
if self.verbose:
print "Funcgradmon: restart from x[%d] %s" % (n, x0)
return x0
def savez(self, npzfile, **kw):
""" np.savez(npzfile, x= f= g=) """
x, f, g = map(np.array, [self.x, self.f, self.g])
if self.verbose:
asum = "f: %s \nx: %s \ng: %s" % (
_asum(f), _asum(x), _asum(g))
print "Funcgradmon: saving to %s: \n%s \n" % (npzfile, asum)
np.savez(npzfile, x=x, f=f, g=g, **kw)
def load(self, npzfile):
load = np.load(npzfile)
x, f, g = load["x"], load["f"], load["g"]
if self.verbose:
asum = "f: %s \nx: %s \ng: %s" % (
_asum(f), _asum(x), _asum(g))
print "Funcgradmon: load %s: \n%s \n" % (npzfile, asum)
self.x = list(x)
self.f = list(f)
self.g = list(g)
self.loaddict = load
return self.restart(len(x) - 1)
def _asum(X):
""" one-line array summary: "shape type min av max" """
if not hasattr(X, "dtype"):
return str(X)
return "%s %s min av max %.3g %.3g %.3g" % (
X.shape, X.dtype, X.min(), X.mean(), X.max())
def _copy(x):
return x if x is None or np.isscalar(x) \
else np.copy(x)
#...............................................................................
if __name__ == "__main__":
import sys
from scipy.optimize import minimize, rosen, rosen_der
np.set_printoptions(threshold=20, edgeitems=10, linewidth=140,
formatter = dict(float = lambda x: "%.3g" % x)) # float arrays %.3g
dim = 3
method = "cg"
maxiter = 10 # 1 linesearch -> 2-3 calls of fg
# to change these params, run this.py a=1 b=None 'c = ...' in sh or ipython
for arg in sys.argv[1:]:
exec(arg)
print "\n", 80 * "-"
print "Funcgradmon: dim %d method %s maxiter %d \n" % (
dim, method, maxiter)
x0 = np.zeros(dim)
#...........................................................................
fg = Funcgradmon(rosen, rosen_der, verbose=1)
options = dict(maxiter=maxiter) # ...
min0 = minimize(fg, x0, jac=True, method=method, options=options)
fg.savez("0.npz", paramstr="...") # to plot or restart
x0 = fg.restart(5) # = fg.x[5]
# change params, print them all
min5 = minimize(fg, x0, jac=True, method=method, options=options)
fg.savez("5.npz", paramstr="...")
私が思い付くした最高のは、ほとんどunthinkably醜いです:1つ以上の「ブレークポイント」のバージョン(あなたの現在実行中の最適化機能の正確なコピーを持つプロセスを作成するプロセスをフォーク - そしてその時、アプリケーション全体!)、ブレークポイント・バージョンをオプティマイザのコールバックまたは評価呼び出しにハングアップさせて、何らかのIPCによって後続するように通知されるか、または廃止された場合には強制終了されます。もちろん、あなたはまだ同じランであるので "ラン"間のパラメータを変更することはできませんでした!再起動しても保持されません。そしてちょっと醜い... – KarenRei
1) 'jac'があなたの関数ならば、* kwargを使って、最初の呼び出しで' xx.jac'を読み込んで返すように簡単に言うことができます。 2)オプティマイザは、具体的には、 3)あなたはしばらく実行したい印刷物/プロット/保存するツリーを実行したいですか?大きな注文。 "A10 =ラン10; A100 =ラン100; B =(A;パラムス= ...;ラン100)..."と表示されます。 – denis
私は、最適化の方法をベンチマークしていないので、どれが最適なものかを知ることができません。パフォーマンスと正確さのために私の評価機能を調整してきました。私は、例えば、それが極小に閉じ込められてしまう傾向があるかどうか、何の手がかりも持っていません。 "jac"は私の評価関数ではありません。それは、最小化関数がジャコビアン(一階微分/勾配)の決定方法を指定するという議論です。実行ツリーは素晴らしいですが、単一のチェックポイントを維持することさえ可能ですばらしいでしょう。どのようにして1つの "100回"反復を維持することができますか? – KarenRei