我正在尝试为几种优化算法设置基准。我目前失败的是“MCMC Hammer”司仪。 我不知道我是不是没有正确设置,或者我的情节是否正常工作。 目标是最小化测试功能,例如rosenbrock,并根据函数调用绘制接受的函数值。我不确定,因为表现和最终结果很糟糕,情节没有“毛毛虫”的样子。也许有人有一些主持人的经验,可以给我一个提示。提前谢谢!
这是一些代码,前半部分是设置和绘图例程,后半部分是实际的主持人:
import numpy as np
import matplotlib.pyplot as plt
n_dim = 5
NoR = 1 #number of runs
problem = 3 #choose test function
if( problem==1 ) :
functionname = "norm(r)"
def testfunction(x) :
return (np.sum(np.power(x, 2.0)) + 1.0e-99)
solutionX = np.zeros(n_dim)
solutionY = 1.0e-99
elif( problem==2 ) :
functionname = "Rosenbrock"
def testfunction(x) :
return np.sum(100.0*np.power( x[1:]-np.power(x[:-1],2),2 ) + np.power(1.0-np.array(x[:-1]),2)) + 1.0e-99
solutionX = np.ones(n_dim)
#np.concatenate(( [-1.0], np.ones(n_dim-1) ))
solutionY = 0.0
elif( problem==3 ) :
functionname = "Schaffer"
def testfunction(x) :
return sum((x**2+x1**2)**0.25 * ((np.sin(50*(x**2+x1**2)**0.1))**2+1.0) for x, x1 in zip(x[:-1], x[1:]))
solutionX = np.zeros(n_dim)
solutionY = 0.0
calls = {} # dictionary; missing entries will be automatically created
y_hist = {};
y_best = {};
def testfunctionCount(x, solver) : # now general
global calls
#global trace
calls[solver] += 1
return testfunction(x)
# one plotting routine for all solvers:
def plot_solver( solver, log=False, y_hist_bins=20 ) :
# General statistics:
y_hist[solver] = np.array( y_hist[solver] ) # allow for transposing etc
hist_len = len( y_hist[solver] )
print "Number of valid hops:", hist_len
print "Function calls:", calls[solver]
print "best value", np.amin(y_hist[solver])
# Plots:
fig, ax = plt.subplots(1, 2, figsize=(12,6))
# y(function calls) :
if( log ) :
ax[0].semilogy( y_hist[solver][:,0], y_hist[solver][:,1], "x-" )
if( solutionY > 0.01 ) : ax[0].axhline(y=solutionY, color="k") # y=0 does not look good
else :
ax[0].plot( y_hist[solver][:,0], y_hist[solver][:,1], "x-" )
ax[0].axhline(y=solutionY, color="k")
ax[0].set_xlabel("function calls")
ax[0].set_ylabel("y")
# y-histogram:
ax[1].hist( y_hist[solver][:,1], bins=y_hist_bins, log=log )
ax[1].axvline(x=solutionY, color="k")
ax[1].set_xlabel("y")
ax[1].set_ylabel("occurrences")
plt.show()
return
# State what is being used:
print "function: ", functionname
print "dimensionality: ", n_dim
import emcee
solver = "emcee"
nwalkers = 10000
def hbprior(x):
if -10.0 < x.all() < 10.0:
return 0.0
return -np.inf
def hbprob(x):
hbp = hbprior(x)
if not np.isfinite(hbp) :
return -np.inf
return hbp + testfunctionCount(x, solver) # "+" only because hbp==0
x0 = np.random.rand(nwalkers, n_dim) #starting point
y_best[solver] = []
for x in range(0, NoR): #number of runs
calls[solver] = 0
#y_hist[solver] = []
sampler = emcee.EnsembleSampler(nwalkers, n_dim, hbprob, a=2.0)
n_burnin = 1
x_pos, prob, state = sampler.run_mcmc(x0, n_burnin) # burn in
sampler.reset()
#calls[solver] = 0; # possible, but the burn-in also costs
n_walk = 100
sampler.run_mcmc(x0, n_walk)
print "Mean acceptance fraction: " + "{0:.3f}".format(np.mean(sampler.acceptance_fraction))
y_hist[solver] = np.transpose( np.array( [ np.arange( nwalkers*(1+n_burnin+1)+1, calls[solver]+1, 1 ), \
np.array( [ testfunction(np.array(x)) for x in sampler.flatchain ] ) ] ) )
# this is not very elegant, maybe there is a better way?
y_best[solver].append(np.amin(y_hist[solver]))
plot_solver( solver, y_hist_bins=np.linspace(0.0,1.0e3,50) )
y_best[solver] = np.array( y_best[solver] )
y_best_mean = np.sum(y_best[solver]) / NoR
y_best_best = np.amin(y_best[solver])
print "best", y_best_best
print "mean", y_best_mean