Python 中的错误消息有区别

Error message in Python with differentiation

我正在使用通用看涨期权的蒙特卡洛方法计算这些导数。我对这个组合导数很感兴趣(关于 S 和 Sigma)。通过算法微分执行此操作,我得到一个错误,可以在页面末尾看到。可能的解决方案是什么?只是为了解释有关代码的一些事情,我将在下面的代码中附上用于计算“X”的公式:

from jax import jit, grad, vmap
import jax.numpy as jnp
from jax import random
Underlying_asset = jnp.linspace(1.1,1.4,100)
volatilities = jnp.linspace(0.5,0.6,100)
def second_derivative_mc(S,vol):
    N = 100
    j,T,q,r,k = 10000,1.,0,0,1.
    S0 = jnp.array([S]).T #(Nx1) vector underlying asset
    C = jnp.identity(N)*vol    #matrix of volatilities with 0 outside diagonal 
    e = jnp.array([jnp.full(j,1.)])#(1xj) vector of "1"
    Rand = np.random.RandomState()
    Rand.seed(10)
    U= Rand.normal(0,1,(N,j)) #Random number for Brownian Motion
    sigma2 = jnp.array([vol**2]).T #Vector of variance Nx1

    first = jnp.dot(sigma2,e) #First part equation
    second = jnp.dot(C,U)     #Second part equation

    X = -0.5*first+jnp.sqrt(T)*second

    St = jnp.exp(X)*S0

    P = jnp.maximum(St-k,0)
    payoff = jnp.average(P, axis=-1)*jnp.exp(-q*T)
    return payoff 


greek = vmap(grad(grad(second_derivative_mc, argnums=1), argnums=0)(Underlying_asset,volatilities)

这是错误信息:

> UnfilteredStackTrace                      Traceback (most recent call
> last) <ipython-input-78-0cc1da97ae0c> in <module>()
>      25 
> ---> 26 greek = vmap(grad(grad(second_derivative_mc, argnums=1), argnums=0))(Underlying_asset,volatilities)
> 
> 18 frames UnfilteredStackTrace: TypeError: Gradient only defined for
> scalar-output functions. Output had shape: (100,).

下面的堆栈跟踪不包括 JAX 内部框架。 上面是原来发生的异常,没有修改。


上述异常是以下异常的直接原因:

> TypeError                                 Traceback (most recent call
> last) /usr/local/lib/python3.7/dist-packages/jax/_src/api.py in
> _check_scalar(x)
>     894     if isinstance(aval, ShapedArray):
>     895       if aval.shape != ():
> --> 896         raise TypeError(msg(f"had shape: {aval.shape}"))
>     897     else:
>     898       raise TypeError(msg(f"had abstract value {aval}"))

> TypeError: Gradient only defined for scalar-output functions. Output had shape: (100,).

如错误消息所示,只能为 return 标量的函数计算梯度。你的函数 return 是一个向量:

print(len(second_derivative_mc(1.1, 0.5)))
# 100

对于向量值函数,您可以计算雅可比矩阵(类似于多维梯度)。这是你的想法吗?

from jax import jacobian
greek = vmap(jacobian(jacobian(second_derivative_mc, argnums=1), argnums=0))(Underlying_asset,volatilities)

另外,这不是你问的,但即使你解决了问题中的问题,上面的功能也可能无法正常工作。 Numpy RandomState 对象是有状态的,因此通常不能与 gradjitvmap 等 jax 转换一起正常工作,这些转换需要无副作用的代码(有关详细信息,请参阅 Stateful Computations In JAX). You might try using jax.random instead; see JAX: Random Numbers