Scipy selects nan as inputs while minimizing

2019-05-30 07:28发布

问题:

I have this objective function (in python) :

actions= [...] # some array
Na= len(actions)    
# maximize p0 * qr(s,a0,b0) + ... + pn * qr(s,an,bn)
def objective(x):
        p = x[:Na] # p is a probability distribution
        b = x[Na:2 * Na] # b is an array of positive unbounded scalars
        q = np.array([qr(s, actions[a], b[a]) for a in range(0, Na)]) # s is an array
        rez = - np.dot(p, q) # np stands for numpy library
        return rez

qr and qc are regression trees, these are functions mapping arrays to scalars.

I have these constraints :

# p0 * qc(s,a0,b0) + ... + pn * qc(s,an,bn) < beta
def constraint(x):
    p = x[:Na]
    b = x[Na:2 * Na]
    q = np.array([qc(s, actions[a], b[a]) for a in range(0, Na)])
    rez = beta - np.dot(p, q) # beta is a scalar        
    return rez

# elements of p should sum to 1
def constraint_proba_sum_1(x):
    p = x[:Na]
    rez = 0
    for i in range(0, Na):
        rez += p[i]
    rez = 1 - rez
    return rez

How I minimize :

constraints = ({'type': 'ineq', 'fun': constraint},
                   {'type': 'eq', 'fun': constraint_proba_sum_1})

res = opt.minimize(fun=objective, x0=np.array([0.5, 0.5, 10, 10]), constraints=constraints,
                       bounds=[(0, 1), (0, 1), (0, None), (0, None)])

The problem is opt.minimize uses nan arrays as inputs sometimes during its minimization process "slsqp". Thus the qr tree raises errors.Why would it evaluate such arrays, in what circumstances ?

I do realize this issue is the same as this post Scipy optimizations methods select nan for input parameter but it is not resolved and it looks like function dependent.

EDIT : It appears that if I remove the constraint constraint_proba_sum_1(x), I dont have NaN value as input anymore.

EDIT 2 : I tryed another API, pyOPT with SLSQP optimization and I have the same issue.

回答1:

I don't have a full answer to this question, but I have experienced the same behaviour as you in my own optimization script and wanted to share my way of fixing it.

First of all, also in my case it helped to remove one of the constraints. The reason that this helps is because Scipy.minimize cannot handle an optimization where you start with voilated constraints. So if c == 0.0 and c = 0.3 at the start point, then it will, at some point, set nan values for the design variables when it's optimizing. Of course, just removing a constraint is generally not an option, so what helped in my case was to set stricter bounds on the design variables such that it is less likely to start with a point that is invalid (hence, has constraint violations). Note that this assumes that you run the optimization multiple times at different start points (which is true for my set-up). In your case, I think it is just a matter of choosing a start point x0 which has an unviolated (valid) constraint_proba_sum_1(x).

So in conclusion, one way of avoiding this issue is to make sure that the start point of your optimization is a valid point in terms of the constraints that you have provided.