主持人表现不佳以进行简单的最小化

时间:2018-03-09 13:47:47

标签: python python-2.7 minimization mcmc emcee

我正在尝试为几种优化算法设置基准。我目前失败的是“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

0 个答案:

没有答案