def test_hvp(): fun = lambda a: np.sum(np.sin(a)) a = npr.randn(5) v = npr.randn(5) H = hessian(fun)(a) hvp = make_hvp(fun)(a)[0] check_equivalent(np.dot(H, v), hvp(v))
def __init__(self, lnpdf, D, glnpdf=None, lnpdf_is_vectorized=False): """ Black Box Variational Inference using stochastic gradients""" if lnpdf_is_vectorized: self.lnpdf = lnpdf if glnpdf is None: self.glnpdf = elementwise_grad(lnpdf) else: # create vectorized version self.glnpdf_single = grad(lnpdf) self.glnpdf = lambda z: np.array( [self.glnpdf_single(zi) for zi in np.atleast_2d(z)]) self.lnpdf = lambda z: np.array( [lnpdf(zi) for zi in np.atleast_2d(z)]) #if glnpdf is None: # self.glnpdf = grad(lnpdf) # hessian and elementwise_grad of glnpdf self.gglnpdf = elementwise_grad(self.glnpdf) self.hlnpdf = hessian(self.lnpdf) self.hvplnpdf = hessian_vector_product(self.lnpdf) # this function creates a generator of Hessian-vector product functions # - make hvp = hvp_maker(lnpdf)(z) # - now hvp(v) = hessian(lnpdf)(z) v self.hvplnpdf_maker = make_hvp(self.lnpdf)
minimize( rosen, x0, method='Newton-CG', jac=jacobian(rosen), hessp=hvp(rosen), options={'xtol': 1e-8, 'disp': True}) minimize( rosen, x0, method='Newton-CG', jac=jacobian(rosen2), hessp=hvp(rosen2), args=(a=5, b=7), options={'xtol': 1e-8, 'disp': True}) a1 = 12 b1 = 7 fn = make_hvp(rosen) fn = hvp(rosen) fn(x0) x2 = x0 * 2 fn(x0, x2) fn = hvp(rosen2) sig = signature(fn) str(sig) inspect.signature(rosen2) inspect.getfullargspec(rosen2) inspect.signature(fn) inspect.getfullargspec(fn) # the returned function has arguments (*args, tensor, **kwargs)
def hvp(): hvp = make_hvp(fun)(a)[0] s = hvp(u) return s
return callback callback = make_callback() spoptions = dict(maxiter=100) #spoptions = dict(ftol=1e-6, gtol=1e-6) #spoptions = dict(ftol=1e-4, gtol=1e-4) #spoptions = dict(ftol=1e-3, gtol=1e-3) res = minimize( objective, params_flat, method='L-BFGS-B', #spoptions = dict(inexact=False) #res = minimize(objective, params_flat, method='trust-krylov', jac=grad(objective), hessp=lambda x, v: make_hvp(objective)(x)[0](v), callback=callback, #tol=1e-6, options=spoptions) new_params = unflatten(res.x) print("opt success: ", res.success) print("opt message: ", res.message) #A_est_full, Q_est = new_params A_est_full, L_Q_est = new_params Q_est = np.dot(L_Q_est, L_Q_est.T) # try stochastic gradient (sample minibatch, scale objective and gradient, # no line-search), then fine-tune with a quasi-second order method for a # few iters #grad_AQ = grad(objective)