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
对象是有状态的,因此通常不能与 grad
、jit
、vmap
等 jax 转换一起正常工作,这些转换需要无副作用的代码(有关详细信息,请参阅 Stateful Computations In JAX). You might try using jax.random
instead; see JAX: Random Numbers。
我正在使用通用看涨期权的蒙特卡洛方法计算这些导数。我对这个组合导数很感兴趣(关于 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
对象是有状态的,因此通常不能与 grad
、jit
、vmap
等 jax 转换一起正常工作,这些转换需要无副作用的代码(有关详细信息,请参阅 Stateful Computations In JAX). You might try using jax.random
instead; see JAX: Random Numbers。